scim-patch
Advanced tools
Comparing version 0.6.7 to 0.7.0
@@ -1,1 +0,1 @@ | ||
{"processes":{"5aba240a-5730-4083-8453-5f874b45336c":{"parent":null,"children":[]}},"files":{"/home/runner/work/scim-patch/scim-patch/lib/src/scimPatch.js":["5aba240a-5730-4083-8453-5f874b45336c"],"/home/runner/work/scim-patch/scim-patch/lib/src/errors/scimErrors.js":["5aba240a-5730-4083-8453-5f874b45336c"]},"externalIds":{}} | ||
{"processes":{"035c88c3-c80b-4b1d-8c31-734cb6ac581c":{"parent":null,"children":[]}},"files":{"/home/runner/work/scim-patch/scim-patch/lib/src/scimPatch.js":["035c88c3-c80b-4b1d-8c31-734cb6ac581c"],"/home/runner/work/scim-patch/scim-patch/lib/src/errors/scimErrors.js":["035c88c3-c80b-4b1d-8c31-734cb6ac581c"]},"externalIds":{}} |
@@ -57,3 +57,3 @@ "use strict"; | ||
*/ | ||
function scimPatch(scimResource, patchOperations, options = { mutateDocument: true }) { | ||
function scimPatch(scimResource, patchOperations, options = { mutateDocument: true, treatMissingAsAdd: false }) { | ||
if (!options.mutateDocument) { | ||
@@ -73,3 +73,3 @@ // Deeply clone the object. | ||
case 'Replace': | ||
return applyAddOrReplaceOperation(patchedResource, patch); | ||
return applyAddOrReplaceOperation(patchedResource, patch, !!options.treatMissingAsAdd); | ||
default: | ||
@@ -155,3 +155,3 @@ throw new scimErrors_1.InvalidScimPatchRequest(`Operator is invalid for SCIM patch request. ${patch}`); | ||
} | ||
function applyAddOrReplaceOperation(scimResource, patch) { | ||
function applyAddOrReplaceOperation(scimResource, patch, treatMissingAsAdd) { | ||
var _a; | ||
@@ -184,2 +184,11 @@ // We manipulate the object directly without knowing his property, that's why we use any. | ||
} | ||
else if (treatMissingAsAdd && | ||
isReplaceOperation(patch.op) && | ||
"compValue" in parsedPath && | ||
parsedPath.compValue !== undefined && | ||
parsedPath.op === "eq") { | ||
// If the target location path specifies an attribute that does not | ||
// exist, the service provider SHALL treat the operation as an "add". | ||
return applyAddOrReplaceOperation(scimResource, Object.assign(Object.assign({}, patch), { op: "add" }), false); | ||
} | ||
throw new scimErrors_1.NoTarget(patch.path); | ||
@@ -186,0 +195,0 @@ } |
@@ -34,2 +34,3 @@ export declare type ScimPatchSchema = 'urn:ietf:params:scim:api:messages:2.0:PatchOp'; | ||
mutateDocument?: boolean; | ||
treatMissingAsAdd?: boolean; | ||
} | ||
@@ -36,0 +37,0 @@ export interface FilterWithQueryOptions { |
@@ -153,2 +153,16 @@ "use strict"; | ||
}); | ||
it('REPLACE: nested object do not exists can be treated as ADD', done => { | ||
var _a, _b; | ||
// empty the surName fields. | ||
scimUser.emails = []; | ||
const patch = { | ||
op: 'replace', | ||
path: 'addresses[type eq "work"].country', | ||
value: 'Denmark', | ||
}; | ||
const afterPatch = (0, scimPatch_1.scimPatch)(scimUser, [patch], { treatMissingAsAdd: true }); | ||
(0, chai_1.expect)((_a = afterPatch.addresses) === null || _a === void 0 ? void 0 : _a[0].country).to.be.eq("Denmark"); | ||
(0, chai_1.expect)((_b = afterPatch.addresses) === null || _b === void 0 ? void 0 : _b[0].type).to.be.eq("work"); | ||
return done(); | ||
}); | ||
it('REPLACE: primary email value', done => { | ||
@@ -155,0 +169,0 @@ const expected = 'toto@toto.com'; |
@@ -38,2 +38,3 @@ import { ScimResource, ScimMeta } from '../../src/types/types'; | ||
formatted: string; | ||
country?: string; | ||
}>; | ||
@@ -40,0 +41,0 @@ roles?: Array<{ |
{ | ||
"name": "scim-patch", | ||
"version": "0.6.7", | ||
"version": "0.7.0", | ||
"description": "SCIM Patch operation (rfc7644).", | ||
@@ -28,12 +28,12 @@ "main": "lib/src/scimPatch.js", | ||
"@types/benchmark": "2.1.2", | ||
"@types/chai": "4.3.3", | ||
"@types/mocha": "10.0.0", | ||
"@typescript-eslint/eslint-plugin": "5.38.1", | ||
"@typescript-eslint/parser": "5.38.1", | ||
"@types/chai": "4.3.4", | ||
"@types/mocha": "10.0.1", | ||
"@typescript-eslint/eslint-plugin": "5.54.0", | ||
"@typescript-eslint/parser": "5.54.0", | ||
"benchmark": "2.1.4", | ||
"chai": "4.3.6", | ||
"chai": "4.3.7", | ||
"coveralls": "3.1.1", | ||
"eslint": "8.24.0", | ||
"eslint": "8.35.0", | ||
"eslint-plugin-mocha": "10.1.0", | ||
"eslint-plugin-testing-library": "5.7.2", | ||
"eslint-plugin-testing-library": "5.10.2", | ||
"mocha": "^10.0.0", | ||
@@ -46,3 +46,3 @@ "nyc": "15.1.0", | ||
"fast-deep-equal": "3.1.3", | ||
"scim2-parse-filter": "0.2.7" | ||
"scim2-parse-filter": "0.2.8" | ||
}, | ||
@@ -49,0 +49,0 @@ "publishConfig": { |
@@ -98,2 +98,4 @@ # SCIM-PATCH | ||
#### Options | ||
##### Mutate Document | ||
By default `scimPatch()` is updating the scim resource you pass in the function. | ||
@@ -109,2 +111,18 @@ If you want to avoid this, you can add an option while calling `scimPatch()`, it will do a copy of the object and work | ||
##### Treat Missing as Add | ||
By default `scimPatch()` will throw an error if a replace operation targets an attribute that does not exist. | ||
If you prefer to treat these operations as additions, then set `treatMissingAsAdd: true` | ||
```typescript | ||
// scimUser has no addresses | ||
const patch = { | ||
op: 'replace', | ||
path: 'addresses[type eq "work"].country', | ||
value: 'Australia', | ||
}; | ||
const patchedUser = scimPatch(scimUser, patch, {treatMissingAsAdd: true}); | ||
// patchedUser.addresses[0].country === "Australia" | ||
``` | ||
# How can I contribute? | ||
@@ -111,0 +129,0 @@ See the [contributor's guide](CONTRIBUTING.md) for some helpful tips. |
@@ -102,3 +102,3 @@ import { | ||
export function scimPatch<T extends ScimResource>(scimResource: T, patchOperations: Array<ScimPatchOperation>, | ||
options: ScimPatchOptions = {mutateDocument: true}): T { | ||
options: ScimPatchOptions = {mutateDocument: true, treatMissingAsAdd: false}): T { | ||
if (!options.mutateDocument) { | ||
@@ -119,3 +119,3 @@ // Deeply clone the object. | ||
case 'Replace': | ||
return applyAddOrReplaceOperation(patchedResource, patch); | ||
return applyAddOrReplaceOperation(patchedResource, patch, !!options.treatMissingAsAdd); | ||
default: | ||
@@ -218,3 +218,3 @@ throw new InvalidScimPatchRequest(`Operator is invalid for SCIM patch request. ${patch}`); | ||
function applyAddOrReplaceOperation<T extends ScimResource>(scimResource: T, patch: ScimPatchAddReplaceOperation): T { | ||
function applyAddOrReplaceOperation<T extends ScimResource>(scimResource: T, patch: ScimPatchAddReplaceOperation, treatMissingAsAdd: boolean): T { | ||
// We manipulate the object directly without knowing his property, that's why we use any. | ||
@@ -248,2 +248,16 @@ let resource: Record<string, any> = scimResource; | ||
return scimResource; | ||
} else if ( | ||
treatMissingAsAdd && | ||
isReplaceOperation(patch.op) && | ||
"compValue" in parsedPath && | ||
parsedPath.compValue !== undefined && | ||
parsedPath.op === "eq" | ||
) { | ||
// If the target location path specifies an attribute that does not | ||
// exist, the service provider SHALL treat the operation as an "add". | ||
return applyAddOrReplaceOperation( | ||
scimResource, | ||
{ ...patch, op: "add" }, | ||
false | ||
); | ||
} | ||
@@ -250,0 +264,0 @@ throw new NoTarget(patch.path); |
@@ -51,2 +51,4 @@ export type ScimPatchSchema = 'urn:ietf:params:scim:api:messages:2.0:PatchOp'; | ||
mutateDocument?: boolean | ||
// if true, missing attributes to be replaced will be treated as an ADD. | ||
treatMissingAsAdd?: boolean | ||
} | ||
@@ -53,0 +55,0 @@ |
@@ -172,2 +172,16 @@ import { | ||
it('REPLACE: nested object do not exists can be treated as ADD', done => { | ||
// empty the surName fields. | ||
scimUser.emails = []; | ||
const patch: ScimPatchAddReplaceOperation = { | ||
op: 'replace', | ||
path: 'addresses[type eq "work"].country', | ||
value: 'Denmark', | ||
}; | ||
const afterPatch = scimPatch(scimUser, [patch], { treatMissingAsAdd: true }); | ||
expect(afterPatch.addresses?.[0].country).to.be.eq("Denmark"); | ||
expect(afterPatch.addresses?.[0].type).to.be.eq("work"); | ||
return done(); | ||
}); | ||
it('REPLACE: primary email value', done => { | ||
@@ -174,0 +188,0 @@ const expected = 'toto@toto.com'; |
@@ -40,2 +40,3 @@ import {ScimResource, ScimMeta} from '../../src/types/types'; | ||
formatted: string; | ||
country?: string; | ||
}>; | ||
@@ -42,0 +43,0 @@ roles?: Array<{ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
327947
53
3653
136
+ Addedscim2-parse-filter@0.2.8(transitive)
- Removedscim2-parse-filter@0.2.7(transitive)
Updatedscim2-parse-filter@0.2.8