diff --git a/package-lock.json b/package-lock.json index e629808..1c58625 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,19 @@ { - "name": "da-admin", + "name": "da-admin-sb", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "da-admin", + "name": "da-admin-sb", "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-s3": "^3.456.0", - "@aws-sdk/s3-request-presigner": "^3.468.0", - "@ssttevee/cfw-formdata-polyfill": "^0.2.1", "jose": "^5.1.3" }, "devDependencies": { "@adobe/eslint-config-helix": "2.0.6", "@redocly/cli": "^1.4.1", - "aws-sdk-client-mock": "^4.0.0", "c8": "^8.0.1", "eslint": "8.56.0", "esmock": "^2.6.4", @@ -44,895 +40,6 @@ "eslint": "^8.0.0" } }, - "node_modules/@aws-crypto/crc32": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", - "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/crc32c": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", - "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha1-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", - "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", - "dependencies": { - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/client-s3": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.600.0.tgz", - "integrity": "sha512-iYoKbJTputbf+ubkX6gSK/y/4uJEBRaXZ18jykLdBQ8UJuGrk2gqvV8h7OlGAhToCeysmmMqM0vDWyLt6lP8nw==", - "dependencies": { - "@aws-crypto/sha1-browser": "5.2.0", - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.600.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-bucket-endpoint": "3.598.0", - "@aws-sdk/middleware-expect-continue": "3.598.0", - "@aws-sdk/middleware-flexible-checksums": "3.598.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-location-constraint": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-sdk-s3": "3.598.0", - "@aws-sdk/middleware-signing": "3.598.0", - "@aws-sdk/middleware-ssec": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/signature-v4-multi-region": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@aws-sdk/xml-builder": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/eventstream-serde-browser": "^3.0.2", - "@smithy/eventstream-serde-config-resolver": "^3.0.1", - "@smithy/eventstream-serde-node": "^3.0.2", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-blob-browser": "^3.1.0", - "@smithy/hash-node": "^3.0.1", - "@smithy/hash-stream-node": "^3.1.0", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/md5-js": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-retry": "^3.0.1", - "@smithy/util-stream": "^3.0.2", - "@smithy/util-utf8": "^3.0.0", - "@smithy/util-waiter": "^3.0.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.598.0.tgz", - "integrity": "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.600.0.tgz", - "integrity": "sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/client-sts": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.600.0.tgz", - "integrity": "sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/core": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.598.0.tgz", - "integrity": "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g==", - "dependencies": { - "@smithy/core": "^2.2.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/signature-v4": "^3.1.0", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "fast-xml-parser": "4.2.5", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.598.0.tgz", - "integrity": "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.598.0.tgz", - "integrity": "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/util-stream": "^3.0.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.598.0.tgz", - "integrity": "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.598.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.600.0.tgz", - "integrity": "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-ini": "3.598.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.598.0.tgz", - "integrity": "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.598.0.tgz", - "integrity": "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA==", - "dependencies": { - "@aws-sdk/client-sso": "3.598.0", - "@aws-sdk/token-providers": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.598.0.tgz", - "integrity": "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sts": "^3.598.0" - } - }, - "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.598.0.tgz", - "integrity": "sha512-PM7BcFfGUSkmkT6+LU9TyJiB4S8yI7dfuKQDwK5ZR3P7MKaK4Uj4yyDiv0oe5xvkF6+O2+rShj+eh8YuWkOZ/Q==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-arn-parser": "3.568.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", - "@smithy/util-config-provider": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.598.0.tgz", - "integrity": "sha512-ZuHW18kaeHR8TQyhEOYMr8VwiIh0bMvF7J1OTqXHxDteQIavJWA3CbfZ9sgS4XGtrBZDyHJhjZKeCfLhN2rq3w==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.598.0.tgz", - "integrity": "sha512-xukAzds0GQXvMEY9G6qt+CzwVzTx8NyKKh04O2Q+nOch6QQ8Rs+2kTRy3Z4wQmXq2pK9hlOWb5nXA7HWpmz6Ng==", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@aws-crypto/crc32c": "5.2.0", - "@aws-sdk/types": "3.598.0", - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.598.0.tgz", - "integrity": "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.598.0.tgz", - "integrity": "sha512-8oybQxN3F1ISOMULk7JKJz5DuAm5hCUcxMW9noWShbxTJuStNvuHf/WLUzXrf8oSITyYzIHPtf8VPlKR7I3orQ==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.598.0.tgz", - "integrity": "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.598.0.tgz", - "integrity": "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.598.0.tgz", - "integrity": "sha512-5AGtLAh9wyK6ANPYfaKTqJY1IFJyePIxsEbxa7zS6REheAqyVmgJFaGu3oQ5XlxfGr5Uq59tFTRkyx26G1HkHA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-arn-parser": "3.568.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/signature-v4": "^3.1.0", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/util-config-provider": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.598.0.tgz", - "integrity": "sha512-XKb05DYx/aBPqz6iCapsCbIl8aD8EihTuPCs51p75QsVfbQoVr4TlFfIl5AooMSITzojdAQqxt021YtvxjtxIQ==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/signature-v4": "^3.1.0", - "@smithy/types": "^3.1.0", - "@smithy/util-middleware": "^3.0.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.598.0.tgz", - "integrity": "sha512-f0p2xP8IC1uJ5e/tND1l81QxRtRFywEdnbtKCE0H6RSn4UIt2W3Dohe1qQDbnh27okF0PkNW6BJGdSAz3p7qbA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.598.0.tgz", - "integrity": "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.598.0.tgz", - "integrity": "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/types": "^3.1.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.600.0.tgz", - "integrity": "sha512-MYRwgti1DDc9/Q9AzvTQy0Ih0j4vLe0zYLV3qtSI0H8G02yRqTzet2s/76pUNOYJK9ASSgcxQ9yeV9EGKBwndQ==", - "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-format-url": "3.598.0", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.598.0.tgz", - "integrity": "sha512-1r/EyTrO1gSa1FirnR8V7mabr7gk+l+HkyTI0fcTSr8ucB7gmYyW6WjkY8JCz13VYHFK62usCEDS7yoJoJOzTA==", - "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/signature-v4": "^3.1.0", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/token-providers": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.598.0.tgz", - "integrity": "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.598.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.598.0.tgz", - "integrity": "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ==", - "dependencies": { - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.568.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.568.0.tgz", - "integrity": "sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.598.0.tgz", - "integrity": "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "@smithy/util-endpoints": "^2.0.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-format-url": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.598.0.tgz", - "integrity": "sha512-1X0PlREk5K6tQg8rFZOjoKVtDyI1WgbKJNCymHhMye6STryY6fhuuayKstiDThkqDYxqahjUJz/Tl2p5W3rbcw==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/querystring-builder": "^3.0.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.568.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", - "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.598.0.tgz", - "integrity": "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.598.0.tgz", - "integrity": "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.598.0.tgz", - "integrity": "sha512-ZIa2RK7CHFTZ4gwK77WRtsZ6vF7xwRXxJ8KQIxK2duhoTVcn0xYxpFLdW9WZZZvdP9GIF3Loqvf8DRdeU5Jc7Q==", - "dependencies": { - "@smithy/types": "^3.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, "node_modules/@babel/runtime": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", @@ -1554,945 +661,218 @@ }, "node_modules/@fastify/busboy": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@redocly/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-9GWx27t7xWhDIR02PA18nzBdLcKQRgc46xNQvjFkrYk4UOmvKhJ/dawwiX0cCOeetN5LcaaiqQbVOWYK62SGHw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@redocly/cli": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.16.0.tgz", - "integrity": "sha512-REmwkNHOd4e50vPeL6mDgHVdyUQ8e+y0cggi/cNXQzGpkZEk17Z+WFL8UFlcM+WebMWDXulJE712jT2lGYS9Zg==", - "dev": true, - "dependencies": { - "@redocly/openapi-core": "1.16.0", - "abort-controller": "^3.0.0", - "chokidar": "^3.5.1", - "colorette": "^1.2.0", - "core-js": "^3.32.1", - "form-data": "^4.0.0", - "get-port-please": "^3.0.1", - "glob": "^7.1.6", - "handlebars": "^4.7.6", - "mobx": "^6.0.4", - "node-fetch": "^2.6.1", - "react": "^17.0.0 || ^18.2.0", - "react-dom": "^17.0.0 || ^18.2.0", - "redoc": "~2.1.5", - "semver": "^7.5.2", - "simple-websocket": "^9.0.0", - "styled-components": "^6.0.7", - "yargs": "17.0.1" - }, - "bin": { - "openapi": "bin/cli.js", - "redocly": "bin/cli.js" - }, - "engines": { - "node": ">=14.19.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@redocly/config": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.6.2.tgz", - "integrity": "sha512-c3K5u64eMnr2ootPcpEI0ioIRLE8QP8ptvLxG9MwAmb2sU8HMRfVwXDU3AZiMVY2w4Ts0mDc+Xv4HTIk8DRqFw==", - "dev": true - }, - "node_modules/@redocly/openapi-core": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.16.0.tgz", - "integrity": "sha512-z06h+svyqbUcdAaePq8LPSwTPlm6Ig7j2VlL8skPBYnJvyaQ2IN7x/JkOvRL4ta+wcOCBdAex5JWnZbKaNktJg==", - "dev": true, - "dependencies": { - "@redocly/ajv": "^8.11.0", - "@redocly/config": "^0.6.0", - "colorette": "^1.2.0", - "https-proxy-agent": "^7.0.4", - "js-levenshtein": "^1.1.6", - "js-yaml": "^4.1.0", - "lodash.isequal": "^4.5.0", - "minimatch": "^5.0.1", - "node-fetch": "^2.6.1", - "pluralize": "^8.0.0", - "yaml-ast-parser": "0.0.43" - }, - "engines": { - "node": ">=14.19.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "node_modules/@smithy/abort-controller": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.0.tgz", - "integrity": "sha512-XOm4LkuC0PsK1sf2bBJLIlskn5ghmVxiEBVlo/jg0R8hxASBKYYgOoJEhKWgOr4vWGkN+5rC+oyBAqHYtxjnwQ==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/chunked-blob-reader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-3.0.0.tgz", - "integrity": "sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/chunked-blob-reader-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-3.0.0.tgz", - "integrity": "sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==", - "dependencies": { - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/config-resolver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.3.tgz", - "integrity": "sha512-4wHqCMkdfVDP4qmr4fVPYOFOH+vKhOv3X4e6KEU9wIC8xXUQ24tnF4CW+sddGDX1zU86GGyQ7A+rg2xmUD6jpQ==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/core": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.3.tgz", - "integrity": "sha512-SpyLOL2vgE6sUYM6nQfu82OirCPkCDKctyG3aMgjMlDPTJpUlmlNH0ttu9ZWwzEjrzzr8uABmPjJTRI7gk1HFQ==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.0.3", - "@smithy/middleware-retry": "^3.0.6", - "@smithy/middleware-serde": "^3.0.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "@smithy/util-middleware": "^3.0.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.2.tgz", - "integrity": "sha512-gqVmUaNoeqyrOAjgZg+rTmFLsphh/vS59LCMdFfVpthVS0jbfBzvBmEPktBd+y9ME4DYMGHFAMSYJDK8q0noOQ==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/property-provider": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/url-parser": "^3.0.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-codec": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.1.tgz", - "integrity": "sha512-s29NxV/ng1KXn6wPQ4qzJuQDjEtxLdS0+g5PQFirIeIZrp66FXVJ5IpZRowbt/42zB5dY8TqJ0G0L9KkgtsEZg==", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.2.0", - "@smithy/util-hex-encoding": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/eventstream-serde-browser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.3.tgz", - "integrity": "sha512-ZXKmNAHl6SWKYuVmtoEc/hBQ7Nym/rbAx2SrqoJHn0i9QopIP7fG1AWmoFIeS5R3/VL6AwUIZMR0g8qnjjVRRA==", - "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.3", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.2.tgz", - "integrity": "sha512-QbE3asvvBUZr7PwbOaxkSfKDjTAmWZkqh2G7pkYlD4jRkT1Y9nufeyu0OBPlLoF4+gl3YMpSVO7TESe8bVkD+g==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-node": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.3.tgz", - "integrity": "sha512-v61Ftn7x/ubWFqH7GHFAL/RaU7QZImTbuV95DYugYYItzpO7KaHYEuO8EskCaBpZEfzOxhUGKm4teS9YUSt69Q==", - "dependencies": { - "@smithy/eventstream-serde-universal": "^3.0.3", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.3.tgz", - "integrity": "sha512-YXYt3Cjhu9tRrahbTec2uOjwOSeCNfQurcWPGNEUspBhqHoA3KrDrVj+jGbCLWvwkwhzqDnnaeHAxm+IxAjOAQ==", - "dependencies": { - "@smithy/eventstream-codec": "^3.1.1", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.1.0.tgz", - "integrity": "sha512-s7oQjEOUH9TYjctpITtWF4qxOdg7pBrP9eigEQ8SBsxF3dRFV0S28pGMllC83DUr7ECmErhO/BUwnULfoNhKgQ==", - "dependencies": { - "@smithy/protocol-http": "^4.0.2", - "@smithy/querystring-builder": "^3.0.2", - "@smithy/types": "^3.2.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/hash-blob-browser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.1.tgz", - "integrity": "sha512-8RwdPG7arvL5pfMAFsH6jfBVcC7MDR1LYHjKevZPHREkVtORIQkRfm2K8px7giJt7x0zzQJnWamrsDM4ig8nTQ==", - "dependencies": { - "@smithy/chunked-blob-reader": "^3.0.0", - "@smithy/chunked-blob-reader-native": "^3.0.0", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/hash-node": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.2.tgz", - "integrity": "sha512-43uGA6o6QJQdXwAogybdTDHDd3SCdKyoiHIHb8PpdE2rKmVicjG9b1UgVwdgO8QPytmVqHFaUw27M3LZKwu8Yg==", - "dependencies": { - "@smithy/types": "^3.2.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/hash-stream-node": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-3.1.1.tgz", - "integrity": "sha512-+uvJHPrFNE9crkh3INVS9FmDcx1DoywDgIzlRWlPy7gqoD8jG14os9ATIFY7wN/ARPz1EWlkCHUap70oXxMmjA==", - "dependencies": { - "@smithy/types": "^3.2.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.2.tgz", - "integrity": "sha512-+BAY3fMhomtq470tswXyrdVBSUhiLuhBVT+rOmpbz5e04YX+s1dX4NxTLzZGwBjCpeWZNtTxP8zbIvvFk81gUg==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/md5-js": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-3.0.2.tgz", - "integrity": "sha512-WlSK9br7fkVucTkCXporwuOttCR3cJ1GV70J8ENYXGNc0nUTPzMdWCyHztgnbbKoekVMjGZOEu+8I52nOdzqwQ==", - "dependencies": { - "@smithy/types": "^3.2.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.2.tgz", - "integrity": "sha512-/Havz3PkYIEmwpqkyRTR21yJsWnFbD1ec4H1pUL+TkDnE7RCQkAVUQepLL/UeCaZeCBXvfdoKbOjSbV01xIinQ==", - "dependencies": { - "@smithy/protocol-http": "^4.0.2", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.3.tgz", - "integrity": "sha512-ARAXHodhj4tttKa9y75zvENdSoHq6VGsSi7XS3+yLutrnxttJs6N10UMInCC1yi3/bopT8xug3iOP/y9R6sKJQ==", - "dependencies": { - "@smithy/middleware-serde": "^3.0.2", - "@smithy/node-config-provider": "^3.1.2", - "@smithy/shared-ini-file-loader": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/url-parser": "^3.0.2", - "@smithy/util-middleware": "^3.0.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.6.tgz", - "integrity": "sha512-ICsFKp8eAyIMmxN5UT3IU37S6886L879TKtgxPsn/VD/laYNwqTLmJaCAn5//+2fRIrV0dnHp6LFlMwdXlWoUQ==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/service-error-classification": "^3.0.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "@smithy/util-middleware": "^3.0.2", - "@smithy/util-retry": "^3.0.2", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.2.tgz", - "integrity": "sha512-oT2abV5zLhBucJe1LIIFEcRgIBDbZpziuMPswTMbBQNcaEUycLFvX63zsFmqfwG+/ZQKsNx+BSE8W51CMuK7Yw==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.2.tgz", - "integrity": "sha512-6fRcxomlNKBPIy/YjcnC7YHpMAjRvGUYlYVJAfELqZjkW0vQegNcImjY7T1HgYA6u3pAcCxKVBLYnkTw8z/l0A==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.2.tgz", - "integrity": "sha512-388fEAa7+6ORj/BDC70peg3fyFBTTXJyXfXJ0Bwd6FYsRltePr2oGzIcm5AuC1WUSLtZ/dF+hYOnfTMs04rLvA==", - "dependencies": { - "@smithy/property-provider": "^3.1.2", - "@smithy/shared-ini-file-loader": "^3.1.2", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.0.tgz", - "integrity": "sha512-pOpgB6B+VLXLwAyyvRz+ZAVXABlbAsJ2xvn3WZvrppAPImxwQOPFbeSUzWYMhpC8Tr7yQ3R8fG990QDhskkf1Q==", - "dependencies": { - "@smithy/abort-controller": "^3.1.0", - "@smithy/protocol-http": "^4.0.2", - "@smithy/querystring-builder": "^3.0.2", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.2.tgz", - "integrity": "sha512-Hzp32BpeFFexBpO1z+ts8okbq/VLzJBadxanJAo/Wf2CmvXMBp6Q/TLWr7Js6IbMEcr0pDZ02V3u1XZkuQUJaA==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.2.tgz", - "integrity": "sha512-X/90xNWIOqSR2tLUyWxVIBdatpm35DrL44rI/xoeBWUuanE0iyCXJpTcnqlOpnEzgcu0xCKE06+g70TTu2j7RQ==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.2.tgz", - "integrity": "sha512-xhv1+HacDYsOLdNt7zW+8Fe779KYAzmWvzs9bC5NlKM8QGYCwwuFwDBynhlU4D5twgi2pZ14Lm4h6RiAazCtmA==", - "dependencies": { - "@smithy/types": "^3.2.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.2.tgz", - "integrity": "sha512-C5hyRKgrZGPNh5QqIWzXnW+LXVrPmVQO0iJKjHeb5v3C61ZkP9QhrKmbfchcTyg/VnaE0tMNf/nmLpQlWuiqpg==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.2.tgz", - "integrity": "sha512-cu0WV2XRttItsuXlcM0kq5MKdphbMMmSd2CXF122dJ75NrFE0o7rruXFGfxAp3BKzgF/DMxX+PllIA/cj4FHMw==", - "dependencies": { - "@smithy/types": "^3.2.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.2.tgz", - "integrity": "sha512-tgnXrXbLMO8vo6VeuqabMw/eTzQHlLmZx0TC0TjtjJghnD0Xl4pEnJtBjTJr6XF5fHMNrt5BcczDXHJT9yNQnA==", - "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.1.tgz", - "integrity": "sha512-2/vlG86Sr489XX8TA/F+VDA+P04ESef04pSz0wRtlQBExcSPjqO08rvrkcas2zLnJ51i+7ukOURCkgqixBYjSQ==", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/types": "^3.2.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.2", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.4.tgz", - "integrity": "sha512-y6xJROGrIoitjpwXLY7P9luDHvuT9jWpAluliuSFdBymFxcl6iyQjo9U/JhYfRHFNTruqsvKOrOESVuPGEcRmQ==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.0.3", - "@smithy/middleware-stack": "^3.0.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/types": "^3.2.0", - "@smithy/util-stream": "^3.0.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.2.0.tgz", - "integrity": "sha512-cKyeKAPazZRVqm7QPvcPD2jEIt2wqDPAL1KJKb0f/5I7uhollvsWZuZKLclmyP6a+Jwmr3OV3t+X0pZUUHS9BA==", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/url-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.2.tgz", - "integrity": "sha512-pRiPHrgibeAr4avtXDoBHmTLtthwA4l8jKYRfZjNgp+bBPyxDMPRg2TMJaYxqbKemvrOkHu9MIBTv2RkdNfD6w==", - "dependencies": { - "@smithy/querystring-parser": "^3.0.2", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", - "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", - "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "dependencies": { - "tslib": "^2.6.2" - }, + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, "engines": { - "node": ">=16.0.0" + "node": ">=14" } }, - "node_modules/@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "tslib": "^2.6.2" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=16.0.0" + "node": ">=10.10.0" } }, - "node_modules/@smithy/util-config-provider": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", - "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.6.tgz", - "integrity": "sha512-tAgoc++Eq+KL7g55+k108pn7nAob3GLWNEMbXhZIQyBcBNaE/o3+r4AEbae0A8bWvLRvArVsjeiuhMykGa04/A==", + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { - "@smithy/property-provider": "^3.1.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">= 10.0.0" + "node": "*" } }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.6.tgz", - "integrity": "sha512-UNerul6/E8aiCyFTBHk+RSIZCo7m96d/N5K3FeO/wFeZP6oy5HAicLzxqa85Wjv7MkXSxSySX29L/LwTV/QMag==", - "dependencies": { - "@smithy/config-resolver": "^3.0.3", - "@smithy/credential-provider-imds": "^3.1.2", - "@smithy/node-config-provider": "^3.1.2", - "@smithy/property-provider": "^3.1.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, "engines": { - "node": ">= 10.0.0" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@smithy/util-endpoints": { + "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.3.tgz", - "integrity": "sha512-Dyi+pfLglDHSGsKSYunuUUSFM5V0tz7UDgv1Ex97yg+Xkn0Eb0rH0rcvl1n0MaJ11fac3HKDOH0DkALyQYCQag==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, "engines": { - "node": ">=16.0.0" + "node": ">=8" } }, - "node_modules/@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "dependencies": { - "tslib": "^2.6.2" - }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { - "node": ">=16.0.0" + "node": ">=6.0.0" } }, - "node_modules/@smithy/util-middleware": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.2.tgz", - "integrity": "sha512-7WW5SD0XVrpfqljBYzS5rLR+EiDzl7wCVJZ9Lo6ChNFV4VYDk37Z1QI5w/LnYtU/QKnSawYoHRd7VjSyC8QRQQ==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "dependencies": { - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@smithy/util-retry": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.2.tgz", - "integrity": "sha512-HUVOb1k8p/IH6WFUjsLa+L9H1Zi/FAAB2CDOpWuffI1b2Txi6sknau8kNfC46Xrt39P1j2KDzCE1UlLa2eW5+A==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "dependencies": { - "@smithy/service-error-classification": "^3.0.2", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=16.0.0" + "node": ">= 8" } }, - "node_modules/@smithy/util-stream": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.4.tgz", - "integrity": "sha512-CcMioiaOOsEVdb09pS7ux1ij7QcQ2jE/cE1+iin1DXMeRgAEQN/47m7Xztu7KFQuQsj0A5YwB2UN45q97CqKCg==", - "dependencies": { - "@smithy/fetch-http-handler": "^3.1.0", - "@smithy/node-http-handler": "^3.1.0", - "@smithy/types": "^3.2.0", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "engines": { - "node": ">=16.0.0" + "node": ">= 8" } }, - "node_modules/@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "dependencies": { - "tslib": "^2.6.2" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=16.0.0" + "node": ">= 8" } }, - "node_modules/@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "node_modules/@redocly/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-9GWx27t7xWhDIR02PA18nzBdLcKQRgc46xNQvjFkrYk4UOmvKhJ/dawwiX0cCOeetN5LcaaiqQbVOWYK62SGHw==", + "dev": true, "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "tslib": "^2.6.2" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=16.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@smithy/util-waiter": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.1.1.tgz", - "integrity": "sha512-xT+Bbpe5sSrC7cCWSElOreDdWzqovR1V+7xrp+fmwGAA+TPYBb78iasaXjO1pa+65sY6JjW5GtGeIoJwCK9B1g==", + "node_modules/@redocly/cli": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.16.0.tgz", + "integrity": "sha512-REmwkNHOd4e50vPeL6mDgHVdyUQ8e+y0cggi/cNXQzGpkZEk17Z+WFL8UFlcM+WebMWDXulJE712jT2lGYS9Zg==", + "dev": true, "dependencies": { - "@smithy/abort-controller": "^3.1.0", - "@smithy/types": "^3.2.0", - "tslib": "^2.6.2" + "@redocly/openapi-core": "1.16.0", + "abort-controller": "^3.0.0", + "chokidar": "^3.5.1", + "colorette": "^1.2.0", + "core-js": "^3.32.1", + "form-data": "^4.0.0", + "get-port-please": "^3.0.1", + "glob": "^7.1.6", + "handlebars": "^4.7.6", + "mobx": "^6.0.4", + "node-fetch": "^2.6.1", + "react": "^17.0.0 || ^18.2.0", + "react-dom": "^17.0.0 || ^18.2.0", + "redoc": "~2.1.5", + "semver": "^7.5.2", + "simple-websocket": "^9.0.0", + "styled-components": "^6.0.7", + "yargs": "17.0.1" + }, + "bin": { + "openapi": "bin/cli.js", + "redocly": "bin/cli.js" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@ssttevee/blob-ponyfill": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@ssttevee/blob-ponyfill/-/blob-ponyfill-0.1.0.tgz", - "integrity": "sha512-JqjpKtbwYukrS24Vk/W4OfHeTWEssnggSUksZZGmCNmxrpwDP3d6BwUcUtOruazmdNp9fB2SXWophjSGZzLd7g==", - "dependencies": { - "@ssttevee/u8-utils": "^0.1.3" - } - }, - "node_modules/@ssttevee/cfw-formdata-polyfill": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@ssttevee/cfw-formdata-polyfill/-/cfw-formdata-polyfill-0.2.1.tgz", - "integrity": "sha512-ZYKPk6Wv4KaYPQ3MXlmEoCRYc7llnp8Uyk/1dWkSrHXa+s1zrPHduV+cmm0Kc6+OMXitIskFIdkSjR8I4QVF5Q==", - "dependencies": { - "@ssttevee/blob-ponyfill": "^0.1.0", - "@ssttevee/formdata-ponyfill": "^0.1.4", - "@ssttevee/multipart-parser": "^0.1.6", - "@ssttevee/u8-utils": "^0.1.3" + "node": ">=14.19.0", + "npm": ">=7.0.0" } }, - "node_modules/@ssttevee/formdata-ponyfill": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@ssttevee/formdata-ponyfill/-/formdata-ponyfill-0.1.4.tgz", - "integrity": "sha512-8GeH2CmdUEqFO68I4XDjqG6z2QNCYfaYnqJ4U+RoQZsM6UXVyudjIUHaF1LLTcNFggyQvE5gUg5wvFZluYBWMw==" - }, - "node_modules/@ssttevee/multipart-parser": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@ssttevee/multipart-parser/-/multipart-parser-0.1.9.tgz", - "integrity": "sha512-4GmChu029N2VHdi3SEQMlqTctNRisGoE4HOLAsL7p6nrlWHQ63dqVZ2IsnI0HGizzt2/0MLFNlaF7EFBsuXK2g==", - "dependencies": { - "@ssttevee/streamsearch": "~0.3.0", - "@ssttevee/u8-utils": "~0.1.5" - } + "node_modules/@redocly/config": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.6.2.tgz", + "integrity": "sha512-c3K5u64eMnr2ootPcpEI0ioIRLE8QP8ptvLxG9MwAmb2sU8HMRfVwXDU3AZiMVY2w4Ts0mDc+Xv4HTIk8DRqFw==", + "dev": true }, - "node_modules/@ssttevee/streamsearch": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@ssttevee/streamsearch/-/streamsearch-0.3.1.tgz", - "integrity": "sha512-qL6bEa8R1KlN0rcLVWaLZfS+IVi5nw51FlO54p8PbCkspM5G8ssZhcCNJjnPxSPNz1BqIIt0Rm4tALBilYx1dw==", + "node_modules/@redocly/openapi-core": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.16.0.tgz", + "integrity": "sha512-z06h+svyqbUcdAaePq8LPSwTPlm6Ig7j2VlL8skPBYnJvyaQ2IN7x/JkOvRL4ta+wcOCBdAex5JWnZbKaNktJg==", + "dev": true, "dependencies": { - "@ssttevee/u8-utils": "~0.1.5" + "@redocly/ajv": "^8.11.0", + "@redocly/config": "^0.6.0", + "colorette": "^1.2.0", + "https-proxy-agent": "^7.0.4", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "lodash.isequal": "^4.5.0", + "minimatch": "^5.0.1", + "node-fetch": "^2.6.1", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=14.19.0", + "npm": ">=7.0.0" } }, - "node_modules/@ssttevee/u8-utils": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@ssttevee/u8-utils/-/u8-utils-0.1.7.tgz", - "integrity": "sha512-bSD+ocJRyAWiav1w7iQmAJ+ao/DJ5cRLcs2VsFDQeA1pODdF8cVZYy69+/irAeEntYoFbKigID/eM389pZ3vMA==" - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -2529,21 +909,6 @@ "@types/node": "*" } }, - "node_modules/@types/sinon": { - "version": "10.0.20", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", - "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", - "dev": true, - "dependencies": { - "@types/sinonjs__fake-timers": "*" - } - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", - "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", - "dev": true - }, "node_modules/@types/stylis": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", @@ -2852,17 +1217,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sdk-client-mock": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aws-sdk-client-mock/-/aws-sdk-client-mock-4.0.1.tgz", - "integrity": "sha512-yD2mmgy73Xce097G5hIpr1k7j50qzvJ49/+6osGZiCyk4m6cwhb+2x7kKFY1gEMwTzaS8+m8fXv9SB29SkRYyQ==", - "dev": true, - "dependencies": { - "@types/sinon": "^10.0.10", - "sinon": "^16.1.3", - "tslib": "^2.1.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2894,11 +1248,6 @@ "dev": true, "peer": true }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3226,9 +1575,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -4256,27 +2605,6 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, - "node_modules/fast-xml-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", - "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", - "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -5294,12 +3622,6 @@ "json5": "lib/cli.js" } }, - "node_modules/just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5351,12 +3673,6 @@ "dev": true, "peer": true }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -5798,28 +4114,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -6240,9 +4534,9 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, "node_modules/pathe": { @@ -7049,33 +5343,6 @@ } } }, - "node_modules/sinon": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-16.1.3.tgz", - "integrity": "sha512-mjnWWeyxcAf9nC0bXcPmiDut+oE8HYridTNzBbF98AYVLmWwGRp2ISEpyhYflG1ifILT+eNn3BmKUJPxjXUPlA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.4", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/slugify": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", @@ -7241,11 +5508,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, "node_modules/styled-components": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz", @@ -7412,7 +5674,8 @@ "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true }, "node_modules/type-check": { "version": "0.4.0", @@ -7426,15 +5689,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -7617,18 +5871,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -7940,12 +6182,12 @@ } }, "node_modules/youch": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/youch/-/youch-3.3.3.tgz", - "integrity": "sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/youch/-/youch-3.3.4.tgz", + "integrity": "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==", "dev": true, "dependencies": { - "cookie": "^0.5.0", + "cookie": "^0.7.1", "mustache": "^4.2.0", "stacktracey": "^2.1.8" } diff --git a/src/routes/source.js b/src/routes/source.js index a2ad04d..f1548ee 100644 --- a/src/routes/source.js +++ b/src/routes/source.js @@ -12,38 +12,18 @@ import getObject from '../storage/object/get.js'; import putObject from '../storage/object/put.js'; import deleteObjects from '../storage/object/delete.js'; - import putHelper from '../helpers/source.js'; +import { syncCollab } from '../storage/utils/collab.js'; -async function invalidateCollab(api, url, env) { - const invPath = `/api/v1/${api}?doc=${url}`; - - // Use dacollab service binding, hostname is not relevant - const invURL = `https://localhost${invPath}`; - await env.dacollab.fetch(invURL); -} - -export async function deleteSource({ req, env, daCtx }) { - const resp = await deleteObjects(env, daCtx); - - if (resp.status === 204) { - const initiator = req.headers.get('x-da-initiator'); - if (initiator !== 'collab') { - await invalidateCollab('deleteadmin', req.url, env); - } - } - return resp; +export async function deleteSource({ env, daCtx }) { + return deleteObjects(env, daCtx); } export async function postSource({ req, env, daCtx }) { const obj = await putHelper(req, env, daCtx); const resp = await putObject(env, daCtx, obj); - - if (resp.status === 201 || resp.status === 200) { - const initiator = req.headers.get('x-da-initiator'); - if (initiator !== 'collab') { - await invalidateCollab('syncadmin', req.url, env); - } + if (resp.status === 200 || resp.status === 201) { + await syncCollab(env, daCtx); } return resp; } diff --git a/src/storage/object/delete.js b/src/storage/object/delete.js index ced3aaf..0cd6b9a 100644 --- a/src/storage/object/delete.js +++ b/src/storage/object/delete.js @@ -9,35 +9,54 @@ * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ +import { deleteFromCollab } from '../utils/collab.js'; +import { postObjectVersionWithLabel } from '../version/put.js'; +/** + * Deletes an object in the storage, creating a version of it if necessary. + * + * @param {Object} env the CloudFlare environment + * @param {DaCtx} daCtx the DA Context + * @param {String} key the key of the object to delete (excluding Org) + * @param {Boolean} isMove if this was initiated by a move operation + * @return {Promise} + */ +export async function deleteObject(env, daCtx, key, isMove = false) { + const fname = key.split('/').pop(); + + const tmpCtx = { ...daCtx, key }; // For next calls, ctx needs the passed key, as it could contain a folder + if (fname.indexOf('.') > 0 && !key.endsWith('.props')) { + await postObjectVersionWithLabel(env, tmpCtx, isMove ? 'Moved' : 'Deleted'); + } + await env.DA_CONTENT.delete(`${daCtx.org}/${key}`); + await deleteFromCollab(env, tmpCtx); +} /** * Deletes one or more objects in the storage. Object is specified by the key in the daCtx or a list passed in. * Note: folders can not be specified in the `keys` list. * * @param {Object} env the CloudFlare environment * @param {DaCtx} daCtx the DA Context - * @param {String[]} [keys=[]] the list of keys to delete (excluding the Org) * @return {Promise<{body: null, status: number}>} */ -export default async function deleteObjects(env, daCtx, keys = []) { - if (keys.length) { - const fullKeys = keys.map((key) => `${daCtx.org}/${key}`); - await env.DA_CONTENT.delete(fullKeys); - return { body: null, status: 204 }; - } - - const fullKey = `${daCtx.org}/${daCtx.key}`; - const prefix = `${fullKey}/`; +export default async function deleteObjects(env, daCtx) { + const keys = []; + const prefix = `${daCtx.org}/${daCtx.key}/`; // The input prefix has a forward slash to prevent (drafts + drafts-new, etc.). // Which means the list will only pickup children. This adds to the initial list. - keys.push(fullKey, `${fullKey}.props`); + keys.push(daCtx.key, `${daCtx.key}.props`); let truncated = false; do { - const r2objects = await env.DA_CONTENT.list({ prefix, limit: 500 }); + const r2objects = await env.DA_CONTENT.list({ prefix, limit: 100 }); const { objects } = r2objects; truncated = r2objects.truncated; - keys.push(...objects.map(({ key }) => key)); - await env.DA_CONTENT.delete(keys); + keys.push(...objects.map(({ key }) => key.split('/').slice(1).join('/'))); + const promises = []; + keys.forEach((k) => { + promises.push(deleteObject(env, daCtx, k)); + }); + await Promise.all(promises); + keys.length = 0; } while (truncated); return { body: null, status: 204 }; } diff --git a/src/storage/object/get.js b/src/storage/object/get.js index 35e1baf..bc189e0 100644 --- a/src/storage/object/get.js +++ b/src/storage/object/get.js @@ -13,12 +13,12 @@ /** * Retrieve a specified object. * @param {Object} env the CloudFlare environment - * @param {String} org the org of the object - * @param {String} key the key of the object + * @param {DaCtx} daCtx the DA Context * @param {boolean} head flag to only retrieve head info or body as well. * @return {Promise<{Object}>} response object */ -export default async function getObject(env, { org, key }, head = false) { +export default async function getObject(env, daCtx, head = false) { + const { org, key } = daCtx; const daKey = `${org}/${key}`; let obj; diff --git a/src/storage/object/move.js b/src/storage/object/move.js index f2ac1cf..1ccdab1 100644 --- a/src/storage/object/move.js +++ b/src/storage/object/move.js @@ -9,7 +9,8 @@ * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ -import { copyFile, copyFiles } from '../utils/copy.js'; +import { copyFile } from '../utils/copy.js'; +import { deleteObject } from './delete.js'; const limit = 100; @@ -24,7 +25,10 @@ const limit = 100; */ export default async function moveObject(env, daCtx, details) { if (daCtx.isFile) { - await copyFile(env, daCtx, details.source, details.destination, true); + const res = await copyFile(env, daCtx, details.source, details.destination, true); + if (res.success) { + await deleteObject(env, daCtx, details.source, true); + } return { status: 204 }; } @@ -53,14 +57,21 @@ export default async function moveObject(env, daCtx, details) { dest: src.replace(details.source, details.destination), }; })); - await copyFiles(env, daCtx, sourceList, true) - .then(async (values) => { - const successes = values - .filter((item) => item.success) - .map((item) => item.source); - await env.DA_CONTENT.delete(successes); - results.push(...values); - }); + + const promises = []; + sourceList.forEach(({ src, dest }) => { + promises.push( + copyFile(env, daCtx, src, dest, true) + .then(async (res) => { + if (res.success) { + await deleteObject(env, daCtx, src, true); + } + return res; + }) + .then((res) => results.push(res)), + ); + }); + await Promise.allSettled(promises); sourceList.length = 0; /* c8 ignore next 3 */ } catch (e) { diff --git a/src/storage/utils/collab.js b/src/storage/utils/collab.js new file mode 100644 index 0000000..c1b9d34 --- /dev/null +++ b/src/storage/utils/collab.js @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +async function invalidateCollab(env, daCtx, api) { + if (daCtx.initiator === 'collab' || !daCtx.key.endsWith('.html')) { + return; + } + const invPath = `/api/v1/${api}?doc=${daCtx.origin}/${daCtx.api}/${daCtx.org}/${daCtx.key}`; + // Use dacollab service binding, hostname is not relevant + const invURL = `https://localhost${invPath}`; + await env.dacollab.fetch(invURL); +} + +/** + * Removes the specified URL from the Collab cache. + * @param {Object} env the CloudFlare environment + * @param {DaCtx} daCtx the DA Context + * @return {Promise} + */ +export async function deleteFromCollab(env, daCtx) { + await invalidateCollab(env, daCtx, 'deleteadmin'); +} + +/** + * Forces a sync in DaCollab for the specified URL. + * @param {Object} env the CloudFlare environment + * @param {DaCtx} daCtx the DA Context + * @return {Promise} + */ +export async function syncCollab(env, daCtx) { + await invalidateCollab(env, daCtx, 'syncadmin'); +} diff --git a/src/storage/version/get.js b/src/storage/version/get.js index cadd5d7..d9daec4 100644 --- a/src/storage/version/get.js +++ b/src/storage/version/get.js @@ -11,6 +11,14 @@ */ import getObject from '../object/get.js'; -export async function getObjectVersion(env, { org, key }, head) { - return getObject(env, { org, key: `.da-versions/${key}` }, head); +/** + * Gets a specified object version. + * @param {Object} env the CloudFlare environment + * @param {DaCtx} daCtx the DA Context + * @param {Boolean} head only retrieve the head info + * @return {Promise|*>} + */ +export async function getObjectVersion(env, daCtx, head) { + const tmpCtx = { ...daCtx, key: `.da-versions/${daCtx.key}` }; + return getObject(env, tmpCtx, head); } diff --git a/src/storage/version/list.js b/src/storage/version/list.js index 286de0b..dedb81b 100644 --- a/src/storage/version/list.js +++ b/src/storage/version/list.js @@ -12,18 +12,24 @@ import getObject from '../object/get.js'; import listObjects from '../object/list.js'; -export async function listObjectVersions(env, { org, key }) { - const current = await getObject(env, { org, key }, true); +/** + * Lists all versions of an object. + * + * @param {Object} env the CloudFlare environment + * @param {DaCtx} daCtx the DA Context + * @return {Promise<{body: string, status: number}|{body: string, contentType: string, status: number}|number>} + */ +export async function listObjectVersions(env, daCtx) { + const { org } = daCtx; + const current = await getObject(env, daCtx, true); if (current.status === 404 || !current.metadata.id) { return 404; } const objects = await listObjects(env, { org, key: `.da-versions/${current.metadata.id}` }); if (objects) { const promises = await Promise.all(objects.map(async (entry) => { - const entryResp = await getObject(env, { - org, - key: `.da-versions/${current.metadata.id}/${entry.name}.${entry.ext}`, - }, true); + const tmpCtx = { ...daCtx, key: `.da-versions/${current.metadata.id}/${entry.name}.${entry.ext}` }; + const entryResp = await getObject(env, tmpCtx, true); const timestamp = parseInt(entryResp.metadata.timestamp || '0', 10); const users = JSON.parse(entryResp.metadata.users || '[{"email":"anonymous"}]'); const { label, path } = entryResp.metadata; diff --git a/src/storage/version/put.js b/src/storage/version/put.js index 26ec2b7..0ff0ec6 100644 --- a/src/storage/version/put.js +++ b/src/storage/version/put.js @@ -61,7 +61,8 @@ export async function putObjectWithVersion(env, daCtx, update, body) { // While we are automatically storing the body once for the 'Collab Parse' changes, we never // do a HEAD, because we may need the content. Once we don't need to do this automatic store // any more, we can change the 'false' argument in the next line back to !body. - const current = await getObject(env, { org: daCtx.org, key: update.key }, false); + const tmpCtx = { ...daCtx, key: update.key }; + const current = await getObject(env, tmpCtx, false); const id = current.metadata?.id || crypto.randomUUID(); const version = current.metadata?.version || crypto.randomUUID(); const users = JSON.stringify(daCtx.users); @@ -127,6 +128,24 @@ export async function putObjectWithVersion(env, daCtx, update, body) { return 201; } +/** + * Create a version of an object in its current state, with an optional label. + * @param {Object} env the CloudFlare environment + * @param {Object} daCtx the DA context + * @param {String} label the label for the version + * @return {Promise<{status: number}>} the response object + */ +export async function postObjectVersionWithLabel(env, daCtx, label) { + const { body, contentType } = await getObject(env, daCtx); + const { key } = daCtx; + + const resp = await putObjectWithVersion(env, daCtx, { + key, body, type: contentType, label, + }, true); + + return { status: resp }; +} + /** * Create a version of an object in its current state, with an optional label. * @param {Request} req request object @@ -143,12 +162,5 @@ export async function postObjectVersion(req, env, daCtx) { } const label = reqJSON?.label; - const { body, contentType } = await getObject(env, daCtx); - const { key } = daCtx; - - const resp = await putObjectWithVersion(env, daCtx, { - key, body, type: contentType, label, - }, true); - - return { status: resp }; + return postObjectVersionWithLabel(env, daCtx, label); } diff --git a/src/utils/daCtx.js b/src/utils/daCtx.js index 5e56d90..5615bc0 100644 --- a/src/utils/daCtx.js +++ b/src/utils/daCtx.js @@ -15,11 +15,12 @@ import { getUsers, isAuthorized } from './auth.js'; /** * Gets Dark Alley Context * @param {Request} req the request object - * @param env the Cloudflare environment context + * @param {Object} env the Cloudflare environment context * @returns {DaCtx} The Dark Alley Context. */ export default async function getDaCtx(req, env) { - let { pathname } = new URL(req.url); + const url = new URL(req.url); + let { pathname } = url; // Remove proxied api route if (pathname.startsWith('/api')) pathname = pathname.replace('/api', ''); @@ -40,10 +41,12 @@ export default async function getDaCtx(req, env) { // Set base details const daCtx = { path: pathname, + origin: url.origin, api, org, users, fullKey, + initiator: req.headers.get('x-da-initiator'), }; // Get org properties diff --git a/test/it/delete.spec.js b/test/it/delete.spec.js index 437945f..c467821 100644 --- a/test/it/delete.spec.js +++ b/test/it/delete.spec.js @@ -32,11 +32,22 @@ describe('DELETE HTTP Requests', () => { }); it('handles existing file', async () => { + const before = await env.DA_CONTENT.get('wknd/index.html'); + const id = before.customMetadata.id; + const input = { + prefix: `wknd/.da-versions/${id}/`, + delimiter: '/', + } + let list = await env.DA_CONTENT.list(input); + assert.strictEqual(list.objects.length, 0); + const req = new Request('https://admin.da.live/source/wknd/index.html', { method: 'DELETE' }); const resp = await worker.fetch(req, env); assert.strictEqual(resp.status, 204); - const obj = await env.DA_CONTENT.get('wknd/index.html'); - assert.ifError(obj); + const after = await env.DA_CONTENT.get('wknd/index.html'); + assert.ifError(after); + list = await env.DA_CONTENT.list(input); + assert.strictEqual(list.objects.length, 1); }); }); }) diff --git a/test/mocks/miniflare.js b/test/mocks/miniflare.js index cad7d11..f14010c 100644 --- a/test/mocks/miniflare.js +++ b/test/mocks/miniflare.js @@ -35,6 +35,7 @@ const config = { * @return {Miniflare} */ export async function getMiniflare() { + const collabCalls = []; const mf = new Miniflare({ modules: true, // Need a script to initialize Miniflare @@ -46,11 +47,7 @@ export async function getMiniflare() { } `, serviceBindings: { - dacollab() { - return { - fetch: () => { /* no-op fetch */ }, - }; - }, + dacollab(request) { /* no op */ }, }, kvNamespaces: { DA_AUTH: 'DA_AUTH', DA_CONFIG: 'DA_CONFIG' }, r2Buckets: { DA_CONTENT: 'DA_CONTENT' }, diff --git a/test/routes/source.test.js b/test/routes/source.test.js index c154a2d..e151889 100644 --- a/test/routes/source.test.js +++ b/test/routes/source.test.js @@ -9,173 +9,108 @@ * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ -import assert from 'assert'; +import assert from 'node:assert'; import esmock from 'esmock'; describe('Source Route', () => { - it('Test invalidate using service binding', async () => { - const sb_callbacks = []; - const dacollab = { - fetch: async (url) => sb_callbacks.push(url) - }; - const env = { - dacollab, - DA_COLLAB: 'http://localhost:4444' - }; - - const daCtx = {}; - const putResp = async (e, c) => { - if (e === env && c === daCtx) { - return { status: 200 }; - } - }; - - const { postSource } = await esmock( - '../../src/routes/source.js', { - '../../src/storage/object/put.js': { - default: putResp - } - }); - - const headers = new Map(); - headers.set('x-da-initiator', 'blah'); - - const req = { - headers, - url: 'http://localhost:9876/source/somedoc.html' - }; - - const resp = await postSource({ req, env, daCtx }); - assert.equal(200, resp.status); - assert.deepStrictEqual(['https://localhost/api/v1/syncadmin?doc=http://localhost:9876/source/somedoc.html'], sb_callbacks); - }); - - it('Test postSource from collab does not trigger invalidate callback', async () => { - const { postSource } = await esmock( - '../../src/routes/source.js', { - '../../src/storage/object/put.js': { - default: async () => ({ status: 201 }) - } - }); - - const savedFetch = globalThis.fetch; - try { - const callbacks = []; - globalThis.fetch = async (url) => { - callbacks.push(url); - }; - - const headers = new Map(); - headers.set('content-type', 'text/html'); - headers.set('x-da-initiator', 'collab'); - - const req = { - headers, - url: 'http://localhost:8787/source/a/b/mydoc.html' - }; - - const env = { DA_COLLAB: 'http://localhost:1234' }; - const daCtx = {}; - - const resp = await postSource({ req, env, daCtx }); - assert.equal(201, resp.status); - assert.equal(0, callbacks.length); - } finally { - globalThis.fetch = savedFetch; + describe('postSource', () => { + for (const status of [200, 201]) { + it(`invalidates collab w/ put status === ${status}`, async () => { + const called = []; + const req = undefined + const env = {}; + const daCtx = { + key: 'wknd/index.html', + }; + const { postSource } = await esmock( + '../../src/routes/source.js', { + '../../src/helpers/source.js': { + default: async () => undefined, + }, + '../../src/storage/object/put.js': { + default: async (e, d, o) => { + assert.deepStrictEqual(e, env); + assert.deepStrictEqual(d, daCtx); + assert.ifError(o); + return { status: status } + } + }, + '../../src/storage/utils/collab.js': { + syncCollab: async (e, c) => { + assert.deepStrictEqual(e, env); + assert.deepStrictEqual(c, daCtx); + called.push(c.key); + }, + } + }); + const resp = await postSource({ req, env, daCtx }); + assert.strictEqual(status, resp.status); + assert.deepStrictEqual(called, ['wknd/index.html']) + }); } - }); - - it('Test failing postSource does not trigger callback', async () => { - const callbacks = []; - const { postSource } = await esmock( - '../../src/routes/source.js', { - '../../src/storage/object/put.js': { - default: async () => ({ status: 500 }) - } - }); - - const savedFetch = globalThis.fetch; - try { - const callbacks = []; - globalThis.fetch = async (url) => { - callbacks.push(url); - }; - - const headers = new Map(); - headers.set('content-type', 'text/html'); - - const req = { - headers, - url: 'http://localhost:8787/source/a/b/mydoc.html' - }; - - const env = { DA_COLLAB: 'http://localhost:1234' }; + it('does not invalidate collab on put failure', async () => { + const req = undefined + const env = {}; const daCtx = {}; - + const { postSource } = await esmock( + '../../src/routes/source.js', { + '../../src/helpers/source.js': { + default: async () => undefined, + }, + '../../src/storage/object/put.js': { + default: async (e, d, o) => { + assert.deepStrictEqual(e, env); + assert.deepStrictEqual(d, daCtx); + assert.ifError(o); + return { status: 500 } + } + }, + '../../src/storage/utils/collab.js': { + syncCollab: async () => assert.fail('should not call syncCollab'), + } + }); const resp = await postSource({ req, env, daCtx }); - assert.equal(500, resp.status); - assert.equal(0, callbacks.length); - } finally { - globalThis.fetch = savedFetch; - } + assert.strictEqual(500, resp.status); + }); }); - - it('Test getSource', async () => { - const env = {}; - const daCtx = {}; - - const called = []; - const getResp = async (e, c) => { - if (e === env && c === daCtx) { - called.push('getObject'); - return {status: 200}; - } - }; - - const { getSource } = await esmock( - '../../src/routes/source.js', { - '../../src/storage/object/get.js': { - default: getResp - } - } - ); - const resp = await getSource({env, daCtx}); - assert.equal(200, resp.status); - assert.deepStrictEqual(called, ['getObject']); + describe('getSource', () => { + it('succeeds', async () => { + const env = {}; + const daCtx = {}; + const { getSource } = await esmock( + '../../src/routes/source.js', { + '../../src/storage/object/get.js': { + default: (e, c) => { + assert.deepStrictEqual(e, env); + assert.deepStrictEqual(c, daCtx); + return { status: 200 }; + }, + }, + }, + ); + const resp = await getSource({ env, daCtx }); + assert.strictEqual(200, resp.status); + }); }); - it('Test deleteSource', async () => { - const req = { - headers: new Map(), - url: 'http://somehost.com/somedoc.html' - }; - - const daCalled = [] - const dacollab = { fetch: (u) => daCalled.push(u) }; - - const env = { dacollab }; - const daCtx = {}; - - const deleteCalled = []; - const deleteResp = async (e, c) => { - if (e === env && c === daCtx) { - deleteCalled.push('deleteObject'); - return {status: 204}; - } - }; - - const { deleteSource } = await esmock( - '../../src/routes/source.js', { - '../../src/storage/object/delete.js': { - default: deleteResp + describe('deleteSource', () => { + it('succeeds', async () => { + const env = {}; + const daCtx = {}; + const { deleteSource } = await esmock( + '../../src/routes/source.js', { + '../../src/storage/object/delete.js': { + default: (e, c) => { + assert.deepStrictEqual(e, env); + assert.deepStrictEqual(c, daCtx); + return { status: 200 }; + }, + }, }, - } - ); - const resp = await deleteSource({req, env, daCtx}); - assert.equal(204, resp.status); - assert.deepStrictEqual(deleteCalled, ['deleteObject']); - assert.deepStrictEqual(daCalled, - ['https://localhost/api/v1/deleteadmin?doc=http://somehost.com/somedoc.html']); + ); + const resp = await deleteSource({ env, daCtx }); + assert.strictEqual(200, resp.status); + }); }); }); diff --git a/test/storage/object/delete.test.js b/test/storage/object/delete.test.js index 348a33e..5dcbcd8 100644 --- a/test/storage/object/delete.test.js +++ b/test/storage/object/delete.test.js @@ -10,9 +10,8 @@ * governing permissions and limitations under the License. */ import assert from 'node:assert'; +import esmock from 'esmock'; import { destroyMiniflare, getMiniflare } from '../../mocks/miniflare.js'; -import listObjects from '../../../src/storage/object/list.js'; -import deleteObjects from '../../../src/storage/object/delete.js'; describe('delete object(s)', () => { let mf; @@ -26,12 +25,41 @@ describe('delete object(s)', () => { }); it('handles no object', async () => { + const collabCalls = []; + const deleteObjects = await esmock( + '../../../src/storage/object/delete.js', { + '../../../src/storage/utils/collab.js': { + deleteFromCollab: async (env, daCtx, key) => { + collabCalls.push(key); + }, + }, + }, + ); + const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'does-not-exist.html' }; const resp = await deleteObjects(env, daCtx); assert.strictEqual(resp.status, 204); + assert.strictEqual(collabCalls.length, 2); }); it('deletes a single object', async () => { + const collabCalls = []; + const versionCalls = []; + const deleteObjects = await esmock( + '../../../src/storage/object/delete.js', { + '../../../src/storage/utils/collab.js': { + deleteFromCollab: async (env, daCtx) => { + collabCalls.push(daCtx.key); + }, + }, + '../../../src/storage/version/put.js': { + postObjectVersionWithLabel: async (env, daCtx, label) => { + assert.strictEqual(label, 'Deleted'); + versionCalls.push(daCtx.key) + }, + }, + }, + ); const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'outdoors/index.html' }; await env.DA_CONTENT.put('geometrixx/shapes.props', '{"key":"value"}'); @@ -40,26 +68,32 @@ describe('delete object(s)', () => { const resp = await deleteObjects(env, daCtx); assert.strictEqual(resp.status, 204); + assert(collabCalls.includes('outdoors/index.html')); + assert.strictEqual(versionCalls.length, 1); + assert.strictEqual(versionCalls[0], 'outdoors/index.html'); const head = await env.DA_CONTENT.head('geometrixx/outdoors/index.html'); assert.ifError(head); }); - it('deletes a single object (parameter)', async () => { - const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'outdoors/index.html' }; - - await env.DA_CONTENT.put('geometrixx/shapes.props', '{"key":"value"}'); - await env.DA_CONTENT.put('geometrixx/we-retail.props', '{"key":"value"}'); - await env.DA_CONTENT.put('geometrixx/outdoors/index.html', 'Hello'); - - const resp = await deleteObjects(env, daCtx, ['shapes.props']); - assert.strictEqual(resp.status, 204); - let head = await env.DA_CONTENT.head('geometrixx/outdoors/index.html'); - assert(head); - head = await env.DA_CONTENT.head('geometrixx/shapes.props'); - assert.ifError(head); - }); - it('deletes a folder', async () => { + const collabCalls = []; + const versionCalls = []; + const deleteObjects = await esmock( + '../../../src/storage/object/delete.js', { + '../../../src/storage/utils/collab.js': { + deleteFromCollab: async (env, daCtx) => { + collabCalls.push(daCtx.key); + }, + }, + '../../../src/storage/version/put.js': { + postObjectVersionWithLabel: async (env, daCtx, label) => { + assert.strictEqual(label, 'Deleted'); + versionCalls.push(daCtx.key) + }, + }, + }, + ); + await env.DA_CONTENT.put('geometrixx/outdoors/index.html', 'Hello!'); await env.DA_CONTENT.put('geometrixx/outdoors/logo.jpg', '1234'); await env.DA_CONTENT.put('geometrixx/outdoors/hero.jpg', '1234'); @@ -72,57 +106,41 @@ describe('delete object(s)', () => { assert.strictEqual(resp.status, 204); const list = await env.DA_CONTENT.list({ prefix: 'geometrixx/outdoors' }); assert.strictEqual(list.objects.length, 0); - }); - - it('does not delete a folder when passed as parameter', async () => { - await env.DA_CONTENT.put('geometrixx/outdoors/index.html', 'Hello!'); - await env.DA_CONTENT.put('geometrixx/outdoors/logo.jpg', '1234'); - await env.DA_CONTENT.put('geometrixx/outdoors/hero.jpg', '1234'); - await env.DA_CONTENT.put('geometrixx/outdoors/coats/coats.props', '{"key": "value"}'); - await env.DA_CONTENT.put('geometrixx/outdoors/pants/pants.props', '{"key": "value"}'); - await env.DA_CONTENT.put('geometrixx/outdoors/hats/hats.props', '{"key": "value"}'); - - const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'outdoors' }; - const resp = await deleteObjects(env, daCtx, ['outdoors']); - assert.strictEqual(resp.status, 204); - const list = await env.DA_CONTENT.list({ prefix: 'geometrixx/outdoors' }); - assert.strictEqual(list.objects.length, 6); + assert.strictEqual(collabCalls.length, 8); // 1 for each file, 1 for the folder & props + assert.strictEqual(versionCalls.length, 3); // 1 for each file, 1 for the folder & props }); it('deletes a folder (truncated list === true)', async function() { + const collabCalls = []; + const versionCalls = []; + const deleteObjects = await esmock( + '../../../src/storage/object/delete.js', { + '../../../src/storage/utils/collab.js': { + deleteFromCollab: async (env, daCtx, key) => { + collabCalls.push(key); + }, + }, + '../../../src/storage/version/put.js': { + postObjectVersionWithLabel: async (env, daCtx, label) => { + assert.strictEqual(label, 'Deleted'); + versionCalls.push(daCtx.key) + }, + }, + }, + ); + this.timeout(10000); await env.DA_CONTENT.put('geometrixx/outdoors/index.html', 'Hello!'); for (let i = 0; i < 1000; i++) { await env.DA_CONTENT.put(`geometrixx/outdoors/${i}/${i}.html`, 'Content'); } - const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'outdoors' }; + const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'outdoors' }; const resp = await deleteObjects(env, daCtx); assert.strictEqual(resp.status, 204); const list = await env.DA_CONTENT.list({ prefix: 'geometrixx/outdoors' }); assert.strictEqual(list.objects.length, 0); - }); - - it('deletes a list of explicit files', async () => { - await env.DA_CONTENT.put('geometrixx/outdoors/index.html', 'Hello!'); - await env.DA_CONTENT.put('geometrixx/outdoors/logo.jpg', '1234'); - await env.DA_CONTENT.put('geometrixx/outdoors/hero.jpg', '1234'); - await env.DA_CONTENT.put('geometrixx/outdoors/coats/coats.props', '{"key": "value"}'); - await env.DA_CONTENT.put('geometrixx/outdoors/pants/pants.props', '{"key": "value"}'); - await env.DA_CONTENT.put('geometrixx/outdoors/hats/hats.props', '{"key": "value"}'); - - const keys = [ - 'outdoors/index.html', - 'outdoors/logo.jpg', - 'outdoors/hero.jpg', - 'outdoors/coats/coats.props', - 'outdoors/pants/pants.props', - 'outdoors/hats/hats.props', - ]; - const daCtx = { users: [{email: 'aparker@geometrixx.info'}], org: 'geometrixx', key: 'outdoors' }; - const resp = await deleteObjects(env, daCtx, keys); - assert.strictEqual(resp.status, 204); - const list = await env.DA_CONTENT.list({ prefix: 'geometrixx/outdoors' }); - assert.strictEqual(list.objects.length, 0); + assert.strictEqual(collabCalls.length, 1003); // 1 for each file, 1 for the folder & props + assert.strictEqual(versionCalls.length, 1001); // 1 for each file, 1 for the folder & props }); }); diff --git a/test/storage/object/move.test.js b/test/storage/object/move.test.js index 60e07c5..ded6fd0 100644 --- a/test/storage/object/move.test.js +++ b/test/storage/object/move.test.js @@ -27,45 +27,88 @@ describe('Object move', () => { await destroyMiniflare(mf); }); - it('Moves a file', async () => { - const daCtx = { org: 'wknd', users: [{ email: "user@wknd.site" }], key: 'pages/index.html', isFile: true }; - const moveObject = await esmock( - '../../../src/storage/object/move.js', - { - '../../../src/storage/utils/copy.js': { - copyFile: async (env, daCtx, source, destination, isMove) => { - assert(isMove); - assert.strictEqual(source, 'pages/index.html'); - assert.strictEqual(destination, 'newdir/index.html'); - return { success: true, source: `wknd/${source}`, destination: `wknd/${destination}` }; + describe('Move a file', () => { + it('deletes source on success', async () => { + const copied = []; + const deleted = []; + const daCtx = { org: 'wknd', users: [{ email: "user@wknd.site" }], key: 'pages/index.html', isFile: true }; + const moveObject = await esmock( + '../../../src/storage/object/move.js', + { + '../../../src/storage/utils/copy.js': { + copyFile: async (env, daCtx, source, destination, isMove) => { + assert.strictEqual(source, 'pages/index.html'); + assert.strictEqual(destination, 'newdir/index.html'); + assert(isMove); + copied.push({ source, destination }); + return { success: true, source: `wknd/${source}`, destination: `wknd/${destination}` }; + } + }, + '../../../src/storage/object/delete.js': { + deleteObject: async (env, daCtx, key, isMove) => { + assert.strictEqual(key, 'pages/index.html'); + assert(isMove); + deleted.push(key); + } } } - } - ); - const details = { source: 'pages/index.html', destination: 'newdir/index.html' }; + ); + const details = { source: 'pages/index.html', destination: 'newdir/index.html' }; + const resp = await moveObject(env, daCtx, details); + assert.deepStrictEqual(resp, { status: 204 }); + assert.deepStrictEqual(copied, [{ source: 'pages/index.html', destination: 'newdir/index.html' }]); + assert.deepStrictEqual(deleted, ['pages/index.html']); + }); - const resp = await moveObject(env, daCtx, details); - assert.deepStrictEqual(resp, { status: 204 }); + it('retains source on failure', async () => { + const copied = []; + const deleted = []; + const daCtx = { org: 'wknd', users: [{ email: "user@wknd.site" }], key: 'pages/index.html', isFile: true }; + const moveObject = await esmock( + '../../../src/storage/object/move.js', + { + '../../../src/storage/utils/copy.js': { + copyFile: async (env, daCtx, source, destination, isMove) => { + assert.strictEqual(source, 'pages/index.html'); + assert.strictEqual(destination, 'newdir/index.html'); + assert(isMove); + copied.push({ source, destination }); + return { success: false, source: `wknd/${source}`, destination: `wknd/${destination}` }; + } + }, + '../../../src/storage/object/delete.js': { + deleteObject: async () => { + assert.fail('Should not be called'); + } + } + } + ); + const details = { source: 'pages/index.html', destination: 'newdir/index.html' }; + const resp = await moveObject(env, daCtx, details); + assert.deepStrictEqual(resp, { status: 204 }); + assert.deepStrictEqual(copied, [{ source: 'pages/index.html', destination: 'newdir/index.html' }]); + assert.strictEqual(deleted.length, 0); + }); }); - describe('Moves a folder', () => { + describe('Move a folder', () => { it('removes source on copy success', async () => { - const list = []; + const copied = []; + const deleted = []; const moveObject = await esmock( '../../../src/storage/object/move.js', { '../../../src/storage/utils/copy.js': { - copyFiles: async (env, daCtx, files, retainMetadata) => { - assert(retainMetadata); - list.push(...files); - assert.strictEqual(files.length, 2); - assert(files.find(({ src, dest }) => src === 'originaldir.props' && dest === 'newdir.props')); - assert(files.find(({ src, dest }) => src === 'originaldir/index.html' && dest === 'newdir/index.html')); - return files.map((item, idx) => ({ - success: true, - source: `wknd/${item.src}`, - destination: `wknd/${item.dest}` - })); + copyFile: async (env, daCtx, source, destination, isMove) => { + assert(isMove); + copied.push({ source, destination }); + return { success: true, source: `wknd/${source}`, destination: `wknd/${destination}` }; + }, + }, + '../../../src/storage/object/delete.js': { + deleteObject: async (env, daCtx, key, isMove) => { + assert(isMove); + deleted.push(key); } } } @@ -78,35 +121,31 @@ describe('Object move', () => { const details = { source: 'originaldir', destination: 'newdir' }; const resp = await moveObject(env, daCtx, details); assert.strictEqual(resp.status, 204); - assert.strictEqual(list.length, 2); - let head = await env.DA_CONTENT.head('wknd/originaldir.props'); - assert.ifError(head); - head = await env.DA_CONTENT.head('wknd/originaldir/index.html'); - assert.ifError(head); + assert.strictEqual(copied.length, 2); + assert.strictEqual(deleted.length, 2); }); it('retains source on copy failure', async () => { - const list = []; + const copied = []; + const deleted = []; const moveObject = await esmock( '../../../src/storage/object/move.js', { '../../../src/storage/utils/copy.js': { - copyFiles: async (env, daCtx, files, retainMetadata) => { - assert(retainMetadata); - list.push(...files); - assert.strictEqual(files.length, 2); - assert(files.find(({ src, dest }) => src === 'originaldir.props' && dest === 'newdir.props')); - assert(files.find(({ src, dest }) => src === 'originaldir/index.html' && dest === 'newdir/index.html')); - return files.map((item, idx) => ({ - success: false, - source: `wknd/${item.src}`, - destination: `wknd/${item.dest}` - })); + copyFile: async (env, daCtx, source, destination, isMove) => { + assert(isMove); + copied.push({ source, destination }); + return { success: true, source: `wknd/${source}`, destination: `wknd/${destination}` }; + }, + }, + '../../../src/storage/object/delete.js': { + deleteObject: async (env, daCtx, key, isMove) => { + assert.fail('Delete should not have been called'); + deleted.push(key); } } } ); - const daCtx = { org: 'wknd', users: [{ email: "user@wknd.site" }], isFile: false }; await env.DA_CONTENT.put('wknd/originaldir.props', '{"key":"value"}'); await env.DA_CONTENT.put('wknd/originaldir/index.html', 'HelloWorld'); @@ -114,30 +153,36 @@ describe('Object move', () => { const details = { source: 'originaldir', destination: 'newdir' }; const resp = await moveObject(env, daCtx, details); assert.strictEqual(resp.status, 204); - assert.strictEqual(list.length, 2); - let head = await env.DA_CONTENT.head('wknd/originaldir.props'); - assert(head); - head = await env.DA_CONTENT.head('wknd/originaldir/index.html'); - assert(head); + assert.strictEqual(copied.length, 2); + assert.strictEqual(deleted.length, 0); }); it('handles mix of success & failures', async function() { this.timeout(60000); - const list = []; + let i = 0; + const copied = []; + const deleted = []; const moveObject = await esmock( '../../../src/storage/object/move.js', { '../../../src/storage/utils/copy.js': { - copyFiles: async (env, daCtx, files, retainMetadata) => { - assert(retainMetadata); - list.push(...files); - return files.map((item, idx) => ({ - success: (idx % 2 === 0), - source: `wknd/${item.src}`, - destination: `wknd/${item.dest}` - })); + copyFile: async (env, daCtx, source, destination, isMove) => { + assert(isMove); + copied.push({ source, destination }); + i += 1; + return { + success: (i % 2 === 0), + source: `wknd/${source}`, + destination: `wknd/${destination}` + }; } - } + }, + '../../../src/storage/object/delete.js': { + deleteObject: async (env, daCtx, key, isMove) => { + assert(isMove); + deleted.push(key); + } + }, } ); const promises = []; @@ -153,28 +198,34 @@ describe('Object move', () => { const details = { source: 'originaldir', destination: 'newdir' }; const resp = await moveObject(env, daCtx, details); assert.strictEqual(resp.status, 204); - assert.strictEqual(list.length, 103); - const r2o = await env.DA_CONTENT.list({ prefix: 'wknd/originaldir/' }); - assert.strictEqual(r2o.objects.length, 51); // Even indices are successful + assert.strictEqual(copied.length, 103); + assert.strictEqual(deleted.length, 51); }); it('handles truncated folder list', async function() { this.timeout(60000); - const list = []; + const copied = []; + const deleted = []; const moveObject = await esmock( '../../../src/storage/object/move.js', { '../../../src/storage/utils/copy.js': { - copyFiles: async (env, daCtx, files, retainMetadata) => { - assert(retainMetadata); - list.push(...files); - return files.map((item, idx) => ({ + copyFile: async (env, daCtx, source, destination, isMove) => { + assert(isMove); + copied.push({ source, destination }); + return { success: true, - source: `wknd/${item.src}`, - destination: `wknd/${item.dest}` - })); + source: `wknd/${source}`, + destination: `wknd/${destination}` + }; } - } + }, + '../../../src/storage/object/delete.js': { + deleteObject: async (env, daCtx, key, isMove) => { + assert(isMove); + deleted.push(key); + } + }, } ); for (let i = 0; i < 251; i++) { @@ -188,11 +239,8 @@ describe('Object move', () => { const details = { source: 'originaldir', destination: 'newdir' }; const resp = await moveObject(env, daCtx, details); assert.strictEqual(resp.status, 204); - assert.strictEqual(list.length, 253); - - const r2o = await env.DA_CONTENT.list({ prefix: 'wknd/originaldir/' }); - assert.strictEqual(r2o.truncated, false); - assert.strictEqual(r2o.objects.length, 0); + assert.strictEqual(copied.length, 253); + assert.strictEqual(deleted.length, 253); }); }); }); diff --git a/test/storage/utils/collab.test.js b/test/storage/utils/collab.test.js new file mode 100644 index 0000000..6d5779c --- /dev/null +++ b/test/storage/utils/collab.test.js @@ -0,0 +1,89 @@ +/* +* Copyright 2024 Adobe. All rights reserved. +* This file is licensed to you under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. You may obtain a copy +* of the License at http://www.apache.org/licenses/LICENSE-2.0 + * +* Unless required by applicable law or agreed to in writing, software distributed under +* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +* OF ANY KIND, either express or implied. See the License for the specific language +* governing permissions and limitations under the License. +*/ +import { deleteFromCollab, syncCollab } from '../../../src/storage/utils/collab.js'; +import assert from 'node:assert'; + +const DA_CTX = { + origin: 'http://localhost:9876', + api: 'source', + org: 'geometrixx', +}; + + +describe('collab invalidation', () => { + describe('no op cases', () => { + it('does not invalidate collab if initiator is collab', async () => { + const daCtx = { + key: 'somedoc.html', + initiator: 'collab', + ...DA_CTX, + }; + + const env = { + dacollab: { + fetch: async () => { + assert.fail('should not call fetch'); + } + } + }; + await deleteFromCollab(env, daCtx); + }); + it('collab if file is not html', async () => { + const daCtx = { + key: 'somedoc.props', + ...DA_CTX, + }; + const env = { + dacollab: { + fetch: async () => { + assert.fail('should not call fetch'); + } + } + }; + await deleteFromCollab(env, daCtx); + }); + }); + + describe('delete action', () => { + it('deletes from collab', async () => { + const daCtx = { + key: 'somedoc.html', + ...DA_CTX, + }; + const env = { + dacollab: { + fetch: async (url) => { + assert.strictEqual(url, 'https://localhost/api/v1/deleteadmin?doc=http://localhost:9876/source/geometrixx/somedoc.html'); + } + } + }; + await deleteFromCollab(env, daCtx); + }); + }); + + describe('sync action', () => { + it('syncs collab', async () => { + const daCtx = { + key: 'somedoc.html', + ...DA_CTX, + }; + const env = { + dacollab: { + fetch: async (url) => { + assert.strictEqual(url, 'https://localhost/api/v1/syncadmin?doc=http://localhost:9876/source/geometrixx/somedoc.html'); + } + } + }; + await syncCollab(env, daCtx); + }); + }); +});