Repository: scimmyjs/scimmy
Pull request #69 (2025-02-10 15:56:51)

Add `schemas` in `SCIMMY.Messages.PatchOp` documentation and typing
Currently, SCIMMY enforces checks to ensure that schemas on `Resource.Patch` match the expected schema. Please see issue #68 for more details.

However, the typing and documentation don't seem to show this requirement.

This pull request includes changes to:
- the `PatchOp` class in `src/lib/messages/patchop.js` file
- the `Resource` classe in `src/lib/types/resource.js` file

## Details:

### `src/lib/messages/patchop.js`
- Add new typing : `@typedef {String} SCIMMY.Messages.PatchOp~id`
- Add schemas param for constructing new `PatchOp`:  `@param {SCIMMY.Messages.PatchOp~id[]} request.schemas`
### `src/lib/types/resource.js`
- Add schemas param when using `patch` function : `@param {SCIMMY.Messages.PatchOp~id[]} message.schemas`




Patch:
diff --git a/src/lib/messages/patchop.js b/src/lib/messages/patchop.js
index 0473973..5250cb4 100644
--- a/src/lib/messages/patchop.js
+++ b/src/lib/messages/patchop.js
@@ -50,12 +50,16 @@ const hasChanges = (original, current, keys) => (
  * *   Provides a method to atomically apply PatchOp operations to a resource instance, handling any exceptions that occur along the way.
  */
 export class PatchOp {
+    /** @private */
+    static #id = "urn:ietf:params:scim:api:messages:2.0:PatchOp";
+    
     /**
      * SCIM Patch Operation Message Schema ID
-     * @type {String}
-     * @private
+     * @type {"urn:ietf:params:scim:api:messages:2.0:PatchOp"}
      */
-    static #id = "urn:ietf:params:scim:api:messages:2.0:PatchOp";
+    static get id() {
+        return PatchOp.#id;
+    }
     
     /**
      * Whether the PatchOp message has been fully formed.
@@ -75,8 +79,10 @@ export class PatchOp {
     
     /**
      * Instantiate a new SCIM Patch Operation Message with relevant details
-     * @param {Object} request - contents of the patch operation request being performed
+     * @param {Object} [request] - contents of the patch operation request being performed
+     * @param {typeof SCIMMY.Messages.PatchOp.id[]} request.schemas - list exclusively containing SCIM PatchOp message schema ID
      * @param {SCIMMY.Messages.PatchOp~PatchOpOperation[]} request.Operations - list of SCIM-compliant patch operations to apply to the given resource
+     * @property {typeof SCIMMY.Messages.PatchOp.id[]} schemas - list exclusively containing the SCIM PatchOp message schema ID
      * @property {SCIMMY.Messages.PatchOp~PatchOpOperation[]} Operations - list of SCIM-compliant patch operations to apply to the given resource
      */
     constructor(request) {
diff --git a/src/lib/types/resource.js b/src/lib/types/resource.js
index 72ff0e5..3322117 100644
--- a/src/lib/types/resource.js
+++ b/src/lib/types/resource.js
@@ -356,6 +356,7 @@ export class Resource {
      * Emits patched resources for consumption with resource's ingress method.
      * @template [T=*] - external context object passed to ingress handler
      * @param {Object} message - the PatchOp message to apply to the received resource
+     * @param {typeof SCIMMY.Messages.PatchOp.id[]} message.schemas - list exclusively containing SCIM PatchOp message schema ID
      * @param {SCIMMY.Messages.PatchOp~PatchOpOperation[]} message.Operations - PatchOp operations to be applied
      * @param {T} [ctx] - any additional context information to pass to the ingress/egress handlers
      * @returns {S} the resource type instance after patching and consumption by ingress method


Test patch:
diff --git a/test/lib/messages/patchop.js b/test/lib/messages/patchop.js
index 41feb5d..f692f6a 100644
--- a/test/lib/messages/patchop.js
+++ b/test/lib/messages/patchop.js
@@ -144,6 +144,23 @@ describe("SCIMMY.Messages.PatchOp", () => {
         });
     });
     
+    describe(".id", () => {
+        it("should be defined", () => {
+            assert.ok("id" in PatchOp,
+                "Static member 'id' not defined");
+        });
+        
+        it("should be a string", () => {
+            assert.ok(typeof PatchOp.id === "string",
+                "Static member 'id' was not a string");
+        });
+        
+        it("should match SCIM Patch Operation Message schema ID", async () => {
+            assert.strictEqual(PatchOp.id, params.id,
+                "Static member 'id' did not match SCIM Patch Operation Message schema ID");
+        });
+    });
+    
     describe("#apply()", () => {
         it("should be implemented", () => {
             assert.ok(typeof (new PatchOp({...template, Operations: [{op: "add", value: {}}]})).apply === "function",