From 9b22a5520ec7beffb8fe8d91cf1f6cb79f1638ba Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Wed, 16 Jul 2025 15:02:10 +0200 Subject: [PATCH 01/14] linting --- package.json | 5 +- src/handler/_patch-operations.ts | 306 +++++++++++++++ src/handler/patch-document.ts | 53 +++ src/routes.ts | 4 + src/types.ts | 19 +- test/index.test.ts | 135 +++++++ yarn.lock | 651 ++++--------------------------- 7 files changed, 598 insertions(+), 575 deletions(-) create mode 100644 src/handler/_patch-operations.ts create mode 100644 src/handler/patch-document.ts diff --git a/package.json b/package.json index 7d91aa7..1b73932 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "raw-body": "2.4.1" }, "devDependencies": { - "@azure/cosmos": "3.10.2", + "@azure/cosmos": "3.17.3", "@types/jest": "^29.5.1", "@types/lru-cache": "5.1.0", "@types/node": "^16.0.0", @@ -104,5 +104,6 @@ }, "engines": { "node": ">=14.17" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/src/handler/_patch-operations.ts b/src/handler/_patch-operations.ts new file mode 100644 index 0000000..225dcea --- /dev/null +++ b/src/handler/_patch-operations.ts @@ -0,0 +1,306 @@ +import Collection from "../account/collection"; +import { parsePartitionKey } from "../utils/get-partition-from-header"; +import { JSONObject, PatchOperation, PatchOperationInput } from "../types"; + +export interface PatchOperationResult { + statusCode: number; + body?: JSONObject; +} + +function getValueAtPath( + obj: any, + pathSegments: string[], + createPath = false +): any { + let current = obj; + + for (let i = 0; i < pathSegments.length; i += 1) { + const segment = pathSegments[i]; + + if (Array.isArray(current)) { + const index = parseInt(segment, 10); + if (Number.isNaN(index) || index < 0 || index >= current.length) { + if (createPath) { + throw new Error( + "Add Operation can only create a child object of an existing node (array or object) and can't create path recursively." + ); + } + return undefined; + } + current = current[index]; + } else if (typeof current === "object" && current !== null) { + if (createPath && !(segment in current)) { + if (i === pathSegments.length - 1) { + // This is the last segment, we don't need to create it here + return current; + } + throw new Error( + "Add Operation can only create a child object of an existing node (array or object) and can't create path recursively." + ); + } + current = current[segment]; + } else { + if (createPath) { + throw new Error( + "Add Operation can only create a child object of an existing node (array or object) and can't create path recursively." + ); + } + return undefined; + } + + if (current === undefined && !createPath) { + return undefined; + } + } + + return current; +} + +function removePatchOperation( + document: JSONObject, + pathSegments: string[] +): JSONObject { + if (pathSegments.length === 0) { + throw new Error("Cannot remove root document."); + } + + const result = JSON.parse(JSON.stringify(document)); + const parentPath = pathSegments.slice(0, -1); + const key = pathSegments[pathSegments.length - 1]; + + const parent = getValueAtPath(result, parentPath); + + if (Array.isArray(parent)) { + const index = parseInt(key, 10); + if (Number.isNaN(index) || index < 0 || index >= parent.length) { + throw new Error("Index to operate on is out of array bounds."); + } + parent.splice(index, 1); + } else if (typeof parent === "object" && parent !== null) { + if (!(key in parent)) { + throw new Error("Node to be removed is absent."); + } + delete parent[key]; + } else { + throw new Error("Node to be removed is absent."); + } + + return result; +} + +function replacePatchOperation( + document: JSONObject, + pathSegments: string[], + value: any +): JSONObject { + if (pathSegments.length === 0) { + throw new Error("Cannot replace root document."); + } + + const result = JSON.parse(JSON.stringify(document)); + const parentPath = pathSegments.slice(0, -1); + const key = pathSegments[pathSegments.length - 1]; + + const parent = getValueAtPath(result, parentPath); + + if (Array.isArray(parent)) { + const index = parseInt(key, 10); + if (Number.isNaN(index) || index < 0 || index >= parent.length) { + throw new Error("Index to operate on is out of array bounds."); + } + parent[index] = value; + } else if (typeof parent === "object" && parent !== null) { + if (!(key in parent)) { + throw new Error("Node to be replaced is absent."); + } + parent[key] = value; + } else { + throw new Error("Node to be replaced is absent."); + } + + return result; +} + +function setPatchOperation( + document: JSONObject, + pathSegments: string[], + value: any +): JSONObject { + if (pathSegments.length === 0) { + throw new Error("Cannot set root document."); + } + + const result = JSON.parse(JSON.stringify(document)); + const parentPath = pathSegments.slice(0, -1); + const key = pathSegments[pathSegments.length - 1]; + + const parent = getValueAtPath(result, parentPath, true); + + if (Array.isArray(parent)) { + const index = parseInt(key, 10); + if (Number.isNaN(index) || index < 0) { + throw new Error("Invalid array index."); + } + if (index >= parent.length) { + throw new Error("Index to operate on is out of array bounds."); + } + parent[index] = value; + } else if (typeof parent === "object" && parent !== null) { + parent[key] = value; + } else { + throw new Error( + "Set Operation can only create a child object of an existing node (array or object)." + ); + } + + return result; +} + +function applySinglePatchOperation( + document: JSONObject, + operation: PatchOperation +): JSONObject { + const { op, path, value } = operation; + + if (!path || typeof path !== "string" || !path.startsWith("/")) { + throw new Error("Invalid path in patch operation."); + } + + // Don't allow patching system properties + if (path.startsWith("/_")) { + const systemProperty = path.split("/")[1]; + throw new Error(`Can't patch system property ${systemProperty}.`); + } + + const pathSegments = path + .slice(1) + .split("/") + .map(segment => + // Unescape JSON Pointer characters (RFC 6901, which is the standard used by + // JSON Patch operations) + segment.replace(/~1/g, "/").replace(/~0/g, "~") + ); + + switch (op) { + case "remove": + return removePatchOperation(document, pathSegments); + case "replace": + return replacePatchOperation(document, pathSegments, value); + case "set": + return setPatchOperation(document, pathSegments, value); + default: + throw new Error(`Unsupported patch operation: ${op}`); + } +} + +function applyPatchOperations( + document: JSONObject, + operations: PatchOperation[] +): JSONObject { + if (operations.length > 10) { + throw new Error("The number of patch operations can't exceed 10."); + } + + let result = document; + for (let i = 0; i < operations.length; i += 1) { + const operation = operations[i]; + try { + result = applySinglePatchOperation(result, operation); + } catch (error) { + throw new Error(`For Operation(${i}): ${error.message}`); + } + } + + return result; +} + +export function patchOperation( + collection: Collection, + input: PatchOperationInput +): PatchOperationResult { + const partitionKey = parsePartitionKey(input.partitionKey, input.id); + const data = collection.document(input.id, partitionKey).read(); + if (!data) { + return { + statusCode: 404, + body: {} + }; + } + + if (input.ifMatch && input.ifMatch !== data._etag) { + return { + statusCode: 412, + body: { + code: "PreconditionFailed", + message: + "Operation cannot be performed because one of the specified precondition is not met." + } + }; + } + + // Check conditional patch + if (input.condition) { + try { + const query = collection.documents.query({ query: input.condition }, {}); + const results = query.result.filter((doc: any) => doc.id === input.id); + if (results.length === 0) { + return { + statusCode: 412, + body: { + code: "PreconditionFailed", + message: + "Condition specified in the patch request is not satisfied." + } + }; + } + } catch (err) { + return { + statusCode: 400, + body: { + code: "BadRequest", + message: "Invalid condition in patch request." + } + }; + } + } + + let patchedData: JSONObject; + try { + patchedData = applyPatchOperations({ ...data }, input.operations); + } catch (error) { + return { + statusCode: 400, + body: { + code: "BadRequest", + message: error.message + } + }; + } + + // Use the replace operation to update the document + try { + const body = collection.documents.replace(patchedData, data); + return { statusCode: 200, body }; + } catch (error) { + if (error.badRequest) { + return { + statusCode: 400, + body: { + code: "BadRequest", + message: error.message + } + }; + } + if (error.conflict) { + return { + statusCode: 409, + body: { + code: "Conflict", + message: error.message + } + }; + } + + throw error; + } +} diff --git a/src/handler/patch-document.ts b/src/handler/patch-document.ts new file mode 100644 index 0000000..e0907df --- /dev/null +++ b/src/handler/patch-document.ts @@ -0,0 +1,53 @@ +import * as http from "http"; +import { patchOperation } from "./_patch-operations"; +import Account from "../account"; +import json from "../json"; +import getPartitionFromHeader from "../utils/get-partition-from-header"; + +export default async ( + account: Account, + req: http.IncomingMessage, + res: http.ServerResponse, + { + dbId, + collId, + docId + }: { + dbId: string; + collId: string; + docId: string; + } +) => { + const body = await json(req); + const collection = account.database(dbId).collection(collId); + + // Handle both formats: Azure SDK sends operations directly as array, + // while our REST API expects { operations: [...] } + let operations: any[]; + if (Array.isArray(body)) { + // Azure SDK format: operations sent directly as array + operations = body; + } else if (body.operations && Array.isArray(body.operations)) { + // REST API format: operations wrapped in object + operations = body.operations; + } else { + res.statusCode = 400; + return { + code: "BadRequest", + message: "Invalid patch request: check syntax of patch specification." + }; + } + + const partitionKey = getPartitionFromHeader(req); + + const result = patchOperation(collection, { + id: docId, + partitionKey, + ifMatch: req.headers["if-match"], + operations, + condition: Array.isArray(body) ? undefined : body.condition + }); + + res.statusCode = result.statusCode; + return result.body; +}; diff --git a/src/routes.ts b/src/routes.ts index ba5c2ee..6c4d14c 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -7,6 +7,7 @@ import deleteCollection from "./handler/delete-collection"; import deleteDocument from "./handler/delete-document"; import deleteDatabase from "./handler/delete-database"; import deleteUserDefinedFunction from "./handler/delete-user-defined-function"; +import patchDocument from "./handler/patch-document"; import queryCollections from "./handler/query-collections"; import queryDatabases from "./handler/query-databases"; import queryDocuments from "./handler/query-documents"; @@ -47,6 +48,9 @@ export default router({ "/dbs": readDatabases, "/": readMeta }, + PATCH: { + "/dbs/:dbId/colls/:collId/docs/:docId": patchDocument + }, POST: { "/dbs/:dbId/colls/:collId/docs": createDocument, "/dbs/:dbId/colls/:collId/udfs": createUserDefinedFunction, diff --git a/src/types.ts b/src/types.ts index 7277efa..ae15939 100644 --- a/src/types.ts +++ b/src/types.ts @@ -22,7 +22,8 @@ export const BulkOperationType = { Upsert: "Upsert", Read: "Read", Delete: "Delete", - Replace: "Replace" + Replace: "Replace", + Patch: "Patch" }; export interface CreateOperationInput { @@ -59,3 +60,19 @@ export interface ReplaceOperationInput { operationType?: typeof BulkOperationType.Replace; resourceBody: JSONObject; } + +export interface PatchOperation { + op: "remove" | "replace" | "set"; + path: string; + value?: any; +} + +export interface PatchOperationInput { + partitionKey?: string; + ifMatch?: string; + ifNoneMatch?: string; + operationType?: typeof BulkOperationType.Patch; + id: string; + operations: PatchOperation[]; + condition?: string; +} diff --git a/test/index.test.ts b/test/index.test.ts index 4e52f9d..f125844 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -379,6 +379,134 @@ const bulkApiDoNotContinueOnError = withTestEnv(async client => { assert.equal(response[4].statusCode, 424); }); +const patchDocumentSet = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-1", + name: "Test Document", + value: 100, + nested: { + property: "original" + } + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-1"); + + const patchOperations = [ + { op: "set", path: "/value", value: 200 }, + { op: "set", path: "/nested/property", value: "updated" }, + { op: "set", path: "/newProperty", value: "created" } + ]; + + await item.patch(patchOperations); + const { resource: result } = await item.read(); + + assert.strictEqual(result.value, 200); + assert.strictEqual(result.nested.property, "updated"); + assert.strictEqual(result.newProperty, "created"); + assert.strictEqual(result.name, "Test Document"); +}); + +const patchDocumentReplace = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-2", + name: "Test Document", + value: 100, + status: "active" + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-2"); + + const patchOperations = [ + { op: "replace", path: "/value", value: 300 }, + { op: "replace", path: "/status", value: "inactive" } + ]; + + await item.patch(patchOperations); + const { resource: result } = await item.read(); + + assert.strictEqual(result.value, 300); + assert.strictEqual(result.status, "inactive"); + assert.strictEqual(result.name, "Test Document"); +}); + +const patchDocumentRemove = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-3", + name: "Test Document", + removeThis: "should be removed", + keepThis: "should stay", + array: [1, 2, 3] + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-3"); + + const patchOperations = [ + { op: "remove", path: "/removeThis" }, + { op: "remove", path: "/array/1" } + ]; + + await item.patch(patchOperations); + const { resource: result } = await item.read(); + + assert.strictEqual(result.removeThis, undefined); + assert.strictEqual(result.keepThis, "should stay"); + assert.deepStrictEqual(result.array, [1, 3]); +}); + +const patchDocumentWithCondition = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-4", + name: "Test Document", + status: "active", + priority: "high", + value: 100 + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-4"); + + // Patch with condition - should succeed because status is "active" + const patchOperations = [ + { op: "set", path: "/value", value: 500 }, + { op: "set", path: "/priority", value: "critical" } + ]; + + const patchOptions = { + condition: "FROM c WHERE c.status = 'active'" + }; + + await item.patch(patchOperations, patchOptions); + const { resource: result } = await item.read(); + + assert.strictEqual(result.value, 500); + assert.strictEqual(result.priority, "critical"); + assert.strictEqual(result.status, "active"); + assert.strictEqual(result.name, "Test Document"); +}); + describe("CosmosDB", () => { it("read document 404", readDocument404); it("upsert document", upsertDocument); @@ -404,4 +532,11 @@ describe("CosmosDB", () => { ); it("bulkApi", bulkApi); it("bulkApiDoNotContinueOnError", bulkApiDoNotContinueOnError); + it("should patch a document with set operation", patchDocumentSet); + it("should patch a document with replace operation", patchDocumentReplace); + it("should patch a document with remove operation", patchDocumentRemove); + it( + "should patch a document with condition that succeeds", + patchDocumentWithCondition + ); }); diff --git a/yarn.lock b/yarn.lock index 3035238..d297646 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,7 +17,14 @@ dependencies: tslib "^2.0.0" -"@azure/core-auth@^1.2.0", "@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0": +"@azure/abort-controller@^2.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-2.1.2.tgz#42fe0ccab23841d9905812c58f1082d27784566d" + integrity sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA== + dependencies: + tslib "^2.6.2" + +"@azure/core-auth@^1.3.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.4.0.tgz#6fa9661c1705857820dbc216df5ba5665ac36a9e" integrity sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ== @@ -25,41 +32,27 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-client@^1.0.0": - version "1.7.2" - resolved "https://registry.yarnpkg.com/@azure/core-client/-/core-client-1.7.2.tgz#e1e0670c9a5086dd62fd0080d2fd8b426babad9e" - integrity sha512-ye5554gnVnXdfZ64hptUtETgacXoRWxYv1JF5MctoAzTSH5dXhDPZd9gOjDPyWMcLIk58pnP5+p5vGX6PYn1ag== +"@azure/core-auth@^1.8.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.10.0.tgz#68dba7036080e1d9d5699c4e48214ab796fa73ad" + integrity sha512-88Djs5vBvGbHQHf5ZZcaoNHo6Y8BKZkt3cw2iuJIQzLEgH4Ox6Tm4hjFhbqOxyYsgIG/eJbFEHpxRIfEEWv5Ow== dependencies: - "@azure/abort-controller" "^1.0.0" - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.9.1" - "@azure/core-tracing" "^1.0.0" - "@azure/core-util" "^1.0.0" - "@azure/logger" "^1.0.0" - tslib "^2.2.0" + "@azure/abort-controller" "^2.0.0" + "@azure/core-util" "^1.11.0" + tslib "^2.6.2" -"@azure/core-rest-pipeline@^1.1.0", "@azure/core-rest-pipeline@^1.9.1": - version "1.10.3" - resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.3.tgz#7603afd71ff3c290351dbeeab2c814832e47b8ef" - integrity sha512-AMQb0ttiGJ0MIV/r+4TVra6U4+90mPeOveehFnrqKlo7dknPJYdJ61wOzYJXJjDxF8LcCtSogfRelkq+fCGFTw== +"@azure/core-rest-pipeline@^1.2.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.0.tgz#76e44a75093a2f477fc54b84f46049dc2ce65800" + integrity sha512-OKHmb3/Kpm06HypvB3g6Q3zJuvyXcpxDpCS1PnU8OV6AJgSFaee/covXBcPbWc6XDDxtEPlbi3EMQ6nUiPaQtw== dependencies: - "@azure/abort-controller" "^1.0.0" - "@azure/core-auth" "^1.4.0" + "@azure/abort-controller" "^2.0.0" + "@azure/core-auth" "^1.8.0" "@azure/core-tracing" "^1.0.1" - "@azure/core-util" "^1.3.0" + "@azure/core-util" "^1.11.0" "@azure/logger" "^1.0.0" - form-data "^4.0.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - tslib "^2.2.0" - -"@azure/core-tracing@1.0.0-preview.12": - version "1.0.0-preview.12" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.12.tgz#f53ff452c0742ad981c244f97d93d37ca2b5e139" - integrity sha512-nvo2Wc4EKZGN6eFu9n3U7OXmASmL8VxoPIH7xaD6OlQqi44bouF0YIi9ID5rEsKLiAU59IYx6M297nqWVMWPDg== - dependencies: - "@opentelemetry/api" "^1.0.0" - tslib "^2.2.0" + "@typespec/ts-http-runtime" "^0.3.0" + tslib "^2.6.2" "@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" @@ -68,56 +61,34 @@ dependencies: tslib "^2.2.0" -"@azure/core-util@^1.0.0", "@azure/core-util@^1.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.3.2.tgz#3f8cfda1e87fac0ce84f8c1a42fcd6d2a986632d" - integrity sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ== +"@azure/core-util@^1.11.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.13.0.tgz#fc2834fc51e1e2bb74b70c284b40f824d867422a" + integrity sha512-o0psW8QWQ58fq3i24Q1K2XfS/jYTxr7O1HRcyUE9bV9NttLU+kYOH82Ixj8DGlMTOWgxm1Sss2QAfKK5UkSPxw== dependencies: - "@azure/abort-controller" "^1.0.0" - tslib "^2.2.0" + "@azure/abort-controller" "^2.0.0" + "@typespec/ts-http-runtime" "^0.3.0" + tslib "^2.6.2" -"@azure/cosmos@3.10.2": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@azure/cosmos/-/cosmos-3.10.2.tgz#8ffdc6bd8f619efbcf19a9e13dcf8f27d53bbf56" - integrity sha512-caWzLGSC9gDmLso1KAa6Scb+uv+ZsZi2xEuyba382/VggHKnNry+pKJIckJ16Cge7fnIdXVtITgf5U1ThFwfIQ== +"@azure/cosmos@3.17.3": + version "3.17.3" + resolved "https://registry.yarnpkg.com/@azure/cosmos/-/cosmos-3.17.3.tgz#380398496af8ef3473ae0a9ad8cdbab32d91eb08" + integrity sha512-wBglkQ6Irjv5Vo2iw8fd6eYj60WYRSSg4/0DBkeOP6BwQ4RA91znsOHd6s3qG6UAbNgYuzC9Nnq07vlFFZkHEw== dependencies: - "@azure/core-auth" "^1.2.0" - "@azure/identity" "^1.1.0" + "@azure/abort-controller" "^1.0.0" + "@azure/core-auth" "^1.3.0" + "@azure/core-rest-pipeline" "^1.2.0" + "@azure/core-tracing" "^1.0.0" debug "^4.1.1" - fast-json-stable-stringify "^2.0.0" + fast-json-stable-stringify "^2.1.0" jsbi "^3.1.3" - node-abort-controller "^1.0.4" - node-fetch "^2.6.0" + node-abort-controller "^3.0.0" priorityqueuejs "^1.0.0" semaphore "^1.0.5" - tslib "^2.0.0" + tslib "^2.2.0" universal-user-agent "^6.0.0" uuid "^8.3.0" -"@azure/identity@^1.1.0": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-1.5.2.tgz#09da6aa8e14f2dace3dd8f66de7d7d56bfee5db7" - integrity sha512-vqyeRbd2i0h9F4mqW5JbkP1xfabqKQ21l/81osKhpOQ2LtwaJW6nw4+0PsVYnxcbPHFCIZt6EWAk74a3OGYZJA== - dependencies: - "@azure/core-auth" "^1.3.0" - "@azure/core-client" "^1.0.0" - "@azure/core-rest-pipeline" "^1.1.0" - "@azure/core-tracing" "1.0.0-preview.12" - "@azure/logger" "^1.0.0" - "@azure/msal-node" "1.0.0-beta.6" - "@types/stoppable" "^1.1.0" - axios "^0.21.1" - events "^3.0.0" - jws "^4.0.0" - msal "^1.0.2" - open "^7.0.0" - qs "^6.7.0" - stoppable "^1.1.0" - tslib "^2.0.0" - uuid "^8.3.0" - optionalDependencies: - keytar "^7.3.0" - "@azure/logger@^1.0.0": version "1.0.4" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.4.tgz#28bc6d0e5b3c38ef29296b32d35da4e483593fa1" @@ -125,23 +96,6 @@ dependencies: tslib "^2.2.0" -"@azure/msal-common@^4.0.0": - version "4.5.1" - resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-4.5.1.tgz#f35af8b634ae24aebd0906deb237c0db1afa5826" - integrity sha512-/i5dXM+QAtO+6atYd5oHGBAx48EGSISkXNXViheliOQe+SIFMDo3gSq3lL54W0suOSAsVPws3XnTaIHlla0PIQ== - dependencies: - debug "^4.1.1" - -"@azure/msal-node@1.0.0-beta.6": - version "1.0.0-beta.6" - resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-1.0.0-beta.6.tgz#da6bc3a3a861057c85586055960e069f162548ee" - integrity sha512-ZQI11Uz1j0HJohb9JZLRD8z0moVcPks1AFW4Q/Gcl67+QvH4aKEJti7fjCcipEEZYb/qzLSO8U6IZgPYytsiJQ== - dependencies: - "@azure/msal-common" "^4.0.0" - axios "^0.21.1" - jsonwebtoken "^8.5.1" - uuid "^8.3.0" - "@babel/code-frame@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" @@ -868,11 +822,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@opentelemetry/api@^1.0.0": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" - integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== - "@sinclair/typebox@^0.25.16": version "0.25.24" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" @@ -892,11 +841,6 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - "@turf/along@5.1.x": version "5.1.5" resolved "https://registry.yarnpkg.com/@turf/along/-/along-5.1.5.tgz#61d6e6a6584acddab56ac5584e07bf8cbe5f8beb" @@ -2191,13 +2135,6 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/stoppable@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/stoppable/-/stoppable-1.1.1.tgz#a6f1f280e29f8f3c743277534425e0a75041d2f9" - integrity sha512-b8N+fCADRIYYrGZOcmOR8ZNBOqhktWTB/bMUl5LvGtT201QKJZOOH5UsFyI3qtteM6ZAJbJqZoBcLqqxKIwjhw== - dependencies: - "@types/node" "*" - "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -2294,6 +2231,15 @@ "@typescript-eslint/types" "5.59.6" eslint-visitor-keys "^3.3.0" +"@typespec/ts-http-runtime@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.0.tgz#f506ff2170e594a257f8e78aa196088f3a46a22d" + integrity sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg== + dependencies: + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" + tslib "^2.6.2" + "@zeit/cosmosdb-query@0.7.2": version "0.7.2" resolved "https://registry.yarnpkg.com/@zeit/cosmosdb-query/-/cosmosdb-query-0.7.2.tgz#7857f28ee8c67593259e7dbe7bbd28a946de3ff0" @@ -2319,12 +2265,10 @@ acorn@^8.8.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" +agent-base@^7.1.0, agent-base@^7.1.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" @@ -2457,11 +2401,6 @@ ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" @@ -2472,13 +2411,6 @@ axe-core@^4.6.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.1.tgz#04392c9ccb3d7d7c5d2f8684f148d56d3442f33d" integrity sha512-sCXXUhA+cljomZ3ZAwb8i1p3oOlkABzPy08ZDAoGcYuvtBPlQ1Ytde129ArXyHWDhfeewq7rlx9F+cUx2SSlkg== -axios@^0.21.1: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - axobject-query@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" @@ -2550,25 +2482,11 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - big-integer@1.6.46: version "1.6.46" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.46.tgz#e18a75f0515be0f3ad10c0d110e37fa882b3f223" integrity sha512-Vj2TNtZ8Y0XaL6HCkzJiEqfykjtv/9wVCWIutMe+QVIXLPe2tCLEzULtYvcX9WRtmNIj3Jqi5tNjIsR0N4QOsg== -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2607,24 +2525,11 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== - buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -2687,11 +2592,6 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - ci-info@^3.2.0: version "3.8.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" @@ -2743,13 +2643,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - commander@2: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2836,13 +2729,6 @@ debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -2884,11 +2770,6 @@ deep-equal@^2.0.5: which-collection "^1.0.1" which-typed-array "^1.1.9" -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -2913,11 +2794,6 @@ define-properties@^1.1.4, define-properties@^1.2.0: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - density-clustering@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/density-clustering/-/density-clustering-1.3.0.tgz#dc9f59c8f0ab97e1624ac64930fd3194817dcac5" @@ -2927,11 +2803,6 @@ depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" -detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -2972,13 +2843,6 @@ earcut@^2.0.0: resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.2.tgz#41b0bc35f63e0fe80da7cddff28511e7e2e80d11" integrity sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ== -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - electron-to-chromium@^1.4.284: version "1.4.401" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.401.tgz#cbd2c332c4a833e9e8d2ec5b3a6cd85ec6920907" @@ -2999,13 +2863,6 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -3361,11 +3218,6 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -events@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -3386,11 +3238,6 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - expect@^29.0.0, expect@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" @@ -3490,11 +3337,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -follow-redirects@^1.14.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -3502,20 +3344,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3621,11 +3449,6 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== - glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -3780,21 +3603,20 @@ http-errors@1.7.3: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== +http-proxy-agent@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" + agent-base "^7.1.0" + debug "^4.3.4" -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== +https-proxy-agent@^7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== dependencies: - agent-base "6" + agent-base "^7.1.2" debug "4" human-signals@^2.1.0: @@ -3809,11 +3631,6 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore@^5.2.0: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" @@ -3858,16 +3675,11 @@ inherits@2: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: +inherits@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - int64-buffer@0.99.1007: version "0.99.1007" resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.99.1007.tgz#211ea089a2fdb960070a2e77cd6d17dc456a5220" @@ -3958,11 +3770,6 @@ is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -4107,13 +3914,6 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" -is-wsl@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -4584,22 +4384,6 @@ json5@^2.2.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonwebtoken@^8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^5.6.0" - "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" @@ -4608,48 +4392,6 @@ jsonwebtoken@^8.5.1: array-includes "^3.1.5" object.assign "^4.1.3" -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jwa@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" - integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - -jws@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" - integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== - dependencies: - jwa "^2.0.0" - safe-buffer "^5.0.1" - -keytar@^7.3.0: - version "7.9.0" - resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" - integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ== - dependencies: - node-addon-api "^4.3.0" - prebuild-install "^7.0.1" - kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -4704,36 +4446,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== - lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -4744,11 +4456,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== - lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4817,28 +4524,11 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -4846,33 +4536,16 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -msal@^1.0.2: - version "1.4.18" - resolved "https://registry.yarnpkg.com/msal/-/msal-1.4.18.tgz#2e626d2b986a388a1ed7736eb346cce6b6e97e5f" - integrity sha512-QyWMWrZqpwtK6LEqhwtbikxIWqA1EOcdMvDeIDjIXdGU29wM4orwq538sPe1+JfKDIgPmJj1Fgi5B7luaw/IyA== - dependencies: - tslib "^1.9.3" - -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -4882,29 +4555,10 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -node-abi@^3.3.0: - version "3.40.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.40.0.tgz#51d8ed44534f70ff1357dfbc3a89717b1ceac1b4" - integrity sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA== - dependencies: - semver "^7.3.5" - -node-abort-controller@^1.0.4: - version "1.2.1" - resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-1.2.1.tgz#1eddb57eb8fea734198b11b28857596dc6165708" - integrity sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ== - -node-addon-api@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - -node-fetch@^2.6.0: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== - dependencies: - whatwg-url "^5.0.0" +node-abort-controller@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== node-int64@^0.4.0: version "0.4.0" @@ -5023,7 +4677,7 @@ object.values@^1.1.6: define-properties "^1.1.4" es-abstract "^1.20.4" -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -5037,14 +4691,6 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -open@^7.0.0: - version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" - integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== - dependencies: - is-docker "^2.0.0" - is-wsl "^2.1.1" - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -5163,24 +4809,6 @@ point-in-polygon@^1.0.1: resolved "https://registry.yarnpkg.com/point-in-polygon/-/point-in-polygon-1.0.1.tgz#d59b64e8fee41c49458aac82b56718c5957b2af7" integrity sha1-1Ztk6P7kHElFiqyCtWcYxZV7Kvc= -prebuild-install@^7.0.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -5222,14 +4850,6 @@ prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -5240,13 +4860,6 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== -qs@^6.7.0: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -5286,16 +4899,6 @@ rbush@^2.0.1: dependencies: quickselect "^1.0.1" -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -5306,15 +4909,6 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - regenerator-runtime@^0.13.11: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" @@ -5411,11 +5005,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.0.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -5441,11 +5030,6 @@ semver@7.x, semver@^7.3.5, semver@^7.3.7: dependencies: lru-cache "^6.0.0" -semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -5482,20 +5066,6 @@ signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" - integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== - dependencies: - decompress-response "^6.0.0" - once "^1.3.1" - simple-concat "^1.0.0" - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -5560,11 +5130,6 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" -stoppable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" - integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== - string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -5639,13 +5204,6 @@ string.prototype.trimstart@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -5672,11 +5230,6 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5702,27 +5255,6 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tar-fs@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -5776,11 +5308,6 @@ topojson-server@3.x: dependencies: commander "2" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-jest@^29.1.0: version "29.1.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.0.tgz#4a9db4104a49b76d2b368ea775b6c9535c603891" @@ -5816,7 +5343,7 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^1.8.1, tslib@^1.9.3: +tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -5831,6 +5358,11 @@ tslib@^2.2.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.2.tgz#1b6f07185c881557b0ffa84b111a0106989e8338" integrity sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA== +tslib@^2.6.2: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -5838,13 +5370,6 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - turf-jsts@*: version "1.2.3" resolved "https://registry.yarnpkg.com/turf-jsts/-/turf-jsts-1.2.3.tgz#59757f542afbff9a577bbf411f183b8f48d38aa4" @@ -5919,11 +5444,6 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - uuid@^8.3.0: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" @@ -5945,19 +5465,6 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" From 62cbf4262a46248b15aa5569b42d88ecbad97594 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Wed, 16 Jul 2025 15:08:54 +0200 Subject: [PATCH 02/14] cleanup --- package.json | 3 +-- src/handler/_patch-operations.ts | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1b73932..d314ba1 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,5 @@ }, "engines": { "node": ">=14.17" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } diff --git a/src/handler/_patch-operations.ts b/src/handler/_patch-operations.ts index 225dcea..429efd5 100644 --- a/src/handler/_patch-operations.ts +++ b/src/handler/_patch-operations.ts @@ -7,6 +7,9 @@ export interface PatchOperationResult { body?: JSONObject; } +// When doing Patch updates, we specify the JSON path to the property we want to update. +// This function is used to get the value at the specified path. +// It also supports creating the path if it doesn't exist (for set operations). function getValueAtPath( obj: any, pathSegments: string[], From e4e334dc9feb129371cd6b228612281139730236 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Wed, 16 Jul 2025 15:11:51 +0200 Subject: [PATCH 03/14] test compatibility with Node 18, 20 and 22 --- .github/workflows/push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 788b8ee..7f40990 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [14, 16] + node: [14, 16, 18, 20, 22] steps: - uses: actions/checkout@v3 - name: Additional Checkout From b03143a45d38eea4a5ac9423b7b1fc764493d603 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Wed, 16 Jul 2025 15:27:44 +0200 Subject: [PATCH 04/14] support Node 20 as minimum version --- .github/workflows/publish.yml | 2 +- .github/workflows/push.yml | 2 +- README.md | 2 +- package.json | 7 ++++--- tsconfig.json | 2 +- yarn.lock | 14 +++++++++++++- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 87e9387..9d341a9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: "16" + node-version: "20" registry-url: "https://registry.npmjs.org" cache: "yarn" - name: Install Dependencies diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 7f40990..f3b05b8 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [14, 16, 18, 20, 22] + node: [20, 22] steps: - uses: actions/checkout@v3 - name: Additional Checkout diff --git a/README.md b/README.md index ab8ad0a..95ec2cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # cosmosdb-server -A Cosmos DB server implementation for testing your apps locally. +A Cosmos DB server implementation for testing your apps locally. The minimum supported NodeJS version is 20. ```js const { default: cosmosServer } = require("@vercel/cosmosdb-server"); diff --git a/package.json b/package.json index d314ba1..a37eaf1 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@azure/cosmos": "3.17.3", "@types/jest": "^29.5.1", "@types/lru-cache": "5.1.0", - "@types/node": "^16.0.0", + "@types/node": "20", "@typescript-eslint/eslint-plugin": "5.59.6", "@typescript-eslint/parser": "5.59.6", "@zeit/git-hooks": "0.1.4", @@ -103,6 +103,7 @@ ] }, "engines": { - "node": ">=14.17" - } + "node": ">=20" + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/tsconfig.json b/tsconfig.json index c530910..e120342 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "module": "CommonJS", "noImplicitAny": true, "outDir": "lib", - "target": "es2019" + "target": "es2022" }, "include": [ "src/**/*.ts" diff --git a/yarn.lock b/yarn.lock index d297646..90602ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2115,11 +2115,18 @@ resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w== -"@types/node@*", "@types/node@^16.0.0": +"@types/node@*": version "16.18.14" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.14.tgz#5465ce598486a703caddbefe8603f8a2cffa3461" integrity sha512-wvzClDGQXOCVNU4APPopC2KtMYukaF1MN/W3xAmslx22Z4/IF1/izDMekuyoUlwfnDHYCIZGaj7jMwnJKBTxKw== +"@types/node@20": + version "20.19.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.8.tgz#d4a81f631d9dc5015c6e608a102c83e19d03c9db" + integrity sha512-HzbgCY53T6bfu4tT7Aq3TvViJyHjLjPNaAS3HOuMc9pw97KHsUtXNX4L+wu59g1WnjsZSko35MbEqnO58rihhw== + dependencies: + undici-types "~6.21.0" + "@types/prettier@^2.1.5": version "2.7.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" @@ -5421,6 +5428,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== + universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" From 4c7c0d228c579dd294e25efa8b6b00ccd5c1da7c Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Wed, 16 Jul 2025 16:47:20 +0200 Subject: [PATCH 05/14] bump git submodule to e405a37e77a9ba483c9a9cc87faedddbef36bb8f --- test/azure-sdk-for-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/azure-sdk-for-js b/test/azure-sdk-for-js index 7537ef6..e405a37 160000 --- a/test/azure-sdk-for-js +++ b/test/azure-sdk-for-js @@ -1 +1 @@ -Subproject commit 7537ef67f0f3d1075ae604060df980c29ae2d6e8 +Subproject commit e405a37e77a9ba483c9a9cc87faedddbef36bb8f From 40ff4f2623e235573dc690759e5529cadb69bf66 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Fri, 18 Jul 2025 15:21:13 +0200 Subject: [PATCH 06/14] multiple fixes --- src/handler/_patch-operations.ts | 184 ++++++++++++++++++++++++++++++- src/types.ts | 3 +- test/index.test.ts | 110 ++++++++++++++++++ test/sdk.sh | 13 ++- test/sdk2.sh | 47 ++++++++ tsconfig.json | 2 +- 6 files changed, 349 insertions(+), 10 deletions(-) create mode 100755 test/sdk2.sh diff --git a/src/handler/_patch-operations.ts b/src/handler/_patch-operations.ts index 429efd5..5c66897 100644 --- a/src/handler/_patch-operations.ts +++ b/src/handler/_patch-operations.ts @@ -159,11 +159,148 @@ function setPatchOperation( return result; } +function addPatchOperation( + document: JSONObject, + pathSegments: string[], + value: any +): JSONObject { + if (pathSegments.length === 0) { + throw new Error("Cannot add root document."); + } + + const result = JSON.parse(JSON.stringify(document)); + const parentPath = pathSegments.slice(0, -1); + const key = pathSegments[pathSegments.length - 1]; + + const parent = getValueAtPath(result, parentPath, true); + + if (Array.isArray(parent)) { + if (key === "-") { + // Special case: append to end of array + parent.push(value); + } else { + const index = parseInt(key, 10); + if (Number.isNaN(index) || index < 0) { + throw new Error("Invalid array index."); + } + if (index > parent.length) { + throw new Error("Index to operate on is out of array bounds."); + } + // Insert at index (or append if index === length) + parent.splice(index, 0, value); + } + } else if (typeof parent === "object" && parent !== null) { + // For objects, add/replace the property + parent[key] = value; + } else { + throw new Error( + "Add Operation can only create a child object of an existing node (array or object)." + ); + } + + return result; +} + +function incrPatchOperation( + document: JSONObject, + pathSegments: string[], + value: any +): JSONObject { + if (pathSegments.length === 0) { + throw new Error("Cannot increment root document."); + } + + if (typeof value !== "number") { + throw new Error("Increment value must be a number."); + } + + const result = JSON.parse(JSON.stringify(document)); + const parentPath = pathSegments.slice(0, -1); + const key = pathSegments[pathSegments.length - 1]; + + const parent = getValueAtPath(result, parentPath, true); + + if (Array.isArray(parent)) { + const index = parseInt(key, 10); + if (Number.isNaN(index) || index < 0 || index >= parent.length) { + throw new Error("Index to operate on is out of array bounds."); + } + const currentValue = parent[index]; + if (typeof currentValue === "number") { + parent[index] = currentValue + value; + } else if (currentValue === undefined || currentValue === null) { + parent[index] = value; + } else { + throw new Error("Cannot increment non-numeric value."); + } + } else if (typeof parent === "object" && parent !== null) { + const currentValue = parent[key]; + if (typeof currentValue === "number") { + parent[key] = currentValue + value; + } else if (currentValue === undefined || currentValue === null) { + parent[key] = value; + } else { + throw new Error("Cannot increment non-numeric value."); + } + } else { + throw new Error( + "Increment Operation can only operate on numeric properties of existing nodes (array or object)." + ); + } + + return result; +} + +function movePatchOperation( + document: JSONObject, + pathSegments: string[], + from?: string +): JSONObject { + if (!from || typeof from !== "string" || !from.startsWith("/")) { + throw new Error("Move operation requires a valid 'from' path."); + } + + if (from === `/${pathSegments.join("/")}`) { + throw new Error("Cannot move a value to itself."); + } + + // Don't allow moving from system properties + if (from.startsWith("/_")) { + const systemProperty = from.split("/")[1]; + throw new Error(`Can't move from system property ${systemProperty}.`); + } + + // Check if 'path' is a child of 'from' + const fromPath = `/${pathSegments.join("/")}`; + if (fromPath.startsWith(`${from}/`)) { + throw new Error("Cannot move a value to a child of itself."); + } + + const fromSegments = from + .slice(1) + .split("/") + .map(segment => segment.replace(/~1/g, "/").replace(/~0/g, "~")); + + // First, get the value from the source location + const result = JSON.parse(JSON.stringify(document)); + const sourceValue = getValueAtPath(result, fromSegments); + + if (sourceValue === undefined) { + throw new Error("Source location for move operation does not exist."); + } + + // Remove the value from the source location + const removedResult = removePatchOperation(result, fromSegments); + + // Add the value to the target location + return addPatchOperation(removedResult, pathSegments, sourceValue); +} + function applySinglePatchOperation( document: JSONObject, operation: PatchOperation ): JSONObject { - const { op, path, value } = operation; + const { op, path, value, from } = operation; if (!path || typeof path !== "string" || !path.startsWith("/")) { throw new Error("Invalid path in patch operation."); @@ -191,6 +328,12 @@ function applySinglePatchOperation( return replacePatchOperation(document, pathSegments, value); case "set": return setPatchOperation(document, pathSegments, value); + case "add": + return addPatchOperation(document, pathSegments, value); + case "incr": + return incrPatchOperation(document, pathSegments, value); + case "move": + return movePatchOperation(document, pathSegments, from); default: throw new Error(`Unsupported patch operation: ${op}`); } @@ -244,9 +387,42 @@ export function patchOperation( // Check conditional patch if (input.condition) { try { - const query = collection.documents.query({ query: input.condition }, {}); - const results = query.result.filter((doc: any) => doc.id === input.id); - if (results.length === 0) { + // Build a complete query to check the condition against the specific document + let conditionQuery: string; + + // Handle both formats: full query vs condition clause + if (input.condition.toLowerCase().includes("select")) { + // Already a complete query + conditionQuery = input.condition; + } else { + // Just a condition clause, build a complete query + const conditionClause = input.condition.toLowerCase().trim(); + + if (conditionClause.startsWith("from c where")) { + // Azure SDK format: "from c where NOT IS_DEFINED(c.newImproved)" + const whereClause = conditionClause + .substring("from c where".length) + .trim(); + conditionQuery = `SELECT * FROM c WHERE c.id = @id AND (${whereClause})`; + } else if (conditionClause.startsWith("where")) { + // Alternative format: "where c.status = 'active'" + const whereClause = conditionClause.substring("where".length).trim(); + conditionQuery = `SELECT * FROM c WHERE c.id = @id AND (${whereClause})`; + } else { + // Legacy format: "FROM c WHERE c.status = 'active'" + conditionQuery = `SELECT * ${input.condition} AND c.id = @id`; + } + } + + const query = collection.documents.query( + { + query: conditionQuery, + parameters: [{ name: "@id", value: input.id }] + }, + {} + ); + + if (query.result.length === 0) { return { statusCode: 412, body: { diff --git a/src/types.ts b/src/types.ts index ae15939..0484ee4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -62,9 +62,10 @@ export interface ReplaceOperationInput { } export interface PatchOperation { - op: "remove" | "replace" | "set"; + op: "remove" | "replace" | "set" | "add" | "incr" | "move"; path: string; value?: any; + from?: string; // Required for move operations } export interface PatchOperationInput { diff --git a/test/index.test.ts b/test/index.test.ts index f125844..a9addcc 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -507,6 +507,110 @@ const patchDocumentWithCondition = withTestEnv(async client => { assert.strictEqual(result.name, "Test Document"); }); +const patchDocumentAdd = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-5", + name: "Test Document", + array: [1, 2, 3], + object: { existing: "value" } + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-5"); + + const patchOperations = [ + { op: "add", path: "/newProperty", value: "added" }, + { op: "add", path: "/object/existing", value: "replaced" }, // replace existing + { op: "add", path: "/object/newProp", value: "new" }, // add new property + { op: "add", path: "/array/1", value: "inserted" }, // insert into array + { op: "add", path: "/array/-", value: "appended" } // append to array + ]; + + await item.patch(patchOperations); + const { resource: result } = await item.read(); + + assert.strictEqual(result.newProperty, "added"); + assert.strictEqual(result.object.existing, "replaced"); + assert.strictEqual(result.object.newProp, "new"); + assert.deepStrictEqual(result.array, [1, "inserted", 2, 3, "appended"]); + assert.strictEqual(result.name, "Test Document"); +}); + +const patchDocumentIncrement = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-6", + name: "Test Document", + counter: 10, + scores: [100, 200, 300] + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-6"); + + const patchOperations = [ + { op: "incr", path: "/counter", value: 5 }, // increment existing + { op: "incr", path: "/newCounter", value: 25 }, // create new field + { op: "incr", path: "/scores/1", value: -50 }, // decrement array element + { op: "incr", path: "/negative", value: -10 } // create with negative value + ]; + + await item.patch(patchOperations); + const { resource: result } = await item.read(); + + assert.strictEqual(result.counter, 15); + assert.strictEqual(result.newCounter, 25); + assert.strictEqual(result.negative, -10); + assert.deepStrictEqual(result.scores, [100, 150, 300]); + assert.strictEqual(result.name, "Test Document"); +}); + +const patchDocumentMove = withTestEnv(async client => { + const { database } = await client.databases.create({ id: "patch-test-db" }); + const { container } = await database.containers.create({ + id: "patch-test-container" + }); + + const testDoc = { + id: "patch-test-7", + name: "Test Document", + source: "value to move", + nested: { + prop: "nested value" + }, + array: ["item1", "item2", "item3"] + }; + + await container.items.create(testDoc); + const item = container.item("patch-test-7"); + + const patchOperations = [ + { op: "move", from: "/source", path: "/destination" }, // move property + { op: "move", from: "/nested/prop", path: "/movedNested" }, // move from nested + { op: "move", from: "/array/0", path: "/firstItem" } // move from array + ]; + + await item.patch(patchOperations); + const { resource: result } = await item.read(); + + assert.strictEqual(result.destination, "value to move"); + assert.strictEqual(result.movedNested, "nested value"); + assert.strictEqual(result.firstItem, "item1"); + assert.strictEqual(result.source, undefined); + assert.deepStrictEqual(result.nested, {}); + assert.deepStrictEqual(result.array, ["item2", "item3"]); + assert.strictEqual(result.name, "Test Document"); +}); + describe("CosmosDB", () => { it("read document 404", readDocument404); it("upsert document", upsertDocument); @@ -539,4 +643,10 @@ describe("CosmosDB", () => { "should patch a document with condition that succeeds", patchDocumentWithCondition ); + it("should patch a document with add operation", patchDocumentAdd); + it( + "should patch a document with increment operation", + patchDocumentIncrement + ); + it("should patch a document with move operation", patchDocumentMove); }); diff --git a/test/sdk.sh b/test/sdk.sh index 8c7c42a..3ce27f1 100755 --- a/test/sdk.sh +++ b/test/sdk.sh @@ -15,6 +15,8 @@ pid=$! cd test/azure-sdk-for-js npm i -g @microsoft/rush + +rush purge rush install || rush install # try twice, the first seems to fail for no reason, but then it works # Override all `tsconfig.json` to prevent it picking up type definitions from our @@ -27,9 +29,12 @@ for f in $(find . -name tsconfig.json | grep -v node_modules); do done cd sdk/cosmosdb/cosmos -rush build:test -t . -git reset --hard +# Lib is required to run the tests. +jq '.compilerOptions.lib = ["ES2017", "DOM"]' tsconfig.json > tsconfig.json.bak && mv tsconfig.json.bak tsconfig.json + +rush build -t . && rush test -t . + +#git reset --hard -ACCOUNT_HOST="https://localhost:$port" npm run integration-test:node -- -i --exit \ - -g 'Authorization|http proxy|Change Feed|Partition|indexing|Offer CRUD|Parallel Query As String|Permission|Query Metrics On Single Partition Collection|ResourceLink Trimming|Session Token|spatial|sproc|stored procedure|Trigger|trigger|TTL|User|Non Partitioned|Validate SSL verification|matching constant version & package version|Conflicts|Partition|GROUP BY|.readOffer|autoscale|with v2 container' +ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginnin\|Full\ Text\ Search\|Full\ text\ search\ feature\|GROUP\ BY\|TOP\|DISTINCT\|ORDER\ BY\|LIMIT\|Conflicts\|readOffer\|validate\ trigger\ functionality\|SELECT\ VALUE\ AVG\ with\ ORDER\ BY\|changeFeedIterator\|test\ changefeed\|validate\ changefeed\ results\|New\ session\ token\|Validate\ SSL\ verification\|test\ batch\ operations\|test\ bulk\ operations\|test\ executeBulkOperations\|Id\ encoding\|Correlated\ Activity.*force\ query\ plan\|Correlated\ Activity.*GROUP\ BY\|aggregate\ query\ over\ null\ value\|Vector\ search\ feature\|Vector\ Search\ Query\|Bad\ partition\ key\ definition\|Reading\ items\ using\ container\|ClientSideEncryption\)\).*' diff --git a/test/sdk2.sh b/test/sdk2.sh new file mode 100755 index 0000000..9b3ec03 --- /dev/null +++ b/test/sdk2.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +## This script is used to build the Azure SDK and run their integration tests +# against our cosmosdb server. +# +# This is done to ensure we maintain compatibility with the Azure SDK. +# +# Note that the `azure-sdk-for-js` is a git submodule of this repo, and we install `rush`, as that is the +# tool they use to manage their monorepo. +set -euo pipefail + +readonly port="$((RANDOM + 3000))" +trap 'kill -9 $pid' EXIT +ts-node ./src/cli.ts -p "$port" & +pid=$! + +# # Update pnpm version in rush.json. Version 7.26.0 contains a bug. +# sed -i '' 's/"pnpmVersion": "7.26.0"/"pnpmVersion": "7.33.7"/' rush.json + +# npm i -g @microsoft/rush +# rush install || rush install # try twice, the first seems to fail for no reason, but then it works + +# # Override all `tsconfig.json` to prevent it picking up type definitions from our +# # node_modules (which is a parent dir). +# # Manually filtering a couple of dodgy ones out, because they contain json comments, which jq can't parse +# for f in $(find . -name tsconfig.json | grep -v node_modules); do +# cp "$f" "$f.bak" +# cat "$f.bak" | jq '. * { "compilerOptions": { "typeRoots": ["./node_modules/@types/"] }}' > "$f" || echo "skipping $f" +# rm "$f.bak" +# done + +cd test/azure-sdk-for-js/sdk/cosmosdb/cosmos +# rush build -t . && rush test -t . + +# git reset --hard + +# ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- \ +# --config vitest.int.config.ts \ +# --exclude="**/*{Authorization,http proxy,Change Feed,Partition,partitions,indexing,Offer CRUD,Parallel Query As String,Permission,Query Metrics On Single Partition Collection,ResourceLink Trimming,Session Token,spatial,sproc,stored procedure,Trigger,trigger,TTL,User,Non Partitioned,Validate SSL verification,matching constant version & package version,Conflicts,GROUP BY,.readOffer,autoscale,with v2 container,nonStreaming,Iterator,startFromBeginning}*" + + + +# Set pattern as environment variable to avoid shell escaping issues +# export VITEST_TEST_NAME_PATTERN='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginning\)\).*\$' +# ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern="$VITEST_TEST_NAME_PATTERN" + +ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginnin\|Full\ Text\ Search\|Full\ text\ search\ feature\|GROUP\ BY\|TOP\|DISTINCT\|ORDER\ BY\|LIMIT\|Conflicts\|readOffer\|validate\ trigger\ functionality\|SELECT\ VALUE\ AVG\ with\ ORDER\ BY\|changeFeedIterator\|test\ changefeed\|validate\ changefeed\ results\|New\ session\ token\|Validate\ SSL\ verification\|test\ batch\ operations\|test\ bulk\ operations\|test\ executeBulkOperations\|Id\ encoding\|Correlated\ Activity.*force\ query\ plan\|Correlated\ Activity.*GROUP\ BY\|aggregate\ query\ over\ null\ value\|Vector\ search\ feature\|Vector\ Search\ Query\|Bad\ partition\ key\ definition\|Reading\ items\ using\ container\|ClientSideEncryption\)\).*' +# ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern="\^.*patch\ operations.*\$" diff --git a/tsconfig.json b/tsconfig.json index e120342..629954b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "module": "CommonJS", "noImplicitAny": true, "outDir": "lib", - "target": "es2022" + "target": "es2017" }, "include": [ "src/**/*.ts" From e2ed778b612a2f778168585bcf874ee4e3ff0bd9 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Fri, 18 Jul 2025 15:26:13 +0200 Subject: [PATCH 07/14] multiple fixes --- test/azure-sdk-for-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/azure-sdk-for-js b/test/azure-sdk-for-js index e405a37..51cb4a5 160000 --- a/test/azure-sdk-for-js +++ b/test/azure-sdk-for-js @@ -1 +1 @@ -Subproject commit e405a37e77a9ba483c9a9cc87faedddbef36bb8f +Subproject commit 51cb4a5c2477897b24aef135fcfe36069bebad7d From 8567a1df1b02fe7f2509a5e3c445d026f40976dc Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Mon, 21 Jul 2025 19:20:36 +0200 Subject: [PATCH 08/14] fixes --- test/azure-sdk-for-js | 2 +- test/sdk.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/azure-sdk-for-js b/test/azure-sdk-for-js index 51cb4a5..aa0b0c7 160000 --- a/test/azure-sdk-for-js +++ b/test/azure-sdk-for-js @@ -1 +1 @@ -Subproject commit 51cb4a5c2477897b24aef135fcfe36069bebad7d +Subproject commit aa0b0c765931b8927991a66210a668ca5ed96d48 diff --git a/test/sdk.sh b/test/sdk.sh index 3ce27f1..0beb11b 100755 --- a/test/sdk.sh +++ b/test/sdk.sh @@ -30,8 +30,9 @@ done cd sdk/cosmosdb/cosmos -# Lib is required to run the tests. -jq '.compilerOptions.lib = ["ES2017", "DOM"]' tsconfig.json > tsconfig.json.bak && mv tsconfig.json.bak tsconfig.json +# Fix TypeScript compilation errors by adding "dom" to lib array for console support +jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' tsconfig.json > tsconfig.json.tmp && mv tsconfig.json.tmp tsconfig.json +jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' test/tsconfig.json > test/tsconfig.json.tmp && mv test/tsconfig.json.tmp test/tsconfig.json rush build -t . && rush test -t . From 5dc794111203c49d0f8922f92c708a93f6be62cb Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Tue, 22 Jul 2025 11:38:40 +0200 Subject: [PATCH 09/14] fixes --- test/azure-sdk-for-js | 2 +- test/sdk.sh | 31 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/test/azure-sdk-for-js b/test/azure-sdk-for-js index aa0b0c7..9788e23 160000 --- a/test/azure-sdk-for-js +++ b/test/azure-sdk-for-js @@ -1 +1 @@ -Subproject commit aa0b0c765931b8927991a66210a668ca5ed96d48 +Subproject commit 9788e2316428580afa110f6ee3fb9d128edae19a diff --git a/test/sdk.sh b/test/sdk.sh index 0beb11b..36b8fd0 100755 --- a/test/sdk.sh +++ b/test/sdk.sh @@ -8,34 +8,41 @@ # tool they use to manage their monorepo. set -euo pipefail -readonly port="$((RANDOM + 3000))" -trap 'kill -9 $pid' EXIT -ts-node ./src/cli.ts -p "$port" & -pid=$! +mv node_modules node_modules.bak cd test/azure-sdk-for-js npm i -g @microsoft/rush rush purge -rush install || rush install # try twice, the first seems to fail for no reason, but then it works +rush install #|| rush install # try twice, the first seems to fail for no reason, but then it works # Override all `tsconfig.json` to prevent it picking up type definitions from our # node_modules (which is a parent dir). # Manually filtering a couple of dodgy ones out, because they contain json comments, which jq can't parse -for f in $(find . -name tsconfig.json | grep -v node_modules); do - cp "$f" "$f.bak" - cat "$f.bak" | jq '. * { "compilerOptions": { "typeRoots": ["./node_modules/@types/"] }}' > "$f" || echo "skipping $f" - rm "$f.bak" -done +# for f in $(find . -name tsconfig.json | grep -v node_modules); do +# cp "$f" "$f.bak" +# cat "$f.bak" | jq '. * { "compilerOptions": { "typeRoots": ["./node_modules/@types/"] }}' > "$f" || echo "skipping $f" +# rm "$f.bak" +# done cd sdk/cosmosdb/cosmos # Fix TypeScript compilation errors by adding "dom" to lib array for console support -jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' tsconfig.json > tsconfig.json.tmp && mv tsconfig.json.tmp tsconfig.json -jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' test/tsconfig.json > test/tsconfig.json.tmp && mv test/tsconfig.json.tmp test/tsconfig.json +# jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' tsconfig.json > tsconfig.json.tmp && mv tsconfig.json.tmp tsconfig.json +# jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' test/tsconfig.json > test/tsconfig.json.tmp && mv test/tsconfig.json.tmp test/tsconfig.json rush build -t . && rush test -t . #git reset --hard +cd ../../../../../ +mv node_modules.bak node_modules + +readonly port="$((RANDOM + 3000))" +trap 'kill -9 $pid' EXIT +ts-node ./src/cli.ts -p "$port" & +pid=$! + +cd test/azure-sdk-for-js/sdk/cosmosdb/cosmos + ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginnin\|Full\ Text\ Search\|Full\ text\ search\ feature\|GROUP\ BY\|TOP\|DISTINCT\|ORDER\ BY\|LIMIT\|Conflicts\|readOffer\|validate\ trigger\ functionality\|SELECT\ VALUE\ AVG\ with\ ORDER\ BY\|changeFeedIterator\|test\ changefeed\|validate\ changefeed\ results\|New\ session\ token\|Validate\ SSL\ verification\|test\ batch\ operations\|test\ bulk\ operations\|test\ executeBulkOperations\|Id\ encoding\|Correlated\ Activity.*force\ query\ plan\|Correlated\ Activity.*GROUP\ BY\|aggregate\ query\ over\ null\ value\|Vector\ search\ feature\|Vector\ Search\ Query\|Bad\ partition\ key\ definition\|Reading\ items\ using\ container\|ClientSideEncryption\)\).*' From b0213f3489bdc1585ee2a235995b8210714e53d6 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Tue, 22 Jul 2025 11:39:22 +0200 Subject: [PATCH 10/14] remove test/sdk2 --- test/sdk2.sh | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100755 test/sdk2.sh diff --git a/test/sdk2.sh b/test/sdk2.sh deleted file mode 100755 index 9b3ec03..0000000 --- a/test/sdk2.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -## This script is used to build the Azure SDK and run their integration tests -# against our cosmosdb server. -# -# This is done to ensure we maintain compatibility with the Azure SDK. -# -# Note that the `azure-sdk-for-js` is a git submodule of this repo, and we install `rush`, as that is the -# tool they use to manage their monorepo. -set -euo pipefail - -readonly port="$((RANDOM + 3000))" -trap 'kill -9 $pid' EXIT -ts-node ./src/cli.ts -p "$port" & -pid=$! - -# # Update pnpm version in rush.json. Version 7.26.0 contains a bug. -# sed -i '' 's/"pnpmVersion": "7.26.0"/"pnpmVersion": "7.33.7"/' rush.json - -# npm i -g @microsoft/rush -# rush install || rush install # try twice, the first seems to fail for no reason, but then it works - -# # Override all `tsconfig.json` to prevent it picking up type definitions from our -# # node_modules (which is a parent dir). -# # Manually filtering a couple of dodgy ones out, because they contain json comments, which jq can't parse -# for f in $(find . -name tsconfig.json | grep -v node_modules); do -# cp "$f" "$f.bak" -# cat "$f.bak" | jq '. * { "compilerOptions": { "typeRoots": ["./node_modules/@types/"] }}' > "$f" || echo "skipping $f" -# rm "$f.bak" -# done - -cd test/azure-sdk-for-js/sdk/cosmosdb/cosmos -# rush build -t . && rush test -t . - -# git reset --hard - -# ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- \ -# --config vitest.int.config.ts \ -# --exclude="**/*{Authorization,http proxy,Change Feed,Partition,partitions,indexing,Offer CRUD,Parallel Query As String,Permission,Query Metrics On Single Partition Collection,ResourceLink Trimming,Session Token,spatial,sproc,stored procedure,Trigger,trigger,TTL,User,Non Partitioned,Validate SSL verification,matching constant version & package version,Conflicts,GROUP BY,.readOffer,autoscale,with v2 container,nonStreaming,Iterator,startFromBeginning}*" - - - -# Set pattern as environment variable to avoid shell escaping issues -# export VITEST_TEST_NAME_PATTERN='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginning\)\).*\$' -# ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern="$VITEST_TEST_NAME_PATTERN" - -ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginnin\|Full\ Text\ Search\|Full\ text\ search\ feature\|GROUP\ BY\|TOP\|DISTINCT\|ORDER\ BY\|LIMIT\|Conflicts\|readOffer\|validate\ trigger\ functionality\|SELECT\ VALUE\ AVG\ with\ ORDER\ BY\|changeFeedIterator\|test\ changefeed\|validate\ changefeed\ results\|New\ session\ token\|Validate\ SSL\ verification\|test\ batch\ operations\|test\ bulk\ operations\|test\ executeBulkOperations\|Id\ encoding\|Correlated\ Activity.*force\ query\ plan\|Correlated\ Activity.*GROUP\ BY\|aggregate\ query\ over\ null\ value\|Vector\ search\ feature\|Vector\ Search\ Query\|Bad\ partition\ key\ definition\|Reading\ items\ using\ container\|ClientSideEncryption\)\).*' -# ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern="\^.*patch\ operations.*\$" From 906e6fcbcb6b0085a281eda0559d0bac47426d0c Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Tue, 22 Jul 2025 11:44:39 +0200 Subject: [PATCH 11/14] bump git submodule --- test/azure-sdk-for-js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/azure-sdk-for-js b/test/azure-sdk-for-js index 9788e23..d5dbcb2 160000 --- a/test/azure-sdk-for-js +++ b/test/azure-sdk-for-js @@ -1 +1 @@ -Subproject commit 9788e2316428580afa110f6ee3fb9d128edae19a +Subproject commit d5dbcb2ec980ec28b815ea20b557835dee63b510 From 7a8764da956f239470ff0eb913dd895a7ae46375 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Tue, 22 Jul 2025 12:12:39 +0200 Subject: [PATCH 12/14] cleanup --- package.json | 3 +-- test/index.test.ts | 23 +++++++++++------------ test/sdk.sh | 27 +++++++++------------------ tsconfig.json | 2 +- 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index a37eaf1..e4ee947 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,5 @@ }, "engines": { "node": ">=20" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } diff --git a/test/index.test.ts b/test/index.test.ts index a9addcc..5b2ad60 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -488,7 +488,6 @@ const patchDocumentWithCondition = withTestEnv(async client => { await container.items.create(testDoc); const item = container.item("patch-test-4"); - // Patch with condition - should succeed because status is "active" const patchOperations = [ { op: "set", path: "/value", value: 500 }, { op: "set", path: "/priority", value: "critical" } @@ -525,10 +524,10 @@ const patchDocumentAdd = withTestEnv(async client => { const patchOperations = [ { op: "add", path: "/newProperty", value: "added" }, - { op: "add", path: "/object/existing", value: "replaced" }, // replace existing - { op: "add", path: "/object/newProp", value: "new" }, // add new property - { op: "add", path: "/array/1", value: "inserted" }, // insert into array - { op: "add", path: "/array/-", value: "appended" } // append to array + { op: "add", path: "/object/existing", value: "replaced" }, + { op: "add", path: "/object/newProp", value: "new" }, + { op: "add", path: "/array/1", value: "inserted" }, + { op: "add", path: "/array/-", value: "appended" } ]; await item.patch(patchOperations); @@ -558,10 +557,10 @@ const patchDocumentIncrement = withTestEnv(async client => { const item = container.item("patch-test-6"); const patchOperations = [ - { op: "incr", path: "/counter", value: 5 }, // increment existing - { op: "incr", path: "/newCounter", value: 25 }, // create new field - { op: "incr", path: "/scores/1", value: -50 }, // decrement array element - { op: "incr", path: "/negative", value: -10 } // create with negative value + { op: "incr", path: "/counter", value: 5 }, + { op: "incr", path: "/newCounter", value: 25 }, + { op: "incr", path: "/scores/1", value: -50 }, + { op: "incr", path: "/negative", value: -10 } ]; await item.patch(patchOperations); @@ -594,9 +593,9 @@ const patchDocumentMove = withTestEnv(async client => { const item = container.item("patch-test-7"); const patchOperations = [ - { op: "move", from: "/source", path: "/destination" }, // move property - { op: "move", from: "/nested/prop", path: "/movedNested" }, // move from nested - { op: "move", from: "/array/0", path: "/firstItem" } // move from array + { op: "move", from: "/source", path: "/destination" }, + { op: "move", from: "/nested/prop", path: "/movedNested" }, + { op: "move", from: "/array/0", path: "/firstItem" } ]; await item.patch(patchOperations); diff --git a/test/sdk.sh b/test/sdk.sh index 36b8fd0..143b230 100755 --- a/test/sdk.sh +++ b/test/sdk.sh @@ -8,41 +8,32 @@ # tool they use to manage their monorepo. set -euo pipefail +# Required so that we do not have a "phantom" node_modules directory when running +# rush. Setting "typeRoots": ["./node_modules/@types/"] in all tsconfig.json files +# does not work. mv node_modules node_modules.bak cd test/azure-sdk-for-js npm i -g @microsoft/rush rush purge -rush install #|| rush install # try twice, the first seems to fail for no reason, but then it works - -# Override all `tsconfig.json` to prevent it picking up type definitions from our -# node_modules (which is a parent dir). -# Manually filtering a couple of dodgy ones out, because they contain json comments, which jq can't parse -# for f in $(find . -name tsconfig.json | grep -v node_modules); do -# cp "$f" "$f.bak" -# cat "$f.bak" | jq '. * { "compilerOptions": { "typeRoots": ["./node_modules/@types/"] }}' > "$f" || echo "skipping $f" -# rm "$f.bak" -# done +rush install cd sdk/cosmosdb/cosmos - -# Fix TypeScript compilation errors by adding "dom" to lib array for console support -# jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' tsconfig.json > tsconfig.json.tmp && mv tsconfig.json.tmp tsconfig.json -# jq '.compilerOptions.lib = (.compilerOptions.lib // ["es2019"]) + ["dom"] | .compilerOptions.lib |= unique' test/tsconfig.json > test/tsconfig.json.tmp && mv test/tsconfig.json.tmp test/tsconfig.json - rush build -t . && rush test -t . -#git reset --hard - +# Cosmos SDK has been built and tested. We can use again the root node_modules directory. cd ../../../../../ mv node_modules.bak node_modules +# Start a local CosmosDB server. readonly port="$((RANDOM + 3000))" trap 'kill -9 $pid' EXIT ts-node ./src/cli.ts -p "$port" & pid=$! +# Run the tests against the local CosmosDB server. +# The executed tests are for Cosmos SDK 4.5.0, but we only have partial support for 3.17.x. +# That is why there are so many ignored test patterns. cd test/azure-sdk-for-js/sdk/cosmosdb/cosmos - ACCOUNT_HOST="https://localhost:$port" npm run test:node:integration -- --testNamePattern='\^\(?!.*\(Authorization\|Change\ Feed\|Partition\|indexing\|Offer\ CRUD\|Permission\|Session\ Token\|sproc\|stored\ procedure\|Trigger\|TTL\|User\|Non\ Partitioned\|autoscale\|nonStreaming\|Iterator\|startFromBeginnin\|Full\ Text\ Search\|Full\ text\ search\ feature\|GROUP\ BY\|TOP\|DISTINCT\|ORDER\ BY\|LIMIT\|Conflicts\|readOffer\|validate\ trigger\ functionality\|SELECT\ VALUE\ AVG\ with\ ORDER\ BY\|changeFeedIterator\|test\ changefeed\|validate\ changefeed\ results\|New\ session\ token\|Validate\ SSL\ verification\|test\ batch\ operations\|test\ bulk\ operations\|test\ executeBulkOperations\|Id\ encoding\|Correlated\ Activity.*force\ query\ plan\|Correlated\ Activity.*GROUP\ BY\|aggregate\ query\ over\ null\ value\|Vector\ search\ feature\|Vector\ Search\ Query\|Bad\ partition\ key\ definition\|Reading\ items\ using\ container\|ClientSideEncryption\)\).*' diff --git a/tsconfig.json b/tsconfig.json index 629954b..c530910 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "module": "CommonJS", "noImplicitAny": true, "outDir": "lib", - "target": "es2017" + "target": "es2019" }, "include": [ "src/**/*.ts" From 8cbd3334957ea74dba7ea8d18243c6d883641646 Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Tue, 22 Jul 2025 12:20:24 +0200 Subject: [PATCH 13/14] bump from 0.15.1 to 1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4ee947..376da1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@vercel/cosmosdb-server", - "version": "0.15.1", + "version": "0.16.0", "description": "A Cosmos DB server implementation", "license": "MIT", "main": "lib/index.js", From a33f6b4fcccf41501cb973a3ec697413da89985a Mon Sep 17 00:00:00 2001 From: Marc Codina Date: Tue, 22 Jul 2025 15:45:28 +0200 Subject: [PATCH 14/14] set version to 1.0.0 and bump types/node --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 376da1d..401cfc3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@vercel/cosmosdb-server", - "version": "0.16.0", + "version": "1.0.0", "description": "A Cosmos DB server implementation", "license": "MIT", "main": "lib/index.js", @@ -37,7 +37,7 @@ "@azure/cosmos": "3.17.3", "@types/jest": "^29.5.1", "@types/lru-cache": "5.1.0", - "@types/node": "20", + "@types/node": "^20.19.9", "@typescript-eslint/eslint-plugin": "5.59.6", "@typescript-eslint/parser": "5.59.6", "@zeit/git-hooks": "0.1.4", diff --git a/yarn.lock b/yarn.lock index 90602ef..fd39560 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2120,10 +2120,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.14.tgz#5465ce598486a703caddbefe8603f8a2cffa3461" integrity sha512-wvzClDGQXOCVNU4APPopC2KtMYukaF1MN/W3xAmslx22Z4/IF1/izDMekuyoUlwfnDHYCIZGaj7jMwnJKBTxKw== -"@types/node@20": - version "20.19.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.8.tgz#d4a81f631d9dc5015c6e608a102c83e19d03c9db" - integrity sha512-HzbgCY53T6bfu4tT7Aq3TvViJyHjLjPNaAS3HOuMc9pw97KHsUtXNX4L+wu59g1WnjsZSko35MbEqnO58rihhw== +"@types/node@^20.19.9": + version "20.19.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.9.tgz#ca9a58193fec361cc6e859d88b52261853f1f0d3" + integrity sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw== dependencies: undici-types "~6.21.0"