{"_id":"@bpa-solutions/camljs","_rev":"1-4e2e0299f7236509559217830ed104b9","name":"@bpa-solutions/camljs","dist-tags":{"latest":"2.15.0"},"versions":{"2.14.3":{"name":"@bpa-solutions/camljs","version":"2.14.3","description":"Library for creating SharePoint CAML queries client-side. For JSOM, REST or SPServices.","main":"dist/camljs.js","types":"dist/camljs.d.ts","directories":{"lib":"lib","test":"tests"},"scripts":{"build":"tsc && node postbuild.js","test":"uvu tests","test:coverage":"c8 --include=lib npm test","clean":"del tests\\Tests.js && del tests\\Tests.bundle.js && del dist\\*.* /Q"},"repository":{"type":"git","url":"git+https://github.com/sbryois/camljs.git"},"keywords":["sharepoint","caml"],"author":{"name":"Andrei Markeev","url":"original"},"license":"MS-PL","bugs":{"url":"https://github.com/sbryois/camljs/issues"},"homepage":"https://github.com/sbryois/camljs#readme","devDependencies":{"@types/node":"^9.6.61","c8":"^7.11.0","typescript":"^4.6.3","uvu":"^0.5.3"},"dependencies":{"@xmldom/xmldom":"^0.7.5"},"gitHead":"3f6a883fa34b01438433d0379f103850f7ad27f1","_id":"@bpa-solutions/camljs@2.14.3","_nodeVersion":"14.17.0","_npmVersion":"8.5.2","dist":{"integrity":"sha512-58iHm3eCb8L9/f95tJibwWhVJ3K1vn6IA3tFEKFvg72d7jskEPl5ob94ev6z3FPkVgiWUA4/jjhMvFAzaZhhFg==","shasum":"d807c9c2c07335611140226b4f0cf0b1f63a1d8c","tarball":"https://registry.npmjs.org/@bpa-solutions/camljs/-/camljs-2.14.3.tgz","fileCount":5,"unpackedSize":106103,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOVXr9xt/fi2RbPBRoh8zYV5NxsqVMq80qyjABnpxCxQIgOEZdpKEJ8yrfWice94J//POGB6nVYIOOjfb4nFYIkFw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiVXxIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr4BA//WOrykecEcy5iO14WaWs9Qz4BBMENIGuxBn2rLZCwCqiEaxYC\r\nr+4gYhClBR5Urb1wDy3C92XBBaFZvHM4vWvmmCnvfBIQNjJcs6H3NEmMY/FT\r\nE4yB+MNzqM/HVmFyxMz8OghZzT0LU9b5Toe+aogfQuaPOdD3HXqtL1nrQ9oj\r\n7osxkwF33raVObxOItGXYCUahucX23rxTIhi2UtIoU+R+39eTk3SLT2WXOSs\r\n+yiWubnx4R7LPmn28mtecWncBFceKrnyrrGUvtKMELovOgInnDcwOwN4Xgsb\r\nlHr8mKWHIx2a+oUjOF0hTmgbLsbKWecxqnrXYx5KUiQC8oMSgtirVH4CIwX2\r\nEz0UNPjQUV5Ufob6TcUMgPm3lVVC77F/LNvX2BCYgBDabMe6QF76mGA+2s3P\r\ns9slNDW6DQaEEUFdSx1J5HP2GjivYB6WC2Zav7xOevu8pIJdAoU5gnRfsWd1\r\nxSZq53nhqH2qo84PqrDUb/4DvG44c/Wd5j/tSc/L9gU67Ied/BRaN685bfCW\r\nRNInPjA/yussGoX8o3RiVUFl7urNGXCChGxOkk2zRecR73j4VAJoVLTQTI5m\r\nfTBo9EI0OpDLkp/0DWMidAQuDAWZNiJOjTWz4E6+fVYOsed7l3NWvBkQSXQs\r\nNxCj6odfZAzEWOl9GSkZOzQn7vxr2Q/BLJ4=\r\n=dTb+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"leomaradan","email":"npm@leomaradan.com"},"maintainers":[{"name":"leomaradan","email":"npm@leomaradan.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/camljs_2.14.3_1649769543836_0.2927977522571794"},"_hasShrinkwrap":false},"2.15.0":{"name":"@bpa-solutions/camljs","version":"2.15.0","description":"Library for creating SharePoint CAML queries client-side. For JSOM, REST or SPServices.","main":"dist/camljs.js","types":"dist/camljs.d.ts","directories":{"lib":"lib","test":"tests"},"scripts":{"build":"tsc && browserify lib/camljs.js -x xmldom -s CamlBuilder -o dist/camljs.js && tsc --declaration lib/camljs.ts --emitDeclarationOnly --outDir dist/","test-common":"npm run build && tsc tests/Tests.ts --target es6 --module commonjs","test-html":"npm run test-common && browserify tests/Tests.js -x xmldom -s Tests -o tests/Tests.bundle.js","test":"npm run test-common && node tests/index.js","clean":"del tests\\Tests.js && del tests\\Tests.bundle.js && del dist\\*.* /Q"},"repository":{"type":"git","url":"git+https://github.com/sbryois/camljs.git"},"keywords":["sharepoint","caml"],"author":{"name":"Andrei Markeev","url":"original"},"license":"MS-PL","bugs":{"url":"https://github.com/sbryois/camljs/issues"},"homepage":"https://github.com/sbryois/camljs#readme","devDependencies":{"@types/node":"^9.6.6","browserify":"^16.2.3","diff":"^3.5.0","sinon":"^4.5.0","ts-unit":"^1.0.1","typescript":"^2.8.1"},"dependencies":{"xmldom":"^0.1.27"},"gitHead":"5f126de942af6e4ba37ea451064a70d0aee7d269","_id":"@bpa-solutions/camljs@2.15.0","_nodeVersion":"14.17.0","_npmVersion":"8.5.2","dist":{"integrity":"sha512-uuYDcPlXCc/DDnQ1SlpF+zyIDFyLANQJVB6fNPxYP0S6c7/gc/fue9FLdQBvm2GHzkcgwwJ/risW8MuxAeM31w==","shasum":"5ef990c813fd4ea051daa89c7d9159c75dcc16d9","tarball":"https://registry.npmjs.org/@bpa-solutions/camljs/-/camljs-2.15.0.tgz","fileCount":5,"unpackedSize":116517,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLajOsqLZeSZvJJhIARAatvDRtUvdGGgnvR1yIQzLbTAIgM8A5LENBiuDMdpVQ+58PCIFa0Z0N3GKR6oXllwUHAcw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiV7v1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoNJhAAlHupowN02KpctgSA/ht8MyPfoLWwNd0HO2rRPIw2nO+0YMoy\r\nLn309eZayySn8smlaP8P/7TwuLMRcmYdAfijWixLwQB354W14X49FC07Mr4D\r\nhUsnXsrlb91gZ9gpUWTfZuMEBxtwgKInDmcNcOK/e/DU+j3ACZl2e01jzq75\r\nRavXdc9a2S5CbuDMvo2VU+dHuPYLXBtmzkjov56Mui8uN2ksco/KC4eQBX1v\r\nW1VnnnFp99Cb7NUlhpuhj0J8aflI2CY0p9SsJS1TDRP3D7IKGC2S7uOClBV/\r\n3K7VoW+M2g7/JAHNBIL3kd37iJybtV6kcX5pSHmTvmgMHvjHfaqKamc64Dx/\r\nB0GhM0YADLd4AdhkevkcPMuZkLK6e5yW8hPi8szLM/W5scf3OxQmmpphFGBs\r\ny+6+Pf0BQcHL+tsHIDTei+e8Z53+zs3QwBgqeaV15VRZIVrTxqI1AB3bEZOJ\r\nCuNU6swlhdqdBQ7DFuq+wdHahDY24n4Pj+oC/dAK/4ezjBJkXgU5bsrG4O28\r\nofHgkCCYl56nvjQAoXJHSwUnY56vx92NL77Kwkf9M5djmi6zNfwVe0mz7hpj\r\nfo1rodxxOqoaCAjNPt3Cj6bnToCuUEZG4v6PzT5qQorCmvZTuGSEmz97WsSy\r\nne/zZvGalEuuY0uVyqyK8nm7/E4VTfiUyjM=\r\n=7cml\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"leomaradan","email":"npm@leomaradan.com"},"maintainers":[{"name":"leomaradan","email":"npm@leomaradan.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/camljs_2.15.0_1649916917123_0.7476932141218362"},"_hasShrinkwrap":false}},"time":{"created":"2022-04-12T13:19:03.755Z","2.14.3":"2022-04-12T13:19:04.226Z","modified":"2022-04-14T06:15:17.381Z","2.15.0":"2022-04-14T06:15:17.287Z"},"maintainers":[{"name":"leomaradan","email":"npm@leomaradan.com"}],"description":"Library for creating SharePoint CAML queries client-side. For JSOM, REST or SPServices.","homepage":"https://github.com/sbryois/camljs#readme","keywords":["sharepoint","caml"],"repository":{"type":"git","url":"git+https://github.com/sbryois/camljs.git"},"author":{"name":"Andrei Markeev","url":"original"},"bugs":{"url":"https://github.com/sbryois/camljs/issues"},"license":"MS-PL","readme":"## Installation\n\nNuget:\n```\nPM> Install-Package CamlJs\n```\n\nNuget TypeScript definitions:\n```\nPM> Install-Package camljs.TypeScript.DefinitelyTyped\n```\n\nNpm:\n```\nnpm install camljs\n```\n\nNpm TypeScript definitions:\n```\nnpm install @types/camljs\n```\n\nAlso check out [CamlJs Console](https://github.com/andrei-markeev/camljs-console) - Chrome extension for testing queries with live preview against real lists.\n\n## Usage\n\nIn browser:\n\n```html\n<script type=\"text/javascript\" src=\"//unpkg.com/camljs\"></script>\n<script>\n    alert(new CamlBuilder().View().ToString());\n</script>\n```\n\nIn node:\n\n```js\nvar CamlBuilder = require('camljs');\nconsole.log(new CamlBuilder().View().ToString());\n```\n\nES2015 modules:\n```js\nimport * as CamlBuilder from 'camljs';\nconsole.log(new CamlBuilder().View().ToString());\n```\n\n## Basics\n\nLet's assume we need to fetch all Google-related emails from a SharePoint list where your company stores archived project emails. To generate the corresponding query using CamlJs, you could use following javascript code:\n\n```js\nvar camlBuilder = new CamlBuilder();\n\nvar caml = camlBuilder.Where()\n    .TextField(\"Email\").EqualTo(\"support@google.com\")\n    .Or()\n    .TextField(\"Email\").EqualTo(\"plus@google.com\")\n    .Or()\n    .TextField(\"Title\").BeginsWith(\"[Google]\")\n    .Or()\n    .TextField(\"Content\").Contains(\"Google\")\n    .ToString();\n```\n\nThis will generate the following CAML code:\n\n```xml\n<Where>\n  <Or>\n    <Eq>\n      <FieldRef Name=\"Email\" />\n      <Value Type=\"Text\">support@google.com</Value>\n    </Eq>\n    <Or>\n      <Eq>\n        <FieldRef Name=\"Email\" />\n        <Value Type=\"Text\">plus@google.com</Value>\n      </Eq>\n      <Or>\n        <BeginsWith>\n          <FieldRef Name=\"Title\" />\n          <Value Type=\"Text\">[Google]</Value>\n        </BeginsWith>\n        <Contains>\n          <FieldRef Name=\"Content\" />\n          <Value Type=\"Text\">Google</Value>\n        </Contains>\n      </Or>\n    </Or>\n  </Or>\n</Where>\n```\n\nIt is also possible to generate SP.CamlQuery object, just change `.ToString()` to `.ToCamlQuery()`.\n\nAnother example:\n```js\nvar caml = camlBuilder.Where()\n    .LookupField(\"Category\").Id().In([2, 3, 10])\n    .And()\n    .DateField(\"ExpirationDate\").LessThanOrEqualTo(CamlBuilder.CamlValues.Now)\n    .OrderByDesc(\"ExpirationDate\")\n    .ToString()\n```\nAs you see, the code is pretty clean and readable. The resulting CAML is much more awkward, especially if you imagine it in javascript strings dress, without indentation and highlighting...\n```xml\n<Where>\n  <And>\n    <In>\n      <FieldRef Name=\"Category\" LookupId=\"TRUE\" />\n      <Values>\n        <Value Type=\"Integer\">2</Value>\n        <Value Type=\"Integer\">3</Value>\n        <Value Type=\"Integer\">10</Value>\n      </Values>\n    </In>\n    <Leq>\n      <FieldRef Name=\"ExpirationDate\" />\n      <Value Type=\"Date\">\n        <Now />\n      </Value>\n    </Leq>\n  </And>\n</Where><OrderBy>\n  <FieldRef Name=\"ExpirationDate\" Ascending=\"FALSE\" />\n</OrderBy>\n```\n\n## Dynamic queries\n\nIt's very easy to create dynamic queries with CamlJs by leveraging the `CamlBuilder.Expression()` construction.\nIt's like a standalone part of query that can be later used in the final `new CamlBuilder.Where()` or `new CamlBuilder.View()`.\n\n```js\nvar categories = [\"Category 1\", \"Category 2\", \"Category 3\"];\n\nvar categoriesExpressions = categories.map(c => CamlBuilder.Expression().TextField(\"Category\").EqualTo(c));\n\nvar caml = new CamlBuilder().Where()\n    .Any(categoriesExpressions),\n    .ToString();\n```\nResult:\n```xml\n<Where>\n    <Or>\n        <Eq>\n            <FieldRef Name=\"Category\" />\n            <Value Type=\"Text\">Category 1</Value>\n        </Eq>\n        <Or>\n            <Eq>\n                <FieldRef Name=\"Category\" />\n                <Value Type=\"Text\">Category 2</Value>\n            </Eq>\n            <Eq>\n                <FieldRef Name=\"Category\" />\n                <Value Type=\"Text\">Category 3</Value>\n            </Eq>\n        </Or>\n    </Or>\n</Where>\n```\n\nWhile `.Any()` generates `<Or>` clauses, `.All()` will generate `<And>`.\n\n## Elements support\n\nCamlJs supports all Query elements that are [described on MSDN](http://msdn.microsoft.com/en-us/library/ms467521.aspx).\n\nFor example, seldom used Membership element:\n```js\nvar caml = camlBuilder.Where()\n    .UserField(\"AssignedTo\").EqualToCurrentUser()\n    .Or()\n    .UserField(\"AssignedTo\").IsInCurrentUserGroups()\n    .GroupBy(\"ProductTitle\")\n    .OrderBy(\"Priority\").ThenBy(\"Title\")\n    .ToString();\n```\nThis code will generate following CAML:\n\n```xml\n<Where>\n  <Or>\n    <Eq>\n      <FieldRef Name=\"AssignedTo\" />\n      <Value Type=\"Integer\">\n        <UserID />\n      </Value>\n    </Eq>\n    <Membership Type=\"CurrentUserGroups\">\n      <FieldRef Name=\"AssignedTo\" />\n    </Membership>\n  </Or>\n</Where>\n<GroupBy>\n  <FieldRef Name=\"ProductTitle\" />\n</GroupBy>\n<OrderBy>\n  <FieldRef Name=\"Priority\" />\n  <FieldRef Name=\"Title\" />\n</OrderBy>\n```\n\nYou can also create the upper-level View element as supported by SP.CamlQuery object.\nScope attribute, ViewFields, Joins and ProjectedFields are supported in this case.\n\nJoining lists via CamlJs is very easy. Here's the example:\n\n```js\nvar query = new CamlBuilder()\n    .View([\"Title\",\"Country\",\"Population\"])\n    .LeftJoin(\"Country\",\"Country\").Select(\"People\",\"Population\")\n    .Query()\n    .Where()\n    .NumberField(\"Population\").LessThan(10)\n    .ToString();\n```\nThe resulting generated CAML query will be the following:\n```xml\n<View>\n    <ViewFields>\n        <FieldRef Name=\"Title\" />\n        <FieldRef Name=\"Country\" />\n        <FieldRef Name=\"Population\" />\n    </ViewFields>\n    <Joins>\n        <Join Type=\"LEFT\" ListAlias=\"Country\">\n            <Eq>\n                <FieldRef Name=\"Country\" RefType=\"ID\" />\n                <FieldRef Name=\"ID\" List=\"Country\" />\n            </Eq>\n        </Join>\n    </Joins>\n    <ProjectedFields>\n        <Field ShowField=\"People\" Type=\"Lookup\" Name=\"Population\" List=\"Country\" />\n    </ProjectedFields>\n    <Query>\n        <Where>\n            <Lt>\n                <FieldRef Name=\"Population\" />\n                <Value Type=\"Number\">10</Value>\n            </Lt>\n        </Where>\n    </Query>\n</View>\n```\n\n## Modify existing queries\n\nOften you need to modify existing query (e.g. that comes from an existing list view), rather than generate a completely new one.\nThis use case is also supported by CamlJs:\n\n- `CamlBuilder.FromXml(xml)` method will create a CamlBuilder object from existing CAML string\n- `ReplaceWhere` method then allows to replace <Where> clause with one generated by CamlJs\n- `ModifyWhere().AppendAnd()` will add new conditions to existing query using \"And\" operator\n- `ModifyWhere().AppendOr()` will add new conditions to existing query using \"Or\" operator\n\nExample:\n\n```js\nvar xml = new CamlBuilder().View().Query().Where()\n    .UserField(\"Author\").EqualToCurrentUser()\n    .ToString();\n\nvar query = CamlBuilder.FromXml(xml)\n    .ModifyWhere().AppendAnd()\n    .LookupField(\"Country\").ValueAsText().BeginsWith(\"G\");\n```\n\nResult:\n```xml\n<View>\n  <Query>\n    <Where>\n      <And>\n        <Eq>\n          <FieldRef Name=\"Author\" LookupId=\"TRUE\" />\n          <Value Type=\"Integer\">\n            <UserID />\n          </Value>\n        </Eq>\n        <BeginsWith>\n          <FieldRef Name=\"Country\" />\n          <Value Type=\"Text\">G</Value>\n        </BeginsWith>\n      </And>\n    </Where>\n  </Query>\n</View>\n```\n","readmeFilename":"README.md"}