diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..4e069023 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,3 @@ +{ + "hooks": {} +} diff --git a/.env.template b/.env.template new file mode 100644 index 00000000..ae9a6dbe --- /dev/null +++ b/.env.template @@ -0,0 +1,5 @@ +# Name of Kontent.ai project: SDK Integration tests + +INTEGRATION_ENVIRONMENT_ID=6bdd84fc-f71e-01a0-0ba6-79ce07af7f9b +# INTEGRATION_DELIVERY_HOST=deliver.kontent.ai +# INTEGRATION_DELIVERY_PROTOCOL=https diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..fcadb2cf --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e6444fd6..c2f5379c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths. # See https://help.github.com/articles/about-code-owners/ -* @IvanKiral @Enngage @kontent-ai/javascript-maintainers +* @Enngage @kontent-ai/javascript-maintainers diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..1505086a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,20 @@ +name: Lint & Build + +on: + push: + branches: [main] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - name: Use Node.js from .nvmrc file + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: pnpm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..29e43016 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,35 @@ +on: + release: + types: [published] + +permissions: + # Required for OIDC publishing + id-token: write + contents: read + +env: + INTEGRATION_ENVIRONMENT_ID: ${{ secrets.INTEGRATION_ENVIRONMENT_ID }} + +name: publish-to-npm +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install --frozen-lockfile + - run: pnpm run build + - run: pnpm run test + + - run: pnpm publish --access=public --no-git-checks + if: ${{!github.event.release.prerelease}} + - run: pnpm publish --tag prerelease --access=public --no-git-checks + if: ${{github.event.release.prerelease}} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index a0ec0cc2..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Test -on: [pull_request] -jobs: - build: - runs-on: windows-latest - strategy: - matrix: - node-version: [14.x] - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm i - - run: npm run test:all diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..aee382ff --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,24 @@ +name: Tests & Coverage + +on: + push: + branches: [main] + pull_request: + +env: + INTEGRATION_ENVIRONMENT_ID: ${{ secrets.INTEGRATION_ENVIRONMENT_ID }} + INTEGRATION_MANAGEMENT_API_KEY: ${{ secrets.INTEGRATION_MANAGEMENT_API_KEY }} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - name: Use Node.js from .nvmrc file + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: pnpm run test diff --git a/.gitignore b/.gitignore index 45b8a0ae..9fcf9394 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,14 @@ # Custom .editorconfig +.env +.claude/settings.local.json # See http://help.github.com/ignore-files/ for more about ignoring files. # compiled output +/definitions /dist +/bundles /tmp /coverage /out-tsc @@ -34,6 +38,7 @@ /coverage /libpeerconnection.log npm-debug.log +package-lock.json testem.log /typings diff --git a/.npmignore b/.npmignore index 79e1373f..587b685a 100644 --- a/.npmignore +++ b/.npmignore @@ -1,10 +1,6 @@ # Ignore everything * - -# But descend into directories - -# Recursively allow files under subtree -!/lib/** +# And allow following !/dist/** !package.json !.npmignore @@ -12,4 +8,3 @@ !LICENSE.md - diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..1a2f5bd2 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/* \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 71f32090..00000000 --- a/.prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "singleQuote": true, - "printWidth": 120, - "proseWrap": "always", - "tabWidth": 4, - "requireConfig": false, - "useTabs": false, - "trailingComma": "none", - "bracketSpacing": true, - "semi": true -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 3fa5069d..c020c803 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,34 @@ { - "typescript.tsdk": "node_modules\\typescript\\lib", -} \ No newline at end of file + "typescript.tsdk": "node_modules\\typescript\\lib", + "files.eol": "\n", + "typescript.updateImportsOnFileMove.enabled": "always", + "editor.defaultFormatter": "biomejs.biome", + "editor.codeActionsOnSave": { + "source.fixAll.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, + "editor.formatOnSave": true, + "typescript.format.enable": false, + "javascript.format.enable": false, + "[markdown]": { + "editor.formatOnSave": true + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[scss]": { + "editor.defaultFormatter": "vscode.css-language-features" + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index f67e36c7..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,1030 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. - -## [16.4.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v16.3.0...v16.4.0) (2025-11-11) - - -### Features - -* updates deps ([3815581](https://github.com/kontent-ai/delivery-sdk-js/commit/3815581bd075aad53e934078d118fb6580bb13d9)) - -## [16.3.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v16.2.1...v16.3.0) (2025-08-05) - - -### Features - -* updates deps ([f4b306b](https://github.com/kontent-ai/delivery-sdk-js/commit/f4b306bd79f9088b64635a81002572a514bc0236)) - -### [16.2.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v16.2.0...v16.2.1) (2025-07-03) - -## [16.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v16.1.0...v16.2.0) (2025-04-30) - - -### Features - -* updates deps ([0d72545](https://github.com/kontent-ai/delivery-sdk-js/commit/0d72545bf8d3aea85731ae279f63d0937fbabff1)) - - -### Bug Fixes - -* **models:** correct typo in workflowStepCodenames property ([58428fd](https://github.com/kontent-ai/delivery-sdk-js/commit/58428fdc16cccd94e4ec84c93b8e2bd0cb68762c)) - -## [16.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v16.0.0...v16.1.0) (2025-04-10) - - -### Features - -* Adds delivery client types to items feed query ([f834b31](https://github.com/kontent-ai/delivery-sdk-js/commit/f834b3171b3f0c51c54bf90a343ba33fcca8b279)) -* Adds support for asset/item used queries ([a321d40](https://github.com/kontent-ai/delivery-sdk-js/commit/a321d40f2ff9f1848f98750750fa0c200259bbb1)) -* updates deps ([5e52ac6](https://github.com/kontent-ai/delivery-sdk-js/commit/5e52ac63bc8d6171fd003f74d0ee2c5418a82b1e)) - -## [16.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v16.0.0-0...v16.0.0) (2025-03-11) - - -### Features - -* adds support for client generics, improving type safety ([89cbc39](https://github.com/kontent-ai/delivery-sdk-js/commit/89cbc3972af5b9d38648afb47b933cb11b2e21e1)) -* updates deps ([7f957d0](https://github.com/kontent-ai/delivery-sdk-js/commit/7f957d0d868e758eda03efed979a926c401d03a1)) - -## [16.0.0-0](https://github.com/kontent-ai/delivery-sdk-js/compare/v15.2.0...v16.0.0-0) (2025-02-13) - - -### Features - -* adds support for client generics, improving type safety in combination with model generator ([d45a0e3](https://github.com/kontent-ai/delivery-sdk-js/commit/d45a0e385e3ddc2b88805ef7c69725c5fdf84f18)) -* removes url-parse package in favor of native URL class ([34bfe8f](https://github.com/kontent-ai/delivery-sdk-js/commit/34bfe8f93df1f801948f4f948f6de0671d4cc524)) -* updates deps ([6335bba](https://github.com/kontent-ai/delivery-sdk-js/commit/6335bbaa49e92a75ae34bfda22844c217b36d31a)) - - -### Bug Fixes - -* package.json & package-lock.json to reduce vulnerabilities ([da3b536](https://github.com/kontent-ai/delivery-sdk-js/commit/da3b536e4b1c99344f3ecb7135257136f07c587c)) - -## [15.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v15.1.1...v15.2.0) (2024-09-27) - - -### Features - -* exports optional 'Snippet' type used for strongly typed modelling ([96ef2d5](https://github.com/kontent-ai/delivery-sdk-js/commit/96ef2d5b708a83006917bdd9d985035cae079445)) - -### [15.1.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v15.1.0...v15.1.1) (2024-09-27) - - -### Bug Fixes - -* re-exports IContentItemElements type ([ddc570f](https://github.com/kontent-ai/delivery-sdk-js/commit/ddc570f9d34bcc7db555cd093f98d9144b67ce94)) - -## [15.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v15.0.0...v15.1.0) (2024-09-26) - - -### Features - -* Adds support for constraining item element properties using pre-defined codenames type ([c7b16b7](https://github.com/kontent-ai/delivery-sdk-js/commit/c7b16b7e70c4ea223e432a76bc059ba94916bc58)) -* updates deps ([03fdc22](https://github.com/kontent-ai/delivery-sdk-js/commit/03fdc22f153d573fc4b0d8bc483795cbafb9a1b5)) - -## [15.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v15.0.0-0...v15.0.0) (2024-09-16) - -### Features - -- updates deps - ([7d0618c](https://github.com/kontent-ai/delivery-sdk-js/commit/7d0618c708530d161fc1febc4e6b89e7819e48cd)) - -## [15.0.0-0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.11.0...v15.0.0-0) (2024-09-10) - -### ⚠ BREAKING CHANGES - -- Removes parser & rich text resolver. To work with RTE use the newer and better `@kontent-ai/rich-text-resolver` - library instead. -- Removes `propertyName` resolver configuration. All elements are now referenced only by their codenames present in - Kontent.ai - -### Features - -- Adds narrowing types for Taxonomy & Multiple choice elements - ([3118752](https://github.com/kontent-ai/delivery-sdk-js/commit/3118752e05fe27f09b72c7bab21804b114fa057e)) -- Adds optional generic types to `IContentItem` narrowing down available values of system attributes - ([8c894af](https://github.com/kontent-ai/delivery-sdk-js/commit/8c894afde62ee2ed40b44fbebc9dd9b8891115c5)) -- Makes `RichTextElement` take generic parameter narrowing down allowed types of linked items - ([68b31a8](https://github.com/kontent-ai/delivery-sdk-js/commit/68b31a81431646a7ab06647652592b81d075527b)) -- Removes `propertyName` resolver configuration. All elements are now referenced only by their codenames present in - Kontent.ai - ([7ef5951](https://github.com/kontent-ai/delivery-sdk-js/commit/7ef5951c505b1acf2424c99255f435aa1a26a53e)) -- Removes parser & rich text resolver. To work with RTE use the newer and better `@kontent-ai/rich-text-resolver` - library instead. - ([2bd30c3](https://github.com/kontent-ai/delivery-sdk-js/commit/2bd30c3d4527b470848984d70e03136c2e01885e)) -- updates deps - ([82c2c11](https://github.com/kontent-ai/delivery-sdk-js/commit/82c2c115482b0ee5ab74e3a94d9e8ebb55112532)) - -### Upgrading to new RTE parser - -In `< 15.0.0` versions of this SDK you were able to resolve RTE elements like this: - -```typescript -import { createRichTextHtmlResolver, createDeliveryClient, linkedItemsHelper } from '@kontent-ai/delivery-sdk'; - -export type Movie = IContentItem<{ - plot: Elements.RichTextElement; -}>; - -export type Actor = IContentItem<{ - firstName: Elements.RichTextElement; -}>; - -// get content item with rich text element -const response = ( - await createDeliveryClient({ environmentId: '' }).item('itemCodename').toPromise() -).data; - -// get rich text element -const richTextElement = response.item.plot; - -// resolve HTML -const resolvedRichText = createRichTextHtmlResolver().resolveRichText({ - element: richTextElement, - linkedItems: linkedItemsHelper.convertLinkedItemsToArray(response.data.linkedItems), - imageResolver: (imageId, image) => { - return { - imageHtml: ``, - // alternatively you may return just url - imageUrl: 'customUrl' - }; - }, - urlResolver: (linkId, linkText, link) => { - return { - linkHtml: `${link?.link?.urlSlug}`, - // alternatively you may return just url - linkUrl: 'customUrl' - }; - }, - contentItemResolver: (itemId, contentItem) => { - if (contentItem && contentItem.system.type === 'actor') { - const actor = contentItem as Actor; - return { - contentItemHtml: `
${actor.elements.firstName.value}
` - }; - } - - return { - contentItemHtml: '' - }; - } -}); - -const resolvedHtml = resolvedRichText.html; -``` - -But since this resolver is now removed in `>= 15.0.0` you need to resolve RTE using the `@kontent-ai/rich-text-resolver` -package: - -```typescript -import { createDeliveryClient, Elements, IContentItem } from '@kontent-ai/delivery-sdk'; -import { PortableTextOptions, toHTML } from '@portabletext/to-html'; -import { nodeParse, transformToPortableText, resolveTable, resolveImage } from '@kontent-ai/rich-text-resolver'; - -type Movie = IContentItem<{ - title: Elements.TextElement; - plot: Elements.RichTextElement; -}>; - -type Actor = IContentItem<{ - first_name: Elements.RichTextElement; -}>; - -const itemResponse = await createDeliveryClient({ - environmentId: 'da5abe9f-fdad-4168-97cd-b3464be2ccb9' -}) - .item('warrior') - .toPromise(); - -const richTextElement = itemResponse.data.item.elements.plot; - -const linkedItems = Object.values(itemResponse.data.linkedItems); -const parsedTree = nodeParse(richTextElement.value); -const portableText = transformToPortableText(parsedTree); - -const portableTextComponents: PortableTextOptions = { - components: { - types: { - image: ({ value }) => { - return resolveImage(value, (image) => { - return ``; - }); - }, - component: ({ value }) => { - const linkedItem = linkedItems.find((item) => item.system.codename === value.component._ref); - switch (linkedItem?.system.type) { - case 'actor': { - const actor = linkedItem as Actor; - return `
${actor.elements.first_name.value}
`; - } - default: { - return `Resolver for type ${linkedItem?.system.type} not implemented.`; - } - } - }, - table: ({ value }) => { - // default impl - return resolveTable(value, toHTML); - } - }, - marks: { - internalLink: ({ children, value }) => { - return `${children}`; - } - } - } -}; - -const resolvedHtml = toHTML(portableText, portableTextComponents); -``` - -## [14.11.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.10.0...v14.11.0) (2024-08-15) - -### Features - -- updates deps (& fixes Axios vulnerability), updates eslint config - ([ba49770](https://github.com/kontent-ai/delivery-sdk-js/commit/ba497700f460c43d2ea18db9b669cdd246112049)) - -## [14.10.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.9.0...v14.10.0) (2024-06-28) - -### Features - -- updates deps - ([769173b](https://github.com/kontent-ai/delivery-sdk-js/commit/769173b6c6b30d3524d5b065cc20b2b1eb3ac7c5)) - -## [14.9.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.8.0...v14.9.0) (2024-04-29) - -### Features - -- updates deps - ([f6c2a2f](https://github.com/kontent-ai/delivery-sdk-js/commit/f6c2a2f44a7830b300c65440f9139e44f5fa5ae8)) - -## [14.8.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.7.0...v14.8.0) (2024-03-06) - -### Features - -- adds support for 'excludeElements' parameter (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/389) - ([64a2b17](https://github.com/kontent-ai/delivery-sdk-js/commit/64a2b17c9c461a0e0a58e96860a111e3dec20e5d)) -- updates deps, adds clean script, updates engine version to >= v18 - ([6135b03](https://github.com/kontent-ai/delivery-sdk-js/commit/6135b035d59f05bb41e9208ca9c02a81d61700c2)) - -## [14.7.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.6.0...v14.7.0) (2024-02-29) - -### Features - -- updates deps (and fixes https://github.com/kontent-ai/delivery-sdk-js/issues/387) - ([4d9df4b](https://github.com/kontent-ai/delivery-sdk-js/commit/4d9df4b30ac897448ed762311c887e58b5fb6f20)) - -### Bug Fixes - -- escapes codenames to prevent collisions with javascript constructs (fixes - https://github.com/kontent-ai/delivery-sdk-js/issues/388) - ([c5ea589](https://github.com/kontent-ai/delivery-sdk-js/commit/c5ea58924fd0113003999432e15a82f46ac88e6b)) - -## [14.6.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.5.0...v14.6.0) (2023-12-19) - -### Features - -- Adds 'workflow' to system attributes - ([6a0bf11](https://github.com/kontent-ai/delivery-sdk-js/commit/6a0bf11f45de93f87774f1d1b1b682c0df2b5c35)) - -## [14.5.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.4.0...v14.5.0) (2023-11-16) - -### Features - -- updates deps (core-sdk with updated axios) (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/382) - ([df83fdd](https://github.com/kontent-ai/delivery-sdk-js/commit/df83fdde6c730702f7567d5b1d43a59b9a463045)) - -## [14.4.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.3.1...v14.4.0) (2023-08-21) - -### Features - -- Adds 'excludeArchivedItems' client configuration & fixes element endpoint mapping due to API change - ([19f3fff](https://github.com/kontent-ai/delivery-sdk-js/commit/19f3fff6ae50ccf81d7dcf49a81329ad3c7c8a09)) -- updates deps & increases required node version - ([4b0dee3](https://github.com/kontent-ai/delivery-sdk-js/commit/4b0dee3f8c3050d3283c12038dad0755a2d5aa98)) - -### [14.3.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.3.0...v14.3.1) (2023-08-02) - -### Bug Fixes - -- Reverts language codename check (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/372) - ([227ec5f](https://github.com/kontent-ai/delivery-sdk-js/commit/227ec5f5c3b58784f612672b57676b34bd240bda)) - -## [14.3.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.2.0...v14.3.0) (2023-07-31) - -### Features - -- updates deps, migrates to eslint, adds migrate related code fixes - ([288cbb7](https://github.com/kontent-ai/delivery-sdk-js/commit/288cbb7ed6a853fce11383ab5f7475fe45758233)) - -### Bug Fixes - -- typos ([3702502](https://github.com/kontent-ai/delivery-sdk-js/commit/3702502f6519e499f51ed2bf09f362d1667cc6ec)) - -## [14.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.1.0...v14.2.0) (2023-06-02) - -### Features - -- adds support for linking items across responses when using toAllPromise items endpoint - ([67e8e16](https://github.com/kontent-ai/delivery-sdk-js/commit/67e8e1653194b0b1e425ff390a094b29e7d4c1ff)) -- updates dependencies - ([b83b3bd](https://github.com/kontent-ai/delivery-sdk-js/commit/b83b3bdbfb799857e1b2804d3afebd3b4693cb20)) - -## [14.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.0.1...v14.1.0) (2023-05-16) - -### Features - -- rangeFilter now accepts strings, other comparison filters now accept numbers - ([14e53e8](https://github.com/kontent-ai/delivery-sdk-js/commit/14e53e86c93625faaa955e7570bdf8bf6c5f609b)) -- updates deps - ([3723aa0](https://github.com/kontent-ai/delivery-sdk-js/commit/3723aa020f4b83420883ba36dda0188c6fc1268a)) - -### Bug Fixes - -- Preserves linked items order when using items-feed with item mapping - ([e62d261](https://github.com/kontent-ai/delivery-sdk-js/commit/e62d261356112a6378d09399ed2b8cf67e866f1c)) - -### [14.0.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v14.0.0...v14.0.1) (2023-04-12) - -### Bug Fixes - -- fixes sync endpoint URL (removes early-access) - ([0fa47b1](https://github.com/kontent-ai/delivery-sdk-js/commit/0fa47b1580380cc0ad27faadc77140d152e37628)) - -## [14.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v13.0.0...v14.0.0) (2023-04-12) - -### ⚠ BREAKING CHANGES - -- Renames `project_id` to `environment_id` across entire library - -## [13.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.4.3...v13.0.0) (2023-04-12) - -### ⚠ BREAKING CHANGES - -- Implements new Sync API models (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/363) -- Uses new URL for Sync API endpoints - -### Features - -- adds automatic object linking for linked items / rich text elements in items feed query - ([c246d31](https://github.com/kontent-ai/delivery-sdk-js/commit/c246d31161d1a058f6f81a131eb3907ecc5d9b34)) -- Implements new Sync API models (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/363) - ([28e6f11](https://github.com/kontent-ai/delivery-sdk-js/commit/28e6f11d74f858d6ab14c53b5768eb9e58873d4e)) -- updates all dependencies - ([4bde5e1](https://github.com/kontent-ai/delivery-sdk-js/commit/4bde5e1cea18549dbb1341b1761e7e8c480242e1)) -- updates dev dependencies - ([1c5cc70](https://github.com/kontent-ai/delivery-sdk-js/commit/1c5cc707ebb519f8eeec5bd62c00034ebd042c41)) -- Uses new URL for Sync API endpoints - ([55fbc11](https://github.com/kontent-ai/delivery-sdk-js/commit/55fbc11b1cd519cf9b1e6c92ca3d2c6a57a16959)) - -### [12.4.3](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.4.2...v12.4.3) (2023-02-20) - -### Bug Fixes - -- Handles '+' sign in name resolvers - ([e30f235](https://github.com/kontent-ai/delivery-sdk-js/commit/e30f23558b790b8c046e26e37889d29a03bd2422)) - -### [12.4.2](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.4.1...v12.4.2) (2022-11-21) - -- Adds support for timezone in date elements - -### [12.4.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.4.0...v12.4.1) (2022-11-01) - -### Bug Fixes - -- fixes query configuration for initialize sync POST request - ([42f317c](https://github.com/kontent-ai/delivery-sdk-js/commit/42f317cf3828b421188bccfb102a0a89077d4cea)) - -## [12.4.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.3.0...v12.4.0) (2022-10-27) - -### Features - -- Adds support for 'Sync API' - Initialize sync & sync changes endpoints - ([60d4198](https://github.com/kontent-ai/delivery-sdk-js/commit/60d41980e9d4babd3e9f613135f48185915103b1)) -- updates dev dependencies - ([b6b3d16](https://github.com/kontent-ai/delivery-sdk-js/commit/b6b3d16855e2ffc40d1a64c1d80da1068e64e0f0)) - -### Bug Fixes - -- fixes mapping of view content type element query - ([8c14c39](https://github.com/kontent-ai/delivery-sdk-js/commit/8c14c393de78a920570de4e0f37694b49df78615)) - -## [12.3.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.2.0...v12.3.0) (2022-10-05) - -### Features - -- updates dependencies - ([b8b85e3](https://github.com/kontent-ai/delivery-sdk-js/commit/b8b85e32b09880fa994b4f97f66c62f33eac0e5c)) - -## [12.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.1.0...v12.2.0) (2022-09-23) - -### Features - -- Preservers the order of mapped linkedItems in RTE - ([5d9db00](https://github.com/kontent-ai/delivery-sdk-js/commit/5d9db0079b1ea87f6225fe225eb1e772ad79743b)) -- Updates dependencies - ([0a4d0bf](https://github.com/kontent-ai/delivery-sdk-js/commit/0a4d0bf83863a2acb453b48ef34a5a4a7cf08a97)) - -## [12.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.0.2...v12.1.0) (2022-09-01) - -### Features - -- Handle commas & semicolons in name resolvers - ([d990dcf](https://github.com/kontent-ai/delivery-sdk-js/commit/d990dcf8f976408efeca7692d05a9ad1f77a4279)) - -### [12.0.2](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.0.1...v12.0.2) (2022-07-21) - -### Bug Fixes - -- Handle '/' character in property name resolvers - ([9ed6c77](https://github.com/kontent-ai/delivery-sdk-js/commit/9ed6c771129fb97e5e68708295fe9277be728380)) - -### [12.0.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.0.0...v12.0.1) (2022-07-15) - -### Bug Fixes - -- escapes property name regex to prevent unintended escaping caused by angular CLI - ([0913986](https://github.com/kontent-ai/delivery-sdk-js/commit/0913986809a73fc09cda47a1acffe2352e3415cc)) - -## [12.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v12.0.0-0...v12.0.0) (2022-07-14) - -## [12.0.0-0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.13.0...v12.0.0-0) (2022-07-14) - -## [11.13.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.7.0...v11.13.0) (2022-05-23) - -### Features - -- Adds underscore to name resolver when it starts with a number - ([5a624e3](https://github.com/kontent-ai/delivery-sdk-js/commit/5a624e3f59626f7b6c6bb94b9730f1c3edf2f721)) -- Automatically removes zero width characters from name resolvers - ([fbf07aa](https://github.com/kontent-ai/delivery-sdk-js/commit/fbf07aab776050ba006d1bc8a8d562679ce2dcfe)) -- convert snake case name resolver to lowercase only text - ([df39537](https://github.com/kontent-ai/delivery-sdk-js/commit/df395375f679a893b2d29b5409c4a0a3c2e6576d)) -- Handles '&' in property name resolver - ([e82ae6d](https://github.com/kontent-ai/delivery-sdk-js/commit/e82ae6d82662fda9786d26b6cebc6480fb95bc98)) -- Handles brackets in property name resolver - ([946db34](https://github.com/kontent-ai/delivery-sdk-js/commit/946db349de6a4add3a614e44daaab17720281011)) -- Improves property name resolvers by handling more special characters and unifies the regex across all name resolvers - ([d153e81](https://github.com/kontent-ai/delivery-sdk-js/commit/d153e81ff2d3114d31ae016bc9d8c3073571da94)) -- updates dependencies - ([5830491](https://github.com/kontent-ai/delivery-sdk-js/commit/5830491080767f22b49763051fda89c86f500b47)) -- updates dependencies - ([a373528](https://github.com/kontent-ai/delivery-sdk-js/commit/a373528b6f6167ebcf9b6c2e5395b1ba0d061bd2)) - -### Bug Fixes - -- fixes property name resolver to cover cases with mixed upper/lower case strings - ([66918c9](https://github.com/kontent-ai/delivery-sdk-js/commit/66918c99b6da2d94d7115baa581669ccb7fd048c)) -- Properly sets query headers (some headers were not applied which caused issues especially in combination with - paging) ([59af6c4](https://github.com/kontent-ai/delivery-sdk-js/commit/59af6c404846d71e52810813d837a8ea4c26c802)) - -## [11.12.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.11.0...v11.12.0) (2022-04-20) - -### Features - -- Handles '&' in property name resolver - ([e82ae6d](https://github.com/kontent-ai/delivery-sdk-js/commit/e82ae6d82662fda9786d26b6cebc6480fb95bc98)) - -## [11.11.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.10.0...v11.11.0) (2022-04-20) - -### Features - -- convert snake case name resolver to lowercase only text - ([df39537](https://github.com/kontent-ai/delivery-sdk-js/commit/df395375f679a893b2d29b5409c4a0a3c2e6576d)) -- Handles brackets in property name resolver - ([946db34](https://github.com/kontent-ai/delivery-sdk-js/commit/946db349de6a4add3a614e44daaab17720281011)) - -## [11.10.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.9.0...v11.10.0) (2022-04-20) - -### Features - -- Adds underscore to name resolver when it starts with a number - ([5a624e3](https://github.com/kontent-ai/delivery-sdk-js/commit/5a624e3f59626f7b6c6bb94b9730f1c3edf2f721)) - -## [11.9.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.8.1...v11.9.0) (2022-04-20) - -### Features - -- Automatically removes zero width characters from name resolvers - ([fbf07aa](https://github.com/kontent-ai/delivery-sdk-js/commit/fbf07aab776050ba006d1bc8a8d562679ce2dcfe)) - -### [11.8.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.8.0...v11.8.1) (2022-04-20) - -### Bug Fixes - -- fixes property name resolver to cover cases with mixed upper/lower case strings - ([66918c9](https://github.com/kontent-ai/delivery-sdk-js/commit/66918c99b6da2d94d7115baa581669ccb7fd048c)) - -## [11.8.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.6.0...v11.8.0) (2022-04-20) - -### Features - -- Adds support for strongly typed taxonomy element - ([c3d85ee](https://github.com/kontent-ai/delivery-sdk-js/commit/c3d85eecfd7fa3ced980d741195207596a3e44b8)) -- Improves property name resolvers by handling more special characters and unifies the regex across all name resolvers - ([d153e81](https://github.com/kontent-ai/delivery-sdk-js/commit/d153e81ff2d3114d31ae016bc9d8c3073571da94)) -- updates dependencies - ([a373528](https://github.com/kontent-ai/delivery-sdk-js/commit/a373528b6f6167ebcf9b6c2e5395b1ba0d061bd2)) - -## [11.7.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.5.0...v11.7.0) (2022-03-28) - -### Features - -- Adds support for strongly typed taxonomy element - ([c3d85ee](https://github.com/kontent-ai/delivery-sdk-js/commit/c3d85eecfd7fa3ced980d741195207596a3e44b8)) -- updates deps - ([d899b0b](https://github.com/kontent-ai/delivery-sdk-js/commit/d899b0ba4eb4b52032657f6909eae1a833d2ec38)) - -## [11.6.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.5.0...v11.6.0) (2022-03-23) - -### Features - -- updates deps - ([d899b0b](https://github.com/kontent-ai/delivery-sdk-js/commit/d899b0ba4eb4b52032657f6909eae1a833d2ec38)) - -## [11.5.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.5.0-1...v11.5.0) (2022-03-14) - -## [11.5.0-1](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.5.0-0...v11.5.0-1) (2022-03-10) - -## [11.5.0-0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.4.0...v11.5.0-0) (2022-03-07) - -### Features - -- Adds 'linkedItems' property to Rich text element that contains array or mapped linked items included in the element - (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/338) - ([9a48ae5](https://github.com/kontent-ai/delivery-sdk-js/commit/9a48ae53c1c2075a313207e6d7bba6a57c72d193)) -- adds ability to preserve 'object' tags in RTE Html - ([6034f89](https://github.com/kontent-ai/delivery-sdk-js/commit/6034f89da4a7df046e5c6d514780c96fa5ed228c)) -- adds ability to set custom wrap tag for object & json Rich text resolvers (fixes - https://github.com/kontent-ai/delivery-sdk-js/issues/339) - ([a6899ff](https://github.com/kontent-ai/delivery-sdk-js/commit/a6899ff06a7edb6256b3c7675d7a4ff635cefe7d)) -- Removes 'object' wrapper tag from resolved Rich text element HTML (fixes - https://github.com/kontent-ai/delivery-sdk-js/issues/332) - ([d9f9f74](https://github.com/kontent-ai/delivery-sdk-js/commit/d9f9f741f5bc7fbaec44c54c7703627af1b032b4)) -- updates deps ( fixes https://github.com/kontent-ai/delivery-sdk-js/issues/342) - ([517501e](https://github.com/kontent-ai/delivery-sdk-js/commit/517501e3228c59679adfbc22c42c9feb7f4e6904)) - -## [11.4.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.4.0-0...v11.4.0) (2022-02-04) - -### Features - -- updates deps - ([dbb0474](https://github.com/kontent-ai/delivery-sdk-js/commit/dbb0474c551088257a71c7200d5ce2a28ea05a5a)) -- adds ability to configure default asset rendition - -## [11.3.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.3.0-0...v11.3.0) (2021-12-16) - -### Features - -- Adds support for custom asset domains (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/333) - ([c8e70e4](https://github.com/kontent-ai/delivery-sdk-js/commit/c8e70e402a3b81fcdf965c68fd51842e39958bef)) - -### [11.2.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.2.1-0...v11.2.1) (2021-12-09) - -### Bug Fixes - -- use null instead of undefined for asset model properties - ([da7ff46](https://github.com/kontent-ai/delivery-sdk-js/commit/da7ff461aad6dbf04c31dabdbcd4c9a11cdf743e)) - -## [11.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.2.0-0...v11.2.0) (2021-12-02) - -### Features - -- adds absolute url to rendition record - ([a6a0ece](https://github.com/kontent-ai/delivery-sdk-js/commit/a6a0ece29e001fc4c892d54ca816bb75d494176a)) - -## [11.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.1.0-0...v11.1.0) (2021-11-29) - -### Features - -- updates dependencies - ([b0b3ff5](https://github.com/kontent-ai/delivery-sdk-js/commit/b0b3ff564fd3d35691a2b9b92d6b3e6fb04fe5af)) - -## [11.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-11...v11.0.0) (2021-11-16) - -### Features - -- renames INetworkResponse interface to IDeliveryNetworkResponse - ([e566537](https://github.com/kontent-ai/delivery-sdk-js/commit/e5665372563b485dc050ae1919910612b00c4bf2)) -- updates deps - ([42a6ff9](https://github.com/kontent-ai/delivery-sdk-js/commit/42a6ff9bbc070133f8f3e52f02c0f3e5d3cd9939)) - -## [11.0.0-11](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-10...v11.0.0-11) (2021-10-27) - -## [11.0.0-10](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-9...v11.0.0-10) (2021-10-27) - -### Features - -- updates readme, creates base rich text resolvers and uses function to create each and every available resolver - ([1cf140c](https://github.com/kontent-ai/delivery-sdk-js/commit/1cf140ce98074d2e590e5eefad5fed7fac3afe39)) - -## [11.0.0-9](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-8...v11.0.0-9) (2021-10-27) - -### Features - -- updates names rich text related async models - ([231f4f6](https://github.com/kontent-ai/delivery-sdk-js/commit/231f4f684fe81982b1f5c8c5956dc55aae4fdbc5)) - -## [11.0.0-8](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-7...v11.0.0-8) (2021-10-26) - -### Features - -- removes remaning usage of browser API in rich text resolver - ([74d1922](https://github.com/kontent-ai/delivery-sdk-js/commit/74d1922451d4350778587b9f2a183c34dccfe87d)) - -## [11.0.0-7](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-6...v11.0.0-7) (2021-10-26) - -### Bug Fixes - -- fixes object / json resolver result - ([dc03d75](https://github.com/kontent-ai/delivery-sdk-js/commit/dc03d757b08c74187a17104f9ab5ee1451903ea0)) - -## [11.0.0-6](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-5...v11.0.0-6) (2021-10-26) - -### Features - -- adds experimental json / object rich text resolvers, simplifies filter classes - ([326dff6](https://github.com/kontent-ai/delivery-sdk-js/commit/326dff69ebf6e2ab8932f60048118527377f1d17)) -- refactors rich text processing by separating parser & rich text resolvers - ([48b49da](https://github.com/kontent-ai/delivery-sdk-js/commit/48b49dac077ff91f89f5e959bb29b37f33909e5d)) -- separates parser from resolvers and makes resolvers independent on parser implementation, adds experimental json / - object rich text element resolvers - ([24082ec](https://github.com/kontent-ai/delivery-sdk-js/commit/24082ec9c1d8d1ff0a4ea6212c52f23ee015cd1b)) -- updates deps - ([f3ccfb9](https://github.com/kontent-ai/delivery-sdk-js/commit/f3ccfb9f6af5f659c20f9d0825e404aa5b4bf0e3)) - -## [11.0.0-5](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-4...v11.0.0-5) (2021-10-19) - -### Bug Fixes - -- fixes value type for LinkedItemsElement - ([b6cfc8e](https://github.com/kontent-ai/delivery-sdk-js/commit/b6cfc8e765ec90c475e87ba25ddc3c69c284f4b1)) - -## [11.0.0-4](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-3...v11.0.0-4) (2021-10-14) - -### Features - -- removes log message when content item is not in response - ([b60f36b](https://github.com/kontent-ai/delivery-sdk-js/commit/b60f36b9b50cefbb2e7e5f8340c58143740698ee)) -- use null for instead of undefined for some response models - ([ff27a93](https://github.com/kontent-ai/delivery-sdk-js/commit/ff27a9346b9d1dcd587c337d37f629eddf933855)) - -### Bug Fixes - -- use null for response models - ([53792f1](https://github.com/kontent-ai/delivery-sdk-js/commit/53792f1cf2edc205f7270bdd6c9d361681fd8676)) - -## [11.0.0-3](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-2...v11.0.0-3) (2021-10-14) - -### ⚠ BREAKING CHANGES - -- use "string" type for all "Date" properties to support more serialization scenarios - -### Features - -- updates deps, removes duplicate license - ([035335f](https://github.com/kontent-ai/delivery-sdk-js/commit/035335f050782091932a70cab6a8ba4ceb76e990)) -- use "string" type for all "Date" properties to support more serialization scenarios - ([909102f](https://github.com/kontent-ai/delivery-sdk-js/commit/909102fa8dc804a44d3480e166112232b98f2c39)) - -## [11.0.0-2](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-1...v11.0.0-2) (2021-10-04) - -### Features - -- adds ability to disable mapping of content items in linked items & rich text elements - ([f67661c](https://github.com/kontent-ai/delivery-sdk-js/commit/f67661c2cc36a1d19d42a4036ac8ee67c7fd365a)) -- adds came case, pascal case & snake case property name resolvers - ([b422697](https://github.com/kontent-ai/delivery-sdk-js/commit/b42269721a930a83442d5842b2c31076e8ef6a92)) - -## [11.0.0-1](https://github.com/kontent-ai/delivery-sdk-js/compare/v11.0.0-0...v11.0.0-1) (2021-10-01) - -### ⚠ BREAKING CHANGES - -- makes rich text resolver generic, uninstalls unused packages, better organizes browser rich text parser code - -### Features - -- makes rich text resolver generic, uninstalls unused packages, better organizes browser rich text parser code - ([29042b8](https://github.com/kontent-ai/delivery-sdk-js/commit/29042b8459c4ad5dedd357cc7a2f43c81da3bf3c)) - -## [11.0.0-0](https://github.com/kontent-ai/delivery-sdk-js/compare/v10.4.1...v11.0.0-0) (2021-09-30) - -### ⚠ BREAKING CHANGES - -- unifies contracts under a shared 'Contracts' namespace -- unifies all response models under common 'Responses' namespace -- converts image transformation enums (ImageFitModeEnum, ImageCompressionEnum, ImageFormatEnum) to types and removes - the 'enum' suffix. -- renames 'ImageUrlBuilder' to 'ImageTransformationUrlBuilder' -- converts elements to types instead of interfaces (also removes the 'I' in the type names), adds - 'createDeliveryClient' factory function, improves custom element sample -- renames 'IKontentNetworkResponse' and 'IGroupedKontentNetworkResponse' interfaces to 'INetworkResponse' and - 'IGroupedNetworkResponse' -- removes query config from mapping service as its no longer necessary due to rich text resolver being separated -- refactors rich text resolver, removes parse5 and default html resolver for node, creates new html resolver for use - in browsers and export it with the library -- removes 'itemCodenames' property from LinkedItemsElement because this data is already available in the value - property -- `globalQueryConfig` configuration option was renamed to `defaultQueryConfig` -- removes \_raw properties from content item & element to reduce the size of mapped response & to avoid data - duplication -- uses interface for all remaining models & responses -- uses interfaces instead of classes for all responses -- refactors element models by using interfaces instead of classes, changes the ElementResolver to resolve only value - instead of the whole custom element -- removes ItemResolver, refactors ContentItem from strongly types class to interface (removes ability to define - resolvers on the class level) -- moves elements to 'elements' property within the content item (they were on the content item previously), removes - property mapping with reflect metadata, removes collision resolver -- introduces new "IKontentNetworkResponse" model that wraps responses with network related data and separates response - specific data for improved mapping of stored json data -- introduces BaseListingQuery for all endpoint with pagination, removes itemsFeedAll method & query, refactors queries - to improve their readability, adds missing filter methods, unifies query config and some other minor improvements & - changes -- renames withUrl query extension method to withCustomUrl -- renames query extension method 'withParameter' to 'withCustomParameter'. Adds new 'withParameter' method which takes - IQueryParameter object similarly as 'withParameters' does for array parameters -- makes SortOrder type instead of enum -- updates kontent-core, removes rxjs from repository in favor of Promises and async based approach -- updates build process (puts all output to "dist" folder), consolidates tests, updates tsconfig - -### Features - -- `globalQueryConfig` configuration option was renamed to `defaultQueryConfig` - ([8817105](https://github.com/kontent-ai/delivery-sdk-js/commit/881710530e4009defec3e7da9cc7763e18257a84)) -- adds 'createUrlBuilder' factory function - ([54b5085](https://github.com/kontent-ai/delivery-sdk-js/commit/54b5085a8dc0748f088b0b4ba894e403bb79bf42)) -- adds 'withContinuationToken' extension method to all listing queries - ([a28ddb3](https://github.com/kontent-ai/delivery-sdk-js/commit/a28ddb3e18162c8b80dabbf8967e64a23b40fbb1)) -- adds 'withHeader' query extension method, improves docs of some extension methods - ([20b9334](https://github.com/kontent-ai/delivery-sdk-js/commit/20b9334f22c2186a1b7276e5dbffbce05140fb36)) -- adds ability to define number of pages to fetch in 'toAllPromise' method - ([d5d8c2c](https://github.com/kontent-ai/delivery-sdk-js/commit/d5d8c2c2634d5d9f40718ab323184d6bf9c79ad7)) -- adds ability to map raw json data with 'map' query extension method - ([dab3618](https://github.com/kontent-ai/delivery-sdk-js/commit/dab3618a542692d67be18d8380b4d917e827d01f)) -- adds network response tests - ([0e8b690](https://github.com/kontent-ai/delivery-sdk-js/commit/0e8b6904af2b6205f6fb6426dabec9b6bf387539)) -- adds support for 'workflow_step' in content item system attributes (fixes - https://github.com/kontent-ai/delivery-sdk-js/issues/309) - ([ad2d965](https://github.com/kontent-ai/delivery-sdk-js/commit/ad2d965dc55742209b0715efabb0ea96cbc51638)) -- adds support for async browser rich text resolver - ([ece99b7](https://github.com/kontent-ai/delivery-sdk-js/commit/ece99b764013f6d6fd2663ae23eba68c4ad11c5e)) -- converts elements to types instead of interfaces (also removes the 'I' in the type names), adds - 'createDeliveryClient' factory function, improves custom element sample - ([2ccb97c](https://github.com/kontent-ai/delivery-sdk-js/commit/2ccb97cd2f952bf20509956bf63832c0d39dee35)) -- converts image transformation enums (ImageFitModeEnum, ImageCompressionEnum, ImageFormatEnum) to types and removes - the 'enum' suffix. - ([d44573a](https://github.com/kontent-ai/delivery-sdk-js/commit/d44573a472fce2baeadef25283a881e1b9ae094b)) -- improves typings of raw response data by providing contract types for each query - ([be654f1](https://github.com/kontent-ai/delivery-sdk-js/commit/be654f186cf1e62e7de8160bcf6adc4e73b85b48)) -- introduces BaseListingQuery for all endpoint with pagination, removes itemsFeedAll method & query, refactors queries - to improve their readability, adds missing filter methods, unifies query config and some other minor improvements & - changes ([7c68b8f](https://github.com/kontent-ai/delivery-sdk-js/commit/7c68b8f910a1bf55c1ec6954c560d6e9f912c3c3)) -- introduces new "IKontentNetworkResponse" model that wraps responses with network related data and separates response - specific data for improved mapping of stored json data - ([ba4c265](https://github.com/kontent-ai/delivery-sdk-js/commit/ba4c2657e70ab205fb776463170f2a1ab8fe7455)) -- makes SortOrder type instead of enum - ([1d61369](https://github.com/kontent-ai/delivery-sdk-js/commit/1d6136970b92f119c51612397a461603c0656a4c)) -- moves elements to 'elements' property within the content item (they were on the content item previously), removes - property mapping with reflect metadata, removes collision resolver - ([8f6ed55](https://github.com/kontent-ai/delivery-sdk-js/commit/8f6ed55eb6d716d09edefcf30756ffe582d579ea)) -- refactors element models by using interfaces instead of classes, changes the ElementResolver to resolve only value - instead of the whole custom element - ([c3fbd51](https://github.com/kontent-ai/delivery-sdk-js/commit/c3fbd51ccdba1ec15943f4ff31436696ef406d4f)) -- refactors internal use of headers (stores headers in a single location) - ([9c0fe73](https://github.com/kontent-ai/delivery-sdk-js/commit/9c0fe73cbf09de13593096bfdadf82abbd5effcd)) -- refactors rich text resolver, removes parse5 and default html resolver for node, creates new html resolver for use - in browsers and export it with the library - ([04633a9](https://github.com/kontent-ai/delivery-sdk-js/commit/04633a94cbd1757166fc50450ee9ac0e529887ad)) -- removes \_raw properties from content item & element to reduce the size of mapped response & to avoid data - duplication - ([5c4eb8c](https://github.com/kontent-ai/delivery-sdk-js/commit/5c4eb8cf6dd2c1d9f2d6dcb3401c8afdb02af8b7)) -- removes 'itemCodenames' property from LinkedItemsElement because this data is already available in the value - property ([acefbe8](https://github.com/kontent-ai/delivery-sdk-js/commit/acefbe80bec23b788d659de827250d4fb0ac9a73)) -- removes ItemResolver, refactors ContentItem from strongly types class to interface (removes ability to define - resolvers on the class level) - ([039ed29](https://github.com/kontent-ai/delivery-sdk-js/commit/039ed29b43870f3e7ee949106d85c7c49fe03c53)) -- removes query config from mapping service as its no longer necessary due to rich text resolver being separated - ([748b2f7](https://github.com/kontent-ai/delivery-sdk-js/commit/748b2f7c374e3e6c99a9d0d54c6dbd7dbcbe537b)) -- renames 'IKontentNetworkResponse' and 'IGroupedKontentNetworkResponse' interfaces to 'INetworkResponse' and - 'IGroupedNetworkResponse' - ([9000c14](https://github.com/kontent-ai/delivery-sdk-js/commit/9000c141c6185ee0adc57cf902f47dc46af7b6ec)) -- renames 'ImageUrlBuilder' to 'ImageTransformationUrlBuilder' - ([8124cfe](https://github.com/kontent-ai/delivery-sdk-js/commit/8124cfe9ad62153832197883f053132b60a95b47)) -- renames query extension method 'withParameter' to 'withCustomParameter'. Adds new 'withParameter' method which takes - IQueryParameter object similarly as 'withParameters' does for array parameters - ([a518694](https://github.com/kontent-ai/delivery-sdk-js/commit/a51869401f33a471829f648f93bd773006c98814)) -- renames withUrl query extension method to withCustomUrl - ([dbe6b77](https://github.com/kontent-ai/delivery-sdk-js/commit/dbe6b77efb9cf49f3ef26e57c59fc8fec8d9ce6b)) -- unifies all response models under common 'Responses' namespace - ([ad28631](https://github.com/kontent-ai/delivery-sdk-js/commit/ad286313d80a2683fd9100c79def21e0269cf0e8)) -- unifies contracts under a shared 'Contracts' namespace - ([41ddd98](https://github.com/kontent-ai/delivery-sdk-js/commit/41ddd98b31f4d54f90a7de97be8a0c96bd5ffd52)) -- updates build process (puts all output to "dist" folder), consolidates tests, updates tsconfig - ([c2946f7](https://github.com/kontent-ai/delivery-sdk-js/commit/c2946f7ce0d94d9b6365a42f5c04ea7e5c01126e)) -- updates deps - ([a18d770](https://github.com/kontent-ai/delivery-sdk-js/commit/a18d770c077620305be5b9b46254baf38a5ab42b)) -- updates deps - ([320d2df](https://github.com/kontent-ai/delivery-sdk-js/commit/320d2df3c00fcf71a76bb43fa4859cb13ed374af)) -- updates deps - ([67da9df](https://github.com/kontent-ai/delivery-sdk-js/commit/67da9dfb0184797909e0c78022653cf32a5a0951)) -- updates kontent-core, removes rxjs from repository in favor of Promises and async based approach - ([b213a7d](https://github.com/kontent-ai/delivery-sdk-js/commit/b213a7d2a520c3c9f395ce909d71f15802fc6581)) -- uses interface for all remaining models & responses - ([ad7b18d](https://github.com/kontent-ai/delivery-sdk-js/commit/ad7b18dcaa52b5fcdb9d7392da8e246567615796)) -- uses interfaces instead of classes for all responses - ([2cd8cb2](https://github.com/kontent-ai/delivery-sdk-js/commit/2cd8cb2684e54a7ad14292865b2adf5cf92c40df)) - -### [10.4.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v10.4.0...v10.4.1) (2021-03-31) - -## [10.4.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v10.3.0...v10.4.0) (2021-03-18) - -### Features - -- adds resolved attribute to BrowserRichTextParser, adds index to every resolved linked item & component within rich - text element values - ([b81d523](https://github.com/kontent-ai/delivery-sdk-js/commit/b81d523bb375b249e7ff44aec2df069890dfaba4)) -- use switchMap instead of deprecated flatMap operator - ([59bd752](https://github.com/kontent-ai/delivery-sdk-js/commit/59bd752dc7a1288218d5a2b9e63a682a773833c9)) - -## [10.3.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v10.2.0...v10.3.0) (2021-02-05) - -### Features - -- adds languages support (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/303) - ([c145d93](https://github.com/kontent-ai/delivery-sdk-js/commit/c145d93ca8f293ec4fc99eb79fe1fa5a2c85cc60)) - -## [10.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v10.1.0...v10.2.0) (2021-01-08) - -### Features - -- updates dependencies - ([651ccb4](https://github.com/kontent-ai/delivery-sdk-js/commit/651ccb44626c2542bf1caee83fc31ee4fd0b53a5)) - -### Bug Fixes - -- updates internal types of parse5 parser adapter - ([83109f7](https://github.com/kontent-ai/delivery-sdk-js/commit/83109f73003e233938c753d6795899f1b55e8ce4)) - -## [10.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v10.0.0...v10.1.0) (2020-11-26) - -### Features - -- adds support for collections -- updates all dependencies, uses axios models directly for request interceptors - ([5aa5f8b](https://github.com/kontent-ai/delivery-sdk-js/commit/5aa5f8b4529ecfb8c3a9763db3755a36fa385267)) - -## [10.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v9.2.1...v10.0.0) (2020-08-25) - -### ⚠ BREAKING CHANGES - -- Refactors IQueryParameter to allows value-less parameters which are required by new filtering operators (empty / - nempty), adds support for new filter options (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/297) - -### Features - -- Refactors IQueryParameter to allows value-less parameters which are required by new filtering operators (empty / - nempty), adds support for new filter options (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/297) - ([b2ae46f](https://github.com/kontent-ai/delivery-sdk-js/commit/b2ae46f615c6db7465125e09f8527fcfd49084a2)) - -### Bug Fixes - -- fixes url resolving test for node.js - ([212d343](https://github.com/kontent-ai/delivery-sdk-js/commit/212d34355104eb0201a3768d2bd198fc4b537176)) - -### [9.2.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v9.2.0...v9.2.1) (2020-08-11) - -### Bug Fixes - -- fixes automatic format for image transformation api (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/296) - ([42204ff](https://github.com/kontent-ai/delivery-sdk-js/commit/42204ff31a5f7cdbfcb684cb724ca6f24298f36c)) - -## [9.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v9.1.1...v9.2.0) (2020-07-30) - -### Features - -- updates dependencies, moves error handling logic from core package to sdk + fixes error mapping after recent error - response change which now allows null in request_id property - ([a11e745](https://github.com/kontent-ai/delivery-sdk-js/commit/a11e745d4148ac93dafa038f09bd6cd3b6b41a35)) - -### Bug Fixes - -- improves handling of image resolving in rich text element and fixes parse5 parsing in nested component rich text - resolver (https://github.com/kontent-ai/delivery-sdk-js/issues/294) - ([9b82718](https://github.com/kontent-ai/delivery-sdk-js/commit/9b82718220c6affe62dfe8b79380323858db9e71)) - -### [9.1.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v9.1.0...v9.1.1) (2020-04-02) - -### Bug Fixes - -- fixes missing attributes in parse5 resolved links with custom html - ([2e2f8c1](https://github.com/kontent-ai/delivery-sdk-js/commit/2e2f8c1d1c92d15395a0bfb646c32781ae06fdbf)) - -## [9.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v9.0.0...v9.1.0) (2020-03-26) - -### Features - -- exposes richTextParserAdapter via config - ([62659a6](https://github.com/kontent-ai/delivery-sdk-js/commit/62659a688661b5e786b853e7dd0e59aac2eeb02c)) - -### Bug Fixes - -- fixes https://github.com/kontent-ai/delivery-sdk-js/issues/286 & unifies parse5 / browser tests - ([2a787f4](https://github.com/kontent-ai/delivery-sdk-js/commit/2a787f4ec237528a55ae3df7676ed348cf502e87)) - -## [9.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v8.2.0...v9.0.0) (2020-01-20) - -### ⚠ BREAKING CHANGES - -- updates deps, refactors retry-strategy which enables specifying either maximum number of attemps or wait time and - allows retry of any error even when response is not received (e.g. timeout which could not be retried previously) - -### Features - -- distributes library in esNext format - ([bd9ea6f](https://github.com/kontent-ai/delivery-sdk-js/commit/bd9ea6f5f7dd81277d59c8a85e9952bde0ed74f6)) -- refactors item mappers and adds full mapping support to items-feed endpoints (e.g. rich text resolver, url slug - resolver, image resolver ..) - ([6e30485](https://github.com/kontent-ai/delivery-sdk-js/commit/6e304856fda0a7d9c55e2910dac2578014cedc37)) -- updates deps, refactors retry-strategy which enables specifying either maximum number of attemps or wait time and - allows retry of any error even when response is not received (e.g. timeout which could not be retried previously) - ([b7cf414](https://github.com/kontent-ai/delivery-sdk-js/commit/b7cf414bc2da0f4fc42368fd5ab44a555bf36afc)) - -## [8.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v8.1.0...v8.2.0) (2019-11-25) - -### Features - -- adds helper method to return linked items as array (fixes https://github.com/kontent-ai/delivery-sdk-js/issues/240) - ([b832f7b](https://github.com/kontent-ai/delivery-sdk-js/commit/b832f7b67c85fce0d80e763a2207afb859855fc8)) -- extends ContentItem with ability to get all elements in an array (fixes - https://github.com/kontent-ai/delivery-sdk-js/issues/241) - ([120918b](https://github.com/kontent-ai/delivery-sdk-js/commit/120918bc9d724efd765cf320e676bbd56a6f9fa4)) -- updates all dependencies (including dev depencies such as the use of latest TypeScript..) - ([62a9ffc](https://github.com/kontent-ai/delivery-sdk-js/commit/62a9ffc1b8ead493b6adc891fbb9bd05ed629070)) - -### Bug Fixes - -- fixes github repo url in package.json & fixes changelog links (fixes - https://github.com/kontent-ai/delivery-sdk-js/issues/268) - ([a4132e7](https://github.com/kontent-ai/delivery-sdk-js/commit/a4132e7d95a6c99ade17c487b68721fb0bafc58c)) - -## [8.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v8.0.0...v8.1.0) (2019-11-18) - -### Features - -- adds support for 'includeTotalCount| parameter - ([c39a301](https://github.com/kontent-ai/delivery-sdk-js/commit/c39a301bf73c72b4e87db071a4293c7f45ef0c8e)) - -### Bug Fixes - -- updates kontent-core package which fixes http retry requests - ([53a4318](https://github.com/kontent-ai/delivery-sdk-js/commit/53a43184a708c0c36fbe611d99a6298f24ad097a)) - -## [8.0.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v7.2.0...v8.0.0) (2019-10-25) - -### ⚠ BREAKING CHANGES - -- Updates @kentico/kontent-core to v4 and uses new and improved retry strategy. 'retryAttempts' configuration option - was removed in favor of 'retryStrategy' object. - -### Features - -- adds 'itemsFeedAll' method to get all items from a project. This method may execute multiple HTTP requests. Reworks - base responses & debug to allow different debug types per response. - ([72e03fd](https://github.com/kontent-ai/delivery-sdk-js/commit/72e03fd3587573d82d665e0010c696e122e73248)) -- adds support for 'items-feed' endpoint - ([29913c9](https://github.com/kontent-ai/delivery-sdk-js/commit/29913c984b073166a8f0ddc12f69106c7d476efd)) -- Updates @kentico/kontent-core to v4 and uses new and improved retry strategy. 'retryAttempts' configuration option - was removed in favor of 'retryStrategy' object. - ([e2abd02](https://github.com/kontent-ai/delivery-sdk-js/commit/e2abd02a233f78f9c9152397f5eb915d73ba1189)) - -### Bug Fixes - -- prepares instances of all items before resolving occurs to prevent some items from being skipped - ([5559cb6](https://github.com/kontent-ai/delivery-sdk-js/commit/5559cb608668f608f759256f0a35486fb7397d9c)) - -## [7.2.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v7.1.0...v7.2.0) (2019-10-21) - -### Features - -- Enables resolving links without content item representation in response - ([6472265](https://github.com/kontent-ai/delivery-sdk-js/commit/6472265867d8b6dc200ff756032a75a848b0d92c)) -- takes 'isDeveloperMode' settings into account when displaying root debug element - (https://github.com/kontent-ai/delivery-sdk-js/issues/255] - ([7ab56cb](https://github.com/kontent-ai/delivery-sdk-js/commit/7ab56cb64703e7481ea02433ad5aca95bd9b8b51)) -- updates @kentico/kontent-core dependency which enables configuring axios request - (https://github.com/kontent-ai/delivery-sdk-js/issues/256) - ([ea3a504](https://github.com/kontent-ai/delivery-sdk-js/commit/ea3a504e3a2eb37a06d40daf5a40ea11dfbe517f)) - -## 7.1.0 (2019-10-14) - -## [7.1.0](https://github.com/kontent-ai/delivery-sdk-js/compare/v7.0.1...v7.1.0) (2019-10-14) - -### Features - -- adds hasStaleContent property to all responses and uses new BaseDeliveryResponse base class - ([3dc5046](https://github.com/kontent-ai/delivery-sdk-js/commit/3dc50463a70a3f70e3f0920ed11758f62efdb236)) - -### [7.0.1](https://github.com/kontent-ai/delivery-sdk-js/compare/v1.1.0...v7.0.1) (2019-10-14) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..78f5572b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,24 @@ +# Code Style + +## Functional Programming + +- Prefer functional style: pure functions, immutable data, expressions over statements +- Small, single-purpose functions — if a function does more than one thing, split it +- `const` everywhere; never use `let` unless mutation is genuinely unavoidable, never use `var` +- `readonly` on all type properties, function parameters, and array types (`readonly T[]`); exception: a mutable array used as a local accumulator within a single function body (built with `.push()`, never returned or exposed as mutable) is acceptable when the immutable alternative would cause repeated full-array copies — e.g. `[...acc, item]` inside a loop or recursion allocates a new array on every iteration (O(n) per step), whereas `.push()` is O(1) amortised +- Avoid side effects — functions should return values, not mutate external state +- Prefer `map`, `filter`, `reduce`, and other higher-order functions over imperative loops +- Prefer early returns over nested conditionals + +## Libraries + +- Use **ts-pattern** for non-trivial `switch`/`if-else` chains — anything beyond a simple 2-branch condition should use `match()` from `ts-pattern` +- Use **Zod** to define schemas for all API response payloads and API endpoint inputs — the Zod schema is the source of truth; TypeScript types are always derived via `z.infer<>`, never written by hand alongside a schema + +## Exports + +- All API queries and API-related models must be exported from `lib/public_api.ts` — nothing is part of the public API unless it appears there + +# Tooling + +- After making code changes, run `pnpm run biome:fix` to auto-format and fix lint issues diff --git a/LICENSE.md b/LICENSE.md index ac4d0f70..e67552f6 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ -MIT License +# MIT License -Copyright (c) 2023 Kontent s.r.o. +Copyright (c) 2026 Kontent s.r.o. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md new file mode 100644 index 00000000..685e4647 --- /dev/null +++ b/README.md @@ -0,0 +1,261 @@ +[![npm version](https://badge.fury.io/js//%40kontent-ai%2Fdelivery-sdk.svg)](https://www.npmjs.com/package/@kontent-ai/delivery-sdk) +[![Build](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/build.yml/badge.svg)](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/build.yml) +[![Integration Tests](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/integration-tests.yml) +[![Unit Tests](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/unit-tests.yml) +[![npm](https://img.shields.io/npm/dt/@kontent-ai/delivery-sdk.svg)](https://www.npmjs.com/package/@kontent-ai/delivery-sdk) +[![Known Vulnerabilities](https://snyk.io/test/github/Kontent-ai/delivery-sdk-js/badge.svg)](https://snyk.io/test/github/kontent-ai/delivery-sdk-js) +[![GitHub license](https://img.shields.io/github/license/Kontent-ai/delivery-sdk-js.svg)](https://github.com/kontent-ai/delivery-sdk-js) + +# Kontent.ai Delivery SDK for JavaScript + +A TypeScript/JavaScript SDK for the [Kontent.ai Delivery API](https://kontent.ai/learn/docs/apis/openapi/delivery-api/). +It fetches content items, types, taxonomies, and languages, with first-class TypeScript typing and optional +runtime validation. + +> **Upgrading from v16?** See the [migration guide](./migration.md). + +## Installation + +The SDK has three peer dependencies: `@kontent-ai/core-sdk`, `zod`, and `ts-pattern`. + +```bash +# npm installs peer dependencies automatically +npm install @kontent-ai/delivery-sdk + +# pnpm needs them listed explicitly +pnpm add @kontent-ai/delivery-sdk @kontent-ai/core-sdk zod ts-pattern +``` + +Requires Node.js ≥ 22. + +## Quick start + +```typescript +import { createDeliveryClient } from "@kontent-ai/delivery-sdk"; + +const client = createDeliveryClient({ + apiMode: "public", + environmentId: "", +}); + +// Fetch a single content item +const { response } = await client.fetchContentItem({ codename: "my_article" }).fetchSafe(); +``` + +Every query returns `{ payload, meta }`. The `payload` is the raw API response (content lives in +`payload.items` / `payload.item`); `meta` holds response metadata such as the continuation token. + +## Configuration + +The API mode is set once, when you create the client: + +```typescript +// Public — published content +createDeliveryClient({ apiMode: "public", environmentId: "" }); + +// Preview — unpublished content +createDeliveryClient({ apiMode: "preview", environmentId: "", deliveryApiKey: "" }); + +// Secure — published content with Secured access enabled +createDeliveryClient({ apiMode: "secure", environmentId: "", deliveryApiKey: "" }); +``` + +| Option | Required | Description | +|---|---|---| +| `apiMode` | yes | `"public"`, `"preview"`, or `"secure"` | +| `environmentId` | yes | Your Kontent.ai environment ID | +| `deliveryApiKey` | for preview/secure | The preview or secure access API key | +| `baseUrl`, `httpService`, `retryStrategy` | no | Advanced options from [`@kontent-ai/core-sdk`](https://github.com/kontent-ai/core-sdk-js) | +| `runtimeValidation` | no | Opt-in Zod validation of responses (see [Runtime validation](#runtime-validation)) | + +## Safe vs. throwing queries + +Every query offers two execution styles: + +- **Safe** (`fetchSafe` / `fetchPageSafe` / `fetchAllPagesSafe`) — never throws; returns + `{ success, response, error }`. +- **Throwing** (`fetch` / `fetchPage` / `fetchAllPages`) — returns the response directly and throws on + failure. + +```typescript +// Safe — handle the result object +const { success, response, error } = await client.listContentItems().fetchPageSafe(); +if (success) { + console.log(response.payload.items); +} + +// Throwing — use try/catch +try { + const response = await client.listContentItems().fetchPage(); + console.log(response.payload.items); +} catch (error) { + // error is a DeliverySdkError +} +``` + +Use single-item queries with `fetch` / `fetchSafe`; paged queries (`listContentItems`, `listContentTypes`, +`listTaxonomies`, `listLanguages`, `itemsFeed`, …) with `fetchPage` / `fetchPageSafe` / +`fetchAllPages` / `fetchAllPagesSafe`. + +## Error handling + +Failures are reported as a `DeliverySdkError`. With safe queries, inspect `error` on the result; with +throwing queries, catch it. + +```typescript +const { success, error } = await client.fetchContentItem({ codename: "missing" }).fetchSafe(); + +if (!success) { + console.error(error.message); + console.error(error.details.reason); // e.g. "parsingFailed" +} +``` + +## Paging + +```typescript +// One page +const { response } = await client + .listContentItems({ query: { limit: 10, skip: 0 } }) + .fetchPageSafe(); + +console.log(response?.payload.items); + +// All pages at once +const { success, responses } = await client.listContentItems().fetchAllPagesSafe(); +if (success) { + const allItems = responses.flatMap((r) => r.payload.items); +} + +// Or iterate page-by-page +for await (const page of client.listContentItems().pages()) { + console.log(page.payload.items.length); +} +``` + +The `itemsFeed` query pages with a continuation token instead of skip/limit — pass it via the request +headers and read the next token from `response.meta.continuationToken`: + +```typescript +const { response } = await client + .itemsFeed({ headers: { "X-Continuation": "" } }) + .fetchPageSafe(); + +console.log(response?.meta.continuationToken); +``` + +## Strong typing + +Pass a `DeliveryClientSchema` to `createDeliveryClient` to narrow every codename, then describe each +content type with `ContentItemOf` and the `Elements` namespace. (We recommend generating both with +[`@kontent-ai/model-generator`](https://github.com/kontent-ai/model-generator-js) rather than writing them +by hand.) + +```typescript +import { createDeliveryClient, type ContentItemOf, type DeliveryClientSchema, type Elements } from "@kontent-ai/delivery-sdk"; + +type MySchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["en-US"]; + readonly collectionCodenames: readonly ["default"]; + readonly workflowCodenames: readonly ["default"]; + readonly workflowStepCodenames: readonly ["published"]; + readonly taxonomies: { readonly genre: readonly ["action", "comedy"] }; + readonly contentTypes: { + readonly movie: readonly ["title", "stars"]; + readonly actor: readonly ["first_name"]; + }; +}>; + +type Actor = ContentItemOf; + +type Movie = ContentItemOf; +}>; + +const client = createDeliveryClient({ apiMode: "public", environmentId: "" }); +``` + +Codenames are now checked at compile time, and linked items are resolved onto each element's `items` +array (e.g. `movie.elements.stars.items` is `Actor[]`). + +## Type guards + +When a query returns items of mixed types, narrow each one to its typed model with a guard on +`system.type`: + +```typescript +import type { ContentItemPayload } from "@kontent-ai/delivery-sdk"; + +function isMovie(item: ContentItemPayload): item is Movie { + return item.system.type === "movie"; +} + +const { response } = await client.listContentItems().fetchPageSafe(); + +for (const item of response?.payload.items ?? []) { + if (isMovie(item)) { + console.log(item.elements.title.value); // typed as string + const stars = item.elements.stars.items; // resolved Actor[] + } +} +``` + +`@kontent-ai/model-generator` generates one of these guards (`isMovie`, `isActor`, …) per content type. + +## Runtime validation + +Optionally validate responses against the SDK's Zod schemas at runtime — handy for catching unexpected +payload shapes early: + +```typescript +const client = createDeliveryClient({ + apiMode: "public", + environmentId: "", + runtimeValidation: { validateResponses: true }, +}); +``` + +The schemas are also exported on their own subpath for standalone use: + +```typescript +import { listContentItemsSchema } from "@kontent-ai/delivery-sdk/schemas"; + +const result = await listContentItemsSchema().safeParseAsync(storedJson); +``` + +## Resolved linked items & serialization + +By default, content-item queries (`fetchContentItem`, `listContentItems`, `itemsFeed`) return an +**extended** response: every rich-text and linked-items (modular content) element is augmented with a +mapped `items` property holding the fully-resolved referenced items. This lets you traverse the content +tree directly instead of looking codenames up in `modular_content` yourself — `element.value` still holds +the referenced codenames, while `element.items` holds the resolved items. + +```typescript +const { response } = await client.listContentItems().fetchPageSafe(); +const movie = response?.payload.items[0]; + +const starCodenames = movie?.elements.stars.value; // string[] of codenames +const stars = movie?.elements.stars.items; // resolved items +``` + +Because resolved items can reference one another — possibly in a **circular** way — the extended response +is **not** safe to `JSON.stringify`. When you need to serialize the response (caching, SSR payloads, +sending it over the wire), use the query's `raw()` variant. It returns the plain API payload with **no** +resolved `items`; linked items remain referenced by codename in `modular_content`. + +```typescript +// Raw payload — safe to serialize (no resolved `items`, so no circular references) +const { response } = await client.listContentItems().raw().fetchPageSafe(); + +const json = JSON.stringify(response?.payload); // safe + +// In the raw payload, resolve linked items yourself from `payload.modular_content` when needed. +``` + +## License + +MIT diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..d7e9b719 --- /dev/null +++ b/biome.json @@ -0,0 +1,36 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["@kontent-ai/biome-config/base"], + "formatter": { + "indentWidth": 4, + "indentStyle": "tab", + "lineWidth": 140 + }, + "linter": { + "rules": { + "correctness": { + "noUnusedImports": { + "fix": "safe", + "level": "error" + }, + "useImportExtensions": { + "level": "error", + "options": { + "forceJsExtensions": true + } + } + } + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + }, + "files": { + "includes": ["lib/**/*.ts", "tests/**/*.ts", "scripts/**/*.ts", "sample/**/*.ts", "**/*.json", "!_legacy/**/*"] + } +} diff --git a/clean.ts b/clean.ts deleted file mode 100644 index 6e89e5bc..00000000 --- a/clean.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { existsSync, rmSync } from 'fs'; -import { yellow } from 'colors'; - -const paths = ['dist']; -for (const path of paths) { - if (existsSync(path)) { - rmSync(path, { recursive: true }); - console.log(`Path '${yellow(path)}' has been deleted`); - } -} diff --git a/eslint.config.mjs b/eslint.config.mjs index 21cb16dd..5e8fed3b 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,23 +1,57 @@ -import eslint from '@eslint/js'; -import tseslint from 'typescript-eslint'; +import kontentAiConfig from "@kontent-ai/eslint-config"; +import { defineConfig } from "eslint/config"; -export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.recommendedTypeChecked, { - languageOptions: { - parserOptions: { - project: true, - tsconfigRootDir: import.meta.dirname - } - }, - rules: { - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unsafe-assignment': 'off', - '@typescript-eslint/no-unsafe-argument': 'off', - '@typescript-eslint/no-empty-object-type': 'off', - '@typescript-eslint/restrict-template-expressions': 'off', - '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/prefer-promise-reject-errors': 'off' - } -}); +const restrictedZodPaths = [ + { + name: "zod", + message: "Import from 'zod/mini' instead to keep the SDK tree-shakeable.", + }, +]; + +const restrictedSchemaPattern = { + regex: "\\.schemas\\.js$", + // Type-only imports are erased by the compiler, so they don't pull schema code into the bundle. + // The model files legitimately `import type` from schemas to derive types via `z.infer`. + allowTypeImports: true, + message: + "Schema modules must be loaded with a dynamic `await import(...)` so they're not bundled into the main entry. For top-level use, import them from the public '@kontent-ai/delivery-sdk/schemas' entry instead.", +}; + +export default defineConfig( + { + // Global ignores + ignores: ["dist/**/*", "_legacy/**/*"], + }, + { + extends: [kontentAiConfig], + files: ["lib/**/*.ts", "tests/**/*.ts", "scripts/**/*.ts", "sample/**/*.ts"], + rules: { + "no-unused-vars": "off", + // Switched to the typescript-eslint variant so we can `allowTypeImports` on the schema pattern. + "no-restricted-imports": "off", + "@typescript-eslint/no-restricted-imports": [ + "error", + { + paths: restrictedZodPaths, + patterns: [restrictedSchemaPattern], + }, + ], + "no-restricted-syntax": [ + "error", + { + selector: "ImportDeclaration[source.value='zod/mini'] > ImportSpecifier[imported.name='z']", + message: + 'Use `import * as z from "zod/mini"` instead. The named `{ z }` import defeats esbuild\'s namespace tree-shaking and pulls ~280 kB of zod locales into consumer bundles.', + }, + ], + }, + }, + { + // Schema files (which import each other), the public `./schemas` barrel, and tests are + // allowed to import schema modules statically as values — they keep only the zod restriction. + files: ["**/*.schemas.ts", "lib/public_schemas.ts", "tests/**/*.ts"], + rules: { + "@typescript-eslint/no-restricted-imports": ["error", { paths: restrictedZodPaths }], + }, + }, +); diff --git a/karma-gh-actions.conf.js b/karma-gh-actions.conf.js deleted file mode 100644 index d013c92c..00000000 --- a/karma-gh-actions.conf.js +++ /dev/null @@ -1,56 +0,0 @@ -module.exports = function (config) { - config.set({ - frameworks: ["jasmine", "karma-typescript"], - plugins: [ - require("karma-jasmine"), - require("karma-typescript"), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - ], - files: [ - { pattern: "lib/**/*.ts" }, - { pattern: "test/browser/**/*.ts" } - ], - exclude: [ - ], - preprocessors: { - "lib/**/*.ts": ["karma-typescript"], - "test/browser/**/*.ts": ["karma-typescript"] - }, - reporters: ["kjhtml", "progress", "karma-typescript"], - browsers: ["Chrome"], - karmaTypescriptConfig: { - compilerOptions: { - emitDecoratorMetadata: true, - experimentalDecorators: true, - resolveJsonModule: true, - module: "commonjs", - sourceMap: true, - target: "ES5" - }, - exclude: ["node_modules"], - bundlerOptions: { - transforms: [ - require("karma-typescript-es6-transform")() - ] - } - }, - coverageReporter: { - reporters: [ - { type: 'html', subdir: 'html' }, - { type: 'lcov', subdir: 'lcov' }, - { type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt' } - ] - }, - port: 9669, - colors: true, - autoWatch: false, - singleRun: true, - client: { - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - logLevel: config.DEBUG, - browserDisconnectTolerance: 2, - browserNoActivityTimeout: 5000000 - }); -}; diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 32c6c092..00000000 --- a/karma.conf.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = function (config) { - config.set({ - frameworks: ['jasmine', 'karma-typescript'], - plugins: [ - require('karma-jasmine'), - require('karma-typescript'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter') - ], - files: [{ pattern: 'lib/**/*.ts' }, { pattern: 'test/browser/**/*.ts' }], - exclude: [], - preprocessors: { - 'lib/**/*.ts': ['karma-typescript'], - 'test/browser/**/*.ts': ['karma-typescript'] - }, - reporters: ['kjhtml', 'progress', 'karma-typescript'], - browsers: ['Chrome'], - karmaTypescriptConfig: { - compilerOptions: { - emitDecoratorMetadata: true, - experimentalDecorators: true, - resolveJsonModule: true, - module: 'commonjs', - sourceMap: true, - target: 'ES5' - }, - exclude: ['node_modules'], - bundlerOptions: { - transforms: [require('karma-typescript-es6-transform')()] - } - }, - coverageReporter: { - reporters: [ - { type: 'html', subdir: 'html' }, - { type: 'lcov', subdir: 'lcov' }, - { type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt' } - ] - }, - port: 9669, - colors: true, - autoWatch: true, - singleRun: false, - client: { - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - logLevel: config.DEBUG, - browserDisconnectTolerance: 2, - browserNoActivityTimeout: 5000000 - }); -}; diff --git a/lib/client/delivery-client.factory.ts b/lib/client/delivery-client.factory.ts deleted file mode 100644 index 861343f0..00000000 --- a/lib/client/delivery-client.factory.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ClientTypes } from '../models'; -import { IDeliveryClientConfig } from '../config/delivery-configs'; -import { DeliveryClient } from './delivery-client'; - -export function createDeliveryClient( - config: IDeliveryClientConfig -): DeliveryClient { - return new DeliveryClient(config); -} diff --git a/lib/client/delivery-client.ts b/lib/client/delivery-client.ts index 10ff1ac0..5adda987 100644 --- a/lib/client/delivery-client.ts +++ b/lib/client/delivery-client.ts @@ -1,163 +1,51 @@ -import { HttpService } from '@kontent-ai/core-sdk'; -import { IDeliveryClientConfig } from '../config'; -import { ClientTypes, IContentItem } from '../models'; +import type { DeliveryClient, DeliveryClientConfig, DeliveryClientSchema } from "../models/core.models.js"; +import { type FetchContentItemQueryRequest, fetchContentItemQuery } from "../queries/content-items/fetch-content-item-query.js"; +import { type ItemsFeedQueryRequest, itemsFeedQuery } from "../queries/content-items/items-feed-query.js"; import { - ElementQuery, - ItemsFeedQuery, - MultipleItemsQuery, - MultipleTypeQuery, - SingleItemQuery, - SingleTypeQuery, - TaxonomiesQuery, - TaxonomyQuery, - LanguagesQuery, - InitializeSyncQuery, - SyncChangesQuery, - UsedInQuery -} from '../query'; -import { sdkInfo } from '../sdk-info.generated'; -import { IMappingService, MappingService, QueryService } from '../services'; -import { IDeliveryClient } from './idelivery-client.interface'; - -export class DeliveryClient implements IDeliveryClient { - private queryService: QueryService; - public mappingService: IMappingService; - - /** - * Delivery client used to fetch data from Kontent.ai - * @constructor - * @param {IDeliveryClientConfig} config - The client configuration - */ - constructor(protected config: IDeliveryClientConfig) { - if (!config) { - throw Error(`Delivery client configuration is not set`); - } - - this.mappingService = new MappingService(config); - this.queryService = new QueryService( - config, - config.httpService ? config.httpService : new HttpService(), - { - host: sdkInfo.host, - name: sdkInfo.name, - version: sdkInfo.version - }, - this.mappingService - ); - } - - /** - * Gets query for multiple languages - */ - languages(): LanguagesQuery { - return new LanguagesQuery(this.config, this.queryService); - } - - /** - * Gets query for multiple types - */ - types(): MultipleTypeQuery { - return new MultipleTypeQuery(this.config, this.queryService); - } - - /** - * Gets query for single type - * @param {string} typeCodename - Codename of the type to fetch - */ - type(typeCodename: TClientTypes['contentTypeCodenames']): SingleTypeQuery { - return new SingleTypeQuery(this.config, this.queryService, typeCodename); - } - - /** - * Gets query for multiple items - */ - items(): MultipleItemsQuery< - TClientTypes, - TContentItem - > { - return new MultipleItemsQuery(this.config, this.queryService); - } - - /** - * Gets query for single item - * @param {string} codename - Codename of item to fetch - */ - item( - codename: string - ): SingleItemQuery { - return new SingleItemQuery(this.config, this.queryService, codename); - } - - /** - * Gets query for items feed. Executes single HTTP request only - */ - itemsFeed(): ItemsFeedQuery< - TClientTypes, - TContentItem - > { - return new ItemsFeedQuery(this.config, this.queryService); - } - - /** - * Gets query for single taxonomy - * @param {string} codename - Codename of taxonomy to fetch - */ - taxonomy(codename: TClientTypes['taxonomyCodenames']): TaxonomyQuery { - return new TaxonomyQuery(this.config, this.queryService, codename); - } - - /** - * Gets query for multiple taxonomies - */ - taxonomies(): TaxonomiesQuery { - return new TaxonomiesQuery(this.config, this.queryService); - } - - /** - * Gets query for an element within a type - * @param {string} typeCodename - Codename of the type - * @param {string} elementCodename - Codename of the element - */ - element( - typeCodename: TClientTypes['contentTypeCodenames'], - elementCodename: TClientTypes['elementCodenames'] - ): ElementQuery { - return new ElementQuery(this.config, this.queryService, typeCodename, elementCodename); - } - - /** - * @deprecated Sync API v1 is deprecated and will be shut down by the end of this year. - * Please migrate to Sync API v2 using the `@kontent-ai/sync-sdk` package. - * - * For migration guidance and full documentation, visit: - * https://kontent.ai/learn/docs/apis/openapi/sync-api-v2/ - */ - initializeSync(): InitializeSyncQuery { - return new InitializeSyncQuery(this.config, this.queryService); - } - - /** - * @deprecated Sync API v1 is deprecated and will be shut down by the end of this year. - * Please migrate to Sync API v2 using the `@kontent-ai/sync-sdk` package. - * - * For migration guidance and full documentation, visit: - * https://kontent.ai/learn/docs/apis/openapi/sync-api-v2/ - */ - syncChanges(): SyncChangesQuery { - return new SyncChangesQuery(this.config, this.queryService); - } - - /** - * Item listing of where an asset is used - */ - assetUsedIn(assetCodename: string): UsedInQuery { - return new UsedInQuery(this.config, this.queryService, { entity: 'asset', codename: assetCodename }); - } - - /** - * Item listing of where a content item is used - */ - itemUsedIn(itemCodename: string): UsedInQuery { - return new UsedInQuery(this.config, this.queryService, { entity: 'contentItem', codename: itemCodename }); - } + type ItemsReferencingAssetQueryRequest, + itemsReferencingAssetQuery, +} from "../queries/content-items/items-referencing-asset-query.js"; +import { type ItemsReferencingItemQueryRequest, itemsReferencingItemQuery } from "../queries/content-items/items-referencing-item-query.js"; +import { type ListContentItemsQueryRequest, listContentItemsQuery } from "../queries/content-items/list-content-items-query.js"; +import { + type FetchContentTypeElementQueryRequest, + fetchContentTypeElementQuery, +} from "../queries/content-types/fetch-content-type-element-query.js"; +import { type FetchContentTypeQueryRequest, fetchContentTypeQuery } from "../queries/content-types/fetch-content-type-query.js"; +import { type ListContentTypesQueryRequest, listContentTypesQuery } from "../queries/content-types/list-content-types-query.js"; +import type { ContentTypeCodenameOf } from "../queries/content-types/models/content-type.models.js"; +import { type ListLanguagesQueryRequest, listLanguagesQuery } from "../queries/languages/list-languages-query.js"; +import { type FetchTaxonomyQueryRequest, fetchTaxonomyQuery } from "../queries/taxonomies/fetch-taxonomy-query.js"; +import { type ListTaxonomiesQueryRequest, listTaxonomiesQuery } from "../queries/taxonomies/list-taxonomies-query.js"; +import type { TaxonomyCodenameOf } from "../queries/taxonomies/models/taxonomy.models.js"; + +/** + * Creates a delivery client. When you supply a `TSchema` type argument, codenames are narrowed for type safety. + * Without a type argument, codenames fall back to generic strings. + * + * We highly recommend generating the schema type using the `@kontent-ai/model-generator` npm package + * and passing it as the type argument for full compile-time safety. + */ +export function createDeliveryClient( + config: DeliveryClientConfig, +): DeliveryClient { + return { + config, + listTaxonomies: (request?: ListTaxonomiesQueryRequest) => listTaxonomiesQuery(config, request), + listLanguages: (request?: ListLanguagesQueryRequest) => listLanguagesQuery(config, request), + listContentTypes: (request?: ListContentTypesQueryRequest) => listContentTypesQuery(config, request), + fetchTaxonomy: >(request: FetchTaxonomyQueryRequest) => + fetchTaxonomyQuery(config, request), + fetchContentType: >( + request: FetchContentTypeQueryRequest, + ) => fetchContentTypeQuery(config, request), + fetchContentTypeElement: >( + request: FetchContentTypeElementQueryRequest, + ) => fetchContentTypeElementQuery(config, request), + fetchContentItem: (request: FetchContentItemQueryRequest) => fetchContentItemQuery(config, request), + listContentItems: (request?: ListContentItemsQueryRequest) => listContentItemsQuery(config, request), + itemsFeed: (request?: ItemsFeedQueryRequest) => itemsFeedQuery(config, request), + itemsReferencingAsset: (request: ItemsReferencingAssetQueryRequest) => itemsReferencingAssetQuery(config, request), + itemsReferencingItem: (request: ItemsReferencingItemQueryRequest) => itemsReferencingItemQuery(config, request), + }; } diff --git a/lib/client/idelivery-client.interface.ts b/lib/client/idelivery-client.interface.ts deleted file mode 100644 index 4f1ee49c..00000000 --- a/lib/client/idelivery-client.interface.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { ClientTypes, IContentItem } from '../models'; -import { - ElementQuery, - ItemsFeedQuery, - MultipleItemsQuery, - MultipleTypeQuery, - SingleItemQuery, - SingleTypeQuery, - TaxonomiesQuery, - TaxonomyQuery, - LanguagesQuery, - InitializeSyncQuery, - SyncChangesQuery, - UsedInQuery -} from '../query'; -import { IMappingService } from '../services'; - -export interface IDeliveryClient { - /** - * Mapping service - can be used to get strongly typed responses from json result - */ - mappingService: IMappingService; - - /** - * Gets query for languages - */ - languages(): LanguagesQuery; - - /** - * Gets query for multiple types - */ - types(): MultipleTypeQuery; - - /** - * Gets query for single type - * @param {string} typeCodename - Codename of the type to retrieve - */ - type(typeCodename: TClientTypes['contentTypeCodenames']): SingleTypeQuery; - - /** - * Gets query for multiple items - */ - items(): MultipleItemsQuery< - TClientTypes, - TContentItem - >; - - /** - * Gets query for items feed. Executes single HTTP request only - */ - itemsFeed(): ItemsFeedQuery< - TClientTypes, - TContentItem - >; - - /** - * Gets query for single item - * @param {string} codename - Codename of item to retrieve - */ - item( - codename: string - ): SingleItemQuery; - - /** - * Gets query for multiple taxonomies - */ - taxonomies(): TaxonomiesQuery; - - /** - * Gets query for single item - * @param {string} codename - Codename of taxonomy to retrieve - */ - taxonomy(codename: TClientTypes['taxonomyCodenames']): TaxonomyQuery; - - /** - * Gets query for an element within a type - */ - element( - typeCodename: TClientTypes['contentTypeCodenames'], - elementCodename: TClientTypes['elementCodenames'] - ): ElementQuery; - - /** - * @deprecated Sync API v1 is deprecated and will be shut down by the end of this year. - * Please migrate to Sync API v2 using the `@kontent-ai/sync-sdk` package. - * - * For migration guidance and full documentation, visit: - * https://kontent.ai/learn/docs/apis/openapi/sync-api-v2/ - */ - initializeSync(): InitializeSyncQuery; - - /** - * @deprecated Sync API v1 is deprecated and will be shut down by the end of this year. - * Please migrate to Sync API v2 using the `@kontent-ai/sync-sdk` package. - * - * For migration guidance and full documentation, visit: - * https://kontent.ai/learn/docs/apis/openapi/sync-api-v2/ - */ - syncChanges(): SyncChangesQuery; - - /** - * Item listing of where an asset is used - */ - assetUsedIn(assetCodename: string): UsedInQuery; - - /** - * Item listing of where a content item is used - */ - itemUsedIn(itemCodename: string): UsedInQuery; -} diff --git a/lib/client/index.ts b/lib/client/index.ts deleted file mode 100644 index fd0ce3d7..00000000 --- a/lib/client/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './delivery-client'; -export * from './idelivery-client.interface'; -export * from './delivery-client.factory'; diff --git a/lib/config/delivery-configs.ts b/lib/config/delivery-configs.ts deleted file mode 100644 index 77a531fc..00000000 --- a/lib/config/delivery-configs.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { IHeader, IHttpService, IRetryStrategyOptions } from '@kontent-ai/core-sdk'; - -import { ElementResolver } from '../elements'; -import { IProxyUrlData, IQueryConfig, LinkedItemsReferenceHandler } from '../models'; - -export interface IDeliveryClientProxyConfig { - /** - * Base url used for preview reqeusts. Defaults to 'preview-deliver.kontent.ai' - */ - basePreviewUrl?: string; - - /** - * Can be used to generate custom request urls. - * Useful when you have a proxy server and need to transform url to a specific format - * and setting 'baseUrl' is not sufficient. - */ - advancedProxyUrlResolver?: (data: IProxyUrlData) => string; - - /** - * Base url used for all requests. Defaults to 'deliver.kontent.ai' - */ - baseUrl?: string; -} - -export interface IDeliveryClientConfig { - /** - * EnvironmentId - */ - environmentId: string; - - /** - * Preview API key - */ - previewApiKey?: string; - - /** - * Secure API key - * Important: Use secured API only when running on Node.JS server, otherwise - * your key would be exposed in browsers - */ - secureApiKey?: string; - - /** - * Resolver used for using custom models for custom elements. - */ - elementResolver?: ElementResolver; - - /** - * Proxy configuration - */ - proxy?: IDeliveryClientProxyConfig; - - /** - * Default language of content items - */ - defaultLanguage?: string; - - /** - * Retry policy configuration - */ - retryStrategy?: IRetryStrategyOptions; - - /** - * Can be used to inject custom Http service to perform requests - */ - httpService?: IHttpService; - - /** - * Extra headers added to each http request - */ - globalHeaders?: (queryConfig: IQueryConfig) => IHeader[]; - - /** - * Default query configuration. Can be overriden by individual queries. - */ - defaultQueryConfig?: IQueryConfig; - - /** - * Indicates how linked item references are handled (can be used to disable refence mapping when you encounter an issue - * with circular refences) - */ - linkedItemsReferenceHandler?: LinkedItemsReferenceHandler; - - /** - * Sets custom domain for assets - */ - assetsDomain?: string; - - /** - * Codename of rendition preset to be applied by default to the base asset URL path. - */ - defaultRenditionPreset?: string; - - /** - * Can be used to exclude archived items from all queries by default. Only applicable when preview API is used - */ - excludeArchivedItems?: boolean; -} diff --git a/lib/config/index.ts b/lib/config/index.ts deleted file mode 100644 index a6e72ace..00000000 --- a/lib/config/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './delivery-configs'; diff --git a/lib/contracts/contracts.ts b/lib/contracts/contracts.ts deleted file mode 100644 index 0e033e0b..00000000 --- a/lib/contracts/contracts.ts +++ /dev/null @@ -1,265 +0,0 @@ -export namespace Contracts { - export interface IPaginationContract { - skip: number; - limit: number; - count: number; - next_page: string; - total_count?: number; - } - - export interface IContentTypeElementContract { - codename?: string; - type: string; - name: string; - taxonomy_group?: string; - options?: IElementOptionContract[]; - } - - export interface IContentTypeElementsContainer { - [key: string]: IContentTypeElementContract; - } - - export interface IElementOptionContract { - name: string; - codename: string; - } - - export interface IListLanguagesContract { - languages: ILanguageContract[]; - pagination: IPaginationContract; - } - - export interface IContentItemDeltaContract { - data: { - system: IContentItemSystemAttributesContract; - elements: IContentItemElementsContracts | undefined; - }; - change_type: 'changed_item' | 'deleted_item'; - timestamp: string; - } - - export interface IInitializeSyncContract { - items: IContentItemDeltaContract[]; - } - - export interface ISyncChangesContract { - items: IContentItemDeltaContract[]; - } - - export interface ILanguageContract { - system: { - id: string; - name: string; - codename: string; - }; - } - - export interface IViewContentTypeElementContract { - codename?: string; - type: string; - name: string; - taxonomy_group?: string; - options?: IElementOptionContract[]; - } - - export interface IElementContract { - codename?: string; - name: string; - type: string; - value: any; - taxonomy_group?: string; - } - - export interface IDateTimeElementContract extends IElementContract { - /** - * Display time zone - */ - display_timezone: string; - } - - export interface IAsssetRenditionContract { - rendition_id: string; - preset_id: string; - width: number; - height: number; - query: string; - } - - export interface IAssetContract { - name: string; - type: string; - size: number; - description: string; - url: string; - width: number | null; - height: number | null; - renditions?: { [renditionPresetCodename: string]: IAsssetRenditionContract }; - } - - export interface IMultipleChoiceOptionContract { - name: string; - codename: string; - } - - export interface ITaxonomyTerm { - name: string; - codename: string; - } - - export interface IRichTextElementLinkWrapperContract { - [key: string]: IRichTextElementLinkContract; - } - - export interface IRichTextElementLinkContract { - type: string; - codename: string; - url_slug: string; - } - - export interface IRichTextElementImageWrapperContract { - [key: string]: IRichTextElementImageContract; - } - - export interface IRichTextElementImageContract { - image_id: string; - url: string; - description: string | null; - height: number | null; - width: number | null; - } - - export interface IRichTextElementContract extends IElementContract { - /** - * Modular content items - */ - modular_content: string[]; - - /** - * Json with links - */ - links: IRichTextElementLinkWrapperContract; - - /** - * Json with images - */ - images: IRichTextElementImageWrapperContract; - } - - export interface IContentItemElementsContracts { - [key: string]: IElementContract; - } - - export interface ILinkContract { - codename: string; - type: string; - url_slug: string; - } - - export interface IModularContentContract { - [key: string]: IModularContentContentItemContract; - } - - export interface IModularContentContentItemContract { - system: IContentItemSystemAttributesContract; - elements: IContentItemElementsContracts; - } - - export interface IContentItemContract { - system: IContentItemSystemAttributesContract; - elements: IContentItemElementsContracts; - } - - export interface IContentItemSystemAttributesContract { - id: string; - name: string; - codename: string; - type: string; - last_modified: string; - language: string; - sitemap_locations: string[]; - collection: string; - workflow_step: string | null; - workflow: string | null; - } - - export interface IItemsWithModularContentContract { - items: IContentItemContract[]; - modular_content: IModularContentContract; - } - - export interface IItemsFeedContract extends IItemsWithModularContentContract {} - - export interface IUsedInItemsContract { - items: IUsedInItemContract[]; - } - - export interface IUsedInItemContract { - system: { - id: string; - name: string; - codename: string; - language: string; - type: string; - collection: string; - workflow: string; - workflow_step: string; - last_modified: string; - }; - } - - export interface IListContentItemsContract extends IItemsWithModularContentContract { - pagination: IPaginationContract; - } - - export interface IViewContentItemContract { - item: IContentItemContract; - modular_content: IModularContentContract; - } - - export interface ITaxonomyTermsContract { - name: string; - codename: string; - terms: ITaxonomyTermsContract[]; - } - - export interface ITaxonomySystemAttributesContract { - id: string; - name: string; - codename: string; - last_modified: Date; - } - - export interface ITaxonomyGroupContract { - system: ITaxonomySystemAttributesContract; - terms: ITaxonomyTermsContract[]; - } - - export interface IViewTaxonomyGroupContract { - system: ITaxonomySystemAttributesContract; - terms: ITaxonomyTermsContract[]; - } - - export interface IListTaxonomyGroupsContract { - taxonomies: ITaxonomyGroupContract[]; - pagination: IPaginationContract; - } - - export interface IContentTypeSystemAttributesContract { - id: string; - name: string; - codename: string; - last_modified: Date; - } - - export interface IContentTypeContract { - system: IContentTypeSystemAttributesContract; - elements: IContentTypeElementsContainer; - } - - export interface IListContentTypeContract { - types: IContentTypeContract[]; - pagination: IPaginationContract; - } - - export interface IViewContentTypeContract extends IContentTypeContract {} -} diff --git a/lib/contracts/index.ts b/lib/contracts/index.ts deleted file mode 100644 index c7041c4c..00000000 --- a/lib/contracts/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './contracts'; diff --git a/lib/delivery-sdk-info.ts b/lib/delivery-sdk-info.ts new file mode 100644 index 00000000..04008a85 --- /dev/null +++ b/lib/delivery-sdk-info.ts @@ -0,0 +1,7 @@ +import type { SdkInfo } from "@kontent-ai/core-sdk"; + +export const deliverySdkInfo: SdkInfo = { + version: "{{version}}", + name: "@kontent-ai/delivery-sdk", + host: "npmjs.com", +}; diff --git a/lib/elements/element-models.ts b/lib/elements/element-models.ts deleted file mode 100644 index bd40c7f0..00000000 --- a/lib/elements/element-models.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Contracts } from '../contracts'; -import { IContentItemSystemAttributes } from '../models/item-models'; -import { ElementType } from './element-type'; - -export namespace ElementModels { - export interface IElementWrapper { - element: string; - system: IContentItemSystemAttributes; - rawElement: Contracts.IElementContract; - } - - export interface IElement { - /** - * Name of the element - */ - name: string; - - /** - * Element type - */ - type: ElementType; - - /** - * Element value - */ - value: TValue; - } - - export interface AssetModel { - /** - * Name of the asset - */ - name: string; - - /** - * Type of the asset - */ - type: string; - - /** - * Size of the asset - */ - size: number; - - /** - * Description of the asset - */ - description: string | null; - - /** - * Url of the asset - */ - url: string; - - /** - * Width in pixels for image assets - */ - width: number | null; - - /** - * Height in pixels for image assets - */ - height: number | null; - - /** - * Dictionary with rendition preset codenames as keys and respective renditions as values. - */ - renditions: { [renditionPresetCodename: string]: Rendition } | null; - } - - export interface Rendition { - rendition_id: string; - preset_id: string; - width: number; - height: number; - query: string; - url: string; - } - - export interface MultipleChoiceOption { - name: string; - codename: TOptionCodename; - } - - export interface TaxonomyTerm { - name: string; - codename: TTaxonomyCodename; - } -} diff --git a/lib/elements/element-resolver.ts b/lib/elements/element-resolver.ts deleted file mode 100644 index a9906f0b..00000000 --- a/lib/elements/element-resolver.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ElementModels } from './element-models'; - -export type ElementResolver = (element: ElementModels.IElementWrapper) => any; diff --git a/lib/elements/element-type.ts b/lib/elements/element-type.ts deleted file mode 100644 index 2c2c5818..00000000 --- a/lib/elements/element-type.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** -* Represents codename of Kontent.ai element types -*/ -export enum ElementType { - Text = 'text', - Number = 'number', - ModularContent = 'modular_content', - Asset = 'asset', - DateTime = 'date_time', - RichText = 'rich_text', - MultipleChoice = 'multiple_choice', - UrlSlug = 'url_slug', - Taxonomy = 'taxonomy', - Custom = 'custom', - Unknown = 'unknown' -} diff --git a/lib/elements/elements.ts b/lib/elements/elements.ts deleted file mode 100644 index 79824d11..00000000 --- a/lib/elements/elements.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { IContentItem, ILink, IRichTextImage } from '../models'; -import { ElementModels } from './element-models'; - -export namespace Elements { - export type TextElement = ElementModels.IElement; - - export type LinkedItemsElement = ElementModels.IElement< - string[] - > & { - /** - * Linked items - */ - linkedItems: TContentItem[]; - }; - - export type MultipleChoiceElement = ElementModels.IElement< - ElementModels.MultipleChoiceOption[] - >; - - export type DateTimeElement = ElementModels.IElement & { - /** - * Display time zone - */ - displayTimeZone: string | null; - }; - - export type RichTextElement = ElementModels.IElement & { - /** - * Links - */ - links: ILink[]; - - /** - * Images included within rich text element - */ - images: IRichTextImage[]; - - /** - * Array of linked item codenames - */ - linkedItemCodenames: string[]; - - /** - * Array of linked items retrieved from `modular_content` part of the response. Not all items might be here - * as it depends on the `depth` parameter of query. - * The `linkedItemsReferenceHandler` configuration can be used to disable mapping of linked items - */ - linkedItems: TContentItem[]; - }; - - export type NumberElement = ElementModels.IElement; - - export type AssetsElement = ElementModels.IElement; - - export type UrlSlugElement = ElementModels.IElement; - - export type TaxonomyElement< - TaxonomyCodenames extends string = string, - TaxonomyGroupCodename extends string = string - > = ElementModels.IElement[]> & { - /** - * Taxonomy group - */ - taxonomyGroup: TaxonomyGroupCodename; - }; - - export type UnknownElement = ElementModels.IElement; - - export type CustomElement = ElementModels.IElement; -} diff --git a/lib/elements/index.ts b/lib/elements/index.ts deleted file mode 100644 index 16bcf153..00000000 --- a/lib/elements/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './element-models'; -export * from './element-type'; -export * from './elements'; -export * from './element-resolver'; diff --git a/lib/images/image-url-transformation-builder.factory.ts b/lib/images/image-url-transformation-builder.factory.ts deleted file mode 100644 index 143d1d09..00000000 --- a/lib/images/image-url-transformation-builder.factory.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ImageUrlTransformationBuilder } from './image-url-transformation-builder'; - -export function transformImageUrl(url: string): ImageUrlTransformationBuilder { - return new ImageUrlTransformationBuilder(url); -} diff --git a/lib/images/image-url-transformation-builder.ts b/lib/images/image-url-transformation-builder.ts deleted file mode 100644 index 7582c4e8..00000000 --- a/lib/images/image-url-transformation-builder.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { Parameters } from '../models'; -import { ImageCompression, ImageFitMode, ImageFormat } from './image.models'; - -export class ImageUrlTransformationBuilder { - private queryParams: IQueryParameter[] = []; - private readonly automaticFormatValue: string = 'format'; - - constructor( - /** Image url */ - public imageUrl: string - ) { } - - /** - * Used to add custom parameters to existing query string - * @param param Parameter (may or may not include value) - */ - withCustomParam(param: string): this { - this.queryParams.push( - new Parameters.CustomParameter(param) - ); - return this; - } - - /** - * The dpr transformation is used to serve correctly sized images for devices that expose a device pixel ratio. - * @param dpr A required DPR value. - */ - withDpr(dpr: number): this { - this.queryParams.push( - new Parameters.QueryParameter('dpr', dpr.toString()) - ); - - return this; - } - - /** - * Applies the crop transformation that removes pixels from an image outside the specified rectangle. - * @param x Rectangle offset on the X-axis. - * @param y Rectangle offset on the Y-axis. - * @param width Rectangle width. - * @param height Rectangle height. - */ - withRectangleCrop(x: number, y: number, width: number, height: number): this { - this.queryParams.push( - new Parameters.QueryParameter('rect', [x, y, width, height].join(',')) - ); - return this; - } - - /** - * Applies the crop transformation centered on the specified point. - * @param x Focal point X coordinate. - * @param y Focal point Y coordinate. - * @param z Zoom of the transformation. - */ - withFocalPointCrop(x: number, y: number, z: number): this { - this.withFitMode('crop'); - - this.queryParams.push(new Parameters.QueryParameter('crop', 'focalpoint')); - this.queryParams.push(new Parameters.QueryParameter('fp-x', x.toString())); - this.queryParams.push(new Parameters.QueryParameter('fp-y', y.toString())); - this.queryParams.push(new Parameters.QueryParameter('fp-z', z.toString())); - - return this; - } - - /** - * Enables WebP image support. - * @param compression Specifies the lossy or lossless compression. - */ - withAutomaticFormat(backupFormat?: ImageFormat): this { - this.queryParams.push( - new Parameters.QueryParameter('auto', this.automaticFormatValue) - ); - - if (backupFormat) { - this.withFormat(backupFormat); - } - - return this; - } - - /** - * The fit transformation controls how the output image is fit to its target dimensions after resizing. - * @param fitMode Specifies the mode for the transformation. - */ - withFitMode(fitMode: ImageFitMode): this { - this.queryParams.push(new Parameters.QueryParameter('fit', fitMode)); - return this; - } - - /** - * Specifies the compression mode for the WebP image transformations. - * @param compression Specifies the lossy or lossless compression. - */ - withCompression(compression: ImageCompression): this { - this.queryParams.push( - new Parameters.QueryParameter( - 'lossless', - compression === 'lossless' ? 'true' : 'false' - ) - ); - return this; - } - - /** - * Applies the quality parameter that enables control over the compression level for lossy file-formatted images. - * @param quality The required quality of the image. - */ - withQuality(quality: number): this { - this.queryParams.push( - new Parameters.QueryParameter('q', quality.toString()) - ); - return this; - } - - /** - * The format transformation enables the source image to be converted (a.k.a., "transcoded") from - * one encoded format to another. This is very useful when the source image has been saved in a sub-optimal - * file format that hinders performance. - * @param format Target image file type. - */ - withFormat(format: ImageFormat): this { - this.queryParams.push( - new Parameters.QueryParameter('fm', format) - ); - return this; - } - - /** - * The height transformation enables dynamic height resizing based on pixels and percent values. - * @param height A required image height. - */ - withHeight(height: number): this { - this.queryParams.push( - new Parameters.QueryParameter('h', height.toString()) - ); - return this; - } - - /** - * The width transformation enables dynamic width resizing based on pixels and percent values. - * @param width A required image width. - */ - withWidth(width: number): this { - this.queryParams.push(new Parameters.QueryParameter('w', width.toString())); - return this; - } - - /** - * Gets params applied to image - */ - getParams(): IQueryParameter[] { - return this.queryParams; - } - - /** - * Gets query string part of the image URL - */ - getQueryString(): string { - let query: string = ''; - this.queryParams.forEach(filter => { - if (query.indexOf('?') > -1) { - query = query + '&' + filter.getParam(); - } else { - query = query + '?' + filter.getParam(); - } - }); - - return query; - } - - /** - * Gets full transformed url to image with parameters - */ - getUrl(): string { - return this.imageUrl + this.getQueryString(); - } -} diff --git a/lib/images/image.models.ts b/lib/images/image.models.ts deleted file mode 100644 index 0181e969..00000000 --- a/lib/images/image.models.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type ImageFitMode = 'clip' | 'scale' | 'crop'; -export type ImageFormat = 'gif' | 'png' |'png8' | 'jpg' | 'pjpg' |'webp'| 'mp4'; -export type ImageCompression = 'lossless' | 'lossy'; - diff --git a/lib/images/index.ts b/lib/images/index.ts deleted file mode 100644 index 77c422db..00000000 --- a/lib/images/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './image-url-transformation-builder'; -export * from './image.models'; -export * from './image-url-transformation-builder.factory'; diff --git a/lib/index.ts b/lib/index.ts deleted file mode 100644 index 9305851b..00000000 --- a/lib/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Public API -export * from './client'; -export * from './config'; -export * from './contracts'; -export * from './elements'; -export * from './images'; -export * from './mappers'; -export * from './models'; -export * from './query'; -export * from './sdk-info.generated'; -export * from './services'; -export * from './utilities'; diff --git a/lib/mappers/element.mapper.ts b/lib/mappers/element.mapper.ts deleted file mode 100644 index 66eb5d75..00000000 --- a/lib/mappers/element.mapper.ts +++ /dev/null @@ -1,504 +0,0 @@ -import { codenameHelper, deliveryUrlHelper, enumHelper } from '../utilities'; - -import { IDeliveryClientConfig } from '../config'; -import { Contracts } from '../contracts'; -import { ElementModels, Elements, ElementType } from '../elements'; -import { - IContentItem, - IContentItemsContainer, - IContentItemWithRawDataContainer, - IContentItemWithRawElements, - ILink, - IMapElementsResult, - IRichTextImage -} from '../models'; - -interface IRichTextImageUrlRecord { - originalUrl: string; - newUrl: string; -} - -export class ElementMapper { - constructor(private readonly config: IDeliveryClientConfig) {} - - mapElements(data: { - dataToMap: IContentItemWithRawElements; - processedItems: IContentItemsContainer; - processingStartedForCodenames: string[]; - preparedItems: IContentItemWithRawDataContainer; - }): IMapElementsResult | undefined { - // return processed item to avoid infinite recursion - const processedItem = - data.processedItems[codenameHelper.escapeCodenameInCodenameIndexer(data.dataToMap.item.system.codename)]; - if (processedItem) { - // item was already resolved - return { - item: processedItem, - processedItems: data.processedItems, - preparedItems: data.preparedItems, - processingStartedForCodenames: data.processingStartedForCodenames - }; - } - - const preparedItem = - data.preparedItems[codenameHelper.escapeCodenameInCodenameIndexer(data.dataToMap.item.system.codename)]; - - const itemInstance = preparedItem?.item; - - if (!itemInstance) { - // item is not present in response - return undefined; - } - - // mapp elements - const elementCodenames = Object.getOwnPropertyNames(data.dataToMap.rawItem.elements); - - for (const elementCodename of elementCodenames) { - const elementWrapper: ElementModels.IElementWrapper = { - system: data.dataToMap.item.system, - rawElement: data.dataToMap.rawItem.elements[elementCodename], - element: elementCodename - }; - - const mappedElement = this.mapElement({ - elementWrapper: elementWrapper, - item: itemInstance, - preparedItems: data.preparedItems, - processingStartedForCodenames: data.processingStartedForCodenames, - processedItems: data.processedItems - }); - - // set mapped elements - itemInstance.elements[elementCodename] = mappedElement; - } - - return { - item: itemInstance as TContentItem, - processedItems: data.processedItems, - preparedItems: data.preparedItems, - processingStartedForCodenames: data.processingStartedForCodenames - }; - } - - private mapElement(data: { - elementWrapper: ElementModels.IElementWrapper; - item: IContentItem; - processedItems: IContentItemsContainer; - processingStartedForCodenames: string[]; - preparedItems: IContentItemWithRawDataContainer; - }): ElementModels.IElement { - const elementType = enumHelper.getEnumFromValue(ElementType, data.elementWrapper.rawElement.type); - if (elementType) { - if (elementType === ElementType.ModularContent) { - return this.mapLinkedItemsElement({ - elementWrapper: data.elementWrapper, - preparedItems: data.preparedItems, - processingStartedForCodenames: data.processingStartedForCodenames, - processedItems: data.processedItems - }); - } - - if (elementType === ElementType.Text) { - return this.mapTextElement(data.elementWrapper); - } - if (elementType === ElementType.Asset) { - return this.mapAssetsElement(data.elementWrapper); - } - - if (elementType === ElementType.Number) { - return this.mapNumberElement(data.elementWrapper); - } - if (elementType === ElementType.MultipleChoice) { - return this.mapMultipleChoiceElement(data.elementWrapper); - } - - if (elementType === ElementType.DateTime) { - return this.mapDateTimeElement(data.elementWrapper); - } - - if (elementType === ElementType.RichText) { - // add to parent items - return this.mapRichTextElement( - data.elementWrapper, - data.processedItems, - data.processingStartedForCodenames, - data.preparedItems - ); - } - - if (elementType === ElementType.UrlSlug) { - return this.mapUrlSlugElement(data.elementWrapper); - } - - if (elementType === ElementType.Taxonomy) { - return this.mapTaxonomyElement(data.elementWrapper); - } - - if (elementType === ElementType.Custom) { - return this.mapCustomElement(data.elementWrapper); - } - } - console.warn( - `Could not map element '${data.elementWrapper.rawElement.name}' of type '${data.elementWrapper.rawElement.type}'. Returning unknown element instead.` - ); - return this.mapUnknowElement(data.elementWrapper); - } - - private mapRichTextElement( - elementWrapper: ElementModels.IElementWrapper, - processedItems: IContentItemsContainer, - processingStartedForCodenames: string[], - preparedItems: IContentItemWithRawDataContainer - ): Elements.RichTextElement { - const rawElement = elementWrapper.rawElement as Contracts.IRichTextElementContract; - - // get all linked items and linked items codenames nested in rich text - const richTextLinkedItems: IContentItem[] = []; - const richTextLinkedItemsCodenames: string[] = []; - - // The Kontent Delivery API is not guaranteed to return rich-text modular_content array items in the same order in which they appear inside the `value` property. - // We extract the modular_content codenames in the rich-text value and sort the raw modular_content based on that order instead. - const rawModularContentCodenamesMatches = (rawElement.value as string).matchAll( - /]+data-codename="(?[a-z0-9_]*)".*?>/g - ); - const rawModularContentCodenamesSorted = Array.from(rawModularContentCodenamesMatches).reduce( - (acc, match) => { - if (match.groups && match.groups.codename) { - acc.push(match.groups.codename); - } - return acc; - }, - [] as string[] - ); - const rawModularContentCodenames = [...rawElement.modular_content].sort(function (a, b) { - return rawModularContentCodenamesSorted.indexOf(a) - rawModularContentCodenamesSorted.indexOf(b); - }); - - for (const codename of rawModularContentCodenames) { - richTextLinkedItemsCodenames.push(codename); - // get linked item and check if it exists (it might not be included in response due to 'Depth' parameter) - const preparedData = preparedItems[codename]; - - // first try to get existing item - if (this.canMapLinkedItems()) { - const existingLinkedItem = this.getOrSaveLinkedItemForElement( - codename, - rawElement, - processedItems, - processingStartedForCodenames, - preparedItems - ); - - if (existingLinkedItem) { - // item was found, add it to linked items - richTextLinkedItems.push(existingLinkedItem); - } else { - // item was not found or not yet resolved - if (preparedData) { - const mappedLinkedItemResult = this.mapElements({ - dataToMap: preparedData, - preparedItems: preparedItems, - processingStartedForCodenames: processingStartedForCodenames, - processedItems: processedItems - }); - - // add mapped linked item to result - if (mappedLinkedItemResult) { - richTextLinkedItems.push(mappedLinkedItemResult.item); - } - } - } - } - } - - // get rich text images - const richTextImagesResult = this.getRichTextImages(rawElement.images); - - // extract and map links & images - const links: ILink[] = this.mapRichTextLinks(rawElement.links); - const images: IRichTextImage[] = richTextImagesResult.richTextImages; - - // replace asset urls in html - const richTextHtml: string = this.getRichTextHtml(rawElement.value, richTextImagesResult.imageUrlRecords); - - return { - images: images, - linkedItemCodenames: richTextLinkedItemsCodenames, - linkedItems: richTextLinkedItems, - links: links, - name: rawElement.name, - type: ElementType.RichText, - value: richTextHtml - }; - } - - private mapDateTimeElement(elementWrapper: ElementModels.IElementWrapper): Elements.DateTimeElement { - const rawElement = elementWrapper.rawElement as Contracts.IDateTimeElementContract; - return { - ...this.buildElement(elementWrapper, ElementType.DateTime, () => rawElement.value), - displayTimeZone: rawElement.display_timezone ?? null - }; - } - - private mapMultipleChoiceElement(elementWrapper: ElementModels.IElementWrapper): Elements.MultipleChoiceElement { - return this.buildElement(elementWrapper, ElementType.MultipleChoice, () => elementWrapper.rawElement.value); - } - - private mapNumberElement(elementWrapper: ElementModels.IElementWrapper): Elements.NumberElement { - return this.buildElement(elementWrapper, ElementType.Number, () => { - if (elementWrapper.rawElement.value === 0) { - return 0; - } else if (elementWrapper.rawElement.value) { - return +elementWrapper.rawElement.value; - } - return null; - }); - } - - private mapTextElement(elementWrapper: ElementModels.IElementWrapper): Elements.TextElement { - return this.buildElement(elementWrapper, ElementType.Text, () => elementWrapper.rawElement.value); - } - - private mapAssetsElement(elementWrapper: ElementModels.IElementWrapper): Elements.AssetsElement { - return this.buildElement(elementWrapper, ElementType.Asset, () => { - const assetContracts = elementWrapper.rawElement.value as Contracts.IAssetContract[]; - - const assets: ElementModels.AssetModel[] = []; - - for (const assetContract of assetContracts) { - let renditions: { [renditionPresetCodename: string]: ElementModels.Rendition } | null = null; - - // get asset url (custom domain may be configured) - const assetUrl: string = this.config.assetsDomain - ? deliveryUrlHelper.replaceAssetDomain(assetContract.url, this.config.assetsDomain) - : assetContract.url; - - if (assetContract.renditions) { - renditions = {}; - - for (const renditionPresetKey of Object.keys(assetContract.renditions)) { - const rendition = assetContract.renditions[renditionPresetKey]; - - renditions[renditionPresetKey] = { - ...rendition, - url: `${assetUrl}?${rendition.query}` // enhance rendition with absolute url - }; - } - } - - const renditionToBeApplied: ElementModels.Rendition | null = - (this.config.defaultRenditionPreset && renditions?.[this.config.defaultRenditionPreset]) || null; - - const finalUrl = renditionToBeApplied?.url ?? assetUrl; - - const asset: ElementModels.AssetModel = { - ...assetContract, - url: finalUrl, // use custom url of asset which may contain custom domain and applied rendition - renditions - }; - - assets.push(asset); - } - - return assets; - }); - } - - private mapTaxonomyElement(elementWrapper: ElementModels.IElementWrapper): Elements.TaxonomyElement { - return { - ...this.buildElement(elementWrapper, ElementType.Taxonomy, () => elementWrapper.rawElement.value), - taxonomyGroup: elementWrapper.rawElement.taxonomy_group ?? '' - }; - } - - private mapUnknowElement(elementWrapper: ElementModels.IElementWrapper): Elements.UnknownElement { - return this.buildElement(elementWrapper, ElementType.Unknown, () => elementWrapper.rawElement.value); - } - - private mapCustomElement( - elementWrapper: ElementModels.IElementWrapper - ): Elements.CustomElement | ElementModels.IElement { - // try to find element resolver - if (this.config.elementResolver) { - const elementResolverValue = this.config.elementResolver(elementWrapper); - - if (elementResolverValue) { - return this.buildElement(elementWrapper, ElementType.Custom, () => elementResolverValue); - } - } - - return this.buildElement(elementWrapper, ElementType.Custom, () => elementWrapper.rawElement.value); - } - - private mapUrlSlugElement(elementWrapper: ElementModels.IElementWrapper): Elements.UrlSlugElement { - return this.buildElement(elementWrapper, ElementType.UrlSlug, () => elementWrapper.rawElement.value); - } - - private mapLinkedItemsElement(data: { - elementWrapper: ElementModels.IElementWrapper; - processedItems: IContentItemsContainer; - processingStartedForCodenames: string[]; - preparedItems: IContentItemWithRawDataContainer; - }): Elements.LinkedItemsElement { - // prepare linked items - const linkedItems: IContentItem[] = []; - - // value = array of item codenames - const linkedItemCodenames = data.elementWrapper.rawElement.value as string[]; - - for (const codename of linkedItemCodenames) { - if (this.canMapLinkedItems()) { - const linkedItem = this.getOrSaveLinkedItemForElement( - codename, - data.elementWrapper.rawElement, - data.processedItems, - data.processingStartedForCodenames, - data.preparedItems - ); - if (linkedItem) { - // add item to result - linkedItems.push(linkedItem); - } - } - } - - return { - ...this.buildElement(data.elementWrapper, ElementType.ModularContent, () => linkedItemCodenames), - linkedItems: linkedItems - }; - } - - private getOrSaveLinkedItemForElement( - codename: string, - element: Contracts.IElementContract, - processedItems: IContentItemsContainer, - mappingStartedForCodenames: string[], - preparedItems: IContentItemWithRawDataContainer - ): IContentItem | undefined { - const escapedCodename = codenameHelper.escapeCodenameInCodenameIndexer(codename); - - // first check if item was already resolved and return it if it was - const processedItem = processedItems[escapedCodename]; - - if (processedItem) { - // item was already resolved - return processedItem; - } - - const preparedItem = preparedItems[escapedCodename]; - - if (mappingStartedForCodenames.includes(codename)) { - return preparedItem?.item; - } - - mappingStartedForCodenames.push(codename); - - // throw error if item is not in response and errors are not skipped - if (!preparedItem) { - return undefined; - } - - let mappedLinkedItem: TContentItemType | undefined; - - // original resolving if item is still undefined - const mappedLinkedItemResult = this.mapElements({ - dataToMap: preparedItem, - preparedItems: preparedItems, - processingStartedForCodenames: mappingStartedForCodenames, - processedItems: processedItems - }); - - if (mappedLinkedItemResult) { - mappedLinkedItem = mappedLinkedItemResult.item; - - // add to processed items - processedItems[escapedCodename] = mappedLinkedItem; - } - - return mappedLinkedItem; - } - - private mapRichTextLinks(linksJson: Contracts.IRichTextElementLinkWrapperContract): ILink[] { - const links: ILink[] = []; - - for (const linkId of Object.keys(linksJson)) { - const linkRaw = linksJson[linkId]; - links.push({ - codename: linkRaw.codename, - linkId: linkId, - urlSlug: linkRaw.url_slug, - type: linkRaw.type - }); - } - - return links; - } - - private getRichTextHtml(richTextHtml: string, richTextImageRecords: IRichTextImageUrlRecord[]): string { - for (const richTextImageRecord of richTextImageRecords) { - // replace rich text image url if it differs - if (richTextImageRecord.newUrl !== richTextImageRecord.originalUrl) { - richTextHtml = richTextHtml.replace( - new RegExp(richTextImageRecord.originalUrl, 'g'), - richTextImageRecord.newUrl - ); - } - } - - return richTextHtml; - } - - private getRichTextImages(imagesJson: Contracts.IRichTextElementImageWrapperContract): { - richTextImages: IRichTextImage[]; - imageUrlRecords: IRichTextImageUrlRecord[]; - } { - const images: IRichTextImage[] = []; - const imageUrlRecords: IRichTextImageUrlRecord[] = []; - - for (const imageId of Object.keys(imagesJson)) { - const imageRaw = imagesJson[imageId]; - - // image may contain custom asset domain - const imageUrl: string = this.config.assetsDomain - ? deliveryUrlHelper.replaceAssetDomain(imageRaw.url, this.config.assetsDomain) - : imageRaw.url; - - images.push({ - description: imageRaw.description ?? null, - imageId: imageRaw.image_id, - url: imageUrl, - height: imageRaw.height ?? null, - width: imageRaw.width ?? null - }); - - imageUrlRecords.push({ - originalUrl: imageRaw.url, - newUrl: imageUrl - }); - } - - return { - imageUrlRecords: imageUrlRecords, - richTextImages: images - }; - } - - private buildElement( - elementWrapper: ElementModels.IElementWrapper, - type: ElementType, - valueFactory: () => TValue - ): ElementModels.IElement { - return { - name: elementWrapper.rawElement.name, - type: type, - value: valueFactory() - }; - } - - private canMapLinkedItems(): boolean { - if (!this.config.linkedItemsReferenceHandler) { - return true; - } - return this.config.linkedItemsReferenceHandler === 'map'; - } -} diff --git a/lib/mappers/generic-element.mapper.ts b/lib/mappers/generic-element.mapper.ts deleted file mode 100644 index 05a70fe0..00000000 --- a/lib/mappers/generic-element.mapper.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Contracts } from '../contracts'; -import { IGenericElement } from '../models'; - -export class GenericElementMapper { - mapElement(response: Contracts.IViewContentTypeElementContract): IGenericElement { - if (!response) { - throw Error(`Invalid response for mapping element`); - } - - const element = response; - - return { - codename: element.codename, - name: element.name, - type: element.type, - options: element.options ? element.options : [], - taxonomyGroup: element.taxonomy_group - }; - } -} diff --git a/lib/mappers/index.ts b/lib/mappers/index.ts deleted file mode 100644 index 562654df..00000000 --- a/lib/mappers/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from './element.mapper'; -export * from './item.mapper'; -export * from './taxonomy.mapper'; -export * from './type.mapper'; -export * from './generic-element.mapper'; -export * from './language.mapper'; -export * from './used-in.mapper'; -export * from './sync.mapper'; diff --git a/lib/mappers/item.mapper.ts b/lib/mappers/item.mapper.ts deleted file mode 100644 index 6abc259c..00000000 --- a/lib/mappers/item.mapper.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { codenameHelper } from '../utilities'; -import { IDeliveryClientConfig } from '../config'; -import { Contracts } from '../contracts'; -import { - IContentItem, - IContentItemsContainer, - IContentItemWithRawDataContainer, - IContentItemWithRawElements -} from '../models'; -import { ElementMapper } from './element.mapper'; - -export interface IMapItemResult< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem -> { - item: TContentItem; - processedItems: IContentItemsContainer; - preparedItems: IContentItemWithRawDataContainer; - processingStartedForCodenames: string[]; -} - -export interface IMultipleItemsMapResult< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem -> { - items: TContentItem[]; - linkedItems: IContentItemsContainer; -} - -export interface ISingleItemMapResult< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem -> { - item: TContentItem; - linkedItems: IContentItemsContainer; -} - -export class ItemMapper { - private readonly elementMapper: ElementMapper; - - constructor(readonly config: IDeliveryClientConfig) { - this.elementMapper = new ElementMapper(config); - } - - /** - * Maps single item to its proper strongly typed model from the given response - * @param response Response used to map the item - * @param queryConfig Query configuration - */ - mapSingleItemFromResponse( - response: Contracts.IViewContentItemContract - ): ISingleItemMapResult { - const mapResult = this.mapItems({ - mainItems: [response.item], - linkedItems: Object.values(response.modular_content) - }); - - return { - item: mapResult.items[0], - linkedItems: mapResult.linkedItems - }; - } - - /** - * Maps multiple items to their strongly typed model from the given response - * @param response Response used to map the item - * @param queryConfig Query configuration - */ - mapMultipleItemsFromResponse( - response: Contracts.IItemsWithModularContentContract - ): IMultipleItemsMapResult { - const mapResult = this.mapItems({ - mainItems: response.items, - linkedItems: Object.values(response.modular_content) - }); - - return mapResult; - } - - /** - * Maps item contracts to full models - */ - mapItems(data: { - mainItems: Contracts.IContentItemContract[]; - linkedItems: Contracts.IContentItemContract[]; - }): IMultipleItemsMapResult { - const processedItems: IContentItemsContainer = {}; - const preparedItems: IContentItemWithRawDataContainer = {}; - const processingStartedForCodenames: string[] = []; - const mappedMainItems: TContentItem[] = []; - const mappedLinkedItems: IContentItemsContainer = {}; - const itemsToResolve: Contracts.IContentItemContract[] = [...data.mainItems, ...data.linkedItems]; - - // first prepare reference for all items - for (const item of itemsToResolve) { - preparedItems[codenameHelper.escapeCodenameInCodenameIndexer(item.system.codename)] = { - item: this.createContentItem(item), - rawItem: item - }; - } - - // then resolve main items - for (const item of data.mainItems) { - const itemResult = this.mapItem({ - item: preparedItems[codenameHelper.escapeCodenameInCodenameIndexer(item.system.codename)], - processedItems: processedItems, - preparedItems: preparedItems, - processingStartedForCodenames: processingStartedForCodenames - }); - mappedMainItems.push(itemResult.item); - } - - // and linked items - for (const item of data.linkedItems) { - const itemResult = this.mapItem({ - item: preparedItems[codenameHelper.escapeCodenameInCodenameIndexer(item.system.codename)], - processedItems: processedItems, - preparedItems: preparedItems, - processingStartedForCodenames: processingStartedForCodenames - }); - - mappedLinkedItems[item.system.codename] = itemResult.item; - } - - return { - items: mappedMainItems, - linkedItems: mappedLinkedItems - }; - } - - /** - * Maps item contract to full model - */ - private mapItem(data: { - item: IContentItemWithRawElements; - processedItems: IContentItemsContainer; - processingStartedForCodenames: string[]; - preparedItems: IContentItemWithRawDataContainer; - }): IMapItemResult { - if (!data.item) { - throw Error(`Could not map item because its undefined`); - } - - const result = this.elementMapper.mapElements({ - dataToMap: data.item, - preparedItems: data.preparedItems, - processingStartedForCodenames: [], - processedItems: data.processedItems - }); - - if (!result) { - throw Error(`Mapping of content item '${data.item.item.system.codename}' failed`); - } - return { - item: result.item, - processedItems: result.processedItems, - preparedItems: result.preparedItems, - processingStartedForCodenames: result.processingStartedForCodenames - }; - } - - private createContentItem(item: Contracts.IContentItemContract): IContentItem { - const contentItem: IContentItem = { - elements: {}, - system: { - codename: item.system.codename, - collection: item.system.collection, - id: item.system.id, - language: item.system.language, - lastModified: item.system.last_modified, - name: item.system.name, - sitemapLocations: item.system.sitemap_locations, - type: item.system.type, - workflowStep: item.system.workflow_step ?? null, - workflow: item.system.workflow ?? null - } - }; - - return contentItem; - } -} diff --git a/lib/mappers/language.mapper.ts b/lib/mappers/language.mapper.ts deleted file mode 100644 index a3e17e4f..00000000 --- a/lib/mappers/language.mapper.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Contracts } from '../contracts'; -import { ILanguage } from '../models'; - -export class LanguageMapper { - mapMultipleLanguages(response: Contracts.IListLanguagesContract): ILanguage[] { - return response.languages.map((language) => { - return this.mapLanguage(language); - }); - } - - private mapLanguage(language: Contracts.ILanguageContract): ILanguage { - if (!language) { - throw Error(`Cannot map language`); - } - - return { - system: { - codename: language.system.codename as TLanguageCodenames, - id: language.system.id, - name: language.system.name - } - }; - } -} diff --git a/lib/mappers/sync.mapper.ts b/lib/mappers/sync.mapper.ts deleted file mode 100644 index 0ed7dbfb..00000000 --- a/lib/mappers/sync.mapper.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Contracts } from '../contracts'; -import { IContentItemDelta } from '../models'; - -export class SyncMapper { - mapContentItemDelta(itemDeltaContract: Contracts.IContentItemDeltaContract): IContentItemDelta { - const systemContract = itemDeltaContract.data.system; - - const elements: Contracts.IContentItemElementsContracts = itemDeltaContract.data.elements - ? itemDeltaContract.data.elements - : {}; - - return { - changeType: itemDeltaContract.change_type, - timestamp: itemDeltaContract.timestamp, - data: { - elements: elements, - system: { - codename: systemContract.codename, - collection: systemContract.collection, - id: systemContract.id, - language: systemContract.language, - lastModified: systemContract.last_modified, - name: systemContract.name, - sitemapLocations: systemContract.sitemap_locations, - type: systemContract.type, - workflowStep: systemContract.workflow_step ?? null, - workflow: systemContract.workflow ?? null - } - } - }; - } -} diff --git a/lib/mappers/taxonomy.mapper.ts b/lib/mappers/taxonomy.mapper.ts deleted file mode 100644 index 7371f5be..00000000 --- a/lib/mappers/taxonomy.mapper.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Contracts } from '../contracts'; -import { ITaxonomyGroup, ITaxonomySystemAttributes, ITaxonomyTerms } from '../models'; - -export class TaxonomyMapper { - mapTaxonomy( - taxonomySystem: Contracts.ITaxonomySystemAttributesContract, - taxonomyTerms: Contracts.ITaxonomyTermsContract[] - ): ITaxonomyGroup { - if (!taxonomySystem) { - throw Error(`Cannot map taxonomy due to missing 'system' property`); - } - - if (!taxonomyTerms) { - throw Error(`Cannot map taxonomy due to missing 'terms' property`); - } - - if (!Array.isArray(taxonomyTerms)) { - throw Error(`Cannot map terms because no terms array was provided`); - } - - const mappedSystemAttributes: ITaxonomySystemAttributes = { - name: taxonomySystem.name, - codename: taxonomySystem.codename as TaxonomyCodenames, - id: taxonomySystem.id, - lastModified: taxonomySystem.last_modified - }; - - const mappedTerms: ITaxonomyTerms[] = this.mapTaxonomyTerms(taxonomyTerms); - - return { - system: mappedSystemAttributes, - terms: mappedTerms - }; - } - - mapTaxonomies(taxonomies: Contracts.ITaxonomyGroupContract[]): ITaxonomyGroup[] { - if (!taxonomies) { - throw Error(`Cannot map taxonomy due to missing 'taxonomies' property`); - } - - if (!Array.isArray(taxonomies)) { - throw Error(`Cannot map taxonomies because the 'taxonomies' property is not an array `); - } - - const mappedTaxonomies: ITaxonomyGroup[] = []; - - taxonomies.forEach((taxonomy) => { - mappedTaxonomies.push(this.mapTaxonomy(taxonomy.system, taxonomy.terms)); - }); - - return mappedTaxonomies; - } - - /** - * Recursively map array of taxonomy terms - * @param termsArray Terms array to map - */ - private mapTaxonomyTerms(termsArray: Contracts.ITaxonomyTermsContract[]): ITaxonomyTerms[] { - if (termsArray.length === 0) { - return []; - } - - const mappedTermsArray: ITaxonomyTerms[] = []; - - termsArray.forEach((terms) => { - const mappedTerms: ITaxonomyTerms = { - codename: terms.codename, - name: terms.name, - terms: this.mapTaxonomyTerms(terms.terms) - }; - - mappedTermsArray.push(mappedTerms); - }); - - return mappedTermsArray; - } -} diff --git a/lib/mappers/type.mapper.ts b/lib/mappers/type.mapper.ts deleted file mode 100644 index 75bdc12a..00000000 --- a/lib/mappers/type.mapper.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Contracts } from '../contracts'; -import { IContentType, IContentTypeSystemAttributes, IGenericElement } from '../models'; - -export class TypeMapper { - mapSingleType(response: Contracts.IViewContentTypeContract): IContentType { - return this.mapType(response); - } - - mapMultipleTypes(response: Contracts.IListContentTypeContract): IContentType[] { - return response.types.map((type) => { - return this.mapType(type); - }); - } - - private mapType(type: Contracts.IContentTypeContract): IContentType { - if (!type) { - throw Error(`Cannot map type`); - } - - if (!type.elements) { - throw Error(`Cannot map type elements`); - } - - const system: IContentTypeSystemAttributes = { - codename: type.system.codename as TContentTypeCodenames, - id: type.system.id, - name: type.system.name, - lastModified: type.system.last_modified - }; - - const elements: IGenericElement[] = []; - - const elementNames = Object.getOwnPropertyNames(type.elements); - elementNames.forEach((elementName: string) => { - const typeElement = type.elements[elementName]; - - if (!typeElement) { - throw Error(`Cannot find element '${elementName}' on type '${type.system.codename}'`); - } - - // use json property as a codename of the type element - const elementCodename = elementName; - - // extra properties for certain element types - const options: Contracts.IElementOptionContract[] = []; - - // some elements can contain options - const rawOptions = typeElement.options; - if (rawOptions) { - if (!Array.isArray(rawOptions)) { - throw Error(`Content type 'options' property has to be an array`); - } - - rawOptions.forEach((rawOption) => { - options.push({ - codename: rawOption.codename, - name: rawOption.name - }); - }); - } - - elements.push({ - codename: elementCodename, - taxonomyGroup: typeElement.taxonomy_group, - options: options, - name: typeElement.name, - type: typeElement.type - }); - }); - - return { - elements: elements, - system: system - }; - } -} diff --git a/lib/mappers/used-in.mapper.ts b/lib/mappers/used-in.mapper.ts deleted file mode 100644 index d06633c2..00000000 --- a/lib/mappers/used-in.mapper.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Contracts } from '../contracts'; -import { ClientTypes, IUsedInItemRecord } from '../models'; - -export class UsedInMapper { - mapUsedInItem(response: Contracts.IUsedInItemContract): IUsedInItemRecord { - return { - system: { - id: response.system.id, - name: response.system.name, - codename: response.system.codename, - language: response.system.language, - type: response.system.type, - collection: response.system.collection, - workflow: response.system.workflow, - workflowStep: response.system.workflow_step, - lastModified: response.system.last_modified - } - }; - } -} diff --git a/lib/models/common/base-responses.ts b/lib/models/common/base-responses.ts deleted file mode 100644 index e9f598f0..00000000 --- a/lib/models/common/base-responses.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IResponse } from '@kontent-ai/core-sdk'; - -export interface IDeliveryNetworkResponse { - data: TData; - response: IResponse; - xContinuationToken?: string; - hasStaleContent: boolean; -} - -export interface IGroupedNetworkResponse { - data: TData; - responses: IDeliveryNetworkResponse[]; -} diff --git a/lib/models/common/common-models.ts b/lib/models/common/common-models.ts deleted file mode 100644 index 9df9958e..00000000 --- a/lib/models/common/common-models.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { IHeader, IHttpCancelRequestToken, IQueryParameter } from '@kontent-ai/core-sdk'; -import { IDeliveryNetworkResponse } from './base-responses'; -import { IPagination } from './pagination.class'; - -export type LinkedItemsReferenceHandler = 'map' | 'ignore'; - -export interface IProxyUrlData { - action: string; - domain: string; - queryParameters: IQueryParameter[]; - queryString: string; - queryConfig: IQueryConfig; - environmentId: string; -} - -export interface ISDKInfo { - /** - * Name of SDK - */ - name: string; - /** - * Version SDK - */ - version: string; - /** - * Host of SDK - */ - host: string; -} - -export interface IKontentResponse {} - -export interface IKontentListWithHeaderResponse extends IKontentResponse { - items: any[]; -} - -export interface IKontentListResponse extends IKontentResponse { - pagination?: IPagination; - items: any[]; -} - -export interface IKontentListAllResponse extends IKontentResponse { - responses: any[]; - items: any[]; -} - -export interface IListAllQueryConfig { - /** - * Number of pages to get. If not set, all available pages are fetched. - */ - pages?: number; - - /** - * Delay between each HTTP requests - */ - delayBetweenRequests?: number; - - /** - * Executed when a list response is loaded - */ - responseFetched?: ( - response: IDeliveryNetworkResponse, - nextPageUrl?: string, - continuationToken?: string - ) => void; -} - -export interface IQueryConfig { - /** - * Indicates if query should use preview mode. Overrides default configuration - */ - usePreviewMode?: boolean; - - /** - * Indicates if query should use secured delivery API mode. Overrides default configuration - */ - useSecuredMode?: boolean; - - /** - * If the requested content has changed since the last request, the header determines whether - * to wait while fetching content. This can be useful when retrieving changed content - * in reaction to a webhook call. By default, when the header is not set, the API - * serves old content (if cached by the CDN) while it's fetching the new content - * to minimize wait time. - */ - waitForLoadingNewContent?: boolean; - - /** - * Extra headers added to request - */ - customHeaders?: IHeader[]; - - /** - * Cancel token - */ - cancelToken?: IHttpCancelRequestToken; -} - -export interface IDeliveryErrorRaw { - message: string; - request_id: string | null; - error_code: number; - specific_code: number; -} - -export class DeliveryError { - public message: string; - public requestId: string | null; - public errorCode: number; - public specificCode: number; - - constructor(data: { message: string; requestId: string | null; errorCode: number; specificCode: number }) { - this.message = data.message; - this.requestId = data.requestId; - this.errorCode = data.errorCode; - this.specificCode = data.specificCode; - } -} diff --git a/lib/models/common/filters.ts b/lib/models/common/filters.ts deleted file mode 100644 index 2877eec9..00000000 --- a/lib/models/common/filters.ts +++ /dev/null @@ -1,280 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -export namespace Filters { - const valueSeparator: string = ','; - const defaultValue: string = ''; - - const getParamValueForSystemFilter = (param: string | string[]): string | undefined => { - if (!param) { - return defaultValue; - } - - if (Array.isArray(param)) { - let value = ''; - // use [in] filter - for (let i = 0; i < param.length; i++) { - value = value + param[i].toString(); - - if (i !== param.length - 1) { - // append separator if its not last item - value = value + valueSeparator; - } - } - - return value; - } - - // single param was given - return param.toString(); - }; - - export class TypeFilter implements IQueryParameter { - constructor(public type: string | string[]) {} - - getParam(): string { - if (Array.isArray(this.type)) { - // multiple types - return `system.type[in]=${getParamValueForSystemFilter(this.type)}`; - } - - // single type - return `system.type=${getParamValueForSystemFilter(this.type)}`; - } - } - - export class CollectionFilter implements IQueryParameter { - constructor(public collection: string | string[]) {} - - getParam(): string { - if (Array.isArray(this.collection)) { - // multiple collections - return `system.collection[in]=${getParamValueForSystemFilter(this.collection)}`; - } - - // single collection - return `system.collection=${getParamValueForSystemFilter(this.collection)}`; - } - } - - export class EmptyFilter implements IQueryParameter { - constructor(public element: string) {} - - getParam(): string { - return `${this.element.trim()}[empty]`; - } - } - - export class NotEmptyFilter implements IQueryParameter { - constructor(public element: string) {} - - getParam(): string { - return `${this.element.trim()}[nempty]`; - } - } - - export class EqualsFilter implements IQueryParameter { - constructor(public element: string, public value: string) {} - - getParam(): string { - return `${this.element.trim()}[eq]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.value) { - return defaultValue; - } - - return this.value; - } - } - - export class NotEqualsFilter implements IQueryParameter { - constructor(public element: string, public value: string) {} - - getParam(): string { - return `${this.element.trim()}[neq]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.value) { - return defaultValue; - } - - return this.value; - } - } - - export class AllFilter implements IQueryParameter { - constructor(public element: string, public values: string[]) {} - - getParam(): string { - return `${this.element.trim()}[all]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.values || !Array.isArray(this.values)) { - return defaultValue; - } - - return this.values.map((m) => m.trim()).join(','); - } - } - - export class AnyFilter implements IQueryParameter { - constructor(public element: string, public values: string[]) {} - - getParam(): string { - return `${this.element.trim()}[any]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.values || !Array.isArray(this.values)) { - return defaultValue; - } - - return this.values.map((m) => m.trim()).join(','); - } - } - - export class ContainsFilter implements IQueryParameter { - constructor(public element: string, public values: string[]) {} - - getParam(): string { - return `${this.element.trim()}[contains]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.values || !Array.isArray(this.values)) { - return defaultValue; - } - - return this.values.map((m) => m.trim()).join(','); - } - } - - export class GreaterThanFilter implements IQueryParameter { - constructor(public element: string, public value: string | number) {} - - getParam(): string { - return `${this.element.trim()}[gt]=${this.getParamValue()}`; - } - - private getParamValue(): string | number | undefined { - if (!this.value) { - return defaultValue; - } - - return this.value; - } - } - - export class GreaterThanOrEqualFilter implements IQueryParameter { - constructor(public element: string, public value: string | number) {} - - getParam(): string { - return `${this.element.trim()}[gte]=${this.getParamValue()}`; - } - - getParamValue(): string | number | undefined { - if (!this.value) { - return defaultValue; - } - - return this.value; - } - } - - export class InFilter implements IQueryParameter { - constructor(public element: string, public values: string[]) {} - - getParam(): string { - return `${this.element.trim()}[in]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.values || !Array.isArray(this.values)) { - return defaultValue; - } - - return this.values - .map((m) => { - return m.trim(); - }) - .join(','); - } - } - - export class NotInFilter implements IQueryParameter { - constructor(public element: string, public values: string[]) {} - - getParam(): string { - return `${this.element.trim()}[nin]=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.values || !Array.isArray(this.values)) { - return defaultValue; - } - - return this.values - .map((m) => { - return m.trim(); - }) - .join(','); - } - } - - export class LessThanFilter implements IQueryParameter { - constructor(public element: string, public value: string | number) {} - - getParam(): string { - return `${this.element.trim()}[lt]=${this.getParamValue()}`; - } - - private getParamValue(): string | number | undefined { - if (!this.value) { - return defaultValue; - } - return this.value; - } - } - - export class LessThanOrEqualFilter implements IQueryParameter { - constructor(public element: string, public value: string | number) {} - - getParam(): string { - return `${this.element.trim()}[lte]=${this.getParamValue()}`; - } - - private getParamValue(): string | number | undefined { - if (!this.value) { - return defaultValue; - } - - return this.value; - } - } - - export class RangeFilter implements IQueryParameter { - constructor(public element: string, public lowerValue: number | string, public higherValue: number | string) {} - - getParam(): string { - return `${this.element.trim()}[range]=${this.getParamValue()}`; - } - - private getParamValue(): string | number | undefined { - let lowerVal = defaultValue; - let higherVal = defaultValue; - - if (this.lowerValue) { - lowerVal = this.lowerValue.toString(); - } - - if (this.higherValue) { - higherVal = this.higherValue.toString(); - } - - return `${lowerVal},${higherVal}`; - } - } -} diff --git a/lib/models/common/headers.ts b/lib/models/common/headers.ts deleted file mode 100644 index 01041a7a..00000000 --- a/lib/models/common/headers.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const continuationTokenHeaderName: string = 'X-Continuation'; -export const waitForLoadingNewContentHeader: string = 'X-KC-Wait-For-Loading-New-Content'; -export const sdkVersionHeader: string = 'X-KC-SDKID'; -export const staleContentHeaderName: string = 'X-Stale-Content'; - diff --git a/lib/models/common/index.ts b/lib/models/common/index.ts deleted file mode 100644 index 332cc006..00000000 --- a/lib/models/common/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './filters'; -export * from './pagination.class'; -export * from './parameters'; -export * from './sort-order'; -export * from './common-models'; -export * from './base-responses'; -export * from './headers'; diff --git a/lib/models/common/pagination.class.ts b/lib/models/common/pagination.class.ts deleted file mode 100644 index 421d842a..00000000 --- a/lib/models/common/pagination.class.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface IPagination { - skip: number; - limit: number; - count: number; - nextPage: string; - totalCount: number | null; -} diff --git a/lib/models/common/parameters.ts b/lib/models/common/parameters.ts deleted file mode 100644 index cbaa7a9f..00000000 --- a/lib/models/common/parameters.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { SortOrder } from './sort-order'; - -export namespace Parameters { - const defaultValue: string = ''; - - export class QueryParameter implements IQueryParameter { - /** - * Parameter - * @constructor - * @param {string} name - Name of the parameter - * @param {string} value - Value of the parameter - */ - constructor(public name: string, public value: string) { - if (!name) { - throw Error(`Name of the parameter is not specified`); - } - } - - getParam(): string { - return `${this.name}=${this.value}`; - } - } - - export class ElementsParameter implements IQueryParameter { - /** - * Sets elements (projection) so that only certain elements from a content item are returned - * @constructor - * @param {string[]} elementCodenames - Array of element codenames to include in response. - */ - constructor(public elementCodenames: string[]) {} - - getParam(): string { - return `elements=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.elementCodenames) { - return defaultValue; - } - - return this.elementCodenames - .map((m) => { - if (!m) { - throw Error(`Codename of 'ElementsParameter' cannot be null or empty`); - } - return m.trim(); - }) - .join(','); - } - } - - export class ExcludeElementsParameter implements IQueryParameter { - /** - * Sets elements (projection) so that only certain elements are excluded from API response - * @constructor - * @param {string[]} elementCodenames - Array of element codenames to exclude from API response. - */ - constructor(public elementCodenames: string[]) {} - - getParam(): string { - return `excludeElements=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - if (!this.elementCodenames) { - return defaultValue; - } - - return this.elementCodenames - .map((m) => { - if (!m) { - throw Error(`Codename of 'ExcludeElementsParameter' cannot be null or empty`); - } - return m.trim(); - }) - .join(','); - } - } - - export class LimitParameter implements IQueryParameter { - /** - * Limits the number of items that are returned from response - * @constructor - * @param {number} limit - Number of elements that will be returned - */ - constructor(public limit: number) { - if (limit <= 0) { - throw Error(`'LimitParameter' must specify a positive integer`); - } - } - - getParam(): string { - return `limit=${this.limit}`; - } - } - - export class IncludeTotalCountParameter implements IQueryParameter { - /** - * Adds 'includeTotalCount' query parameter to query - * @constructor - */ - constructor() {} - - getParam(): string { - return `includeTotalCount=true`; - } - } - - export class SkipParameter implements IQueryParameter { - /** - * Configures response to skip certain number of items - * @constructor - * @param {number} skip - Number of content items that will be skipped - */ - constructor(public skip: number) { - if (skip < 0) { - throw Error(`'SkipParameter' must specify a positive integer number or zero."`); - } - } - - getParam(): string { - return `skip=${this.skip}`; - } - } - - export class OrderParameter implements IQueryParameter { - /** - * Sorts the response based on given element. - * @constructor - * @param {string} element - Element that will be used for sorting (can be both elements. or system.) - * @param {SortOrder} sortOrder - Order type (desc/asc). Defaults to 'asc' if SortOrder is null or invalid. - */ - constructor(public element: string, public sortOrder: SortOrder) { - if (!element) { - throw Error(`Element specified in 'OrderParameter' is null or empty`); - } - } - - getParam(): string { - return `order=${this.getParamValue()}`; - } - - private getParamValue(): string | undefined { - return `${this.element.trim()}[${this.sortOrder}]`; - } - } - - export class CustomParameter implements IQueryParameter { - constructor(public param: string) {} - - getParam(): string { - return this.param; - } - } - - export class DepthParameter implements IQueryParameter { - /** - * Configures the depth of the response. Content items might reference another 'linked items' using the Linked items element. - * Recursively, these linked items can reference another linked items. - * By default, only one level of linked content is returned. - * @constructor - * @param {number} depth - Depth fo the response - */ - constructor(public depth: number) { - if (depth < 0) { - throw Error(`'DepthParameter' must specify a positive integer or zero`); - } - } - - getParam(): string { - return `depth=${this.depth}`; - } - } - - export class LanguageParameter implements IQueryParameter { - /** - * Specifies language version to fetch - * @constructor - * @param {string} languageCodename - Codename of the language - */ - constructor(public languageCodename: string) {} - - getParam(): string { - return `language=${this.languageCodename}`; - } - } -} diff --git a/lib/models/common/sort-order.ts b/lib/models/common/sort-order.ts deleted file mode 100644 index 31f824b6..00000000 --- a/lib/models/common/sort-order.ts +++ /dev/null @@ -1 +0,0 @@ -export type SortOrder = 'asc' | 'desc'; diff --git a/lib/models/content-type-models.ts b/lib/models/content-type-models.ts deleted file mode 100644 index 6a88fff7..00000000 --- a/lib/models/content-type-models.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { IQueryConfig } from './common/common-models'; -import { IGenericElement } from './element-models'; - -export interface IContentTypeSystemAttributes { - /** - * Id of the type - */ - id: string; - - /** - * Name of the type - */ - name: string; - - /** - * Codename of the type - */ - codename: TContentTypeCodename; - - /** - * Date of last modification - */ - lastModified: Date; -} - -export interface IContentType { - /** - * Content type system attributes - */ - system: IContentTypeSystemAttributes; - - /** - * Elements (elements) assigned to content type - */ - elements: IGenericElement[]; -} - -export interface IContentTypeQueryConfig extends IQueryConfig { - /** - * No dedicated properties required at this moment - */ -} diff --git a/lib/models/core.models.ts b/lib/models/core.models.ts new file mode 100644 index 00000000..06e058b9 --- /dev/null +++ b/lib/models/core.models.ts @@ -0,0 +1,139 @@ +import type { FetchQuery, JsonValue, PagedFetchQuery, PickStringLiteral, SdkConfig } from "@kontent-ai/core-sdk"; +import type { FetchContentItemQuery, FetchContentItemQueryRequest } from "../queries/content-items/fetch-content-item-query.js"; +import type { ItemsFeedQuery, ItemsFeedQueryRequest } from "../queries/content-items/items-feed-query.js"; +import type { + ItemsReferencingAssetQuery, + ItemsReferencingAssetQueryRequest, +} from "../queries/content-items/items-referencing-asset-query.js"; +import type { ItemsReferencingItemQuery, ItemsReferencingItemQueryRequest } from "../queries/content-items/items-referencing-item-query.js"; +import type { ListContentItemsQuery, ListContentItemsQueryRequest } from "../queries/content-items/list-content-items-query.js"; +import type { + FetchContentTypeElementQuery, + FetchContentTypeElementQueryRequest, +} from "../queries/content-types/fetch-content-type-element-query.js"; +import type { FetchContentTypeQuery, FetchContentTypeQueryRequest } from "../queries/content-types/fetch-content-type-query.js"; +import type { ListContentTypesQuery, ListContentTypesQueryRequest } from "../queries/content-types/list-content-types-query.js"; +import type { ContentTypeCodenameOf } from "../queries/content-types/models/content-type.models.js"; +import type { ListLanguagesQuery, ListLanguagesQueryRequest } from "../queries/languages/list-languages-query.js"; +import type { FetchTaxonomyQuery, FetchTaxonomyQueryRequest } from "../queries/taxonomies/fetch-taxonomy-query.js"; +import type { ListTaxonomiesQuery, ListTaxonomiesQueryRequest } from "../queries/taxonomies/list-taxonomies-query.js"; +import type { TaxonomyCodenameOf } from "../queries/taxonomies/models/taxonomy.models.js"; +import type { DeliverySdkError } from "./error.models.js"; + +export type DeliveryClientSchema< + TSchema extends DeliveryClientSchema = { + readonly languageCodenames: readonly string[]; + readonly taxonomies: { readonly [taxonomyCodename: string]: readonly string[] }; + readonly contentTypes: { readonly [contentTypeCodename: string]: readonly string[] }; + readonly collectionCodenames: readonly string[]; + readonly workflowCodenames: readonly string[]; + readonly workflowStepCodenames: readonly string[]; + }, +> = TSchema; + +/** + * Placeholder type if extension is needed in future + */ +export type DeliveryMetadata = Record; + +export type DeliveryMetadataWithToken = { + readonly continuationToken: string | undefined; +}; + +export type TokenPagingDeliveryExtraResponseProps = { + readonly nextContinuationToken: string | undefined; +}; + +export type UrlPagingDeliveryExtraResponseProps = { + readonly nextPageUrl: string | undefined; +}; + +export type ApiMode = "public" | "preview" | "secure"; + +export type DeliveryClientConfig = SdkConfig< + DeliveryApiConfig & { + /** + * The environment ID of your Kontent.ai project. Can be found in the Kontent.ai app. + */ + readonly environmentId: string; + } +>; + +export type DeliveryApiConfig = PublicDeliveryClientConfig | PreviewDeliveryClientConfig | SecureDeliveryClientConfig; + +export type DeliveryClient = { + readonly config: DeliveryClientConfig; + + listLanguages(request?: ListLanguagesQueryRequest): ListLanguagesQuery; + listTaxonomies(request?: ListTaxonomiesQueryRequest): ListTaxonomiesQuery; + listContentTypes(request?: ListContentTypesQueryRequest): ListContentTypesQuery; + fetchTaxonomy>( + request: FetchTaxonomyQueryRequest, + ): FetchTaxonomyQuery; + fetchContentType>( + request: FetchContentTypeQueryRequest, + ): FetchContentTypeQuery; + fetchContentTypeElement>( + request: FetchContentTypeElementQueryRequest, + ): FetchContentTypeElementQuery; + fetchContentItem(request: FetchContentItemQueryRequest): FetchContentItemQuery; + listContentItems(request?: ListContentItemsQueryRequest): ListContentItemsQuery; + itemsFeed(request?: ItemsFeedQueryRequest): ItemsFeedQuery; + itemsReferencingAsset(request: ItemsReferencingAssetQueryRequest): ItemsReferencingAssetQuery; + itemsReferencingItem(request: ItemsReferencingItemQueryRequest): ItemsReferencingItemQuery; +}; + +export type DeliveryFetchQuery = FetchQuery< + TPayload, + DeliverySdkError, + TMeta +>; + +export type DeliveryPagedFetchQuery< + TPayload extends JsonValue, + TMeta extends DeliveryMetadata | DeliveryMetadataWithToken, +> = PagedFetchQuery; + +export type DeliveryEndpoint = + | "languages" + | "items" + | `items/${string}` + | "items-feed" + | `assets/${string}/used-in` + | `items/${string}/used-in` + | "taxonomies" + | `taxonomies/${string}` + | "types" + | `types/${string}` + | `types/${string}/elements/${string}`; + +export type WaitForLoadingNewContentHeaderName = "X-KC-Wait-For-Loading-New-Content"; + +type PublicDeliveryClientConfig = { + /** + * The API mode of the delivery client. Public access is the default mode. + */ + readonly apiMode: PickStringLiteral; +}; + +type PreviewDeliveryClientConfig = { + /** + * The API mode of the delivery client. + */ + readonly apiMode: PickStringLiteral; + /** + * The delivery API key of your Kontent.ai project with preview access enabled. + */ + readonly deliveryApiKey: string; +}; + +type SecureDeliveryClientConfig = { + /** + * The API mode of the delivery client. + */ + readonly apiMode: PickStringLiteral; + /** + * The delivery API key of your Kontent.ai project with secure access enabled. + */ + readonly deliveryApiKey: string; +}; diff --git a/lib/models/element-models.ts b/lib/models/element-models.ts deleted file mode 100644 index 70107807..00000000 --- a/lib/models/element-models.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { IQueryConfig } from './common/common-models'; - -export interface IElementQueryConfig extends IQueryConfig { - /** - * No dedicated properties required at this moment - */ -} - -export interface IGenericElementOption { - /** - * Name of the option - */ - name: string; - - /** - * Value of the option - */ - codename: string; -} - -export interface IGenericElement { - /** - * Indexer - */ - [key: string]: any; - - /** - * Codename of the element - */ - codename?: string; - - /** - * Type of the element - */ - type: string; - - /** - * Name of the element - */ - name: string; - - /** - * Taxonomy group in case the element is a taxonomy - */ - taxonomyGroup?: string; - - /** - * Array of options if the element has some - */ - options: IGenericElementOption[]; -} diff --git a/lib/models/error.models.ts b/lib/models/error.models.ts new file mode 100644 index 00000000..fed39929 --- /dev/null +++ b/lib/models/error.models.ts @@ -0,0 +1,15 @@ +import { KontentSdkError } from "@kontent-ai/core-sdk"; + +export class DeliverySdkError extends KontentSdkError { + constructor(error: KontentSdkError) { + super({ + baseErrorData: { + message: error.message, + url: error.url, + retryStrategyOptions: error.retryStrategyOptions, + retryAttempt: error.retryAttempt, + }, + details: error.details, + }); + } +} diff --git a/lib/models/filter.models.ts b/lib/models/filter.models.ts new file mode 100644 index 00000000..94f02ad4 --- /dev/null +++ b/lib/models/filter.models.ts @@ -0,0 +1,35 @@ +export const emptyRichTextOperators = ["isEmptyRichText", "isNotEmptyRichText"] as const; +export const emptyRichTextToFilterOperator: Readonly> = { + isEmptyRichText: "eq", + isNotEmptyRichText: "neq", +}; + +export type ObjectFilter = { + readonly property: FilterProperty; + readonly value: string | number | boolean | undefined | string[]; + readonly operator: SpecialFilterOperator | FilterOperator; +}; + +export type EmptyRichTextFilter = { + readonly property: `elements.${TElementProperties}`; + readonly operator: EmptyRichTextOperator; + readonly value?: never; +}; + +export type Filter = + | ObjectFilter + | EmptyRichTextFilter + | SystemOrElementsFilterQuery; + +type SpecialFilterOperator = "=" | "!="; +type EmptyRichTextOperator = (typeof emptyRichTextOperators)[number]; + +type FilterOperator = "eq" | "neq" | "empty" | "nempty" | "lt" | "lte" | "gt" | "gte" | "range" | "in" | "nin" | "contains" | "any" | "all"; + +type SystemOrElementsFilterQuery = + | `system.${TSystemProperties}[${FilterOperator}]=${string}` + | `elements.${TElementProperties}[${FilterOperator}]=${string}`; + +type FilterProperty = + | `system.${TSystemProperties}` + | `elements.${TElementProperties}`; diff --git a/lib/models/index.ts b/lib/models/index.ts deleted file mode 100644 index bb64e783..00000000 --- a/lib/models/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './common'; -export * from './element-models'; -export * from './item-models'; -export * from './taxonomy-models'; -export * from './content-type-models'; -export * from './language-models'; -export * from './responses'; -export * from './sync-models'; - diff --git a/lib/models/item-models.ts b/lib/models/item-models.ts deleted file mode 100644 index c00d76c2..00000000 --- a/lib/models/item-models.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { Contracts } from '../contracts'; -import { ElementModels } from '../elements/element-models'; -import { IQueryConfig } from './common/common-models'; - -export interface IMapElementsResult< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem -> { - item: TContentItem; - processedItems: IContentItemsContainer; - preparedItems: IContentItemWithRawDataContainer; - processingStartedForCodenames: string[]; -} - -export interface IContentItemSystemAttributes< - TTypeCodename extends string = string, - TLanguageCodenames extends string = string, - TCollectionCodenames extends string = string, - TWorkflowCodenames extends string = string, - TWorkflowStepCodenames extends string = string -> { - /** - * Id of the item - */ - id: string; - - /** - * Name of the item - */ - name: string; - - /** - * Codename of the item - */ - codename: string; - - /** - * Codename of the type this item is using - */ - type: TTypeCodename; - - /** - * Date when the item was last modified - */ - lastModified: string; - - /** - * Codename of the language - */ - language: TLanguageCodenames; - - /** - * Array of sitemap locations (obsolete) - */ - sitemapLocations: string[]; - - /** - * Codename of the collection this item belongs to - */ - collection: TCollectionCodenames; - - /** - * Workflow step of the item - */ - workflowStep: TWorkflowStepCodenames | null; - - /** - * Workflow of the item - */ - workflow: TWorkflowCodenames | null; -} - -/** - * Indexer for elements within content item - */ -export type ContentItemElementsIndexer = ElementModels.IElement> = - TElement; - -export type ContentItemType = 'component' | 'linkedItem'; - -/** - * Prefix with I to keep the name consistent and prevent releasing major version - */ -export type IContentItemElements = Record< - TElementCodenames, - ContentItemElementsIndexer ->; - -export type Snippet< - TElementCodenames extends string, - TElements extends IContentItemElements -> = TElements; - -export interface IContentItem< - TElements extends IContentItemElements = IContentItemElements, - TTypeCodename extends string = string, - TLanguageCodenames extends string = string, - TCollectionCodenames extends string = string, - TWorkflowCodenames extends string = string, - TWorkflowStepCodenames extends string = string, - TTypeElementCodenames extends string = string -> { - /** - * Elements of the content item - */ - elements: TElements; - - /** - * System data of the content item - */ - system: IContentItemSystemAttributes< - TTypeCodename, - TLanguageCodenames, - TCollectionCodenames, - TWorkflowCodenames, - TWorkflowStepCodenames - >; -} - -export interface ILink { - /** - * Id of the link - */ - linkId: string; - - /** - * Codename of the content item - */ - codename: string; - - /** - * Type codename of the content item - */ - type: string; - - /** - * Url slug defined for the content item - */ - urlSlug: string; -} - -export interface IContentItemWithRawElements { - item: IContentItem; - rawItem: Contracts.IContentItemContract; -} - -export interface IContentItemWithRawDataContainer { - [key: string]: IContentItemWithRawElements; -} - -export interface IContentItemsContainer { - [key: string]: TContentItem | undefined; -} - -export interface IRichTextImage { - imageId: string; - url: string; - description: string | null; - width: number | null; - height: number | null; -} - -export interface IItemQueryConfig extends IQueryConfig {} - -export interface IItemFeedQueryConfig extends IQueryConfig { - disableItemLinking?: boolean; -} - -export interface IUsedInItemRecord { - readonly system: { - readonly id: string; - readonly name: string; - readonly codename: string; - readonly language: TClientTypes['languageCodenames']; - readonly type: TClientTypes['contentTypeCodenames']; - readonly collection: TClientTypes['collectionCodenames']; - readonly workflow: TClientTypes['workflowCodenames']; - readonly workflowStep: TClientTypes['workflowStepCodenames']; - readonly lastModified: string; - }; -} - -export type ClientTypes = { - readonly contentItemType: IContentItem; - readonly contentTypeCodenames: string; - readonly workflowCodenames: string; - readonly workflowStepCodenames: string; - readonly collectionCodenames: string; - readonly taxonomyCodenames: string; - readonly languageCodenames: string; - readonly elementCodenames: string; -}; diff --git a/lib/models/language-models.ts b/lib/models/language-models.ts deleted file mode 100644 index 7736c90c..00000000 --- a/lib/models/language-models.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { IQueryConfig } from './common'; - -export interface ILanguageSystem { - id: string; - name: string; - codename: TLanguageCodenames; -} - -export interface ILanguage { - system: ILanguageSystem; -} - -export interface ILanguagesQueryConfig extends IQueryConfig { - /** - * No dedicated properties required at this moment - */ -} diff --git a/lib/models/pagination.models.ts b/lib/models/pagination.models.ts new file mode 100644 index 00000000..e589b12f --- /dev/null +++ b/lib/models/pagination.models.ts @@ -0,0 +1,5 @@ +import type * as z from "zod/mini"; +import type { paginationSchema, paginationWithTotalCountSchema } from "./pagination.schemas.js"; + +export type PaginationPayload = Readonly>; +export type PaginationWithTotalCountPayload = Readonly>; diff --git a/lib/models/pagination.schemas.ts b/lib/models/pagination.schemas.ts new file mode 100644 index 00000000..84567142 --- /dev/null +++ b/lib/models/pagination.schemas.ts @@ -0,0 +1,23 @@ +import * as z from "zod/mini"; + +const nextPageSchema = z.union([z.url(), z.literal("")]); + +const paginationObjectSchema = z.object({ + skip: z.number(), + limit: z.number(), + count: z.number(), + next_page: nextPageSchema, +}); + +export const paginationSchema = z.object({ + pagination: z.readonly(paginationObjectSchema), +}); + +export const paginationWithTotalCountSchema = z.object({ + pagination: z.readonly( + z.object({ + ...paginationObjectSchema.shape, + total_count: z.optional(z.number()), + }), + ), +}); diff --git a/lib/models/request.models.ts b/lib/models/request.models.ts new file mode 100644 index 00000000..f8e5bee3 --- /dev/null +++ b/lib/models/request.models.ts @@ -0,0 +1,84 @@ +import type { Header } from "@kontent-ai/core-sdk"; +import type { Filter } from "./filter.models.js"; + +export type DeliveryRequest[]> = { + readonly config?: DeliveryRequestConfig; + readonly headers?: { + readonly "X-KC-Wait-For-Loading-New-Content"?: boolean; + }; +} & ([TQuery] extends [never] ? object : { readonly query?: TQuery }) & + ([TFilters] extends [never] ? object : { readonly filters?: TFilters }); + +export type DeliveryRequestWithUrlPaging< + TSortableProperties extends string, + TQuery extends QueryParameterRecord, + TFilters extends readonly Filter[], +> = DeliveryRequest & { + readonly query?: { + readonly skip?: number; + readonly limit?: number; + readonly order?: TSortableProperties; + }; +}; + +export type DeliveryRequestWithTokenPaging< + TQuery extends QueryParameterRecord, + TFilters extends readonly Filter[], +> = DeliveryRequest & { + readonly headers?: { + readonly "X-Continuation"?: string; + }; +}; + +export type DeliveryRequestWithCodename< + TCodenames extends readonly string[], + TQuery extends QueryParameterRecord, + TFilters extends readonly Filter[], +> = DeliveryRequest & { + readonly codename: TCodenames[number]; +}; + +export type QueryParameterRecord = Record; + +export type WithRaw = { + readonly raw: () => TRawQuery; +}; + +export type DeliveryRequestConfig = { + /** + * Additional headers to be added to the request. + */ + readonly customHeaders?: readonly Header[]; + readonly abortSignal?: AbortSignal; +}; + +export type OrderDirection = "asc" | "desc"; + +/** + * Matches the format of the order parameter in the Delivery API. + * + * @example + * ```ts + * `order=system.name[asc]` + * `order=system.name[desc]` + */ +export type SystemOrderQueryParam = `system.${TSortableProperties}[${OrderDirection}]`; + +/** + * Matches the format of the order parameter in the Delivery API. + * + * @example + * ```ts + * `order=elements.description[asc]` + * `order=elements.description[desc]` + */ +export type ElementOrderQueryParam = `elements.${TElementCodenames}[${OrderDirection}]`; + +/** + * Array of element codenames that will get transformed into a comma-separated list used in the elements parameter. + * + * @example + * ```ts + * `elements=title,summary,related_articles` + */ +export type ElementSelectionQueryParam = readonly TElementCodenames[]; diff --git a/lib/models/response.models.ts b/lib/models/response.models.ts new file mode 100644 index 00000000..f1d2c229 --- /dev/null +++ b/lib/models/response.models.ts @@ -0,0 +1,12 @@ +import type { JsonValue, QueryResponse } from "@kontent-ai/core-sdk"; +import type { DeliveryMetadata, DeliveryMetadataWithToken } from "./core.models.js"; + +/** + * A resolved delivery query response — what `await query.fetch()` / `.fetchPage()` returns. + * Response-side counterpart to {@link DeliveryFetchQuery}; wraps core-sdk's `QueryResponse` so query + * modules and consumers don't depend on `@kontent-ai/core-sdk` directly. + */ +export type DeliveryResponse = QueryResponse< + TPayload, + TMeta +>; diff --git a/lib/models/responses.ts b/lib/models/responses.ts deleted file mode 100644 index d320821a..00000000 --- a/lib/models/responses.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Contracts } from '../contracts'; -import { IDeliveryNetworkResponse } from './common/base-responses'; -import { IKontentListAllResponse, IKontentListResponse, IKontentResponse } from './common/common-models'; -import { IPagination } from './common/pagination.class'; -import { IContentType } from './content-type-models'; -import { IGenericElementOption } from './element-models'; -import { IContentItem, IContentItemsContainer, IUsedInItemRecord } from './item-models'; -import { ILanguage } from './language-models'; -import { IContentItemDelta } from './sync-models'; -import { ITaxonomyGroup } from './taxonomy-models'; -import { ClientTypes } from './item-models'; - -export namespace Responses { - export interface IListContentTypesResponse extends IKontentListResponse { - items: IContentType[]; - pagination: IPagination; - } - - export interface IListContentTypesAllResponse extends IKontentListAllResponse { - items: IContentType[]; - responses: IDeliveryNetworkResponse< - IListContentTypesResponse, - Contracts.IListContentTypeContract - >[]; - } - - export interface IViewContentTypeResponse extends IKontentResponse { - type: IContentType; - } - - export interface IViewContentTypeElementResponse extends IKontentResponse { - codename?: string; - type: string; - name: string; - taxonomyGroup?: string; - options: IGenericElementOption[]; - } - - export interface IUsedInResponse extends IKontentListResponse { - items: IUsedInItemRecord[]; - } - - export interface IUsedInAllResponse extends IKontentListAllResponse { - items: IUsedInItemRecord[]; - responses: IDeliveryNetworkResponse, Contracts.IUsedInItemsContract>[]; - } - - export interface IListItemsFeedResponse< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem - > extends IKontentListResponse { - items: TContentItem[]; - linkedItems: IContentItemsContainer; - } - - export interface IListItemsFeedAllResponse< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem - > extends IKontentListAllResponse { - items: TContentItem[]; - responses: IDeliveryNetworkResponse< - IListItemsFeedResponse, - Contracts.IItemsFeedContract - >[]; - } - - export interface IListContentItemsResponse< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem - > extends IKontentListResponse { - items: TContentItem[]; - pagination: IPagination; - linkedItems: IContentItemsContainer; - } - - export interface IListContentItemsAllResponse< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem - > extends IKontentListAllResponse { - items: TContentItem[]; - responses: IDeliveryNetworkResponse< - IListContentItemsResponse, - Contracts.IListContentItemsContract - >[]; - } - - export interface IViewContentItemResponse< - TContentItem extends IContentItem = IContentItem, - TLinkedItemType extends IContentItem = IContentItem - > extends IKontentResponse { - item: TContentItem; - linkedItems: IContentItemsContainer; - } - - export interface IInitializeSyncResponse extends IKontentResponse { - items: IContentItemDelta[]; - } - - export interface ISyncChangesResponse extends IKontentResponse { - items: IContentItemDelta[]; - } - - export interface ISyncChangesAllResponse extends IKontentListAllResponse { - items: IContentItemDelta[]; - responses: IDeliveryNetworkResponse[]; - } - - export interface IListLanguagesResponse extends IKontentListResponse { - items: ILanguage[]; - pagination: IPagination; - } - - export interface IListLanguagesAllResponse extends IKontentListAllResponse { - items: ILanguage[]; - responses: IDeliveryNetworkResponse< - IListLanguagesResponse, - Contracts.IListLanguagesContract - >[]; - } - - export interface IViewTaxonomyResponse extends IKontentResponse { - taxonomy: ITaxonomyGroup; - } - - export interface IListTaxonomiesResponse extends IKontentListResponse { - items: ITaxonomyGroup[]; - pagination: IPagination; - } - - export interface IListTaxonomiesAllResponse extends IKontentListAllResponse { - items: ITaxonomyGroup[]; - responses: IDeliveryNetworkResponse< - IListTaxonomiesResponse, - Contracts.IListTaxonomyGroupsContract - >[]; - } -} diff --git a/lib/models/sync-models.ts b/lib/models/sync-models.ts deleted file mode 100644 index 06d44150..00000000 --- a/lib/models/sync-models.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Contracts } from '../contracts'; -import { IQueryConfig } from './common/common-models'; -import { IContentItemSystemAttributes } from './item-models'; - -export interface ISyncInitQueryConfig extends IQueryConfig { - /** - * No dedicated properties required at this moment - */ -} - -export interface IContentItemDelta { - data: { - system: IContentItemSystemAttributes; - elements: Contracts.IContentItemElementsContracts; - }; - changeType: 'deleted_item' | 'changed_item'; - timestamp: string; -} diff --git a/lib/models/taxonomy-models.ts b/lib/models/taxonomy-models.ts deleted file mode 100644 index ff6c67a4..00000000 --- a/lib/models/taxonomy-models.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { IQueryConfig } from './common/common-models'; - -export interface ITaxonomyGroup { - system: ITaxonomySystemAttributes; - terms: ITaxonomyTerms[]; -} - -export interface ITaxonomySystemAttributes { - id: string; - name: string; - codename: TaxonomyCodename; - lastModified: Date; -} - -export interface ITaxonomyTerms { - name: string; - codename: string; - terms: ITaxonomyTerms[]; -} - -export interface ITaxonomyQueryConfig extends IQueryConfig { - /** - * No dedicated properties required at this moment - */ -} diff --git a/lib/public_api.ts b/lib/public_api.ts new file mode 100644 index 00000000..b6a124ad --- /dev/null +++ b/lib/public_api.ts @@ -0,0 +1,99 @@ +// biome-ignore lint/performance/noBarrelFile: One barrel for the public API is fine +export { createDeliveryClient } from "./client/delivery-client.js"; +export type { + ApiMode, + DeliveryApiConfig, + DeliveryClient, + DeliveryClientConfig, + DeliveryClientSchema, + WaitForLoadingNewContentHeaderName, +} from "./models/core.models.js"; +export type { EmptyRichTextFilter, Filter, ObjectFilter } from "./models/filter.models.js"; +export type { + PaginationPayload, + PaginationWithTotalCountPayload, +} from "./models/pagination.models.js"; +export type { + DeliveryRequestConfig, + ElementOrderQueryParam, + ElementSelectionQueryParam, + OrderDirection, + SystemOrderQueryParam, +} from "./models/request.models.js"; +export type { + FetchContentItemQuery, + FetchContentItemQueryRequest, + FetchContentItemResponse, +} from "./queries/content-items/fetch-content-item-query.js"; +export type { ItemsFeedQuery, ItemsFeedQueryRequest, ItemsFeedResponse } from "./queries/content-items/items-feed-query.js"; +export type { + ItemsReferencingAssetQuery, + ItemsReferencingAssetQueryRequest, + ItemsReferencingAssetResponse, +} from "./queries/content-items/items-referencing-asset-query.js"; +export type { + ItemsReferencingItemQuery, + ItemsReferencingItemQueryRequest, + ItemsReferencingItemResponse, +} from "./queries/content-items/items-referencing-item-query.js"; +export type { + ListContentItemsQuery, + ListContentItemsQueryRequest, + ListContentItemsResponse, +} from "./queries/content-items/list-content-items-query.js"; +export type { + ContentItemOf, + ContentItemPayload, + ContentItemSystem, + ContentItemSystemPayload, + FetchContentItemPayload, + ItemsFeedPayload, + ItemsReferencingAssetPayload, + ItemsReferencingItemPayload, + ListContentItemsPayload, + SnippetOf, +} from "./queries/content-items/models/content-item.models.js"; +export type { ContentItemElementPayload } from "./queries/content-items/models/element.models.js"; +export type * as Elements from "./queries/content-items/models/element-types.js"; +export type { + FetchContentTypeElementQuery, + FetchContentTypeElementQueryRequest, + FetchContentTypeElementResponse, +} from "./queries/content-types/fetch-content-type-element-query.js"; +export type { + FetchContentTypeQuery, + FetchContentTypeQueryRequest, + FetchContentTypeResponse, +} from "./queries/content-types/fetch-content-type-query.js"; +export type { + ListContentTypesQuery, + ListContentTypesQueryRequest, + ListContentTypesResponse, +} from "./queries/content-types/list-content-types-query.js"; +export type { + AllElementCodenamesOf, + ContentTypeCodenameOf, + ContentTypeElementPayload, + ContentTypePayload, + ElementCodenamesOf, + ListContentTypesPayload, +} from "./queries/content-types/models/content-type.models.js"; +export type { + ListLanguagesQuery, + ListLanguagesQueryRequest, + ListLanguagesResponse, +} from "./queries/languages/list-languages-query.js"; +export type { LanguagePayload, ListLanguagesPayload } from "./queries/languages/models/language.models.js"; +export type { FetchTaxonomyQuery, FetchTaxonomyQueryRequest, FetchTaxonomyResponse } from "./queries/taxonomies/fetch-taxonomy-query.js"; +export type { + ListTaxonomiesQuery, + ListTaxonomiesQueryRequest, + ListTaxonomiesResponse, +} from "./queries/taxonomies/list-taxonomies-query.js"; +export type { + ListTaxonomiesPayload, + TaxonomyCodenameOf, + TaxonomyPayload, + TaxonomyTermCodenamesOf, + TaxonomyTermPayload, +} from "./queries/taxonomies/models/taxonomy.models.js"; diff --git a/lib/public_schemas.ts b/lib/public_schemas.ts new file mode 100644 index 00000000..b7ef6e6a --- /dev/null +++ b/lib/public_schemas.ts @@ -0,0 +1,28 @@ +// biome-ignore lint/performance/noBarrelFile: One barrel for the schemas subpath is fine +export { + contentItemSchema, + contentItemSchemaExtended, + contentItemSystemSchema, + contentItemSystemWithCodename, + fetchContentItemSchema, + fetchContentItemSchemaExtended, + itemsFeedSchema, + itemsFeedSchemaExtended, + itemsReferencingAssetSchema, + itemsReferencingItemSchema, + listContentItemsSchema, + listContentItemsSchemaExtended, +} from "./queries/content-items/schemas/content-item.schemas.js"; +export { + assetValueSchema, + contentItemElementSchema, + contentItemElementSchemaExtended, + elementDef, +} from "./queries/content-items/schemas/element.schemas.js"; +export { + contentTypeElementSchema, + contentTypeSchema, + listContentTypesSchema, +} from "./queries/content-types/schemas/content-type.schemas.js"; +export { languageSchema, listLanguagesSchema } from "./queries/languages/schemas/language.schemas.js"; +export { listTaxonomiesSchema, taxonomySchema, taxonomyTermSchema } from "./queries/taxonomies/schemas/taxonomy.schemas.js"; diff --git a/lib/queries/content-items/fetch-content-item-query.ts b/lib/queries/content-items/fetch-content-item-query.ts new file mode 100644 index 00000000..ca8d4041 --- /dev/null +++ b/lib/queries/content-items/fetch-content-item-query.ts @@ -0,0 +1,81 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryFetchQuery, DeliveryMetadata } from "../../models/core.models.js"; +import type { DeliveryRequestWithCodename, ElementSelectionQueryParam, WithRaw } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import type { AllElementCodenamesOf } from "../../queries/content-types/models/content-type.models.js"; +import { joinItems, mapToExtendedItem, mapToExtendedModularContent } from "../../transforms/content-item-transforms.js"; +import { createDeliveryFetchQuery, transformDeliveryFetchQuery } from "../delivery-queries.js"; +import type { FetchContentItemPayload, FetchContentItemPayloadExtended } from "./models/content-item.models.js"; + +export type FetchContentItemResponse = DeliveryResponse< + FetchContentItemPayloadExtended, + DeliveryMetadata +>; + +export type FetchContentItemQuery = DeliveryFetchQuery< + FetchContentItemResponse["payload"], + FetchContentItemResponse["meta"] +> & + WithRaw, FetchContentItemResponse["meta"]>>; + +export type FetchContentItemQueryRequest = DeliveryRequestWithCodename< + readonly string[], + { + /** + * Determines which language variant of content items to return. By default, the API returns content in the default language. + */ + readonly language?: NonNullable[number]; + + /** + * Specifies which elements to include in the response. By default, all elements are returned. + */ + readonly elements?: ElementSelectionQueryParam>; + + /** + * Specifies which elements to exclude from the response. By default, no elements are excluded. + */ + readonly excludeElements?: ElementSelectionQueryParam>; + + /** + * Determines the nesting level for linked content items that the API returns. + * By default, only the first level of linked items is returned, which is the same as setting depth=1. + * To include more than one level of linked items in the response, set depth to 2 or more. + * To exclude all linked items from the response, set depth to 0. + */ + readonly depth?: number; + }, + never +>; + +export function fetchContentItemQuery( + config: DeliveryClientConfig, + request: FetchContentItemQueryRequest, +): FetchContentItemQuery { + const rawQuery = createDeliveryFetchQuery>({ + config, + request, + schema: async () => (await import("./schemas/content-item.schemas.js")).fetchContentItemSchema(), + endpoint: `items/${encodeURIComponent(request.codename)}`, + }); + const extendedQuery = transformDeliveryFetchQuery({ + config, + query: rawQuery, + transformSchema: async () => (await import("./schemas/content-item.schemas.js")).fetchContentItemSchemaExtended(), + transform: (response) => { + const allItems = joinItems({ + modularContent: [response.payload.modular_content], + items: [response.payload.item], + }); + + return { + ...response, + meta: response.meta, + payload: { + ...response.payload, + item: mapToExtendedItem({ allItems, item: response.payload.item }), + modular_content: mapToExtendedModularContent({ allItems, modularContents: response.payload.modular_content }), + }, + }; + }, + }); + return { ...extendedQuery, raw: () => rawQuery }; +} diff --git a/lib/queries/content-items/items-feed-query.ts b/lib/queries/content-items/items-feed-query.ts new file mode 100644 index 00000000..0246a0d6 --- /dev/null +++ b/lib/queries/content-items/items-feed-query.ts @@ -0,0 +1,103 @@ +import type { QueryResponse } from "@kontent-ai/core-sdk"; +import type { + DeliveryClientConfig, + DeliveryClientSchema, + DeliveryMetadataWithToken, + DeliveryPagedFetchQuery, +} from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { + DeliveryRequestWithTokenPaging, + ElementOrderQueryParam, + ElementSelectionQueryParam, + SystemOrderQueryParam, + WithRaw, +} from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import type { AllElementCodenamesOf } from "../../queries/content-types/models/content-type.models.js"; +import { joinItems, mapToExtendedItem, mapToExtendedModularContent } from "../../transforms/content-item-transforms.js"; +import { createDeliveryPagedByTokenQuery, transformDeliveryPagedByTokenQuery } from "../delivery-queries.js"; +import type { + ContentItemPayload, + ContentItemPayloadExtended, + ItemsFeedPayload, + ItemsFeedPayloadExtended, +} from "./models/content-item.models.js"; + +type SystemProperties = keyof ContentItemPayload["system"]; +type ElementProperties = AllElementCodenamesOf; + +export type ItemsFeedResponse = DeliveryResponse< + ItemsFeedPayloadExtended, + DeliveryMetadataWithToken +>; + +export type ItemsFeedQuery = DeliveryPagedFetchQuery< + ItemsFeedResponse["payload"], + ItemsFeedResponse["meta"] +> & + WithRaw, ItemsFeedResponse["meta"]>>; + +export type ItemsFeedQueryRequest = DeliveryRequestWithTokenPaging< + { + readonly order?: SystemOrderQueryParam | ElementOrderQueryParam>; + /** + * Determines which language variant of content items to return. By default, the API returns content in the default language. + */ + readonly language?: NonNullable[number]; + + /** + * Specifies which elements to include in the response. By default, all elements are returned. + */ + readonly elements?: ElementSelectionQueryParam>; + + /** + * Specifies which elements to exclude from the response. By default, no elements are excluded. + */ + readonly excludeElements?: ElementSelectionQueryParam>; + + /** + * Determines the nesting level for linked content items that the API returns. + * By default, only the first level of linked items is returned, which is the same as setting depth=1. + * To include more than one level of linked items in the response, set depth to 2 or more. + * To exclude all linked items from the response, set depth to 0. + */ + readonly depth?: number; + }, + readonly Filter>[] +>; + +export function itemsFeedQuery( + config: DeliveryClientConfig, + request?: ItemsFeedQueryRequest, +): ItemsFeedQuery { + const rawQuery = createDeliveryPagedByTokenQuery>({ + config, + request, + schema: async () => (await import("./schemas/content-item.schemas.js")).itemsFeedSchema(), + endpoint: "items-feed", + }); + const extendedQuery = transformDeliveryPagedByTokenQuery({ + config, + query: rawQuery, + transformSchema: async () => (await import("./schemas/content-item.schemas.js")).itemsFeedSchemaExtended(), + transform: (responses) => { + const allItems = joinItems({ + items: responses.flatMap((m) => m.payload.items), + modularContent: responses.map((m) => m.payload.modular_content), + }); + + return responses.map, DeliveryMetadataWithToken>>((m) => { + return { + ...m, + payload: { + ...m.payload, + items: m.payload.items.map>((item) => mapToExtendedItem({ allItems, item })), + modular_content: mapToExtendedModularContent({ allItems, modularContents: m.payload.modular_content }), + }, + }; + }); + }, + }); + return { ...extendedQuery, raw: () => rawQuery }; +} diff --git a/lib/queries/content-items/items-referencing-asset-query.ts b/lib/queries/content-items/items-referencing-asset-query.ts new file mode 100644 index 00000000..4c531978 --- /dev/null +++ b/lib/queries/content-items/items-referencing-asset-query.ts @@ -0,0 +1,43 @@ +import type { + DeliveryClientConfig, + DeliveryClientSchema, + DeliveryMetadataWithToken, + DeliveryPagedFetchQuery, +} from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { DeliveryRequestWithTokenPaging } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryPagedByTokenQuery } from "../delivery-queries.js"; +import type { ContentItemSystemPayload, ItemsReferencingAssetPayload } from "./models/content-item.models.js"; + +export type ItemsReferencingAssetResponse = DeliveryResponse< + ItemsReferencingAssetPayload, + DeliveryMetadataWithToken +>; + +export type ItemsReferencingAssetQuery = DeliveryPagedFetchQuery< + ItemsReferencingAssetResponse["payload"], + ItemsReferencingAssetResponse["meta"] +>; + +export type ItemsReferencingAssetQueryRequest = DeliveryRequestWithTokenPaging< + never, + readonly Filter, never>[] +> & { + /** + * Codename of the asset to retrieve referencing content items for. + */ + readonly codename: string; +}; + +export function itemsReferencingAssetQuery( + config: DeliveryClientConfig, + request: ItemsReferencingAssetQueryRequest, +): ItemsReferencingAssetQuery { + return createDeliveryPagedByTokenQuery({ + config, + request, + schema: async () => (await import("./schemas/content-item.schemas.js")).itemsReferencingAssetSchema(), + endpoint: `assets/${encodeURIComponent(request.codename)}/used-in`, + }); +} diff --git a/lib/queries/content-items/items-referencing-item-query.ts b/lib/queries/content-items/items-referencing-item-query.ts new file mode 100644 index 00000000..6a385e15 --- /dev/null +++ b/lib/queries/content-items/items-referencing-item-query.ts @@ -0,0 +1,43 @@ +import type { + DeliveryClientConfig, + DeliveryClientSchema, + DeliveryMetadataWithToken, + DeliveryPagedFetchQuery, +} from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { DeliveryRequestWithTokenPaging } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryPagedByTokenQuery } from "../delivery-queries.js"; +import type { ContentItemSystemPayload, ItemsReferencingItemPayload } from "./models/content-item.models.js"; + +export type ItemsReferencingItemResponse = DeliveryResponse< + ItemsReferencingItemPayload, + DeliveryMetadataWithToken +>; + +export type ItemsReferencingItemQuery = DeliveryPagedFetchQuery< + ItemsReferencingItemResponse["payload"], + ItemsReferencingItemResponse["meta"] +>; + +export type ItemsReferencingItemQueryRequest = DeliveryRequestWithTokenPaging< + never, + readonly Filter, never>[] +> & { + /** + * Codename of the content item to retrieve referencing content items for. + */ + readonly codename: string; +}; + +export function itemsReferencingItemQuery( + config: DeliveryClientConfig, + request: ItemsReferencingItemQueryRequest, +): ItemsReferencingItemQuery { + return createDeliveryPagedByTokenQuery({ + config, + request, + schema: async () => (await import("./schemas/content-item.schemas.js")).itemsReferencingItemSchema(), + endpoint: `items/${encodeURIComponent(request.codename)}/used-in`, + }); +} diff --git a/lib/queries/content-items/list-content-items-query.ts b/lib/queries/content-items/list-content-items-query.ts new file mode 100644 index 00000000..0bfe11dc --- /dev/null +++ b/lib/queries/content-items/list-content-items-query.ts @@ -0,0 +1,105 @@ +import type { QueryResponse } from "@kontent-ai/core-sdk"; +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryMetadata, DeliveryPagedFetchQuery } from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { + DeliveryRequestWithUrlPaging, + ElementOrderQueryParam, + ElementSelectionQueryParam, + SystemOrderQueryParam, + WithRaw, +} from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import type { AllElementCodenamesOf } from "../../queries/content-types/models/content-type.models.js"; +import { joinItems, mapToExtendedItem, mapToExtendedModularContent } from "../../transforms/content-item-transforms.js"; +import { createDeliveryPagedByUrlQuery, transformDeliveryPagedByUrlQuery } from "../delivery-queries.js"; +import type { + ContentItemPayload, + ContentItemPayloadExtended, + ListContentItemsPayload, + ListContentItemsPayloadExtended, +} from "./models/content-item.models.js"; + +type SystemProperties = keyof ContentItemPayload["system"]; +type ElementProperties = AllElementCodenamesOf; + +export type ListContentItemsResponse = DeliveryResponse< + ListContentItemsPayloadExtended, + DeliveryMetadata +>; + +export type ListContentItemsQuery = DeliveryPagedFetchQuery< + ListContentItemsResponse["payload"], + ListContentItemsResponse["meta"] +> & + WithRaw, ListContentItemsResponse["meta"]>>; + +export type ListContentItemsQueryRequest = DeliveryRequestWithUrlPaging< + SystemOrderQueryParam | ElementOrderQueryParam>, + { + /** + * Determines which language variant of content items to return. By default, the API returns content in the default language. + */ + readonly language?: NonNullable[number]; + + /** + * Specifies which elements to include in the response. By default, all elements are returned. + */ + readonly elements?: ElementSelectionQueryParam>; + + /** + * Specifies which elements to exclude from the response. By default, no elements are excluded. + */ + readonly excludeElements?: ElementSelectionQueryParam>; + + /** + * Determines the nesting level for linked content items that the API returns. + * By default, only the first level of linked items is returned, which is the same as setting depth=1. + * To include more than one level of linked items in the response, set depth to 2 or more. + * To exclude all linked items from the response, set depth to 0. + */ + readonly depth?: number; + + /** + * Adds the information about the total number of content items matching your query. + * Only the content filtering parameters affect the resulting number. + * Other parameters in your query, such as limit, skip, or order, don't have an effect on it. + */ + readonly includeTotalCount?: boolean; + }, + readonly Filter>[] +>; + +export function listContentItemsQuery( + config: DeliveryClientConfig, + request?: ListContentItemsQueryRequest, +): ListContentItemsQuery { + const rawQuery = createDeliveryPagedByUrlQuery>({ + config, + request, + schema: async () => (await import("./schemas/content-item.schemas.js")).listContentItemsSchema(), + endpoint: "items", + }); + const extendedQuery = transformDeliveryPagedByUrlQuery({ + config, + query: rawQuery, + transformSchema: async () => (await import("./schemas/content-item.schemas.js")).listContentItemsSchemaExtended(), + transform: (responses) => { + const allItems = joinItems({ + items: responses.flatMap((m) => m.payload.items), + modularContent: responses.map((m) => m.payload.modular_content), + }); + + return responses.map, DeliveryMetadata>>((m) => { + return { + ...m, + payload: { + ...m.payload, + items: m.payload.items.map>((item) => mapToExtendedItem({ allItems, item })), + modular_content: mapToExtendedModularContent({ allItems, modularContents: m.payload.modular_content }), + }, + }; + }); + }, + }); + return { ...extendedQuery, raw: () => rawQuery }; +} diff --git a/lib/queries/content-items/models/content-item.models.ts b/lib/queries/content-items/models/content-item.models.ts new file mode 100644 index 00000000..b5e7728c --- /dev/null +++ b/lib/queries/content-items/models/content-item.models.ts @@ -0,0 +1,68 @@ +import type * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import type { ContentTypeCodenameOf, ElementCodenamesOf } from "../../content-types/models/content-type.models.js"; +import type { + contentItemSchema, + contentItemSchemaExtended, + contentItemSystemSchema, + contentItemSystemWithCodename, + fetchContentItemSchema, + fetchContentItemSchemaExtended, + itemsFeedSchema, + itemsFeedSchemaExtended, + itemsReferencingAssetSchema, + itemsReferencingItemSchema, + listContentItemsSchema, + listContentItemsSchemaExtended, +} from "../schemas/content-item.schemas.js"; +import type { ContentItemElementPayload } from "./element.models.js"; + +export type ContentItemSystem> = z.infer< + ReturnType> +>; + +export type SnippetOf< + TSchema extends DeliveryClientSchema, + TTypeCodename extends ContentTypeCodenameOf, + TElements extends { + readonly [Codename in keyof TElements]: Codename extends ElementCodenamesOf + ? ContentItemElementPayload + : never; + }, +> = ContentItemOf; + +export type ContentItemOf< + TSchema extends DeliveryClientSchema, + TTypeCodename extends ContentTypeCodenameOf, + TElements extends { + readonly [Codename in keyof TElements]: Codename extends ElementCodenamesOf + ? ContentItemElementPayload + : never; + }, +> = { + readonly system: ContentItemSystem; + readonly elements: TElements; +}; + +export type ContentItemSystemPayload = z.infer>>; +export type ContentItemPayload = z.infer>>; +export type ListContentItemsPayload = z.infer>>; +export type FetchContentItemPayload = z.infer>>; +export type ItemsFeedPayload = z.infer>>; +export type ItemsReferencingAssetPayload = z.infer< + ReturnType> +>; +export type ItemsReferencingItemPayload = z.infer< + ReturnType> +>; + +export type ContentItemPayloadExtended = z.infer< + ReturnType> +>; +export type FetchContentItemPayloadExtended = z.infer< + ReturnType> +>; +export type ListContentItemsPayloadExtended = z.infer< + ReturnType> +>; +export type ItemsFeedPayloadExtended = z.infer>>; diff --git a/lib/queries/content-items/models/element-types.ts b/lib/queries/content-items/models/element-types.ts new file mode 100644 index 00000000..50e22160 --- /dev/null +++ b/lib/queries/content-items/models/element-types.ts @@ -0,0 +1,19 @@ +import type * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import type { elementDef } from "../schemas/element.schemas.js"; +import type { ContentItemPayload } from "./content-item.models.js"; + +export type Text = z.infer; +export type Number = z.infer; +export type RichText = ContentItemPayload> = z.infer< + ReturnType> +>; +export type MultipleChoice = z.infer>>; +export type DateTime = z.infer; +export type Asset = z.infer; +export type Taxonomy = z.infer>>; +export type UrlSlug = z.infer; +export type Custom = z.infer; +export type LinkedItems = ContentItemPayload> = z.infer< + ReturnType> +>; diff --git a/lib/queries/content-items/models/element.models.ts b/lib/queries/content-items/models/element.models.ts new file mode 100644 index 00000000..f87b6a3a --- /dev/null +++ b/lib/queries/content-items/models/element.models.ts @@ -0,0 +1,6 @@ +import type * as z from "zod/mini"; +import type { assetValueSchema, contentItemElementSchema, contentItemElementSchemaExtended } from "../schemas/element.schemas.js"; + +export type Asset = z.infer; +export type ContentItemElementPayload = z.infer; +export type ContentItemElementPayloadExtended = z.infer; diff --git a/lib/queries/content-items/schemas/content-item.schemas.ts b/lib/queries/content-items/schemas/content-item.schemas.ts new file mode 100644 index 00000000..86e96a0a --- /dev/null +++ b/lib/queries/content-items/schemas/content-item.schemas.ts @@ -0,0 +1,134 @@ +import { codenameOf, kontentUuidSchema } from "@kontent-ai/core-sdk"; +import * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import { paginationWithTotalCountSchema } from "../../../models/pagination.schemas.js"; +import type { ContentTypeCodenameOf } from "../../content-types/models/content-type.models.js"; +import { contentItemElementSchema, contentItemElementSchemaExtended } from "./element.schemas.js"; + +const modularContentItem = () => z.union([contentItemSchema(), z.undefined()]); +const modularContentItemExtended = () => + z.union([contentItemSchemaExtended(), z.undefined()]); + +const baseContentItemSystemSchema = () => + z.object({ + id: kontentUuidSchema, + name: z.string(), + codename: codenameOf(), + language: codenameOf(), + type: codenameOf>(), + collection: codenameOf(), + last_modified: z.iso.datetime(), + workflow: codenameOf(), + workflow_step: codenameOf(), + }); + +export const contentItemSchema = () => + z.readonly( + z.object({ + system: contentItemSystemSchema(), + elements: z.readonly(z.record(z.string(), contentItemElementSchema)), + }), + ); + +export const contentItemSystemWithCodename = >( + type: TTypeCodename, +) => + z.readonly( + z.object({ + ...baseContentItemSystemSchema().shape, + sitemap_locations: z.readonly(z.array(z.string())), + type: z.literal(type), + }), + ); + +export const contentItemSystemSchema = () => + z.readonly( + z.object({ + ...baseContentItemSystemSchema().shape, + sitemap_locations: z.readonly(z.array(z.string())), + }), + ); + +export const listContentItemsSchema = () => + z.readonly( + z.object({ + items: z.readonly(z.array(contentItemSchema())), + modular_content: z.readonly(z.record(z.string(), modularContentItem())), + ...paginationWithTotalCountSchema.shape, + }), + ); + +export const itemsFeedSchema = () => + z.readonly( + z.object({ + items: z.readonly(z.array(contentItemSchema())), + modular_content: z.readonly(z.record(z.string(), modularContentItem())), + }), + ); + +export const itemsReferencingAssetSchema = () => + z.readonly( + z.object({ + items: z.readonly( + z.array( + z.object({ + system: baseContentItemSystemSchema(), + }), + ), + ), + }), + ); + +export const itemsReferencingItemSchema = () => + z.readonly( + z.object({ + items: z.readonly( + z.array( + z.object({ + system: baseContentItemSystemSchema(), + }), + ), + ), + }), + ); + +export const fetchContentItemSchema = () => + z.readonly( + z.object({ + item: contentItemSchema(), + modular_content: z.readonly(z.record(z.string(), modularContentItem())), + }), + ); + +export const contentItemSchemaExtended = () => + z.readonly( + z.object({ + system: contentItemSystemSchema(), + elements: z.readonly(z.record(z.string(), contentItemElementSchemaExtended)), + }), + ); + +export const listContentItemsSchemaExtended = () => + z.readonly( + z.object({ + items: z.readonly(z.array(contentItemSchemaExtended())), + modular_content: z.readonly(z.record(z.string(), modularContentItemExtended())), + ...paginationWithTotalCountSchema.shape, + }), + ); + +export const itemsFeedSchemaExtended = () => + z.readonly( + z.object({ + items: z.readonly(z.array(contentItemSchemaExtended())), + modular_content: z.readonly(z.record(z.string(), modularContentItemExtended())), + }), + ); + +export const fetchContentItemSchemaExtended = () => + z.readonly( + z.object({ + item: contentItemSchemaExtended(), + modular_content: z.readonly(z.record(z.string(), modularContentItemExtended())), + }), + ); diff --git a/lib/queries/content-items/schemas/element.schemas.ts b/lib/queries/content-items/schemas/element.schemas.ts new file mode 100644 index 00000000..a574f3cd --- /dev/null +++ b/lib/queries/content-items/schemas/element.schemas.ts @@ -0,0 +1,201 @@ +import { codenameOf, kontentUuidSchema } from "@kontent-ai/core-sdk"; +import * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import type { ContentItemPayload } from "../models/content-item.models.js"; +import { contentItemSchemaExtended } from "./content-item.schemas.js"; + +const multipleChoiceOptionSchema = () => + z.readonly( + z.object({ + name: z.string(), + codename: codenameOf(), + }), + ); + +const taxonomyTermValueSchema = () => + z.readonly( + z.object({ + name: z.string(), + codename: codenameOf(), + }), + ); + +const renditionSchema = z.readonly( + z.object({ + rendition_id: kontentUuidSchema, + preset_id: kontentUuidSchema, + width: z.number(), + height: z.number(), + query: z.string(), + }), +); + +export const assetValueSchema = z.readonly( + z.object({ + name: z.string(), + description: z.nullable(z.string()), + type: z.string(), + size: z.number(), + url: z.url(), + width: z.nullable(z.number()), + height: z.nullable(z.number()), + renditions: z.readonly(z.object({ default: z.optional(renditionSchema) })), + }), +); + +const richTextImageSchema = z.readonly( + z.object({ + image_id: z.string(), + description: z.nullable(z.string()), + url: z.url(), + width: z.nullable(z.number()), + height: z.nullable(z.number()), + }), +); + +const richTextLinkSchema = z.readonly( + z.object({ + codename: codenameOf(), + type: z.string(), + url_slug: z.string(), + }), +); + +/** + * Base element schema as provided by Kontent.ai API + */ +const baseElementSchemas = { + text: z.object({ + type: z.literal("text"), + name: z.string(), + value: z.string(), + }), + number: z.object({ + type: z.literal("number"), + name: z.string(), + value: z.nullable(z.number()), + }), + richText: z.object({ + type: z.literal("rich_text"), + name: z.string(), + value: z.string(), + images: z.record(z.string(), richTextImageSchema), + links: z.record(z.string(), richTextLinkSchema), + modular_content: z.readonly(z.array(codenameOf())), + }), + multipleChoice: z.object({ + type: z.literal("multiple_choice"), + name: z.string(), + value: z.readonly(z.array(multipleChoiceOptionSchema())), + }), + dateTime: z.object({ + type: z.literal("date_time"), + name: z.string(), + value: z.nullable(z.string()), + display_timezone: z.nullable(z.string()), + }), + asset: z.object({ + type: z.literal("asset"), + name: z.string(), + value: z.readonly(z.array(assetValueSchema)), + }), + taxonomy: z.object({ + type: z.literal("taxonomy"), + name: z.string(), + taxonomy_group: z.string(), + value: z.readonly(z.array(taxonomyTermValueSchema())), + }), + urlSlug: z.object({ + type: z.literal("url_slug"), + name: z.string(), + value: z.string(), + }), + custom: z.object({ + type: z.literal("custom"), + name: z.string(), + value: z.nullable(z.string()), + }), + linkedItems: z.object({ + type: z.literal("modular_content"), + name: z.string(), + value: z.readonly(z.array(codenameOf())), + }), +} as const; + +/** + * Building blocks for constructing typed content item schemas. + */ +export const elementDef = { + text: z.readonly(baseElementSchemas.text), + number: z.readonly(baseElementSchemas.number), + richText: = ContentItemPayload>() => + z.readonly( + z.extend(baseElementSchemas.richText, { + items: z.readonly( + z.array( + z.custom((item: unknown): boolean => contentItemSchemaExtended().safeParse(item).success, { + error: "Invalid referenced linked item", + }), + ), + ), + }), + ), + multipleChoice: () => + z.readonly( + z.extend(baseElementSchemas.multipleChoice, { + value: z.readonly(z.array(multipleChoiceOptionSchema())), + }), + ), + dateTime: z.readonly(baseElementSchemas.dateTime), + asset: z.readonly(baseElementSchemas.asset), + taxonomy: () => + z.readonly( + z.extend(baseElementSchemas.taxonomy, { + value: z.readonly(z.array(taxonomyTermValueSchema())), + }), + ), + urlSlug: z.readonly(baseElementSchemas.urlSlug), + custom: z.readonly(baseElementSchemas.custom), + linkedItems: = ContentItemPayload>() => + z.readonly( + z.extend(baseElementSchemas.linkedItems, { + items: z.readonly( + z.array( + z.custom((item: unknown): boolean => contentItemSchemaExtended().safeParse(item).success, { + error: "Invalid referenced linked item", + }), + ), + ), + }), + ), +} as const; + +export const contentItemElementSchema = z.readonly( + z.discriminatedUnion("type", [ + z.readonly(baseElementSchemas.text), + z.readonly(baseElementSchemas.number), + z.readonly(baseElementSchemas.richText), + z.readonly(baseElementSchemas.multipleChoice), + z.readonly(baseElementSchemas.dateTime), + z.readonly(baseElementSchemas.asset), + z.readonly(baseElementSchemas.taxonomy), + z.readonly(baseElementSchemas.urlSlug), + z.readonly(baseElementSchemas.linkedItems), + z.readonly(baseElementSchemas.custom), + ]), +); + +export const contentItemElementSchemaExtended = z.readonly( + z.discriminatedUnion("type", [ + elementDef.text, + elementDef.number, + elementDef.richText(), + elementDef.multipleChoice(), + elementDef.dateTime, + elementDef.asset, + elementDef.taxonomy(), + elementDef.urlSlug, + elementDef.linkedItems(), + elementDef.custom, + ]), +); diff --git a/lib/queries/content-types/fetch-content-type-element-query.ts b/lib/queries/content-types/fetch-content-type-element-query.ts new file mode 100644 index 00000000..4235ba7f --- /dev/null +++ b/lib/queries/content-types/fetch-content-type-element-query.ts @@ -0,0 +1,32 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryFetchQuery, DeliveryMetadata } from "../../models/core.models.js"; +import type { DeliveryRequest } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryFetchQuery } from "../delivery-queries.js"; +import type { ContentTypeCodenameOf, ContentTypeElementPayload, ElementCodenamesOf } from "./models/content-type.models.js"; + +export type FetchContentTypeElementResponse = DeliveryResponse; + +export type FetchContentTypeElementQuery = DeliveryFetchQuery< + FetchContentTypeElementResponse["payload"], + FetchContentTypeElementResponse["meta"] +>; + +export type FetchContentTypeElementQueryRequest< + TSchema extends DeliveryClientSchema, + TCodename extends ContentTypeCodenameOf = ContentTypeCodenameOf, +> = DeliveryRequest & { + readonly typeCodename: TCodename; + readonly elementCodename: ElementCodenamesOf; +}; + +export function fetchContentTypeElementQuery>( + config: DeliveryClientConfig, + request: FetchContentTypeElementQueryRequest, +): FetchContentTypeElementQuery { + return createDeliveryFetchQuery({ + config, + request, + schema: async () => (await import("./schemas/content-type.schemas.js")).contentTypeElementSchema(), + endpoint: `types/${encodeURIComponent(request.typeCodename)}/elements/${encodeURIComponent(request.elementCodename)}`, + }); +} diff --git a/lib/queries/content-types/fetch-content-type-query.ts b/lib/queries/content-types/fetch-content-type-query.ts new file mode 100644 index 00000000..db6bc80e --- /dev/null +++ b/lib/queries/content-types/fetch-content-type-query.ts @@ -0,0 +1,38 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryFetchQuery, DeliveryMetadata } from "../../models/core.models.js"; +import type { DeliveryRequestWithCodename, ElementSelectionQueryParam } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryFetchQuery } from "../delivery-queries.js"; +import type { ContentTypeCodenameOf, ContentTypePayload, ElementCodenamesOf } from "./models/content-type.models.js"; + +export type FetchContentTypeResponse = DeliveryResponse< + ContentTypePayload, + DeliveryMetadata +>; + +export type FetchContentTypeQuery = DeliveryFetchQuery< + FetchContentTypeResponse["payload"], + FetchContentTypeResponse["meta"] +>; + +export type FetchContentTypeQueryRequest< + TSchema extends DeliveryClientSchema, + TCodename extends ContentTypeCodenameOf = ContentTypeCodenameOf, +> = DeliveryRequestWithCodename< + readonly TCodename[], + { + readonly elements?: ElementSelectionQueryParam>; + }, + never +>; + +export function fetchContentTypeQuery>( + config: DeliveryClientConfig, + request: FetchContentTypeQueryRequest, +): FetchContentTypeQuery { + return createDeliveryFetchQuery({ + config, + request, + schema: async () => (await import("./schemas/content-type.schemas.js")).contentTypeSchema(), + endpoint: `types/${encodeURIComponent(request.codename)}`, + }); +} diff --git a/lib/queries/content-types/list-content-types-query.ts b/lib/queries/content-types/list-content-types-query.ts new file mode 100644 index 00000000..f3a2be3a --- /dev/null +++ b/lib/queries/content-types/list-content-types-query.ts @@ -0,0 +1,39 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryMetadata, DeliveryPagedFetchQuery } from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { DeliveryRequestWithUrlPaging, ElementSelectionQueryParam, SystemOrderQueryParam } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryPagedByUrlQuery } from "../delivery-queries.js"; +import type { AllElementCodenamesOf, ContentTypePayload, ListContentTypesPayload } from "./models/content-type.models.js"; + +type SystemProperties = keyof ContentTypePayload["system"]; +type ElementProperties = AllElementCodenamesOf; + +export type ListContentTypesResponse = DeliveryResponse< + ListContentTypesPayload, + DeliveryMetadata +>; + +export type ListContentTypesQuery = DeliveryPagedFetchQuery< + ListContentTypesResponse["payload"], + ListContentTypesResponse["meta"] +>; + +export type ListContentTypesQueryRequest = DeliveryRequestWithUrlPaging< + SystemOrderQueryParam, + { + readonly elements?: ElementSelectionQueryParam>; + }, + readonly Filter[] +>; + +export function listContentTypesQuery( + config: DeliveryClientConfig, + request?: ListContentTypesQueryRequest, +): ListContentTypesQuery { + return createDeliveryPagedByUrlQuery({ + config, + request, + schema: async () => (await import("./schemas/content-type.schemas.js")).listContentTypesSchema(), + endpoint: "types", + }); +} diff --git a/lib/queries/content-types/models/content-type.models.ts b/lib/queries/content-types/models/content-type.models.ts new file mode 100644 index 00000000..743c7743 --- /dev/null +++ b/lib/queries/content-types/models/content-type.models.ts @@ -0,0 +1,36 @@ +import type * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import type { contentTypeElementSchema, contentTypeSchema, listContentTypesSchema } from "../schemas/content-type.schemas.js"; + +export type ContentTypePayload = z.infer>>; + +export type ContentTypeElementPayload = z.infer>; + +export type ListContentTypesPayload = z.infer>>; + +/** + * The content type codenames declared in the schema (the keys of the `contentTypes` map). + * Narrows to a literal union for a concrete schema, falling back to `string` for the generic default. + */ +export type ContentTypeCodenameOf = keyof TSchema["contentTypes"] & string; + +/** + * The element codenames belonging to the content type identified by `TCodename`, derived from the + * schema's `contentTypes` map. Falls back to `string` when the codename is unknown, the type declares + * no elements, or the schema is the generic default. + */ +export type ElementCodenamesOf< + TSchema extends DeliveryClientSchema, + TCodename extends string, +> = TCodename extends keyof TSchema["contentTypes"] + ? [Extract[number], string>] extends [never] + ? string + : Extract[number], string> + : string; + +/** + * The union of every element codename across all content types in the schema. Used by cross-type + * queries (items feed, list/fetch items) that aren't scoped to a single content type. + * Falls back to `string` for the generic default. + */ +export type AllElementCodenamesOf = ElementCodenamesOf>; diff --git a/lib/queries/content-types/schemas/content-type.schemas.ts b/lib/queries/content-types/schemas/content-type.schemas.ts new file mode 100644 index 00000000..10b56014 --- /dev/null +++ b/lib/queries/content-types/schemas/content-type.schemas.ts @@ -0,0 +1,143 @@ +import { codenameOf, jsonValueSchema, kontentUuidSchema } from "@kontent-ai/core-sdk"; +import * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import { paginationSchema } from "../../../models/pagination.schemas.js"; +import type { ContentTypeCodenameOf } from "../models/content-type.models.js"; + +const contentTypeElementOptionSchema = z.readonly( + z.object({ + name: z.string(), + codename: codenameOf(), + }), +); + +const contentTypeAnyElementSchema = z.discriminatedUnion("type", [ + z.readonly( + z.catchall( + z.object({ + type: z.literal("text"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("number"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("rich_text"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("multiple_choice"), + name: z.string(), + options: z.readonly(z.array(contentTypeElementOptionSchema)), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("date_time"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("asset"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("taxonomy"), + name: z.string(), + taxonomy_group: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("url_slug"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("modular_content"), + name: z.string(), + }), + jsonValueSchema, + ), + ), + z.readonly( + z.catchall( + z.object({ + type: z.literal("custom"), + name: z.string(), + }), + jsonValueSchema, + ), + ), +]); + +export const contentTypeSchema = () => + z.readonly( + z.object({ + system: z.readonly( + z.object({ + id: kontentUuidSchema, + name: z.string(), + codename: codenameOf>(), + last_modified: z.iso.datetime(), + }), + ), + elements: z.readonly(z.record(z.string(), contentTypeAnyElementSchema)), + }), + ); + +export const listContentTypesSchema = () => + z.readonly( + z.object({ + types: z.readonly(z.array(contentTypeSchema())), + ...paginationSchema.shape, + }), + ); + +export const contentTypeElementSchema = () => + z.readonly( + z.intersection( + contentTypeAnyElementSchema, + z.readonly( + z.object({ + // Required only for the endpoint `types/{type}/elements/{element}` + codename: codenameOf(), + }), + ), + ), + ); diff --git a/lib/queries/delivery-queries.ts b/lib/queries/delivery-queries.ts new file mode 100644 index 00000000..9e83b5ff --- /dev/null +++ b/lib/queries/delivery-queries.ts @@ -0,0 +1,230 @@ +import { + createFetchQuery, + createPagedFetchQuery, + type FetchQuery, + type FetchQueryRequest, + type Header, + type JsonValue, + type PagedFetchQuery, + transformFetchQuery, + transformPagedFetchQuery, +} from "@kontent-ai/core-sdk"; +import type { ZodMiniType } from "zod/mini"; +import { deliverySdkInfo } from "../delivery-sdk-info.js"; +import type { + DeliveryClientConfig, + DeliveryEndpoint, + DeliveryMetadata, + DeliveryMetadataWithToken, + TokenPagingDeliveryExtraResponseProps, + UrlPagingDeliveryExtraResponseProps, +} from "../models/core.models.js"; +import type { DeliverySdkError } from "../models/error.models.js"; +import type { Filter } from "../models/filter.models.js"; +import type { PaginationPayload } from "../models/pagination.models.js"; +import type { DeliveryRequest, QueryParameterRecord } from "../models/request.models.js"; +import { mapDeliveryError } from "../utils/error.utils.js"; +import { getNextPageByContinuationToken, getNextPageByUrl } from "../utils/paging.utils.js"; +import { addQueryParametersToUrl, getDeliveryUrl } from "../utils/url.utils.js"; + +type AnyDeliveryRequest = DeliveryRequest[]>; + +export function createDeliveryPagedByUrlQuery({ + config, + schema, + endpoint, + request, +}: { + readonly request: AnyDeliveryRequest | undefined; + readonly config: DeliveryClientConfig; + readonly schema: () => Promise>; + readonly endpoint: DeliveryEndpoint; +}): PagedFetchQuery { + return createPagedFetchQuery({ + ...getSharedRequestData({ config, endpoint, schema: schema, request }), + getNextPageData: getNextPageByUrl(), + mapPagingExtraResponseProps: (responses) => ({ + nextPageUrl: responses.at(-1)?.payload?.pagination?.next_page, + }), + mapMetadata: () => ({}), + }); +} + +export function createDeliveryPagedByTokenQuery({ + config, + schema, + endpoint, + request, +}: { + readonly request: AnyDeliveryRequest | undefined; + readonly config: DeliveryClientConfig; + readonly schema: () => Promise>; + readonly endpoint: DeliveryEndpoint; +}): PagedFetchQuery { + return createPagedFetchQuery({ + ...getSharedRequestData({ config, endpoint, schema: schema, request }), + getNextPageData: getNextPageByContinuationToken(), + mapPagingExtraResponseProps: (responses) => ({ + nextContinuationToken: responses.at(-1)?.meta?.continuationToken, + }), + mapMetadata: (_, data) => ({ + continuationToken: data.continuationToken, + }), + }); +} + +export function createDeliveryFetchQuery({ + config, + schema, + endpoint, + request, +}: { + readonly request: AnyDeliveryRequest | undefined; + readonly config: DeliveryClientConfig; + readonly schema: () => Promise>; + readonly endpoint: DeliveryEndpoint; +}): FetchQuery { + return createFetchQuery({ + ...getSharedRequestData({ config, endpoint, schema: schema, request }), + mapMetadata: () => ({}), + }); +} + +export function transformDeliveryFetchQuery({ + config, + query, + transform, + transformSchema, +}: { + readonly query: FetchQuery; +} & Pick< + Parameters>[0], + "transform" | "transformSchema" | "config" +>): FetchQuery { + return transformFetchQuery({ + query, + transform, + transformSchema, + mapError: mapDeliveryError, + config, + }); +} + +export function transformDeliveryPagedByUrlQuery({ + config, + query, + transform, + transformSchema, +}: { + readonly query: PagedFetchQuery; +} & Pick< + Parameters< + typeof transformPagedFetchQuery< + TPayload, + TTransformedPayload, + DeliverySdkError, + DeliveryMetadata, + unknown, + UrlPagingDeliveryExtraResponseProps + > + >[0], + "transform" | "transformSchema" | "config" +>): PagedFetchQuery { + return transformPagedFetchQuery({ + query, + transform, + transformSchema, + mapError: mapDeliveryError, + config, + }); +} + +export function transformDeliveryPagedByTokenQuery({ + config, + query, + transform, + transformSchema, +}: { + readonly query: PagedFetchQuery; +} & Pick< + Parameters< + typeof transformPagedFetchQuery< + TPayload, + TTransformedPayload, + DeliverySdkError, + DeliveryMetadataWithToken, + unknown, + TokenPagingDeliveryExtraResponseProps + > + >[0], + "transform" | "transformSchema" | "config" +>): PagedFetchQuery { + return transformPagedFetchQuery({ + query, + transform, + transformSchema, + mapError: mapDeliveryError, + config, + }); +} + +function getSharedRequestData({ + config, + endpoint, + schema, + request, +}: { + readonly request: AnyDeliveryRequest | undefined; + readonly config: DeliveryClientConfig; + readonly endpoint: DeliveryEndpoint; + readonly schema: () => Promise>; +}): Pick< + FetchQueryRequest, + | "abortSignal" + | "config" + | "sdkInfo" + | "authorizationApiKey" + | "url" + | "requestHeaders" + | "schema" + | "mapError" + | "mapExtraResponseProps" +> { + return { + abortSignal: request?.config?.abortSignal, + config, + sdkInfo: deliverySdkInfo, + mapExtraResponseProps: () => {}, + requestHeaders: getHeaders(request), + url: getUrl({ request, config, endpoint }), + authorizationApiKey: config.apiMode === "preview" || config.apiMode === "secure" ? config.deliveryApiKey : undefined, + schema, + mapError: mapDeliveryError, + }; +} + +function getUrl({ + request, + config, + endpoint, +}: { + readonly request: AnyDeliveryRequest | undefined; + readonly config: DeliveryClientConfig; + readonly endpoint: DeliveryEndpoint; +}): string { + return addQueryParametersToUrl(getDeliveryUrl({ path: endpoint, ...config }), request?.query, request?.filters); +} + +function getHeaders(request?: AnyDeliveryRequest): readonly Header[] { + if (!request) { + return []; + } + + const configHeaders: readonly Header[] = request.config?.customHeaders ?? []; + const requestHeaders: readonly Header[] = Object.entries(request.headers ?? {}).map
(([name, value]) => ({ + name, + value: value?.toString(), + })); + + return [...configHeaders, ...requestHeaders]; +} diff --git a/lib/queries/languages/list-languages-query.ts b/lib/queries/languages/list-languages-query.ts new file mode 100644 index 00000000..d8b3f24b --- /dev/null +++ b/lib/queries/languages/list-languages-query.ts @@ -0,0 +1,36 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryMetadata, DeliveryPagedFetchQuery } from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { DeliveryRequestWithUrlPaging, SystemOrderQueryParam } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryPagedByUrlQuery } from "../delivery-queries.js"; +import type { LanguagePayload, ListLanguagesPayload } from "./models/language.models.js"; + +export type ListLanguagesResponse = DeliveryResponse< + ListLanguagesPayload, + DeliveryMetadata +>; + +export type ListLanguagesQuery = DeliveryPagedFetchQuery< + ListLanguagesResponse["payload"], + ListLanguagesResponse["meta"] +>; + +type SystemProperties = keyof LanguagePayload["system"]; + +export type ListLanguagesQueryRequest = DeliveryRequestWithUrlPaging< + SystemOrderQueryParam, + never, + readonly Filter[] +>; + +export function listLanguagesQuery( + config: DeliveryClientConfig, + request?: ListLanguagesQueryRequest, +): ListLanguagesQuery { + return createDeliveryPagedByUrlQuery({ + config, + request, + schema: async () => (await import("./schemas/language.schemas.js")).listLanguagesSchema(), + endpoint: "languages", + }); +} diff --git a/lib/queries/languages/models/language.models.ts b/lib/queries/languages/models/language.models.ts new file mode 100644 index 00000000..09af0a64 --- /dev/null +++ b/lib/queries/languages/models/language.models.ts @@ -0,0 +1,7 @@ +import type * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import type { languageSchema, listLanguagesSchema } from "../schemas/language.schemas.js"; + +export type LanguagePayload = z.infer>>; + +export type ListLanguagesPayload = z.infer>>; diff --git a/lib/queries/languages/schemas/language.schemas.ts b/lib/queries/languages/schemas/language.schemas.ts new file mode 100644 index 00000000..42c64320 --- /dev/null +++ b/lib/queries/languages/schemas/language.schemas.ts @@ -0,0 +1,25 @@ +import { codenameOf, kontentUuidSchema } from "@kontent-ai/core-sdk"; +import * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import { paginationSchema } from "../../../models/pagination.schemas.js"; + +export const languageSchema = () => + z.readonly( + z.object({ + system: z.readonly( + z.object({ + id: kontentUuidSchema, + name: z.string(), + codename: codenameOf(), + }), + ), + }), + ); + +export const listLanguagesSchema = () => + z.readonly( + z.object({ + languages: z.readonly(z.array(languageSchema())), + ...paginationSchema.shape, + }), + ); diff --git a/lib/queries/taxonomies/fetch-taxonomy-query.ts b/lib/queries/taxonomies/fetch-taxonomy-query.ts new file mode 100644 index 00000000..c1b584b7 --- /dev/null +++ b/lib/queries/taxonomies/fetch-taxonomy-query.ts @@ -0,0 +1,33 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryFetchQuery, DeliveryMetadata } from "../../models/core.models.js"; +import type { DeliveryRequestWithCodename } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryFetchQuery } from "../delivery-queries.js"; +import type { TaxonomyCodenameOf, TaxonomyPayload, TaxonomyTermCodenamesOf } from "./models/taxonomy.models.js"; + +export type FetchTaxonomyResponse< + TSchema extends DeliveryClientSchema = DeliveryClientSchema, + TCodename extends string = TaxonomyCodenameOf, +> = DeliveryResponse>, DeliveryMetadata>; + +export type FetchTaxonomyQuery< + TSchema extends DeliveryClientSchema, + TCodename extends string = TaxonomyCodenameOf, +> = DeliveryFetchQuery["payload"], FetchTaxonomyResponse["meta"]>; + +export type FetchTaxonomyQueryRequest< + TSchema extends DeliveryClientSchema, + TCodename extends TaxonomyCodenameOf = TaxonomyCodenameOf, +> = DeliveryRequestWithCodename; + +export function fetchTaxonomyQuery>( + config: DeliveryClientConfig, + request: FetchTaxonomyQueryRequest, +): FetchTaxonomyQuery { + return createDeliveryFetchQuery({ + config, + request, + schema: async () => + (await import("./schemas/taxonomy.schemas.js")).taxonomySchema>(), + endpoint: `taxonomies/${encodeURIComponent(request.codename)}`, + }); +} diff --git a/lib/queries/taxonomies/list-taxonomies-query.ts b/lib/queries/taxonomies/list-taxonomies-query.ts new file mode 100644 index 00000000..2a00bea1 --- /dev/null +++ b/lib/queries/taxonomies/list-taxonomies-query.ts @@ -0,0 +1,36 @@ +import type { DeliveryClientConfig, DeliveryClientSchema, DeliveryMetadata, DeliveryPagedFetchQuery } from "../../models/core.models.js"; +import type { Filter } from "../../models/filter.models.js"; +import type { DeliveryRequestWithUrlPaging, SystemOrderQueryParam } from "../../models/request.models.js"; +import type { DeliveryResponse } from "../../models/response.models.js"; +import { createDeliveryPagedByUrlQuery } from "../delivery-queries.js"; +import type { ListTaxonomiesPayload, TaxonomyPayload } from "./models/taxonomy.models.js"; + +export type ListTaxonomiesResponse = DeliveryResponse< + ListTaxonomiesPayload, + DeliveryMetadata +>; + +export type ListTaxonomiesQuery = DeliveryPagedFetchQuery< + ListTaxonomiesResponse["payload"], + ListTaxonomiesResponse["meta"] +>; + +type SystemProperties = keyof TaxonomyPayload["system"]; + +export type ListTaxonomiesQueryRequest = DeliveryRequestWithUrlPaging< + SystemOrderQueryParam, + never, + readonly Filter[] +>; + +export function listTaxonomiesQuery( + config: DeliveryClientConfig, + request?: ListTaxonomiesQueryRequest, +): ListTaxonomiesQuery { + return createDeliveryPagedByUrlQuery({ + config, + request, + schema: async () => (await import("./schemas/taxonomy.schemas.js")).listTaxonomiesSchema(), + endpoint: "taxonomies", + }); +} diff --git a/lib/queries/taxonomies/models/taxonomy.models.ts b/lib/queries/taxonomies/models/taxonomy.models.ts new file mode 100644 index 00000000..454d3b39 --- /dev/null +++ b/lib/queries/taxonomies/models/taxonomy.models.ts @@ -0,0 +1,33 @@ +import type * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import type { listTaxonomiesSchema, taxonomySchema, taxonomyTermSchema } from "../schemas/taxonomy.schemas.js"; + +export type TaxonomyTermPayload = z.infer>>; + +export type TaxonomyPayload = z.infer< + ReturnType> +>; + +export type ListTaxonomiesPayload = z.infer< + ReturnType> +>; + +/** + * The taxonomy codenames declared in the schema (the keys of the `taxonomies` map). + * Narrows to a literal union for a concrete schema, falling back to `string` for the generic default. + */ +export type TaxonomyCodenameOf = keyof TSchema["taxonomies"] & string; + +/** + * The term codenames belonging to the taxonomy identified by `TCodename`, derived from the schema's + * `taxonomies` map. Covers every nesting depth (the term tree shares one flat codename union). + * Falls back to `string` when the codename is unknown or the schema is the generic default. + */ +export type TaxonomyTermCodenamesOf< + TSchema extends DeliveryClientSchema, + TCodename extends string, +> = TCodename extends keyof TSchema["taxonomies"] + ? [Extract[number], string>] extends [never] + ? string + : Extract[number], string> + : string; diff --git a/lib/queries/taxonomies/schemas/taxonomy.schemas.ts b/lib/queries/taxonomies/schemas/taxonomy.schemas.ts new file mode 100644 index 00000000..85595144 --- /dev/null +++ b/lib/queries/taxonomies/schemas/taxonomy.schemas.ts @@ -0,0 +1,51 @@ +import { codenameOf, kontentUuidSchema } from "@kontent-ai/core-sdk"; +import * as z from "zod/mini"; +import type { DeliveryClientSchema } from "../../../models/core.models.js"; +import { paginationSchema } from "../../../models/pagination.schemas.js"; +import type { TaxonomyCodenameOf } from "../models/taxonomy.models.js"; + +/** + * Output shape of {@link taxonomyTermSchema}. Hand-written purely because a *recursive* Zod schema + * cannot be wrapped in `z.readonly()` while staying inferrable — `z.readonly`'s `[P in keyof T]` + * mapped type circularly references the recursive `terms` getter. Annotating the schema's return type + * breaks that cycle; this annotation is the source of truth for the deeply-readonly recursive term tree. + */ +export type TaxonomyTermShape = { + readonly name: string; + readonly codename: TTermCodenames; + readonly terms: readonly TaxonomyTermShape[]; +}; + +export const taxonomyTermSchema = (): z.ZodMiniType> => + z.readonly( + z.object({ + name: z.string(), + codename: codenameOf(), + get terms() { + return z.readonly(z.array(taxonomyTermSchema())); + }, + }), + ); + +export const taxonomySchema = () => + z.readonly( + z.object({ + system: z.readonly( + z.object({ + id: kontentUuidSchema, + name: z.string(), + codename: codenameOf>(), + last_modified: z.iso.datetime(), + }), + ), + terms: z.readonly(z.array(taxonomyTermSchema())), + }), + ); + +export const listTaxonomiesSchema = () => + z.readonly( + z.object({ + taxonomies: z.readonly(z.array(taxonomySchema())), + ...paginationSchema.shape, + }), + ); diff --git a/lib/query/common/base-item-listing-query.class.ts b/lib/query/common/base-item-listing-query.class.ts deleted file mode 100644 index be9fcdde..00000000 --- a/lib/query/common/base-item-listing-query.class.ts +++ /dev/null @@ -1,274 +0,0 @@ -import { ElementType, Elements } from '../../elements'; -import { IDeliveryClientConfig } from '../../config'; -import { - ClientTypes, - Filters, - IContentItem, - IKontentListAllResponse, - IKontentListResponse, - IQueryConfig, - Parameters, - SortOrder -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseListingQuery } from './base-listing-query.class'; - -export abstract class BaseItemListingQuery< - TClientTypes extends ClientTypes, - TResponse extends IKontentListResponse, - TAllResponse extends IKontentListAllResponse, - TQueryConfig extends IQueryConfig, - TContract -> extends BaseListingQuery { - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Empty filter condition - * @param element Element with empty value - */ - emptyFilter(element: string): this { - this.parameters.push(new Filters.EmptyFilter(element)); - return this; - } - - /** - * Not empty filter condition - * @param element Element with non-empty value - */ - notEmptyFilter(element: string): this { - this.parameters.push(new Filters.NotEmptyFilter(element)); - return this; - } - - /** - * Equals filter condition - * @param element Element to filter. Example: 'elements.movie' - * @param value Value to match. Example: 'Kingsman' - */ - equalsFilter(element: string, value: string): this { - this.parameters.push(new Filters.EqualsFilter(element, value)); - return this; - } - - /** - * Not equals filter condition - * @param element Element to filter. Example: 'elements.movie' - * @param value Value to match. Example: 'Kingsman' - */ - notEqualsFilter(element: string, value: string): this { - this.parameters.push(new Filters.NotEqualsFilter(element, value)); - return this; - } - - /** - * All filter - * @param element Element to filter. - * @param values Values - */ - allFilter(element: string, values: string[]): this { - this.parameters.push(new Filters.AllFilter(element, values)); - return this; - } - - /** - * Any filter - * @param element Element to filter. - * @param values Values - */ - anyFilter(element: string, values: string[]): this { - this.parameters.push(new Filters.AnyFilter(element, values)); - return this; - } - - /** - * Contains filter - * @param element Element to filter. - * @param values Values - */ - containsFilter(element: string, values: string[]): this { - this.parameters.push(new Filters.ContainsFilter(element, values)); - return this; - } - - /** - * Greater then filter - * @param element Element to filter. - * @param value Value - */ - greaterThanFilter(element: string, value: string | number): this { - this.parameters.push(new Filters.GreaterThanFilter(element, value)); - return this; - } - - /** - * Greater then or equals filter - * @param element Element to filter. - * @param value Value - */ - greaterThanOrEqualFilter(element: string, value: string | number): this { - this.parameters.push(new Filters.GreaterThanOrEqualFilter(element, value)); - return this; - } - - /** - * In filter - * @param element Element to filter. - * @param values Values - */ - inFilter(element: string, values: string[]): this { - this.parameters.push(new Filters.InFilter(element, values)); - return this; - } - - /** - * Not in filter - * @param element Element to filter. - * @param values Values - */ - notInFilter(element: string, values: string[]): this { - this.parameters.push(new Filters.NotInFilter(element, values)); - return this; - } - - /** - * Less then filter - * @param element Element to filter. - * @param value Value - */ - lessThanFilter(element: string, value: string | number): this { - this.parameters.push(new Filters.LessThanFilter(element, value)); - return this; - } - - /** - * @param element Element to filter. - * @param value Value - */ - lessThanOrEqualFilter(element: string, value: string | number): this { - this.parameters.push(new Filters.LessThanOrEqualFilter(element, value)); - return this; - } - - /** - * @param element Element to filter. - * @param lowerValue Lower value of range (e.g. 2) - * @param higherValue Higher value of range (e.g. 10) - */ - rangeFilter(element: string, lowerValue: number | string, higherValue: number | string): this { - this.parameters.push(new Filters.RangeFilter(element, lowerValue, higherValue)); - return this; - } - - /** - * Limits the number of items returned by query - * @param limit Number of items to load - */ - limitParameter(limit: number): this { - this.parameters.push(new Parameters.LimitParameter(limit)); - return this; - } - - /** - * Orders query based on given element and sort order - * @param element Element by which to order - * @param sortOrder Asc/Desc order type - */ - orderParameter(element: string, sortOrder: SortOrder): this { - this.parameters.push(new Parameters.OrderParameter(element, sortOrder)); - return this; - } - - /** - * Sets descending order on given element - * @param element Element by which to order - */ - orderByDescending(element: string): this { - this.parameters.push(new Parameters.OrderParameter(element, 'desc')); - return this; - } - - /** - * Sets Ascending order on given element - * @param element Element by which to order - */ - orderByAscending(element: string): this { - this.parameters.push(new Parameters.OrderParameter(element, 'asc')); - return this; - } - - /** - * Skips the selected number of items - * @param skip Number of items to skip - */ - skipParameter(skip: number): this { - this.parameters.push(new Parameters.SkipParameter(skip)); - return this; - } - - protected linkItemsInRte(allContentItems: IContentItem[]): void { - for (const item of allContentItems) { - for (const elementKey of Object.keys(item.elements)) { - const element = item.elements[elementKey]; - - if (element.type === ElementType.ModularContent) { - const linkedItemElement = element as Elements.LinkedItemsElement; - - // We create separate array for ordered items because the 'linkedItems' from response might be incomplete - // e.g. If 4 items are linked, only 2 might be available in the response. Rest needs to be mapped from all available items - const orderedLinkedItems: IContentItem[] = []; - - for (const linkedItemCodename of linkedItemElement.value) { - let linkedItem: IContentItem | undefined; - - const linkedItemInElement = linkedItemElement.linkedItems.find( - (m) => m.system.codename.toLowerCase() === linkedItemCodename.toLowerCase() - ); - if (linkedItemInElement) { - linkedItem = linkedItemInElement; - } else { - linkedItem = allContentItems.find( - (m) => m.system.codename.toLowerCase() === linkedItemCodename.toLowerCase() - ); - } - - if (linkedItem) { - orderedLinkedItems.push(linkedItem); - } - } - - // Replace linked items with the ordered one - linkedItemElement.linkedItems = orderedLinkedItems; - } - - if (element.type === ElementType.RichText) { - const orderedLinkedItems: IContentItem[] = []; - - const richTextElement = element as Elements.RichTextElement; - - for (const linkedItemCodename of richTextElement.linkedItemCodenames) { - let linkedItem: IContentItem | undefined; - - const linkedItemInElement = richTextElement.linkedItems.find( - (m) => m.system.codename.toLowerCase() === linkedItemCodename.toLowerCase() - ); - if (linkedItemInElement) { - linkedItem = linkedItemInElement; - } else { - linkedItem = allContentItems.find( - (m) => m.system.codename.toLowerCase() === linkedItemCodename.toLowerCase() - ); - } - - if (linkedItem) { - orderedLinkedItems.push(linkedItem); - } - } - - richTextElement.linkedItems = orderedLinkedItems; - } - } - } - } -} diff --git a/lib/query/common/base-listing-query.class.ts b/lib/query/common/base-listing-query.class.ts deleted file mode 100644 index 61455149..00000000 --- a/lib/query/common/base-listing-query.class.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { IDeliveryClientConfig } from '../../config'; -import { - continuationTokenHeaderName, - IGroupedNetworkResponse, - IKontentListAllResponse, - IKontentListResponse, - IDeliveryNetworkResponse, - IListAllQueryConfig, - IQueryConfig, - IContentItem, - ClientTypes, - IUsedInItemRecord, - IContentType, - ITaxonomyGroup, - IContentItemDelta, - ILanguage -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseQuery } from './base-query.class'; - -type ListingRecord = - | IContentItem - | IContentItemDelta - | IUsedInItemRecord - | IContentType - | ILanguage - | ITaxonomyGroup; - -export abstract class BaseListingQuery< - TClientTypes extends ClientTypes, - TRecord extends ListingRecord, - TResponse extends IKontentListResponse, - TAllResponse extends IKontentListAllResponse, - TQueryConfig extends IQueryConfig, - TContract -> extends BaseQuery { - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Sets continuation token header - */ - withContinuationToken(token: string): this { - // remove previous continuation token if there is any - let queryHeaders = this._queryConfig.customHeaders ?? []; - queryHeaders = queryHeaders.filter((m) => m.header !== continuationTokenHeaderName); - - this._queryConfig.customHeaders = queryHeaders; - - this.withHeaders([ - { - header: continuationTokenHeaderName, - value: token - } - ]); - - return this; - } - - /** - * Query to get all items. Uses paging data and may execute multiple HTTP requests depending on number of items - */ - toAllPromise( - queryAllConfig?: IListAllQueryConfig - ): Promise> { - return this.queryService.getListAllResponse({ - page: 1, - listQueryConfig: queryAllConfig, - allResponseFactory: (items, responses) => { - const response = this.allResponseFactory(items, responses); - - return { - data: response, - responses: responses - }; - }, - getResponse: (nextPageUrl, continuationToken) => { - if (nextPageUrl) { - this.withCustomUrl(nextPageUrl); - } - if (continuationToken) { - this.withContinuationToken(continuationToken); - } - - return this.toPromise(); - } - }); - } - - protected abstract allResponseFactory( - items: TRecord[], - responses: IDeliveryNetworkResponse[] - ): TAllResponse; -} diff --git a/lib/query/common/base-query.class.ts b/lib/query/common/base-query.class.ts deleted file mode 100644 index a435182b..00000000 --- a/lib/query/common/base-query.class.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { IHeader, IQueryParameter } from '@kontent-ai/core-sdk'; - -import { IDeliveryClientConfig } from '../../config'; -import { - ClientTypes, - Filters, - IDeliveryNetworkResponse, - IKontentResponse, - IQueryConfig, - Parameters -} from '../../models'; -import { QueryService } from '../../services'; - -export abstract class BaseQuery< - TClientTypes extends ClientTypes, - TResponse extends IKontentResponse, - TQueryConfig extends IQueryConfig, - TContract -> { - protected parameters: IQueryParameter[] = []; - protected customUrl?: string; - protected abstract _queryConfig: TQueryConfig; - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) {} - - /** - * Gets URL of the query - */ - abstract getUrl(): string; - - /** - * Gets promise for query execution - */ - abstract toPromise(): Promise>; - - /** - * Maps json data to response - */ - abstract map(json: any): TResponse; - - /** - * Adds custom parameter to query - * @param name Name of parameter - * @param value Value of parameter - */ - withCustomParameter(name: string, value: string): this { - this.parameters.push(new Parameters.QueryParameter(name, value)); - return this; - } - - /** - * Adds parameter to query - * @param name Name of parameter - * @param value Value of parameter - */ - withParameter(parameter: IQueryParameter): this { - this.parameters.push(parameter); - return this; - } - - /** - * Adds parameters to query - * @param parameters Array of parameters - */ - withParameters(parameters: IQueryParameter[]): this { - this.parameters.push(...parameters); - return this; - } - - /** - * Gets headers used by this query - */ - getHeaders(): IHeader[] { - return this.queryService.getHeaders(this._queryConfig, []); - } - - /** - * Sets request headers - */ - withHeaders(headers: IHeader[]): this { - const queryHeaders = this._queryConfig.customHeaders ?? []; - queryHeaders.push(...headers); - this._queryConfig.customHeaders = queryHeaders; - return this; - } - - /** - * Sets request header - */ - withHeader(header: IHeader): this { - const queryHeaders = this._queryConfig.customHeaders ?? []; - queryHeaders.push(header); - this._queryConfig.customHeaders = queryHeaders; - return this; - } - - /** - * Sets custom URL of request (overrides default URL of the query) - */ - withCustomUrl(url: string): this { - this.customUrl = url; - return this; - } - - /** - * Gets all query parameter currently applied to query - */ - getParameters(): IQueryParameter[] { - return this.parameters; - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: TQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - protected resolveUrlInternal(action: string): string { - // use custom URL if user specified it - if (this.customUrl) { - return this.customUrl; - } - - // use original url - return this.queryService.getUrl(action, this._queryConfig ?? {}, this.getParameters()); - } - - protected processDefaultLanguageParameter(): void { - // add default language if none is specified && default language is specified globally - if (this.config.defaultLanguage) { - const languageParameter = this.getParameters().find((m) => - m.getParam()?.toLowerCase().includes('language='.toLowerCase()) - ); - if (!languageParameter) { - // language parameter was not specified in query, use globally defined language - this.parameters.push(new Parameters.LanguageParameter(this.config.defaultLanguage)); - } - } - } - - protected processExcludeArchivedItemsParameter(): void { - if (this.config.excludeArchivedItems) { - this.parameters.push(new Filters.NotEqualsFilter('system.workflow_step', 'archived')); - } - } -} diff --git a/lib/query/element/element-query.class.ts b/lib/query/element/element-query.class.ts deleted file mode 100644 index a67d05b7..00000000 --- a/lib/query/element/element-query.class.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { Responses, IElementQueryConfig, IDeliveryNetworkResponse, ClientTypes } from '../../models'; -import { QueryService } from '../../services'; -import { BaseQuery } from '../common/base-query.class'; - -export class ElementQuery extends BaseQuery< - TClientTypes, - Responses.IViewContentTypeElementResponse, - IElementQueryConfig, - Contracts.IViewContentTypeElementContract -> { - protected _queryConfig: IElementQueryConfig = {}; - - constructor( - protected config: IDeliveryClientConfig, - protected queryService: QueryService, - private typeCodename: string, - private elementCodename: string - ) { - super(config, queryService); - - if (!typeCodename) { - throw Error(`Codename of the type has to be provided`); - } - - if (!elementCodename) { - throw Error(`Codename of the element has to be provided`); - } - } - - toPromise(): Promise< - IDeliveryNetworkResponse - > { - return this.queryService.getElementAsync(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - return super.resolveUrlInternal(`/types/${this.typeCodename}/elements/${this.elementCodename}`); - } - - map(json: any): Responses.IViewContentTypeElementResponse { - return this.queryService.mappingService.viewContentTypeElementResponse(json); - } -} diff --git a/lib/query/index.ts b/lib/query/index.ts deleted file mode 100644 index 7d64bea9..00000000 --- a/lib/query/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export * from './common/base-query.class'; -export * from './element/element-query.class'; -export * from './item/multiple-items-query.class'; -export * from './item/single-item-query.class'; -export * from './taxonomy/taxonomies-query.class'; -export * from './taxonomy/taxonomy-query.class'; -export * from './type/multiple-type-query.class'; -export * from './type/single-type-query.class'; -export * from './items-feed/items-feed-query.class'; -export * from './language/languages-query.class'; -export * from './sync/initialize-sync-query.class'; -export * from './sync/sync-changes-query.class'; -export * from './used-in/used-in-query.class'; diff --git a/lib/query/item/multiple-items-query.class.ts b/lib/query/item/multiple-items-query.class.ts deleted file mode 100644 index a5ad925d..00000000 --- a/lib/query/item/multiple-items-query.class.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - Filters, - IContentItem, - IItemQueryConfig, - IDeliveryNetworkResponse, - Responses, - Parameters, - ClientTypes -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseItemListingQuery } from '../common/base-item-listing-query.class'; - -export class MultipleItemsQuery< - TClientTypes extends ClientTypes, - TContentItem extends IContentItem = IContentItem -> extends BaseItemListingQuery< - TClientTypes, - Responses.IListContentItemsResponse, - Responses.IListContentItemsAllResponse, - IItemQueryConfig, - Contracts.IListContentItemsContract -> { - protected _queryConfig: IItemQueryConfig = {}; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Adds information about the total number of content items matching your query. - * When set to true, the pagination object returned in the API response contains - * an additional total_count property. - */ - includeTotalCountParameter(): this { - this.parameters.push(new Parameters.IncludeTotalCountParameter()); - return this; - } - - /** - * Gets only item of given type - * @param type Codename of type to get - */ - type(type: TClientTypes['contentTypeCodenames']): this { - this.parameters.push(new Filters.TypeFilter(type)); - return this; - } - - /** - * Gets items of given types (logical or) - * I.e. get items of either 'Actor' or 'Movie' type - * @param types Types to get - */ - types(types: TClientTypes['contentTypeCodenames'][]): this { - this.parameters.push(new Filters.TypeFilter(types)); - return this; - } - - /** - * Gets only item from given collection - * @param collection Codename of collection to get - */ - collection(collection: TClientTypes['collectionCodenames']): this { - this.parameters.push(new Filters.CollectionFilter(collection)); - return this; - } - - /** - * Gets items from given collections (logical or) - * I.e. get items of either 'default' or 'christmas-campaign' collection - * @param collections Collections to get - */ - collections(collections: TClientTypes['collectionCodenames'][]): this { - this.parameters.push(new Filters.CollectionFilter(collections)); - return this; - } - - /** - * Indicates depth of query that affects loading of nested linked items. - * @param depth Depth of the query (> 0) - */ - depthParameter(depth: number): this { - this.parameters.push(new Parameters.DepthParameter(depth)); - return this; - } - - /** - * Language codename - * @param languageCodename Codename of the language - */ - languageParameter(languageCodename: TClientTypes['languageCodenames']): this { - this.parameters.push(new Parameters.LanguageParameter(languageCodename)); - return this; - } - - /** - * Used to limit the number of elements returned by query. - * @param elementCodenames Array of element codenames to fetch - */ - elementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ElementsParameter(elementCodenames)); - return this; - } - - /** - * Used to exclude elements returned by query. - * @param elementCodenames Array of element codenames to exclude - */ - excludeElementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ExcludeElementsParameter(elementCodenames)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IListContentItemsResponse, - Contracts.IListContentItemsContract - > - > { - return this.queryService.getMultipleItems(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/items'; - - // handle default language - this.processDefaultLanguageParameter(); - - // handle archived items - this.processExcludeArchivedItemsParameter(); - - return super.resolveUrlInternal(action); - } - - map(json: any): Responses.IListContentItemsResponse { - return this.queryService.mappingService.listContentItemsResponse(json); - } - - protected allResponseFactory( - items: any[], - responses: IDeliveryNetworkResponse< - Responses.IListContentItemsResponse, - Contracts.IListContentItemsContract - >[] - ): Responses.IListContentItemsAllResponse { - this.linkItems(items, responses); - - return { - items: items, - responses: responses - }; - } - - private linkItems( - items: IContentItem[], - responses: IDeliveryNetworkResponse< - Responses.IListContentItemsResponse, - Contracts.IListContentItemsContract - >[] - ): void { - // prepare all available items (including components) for linking - const allContentItems: IContentItem[] = []; - - // process linked items (modular_content part of the response) - for (const response of responses) { - allContentItems.push( - ...Object.values(response.data.linkedItems) - .filter((m) => m !== undefined) - .map((m) => m as TClientTypes['contentItemType']) - ); - } - - // add standard items - for (const item of items) { - if (!allContentItems.find((m) => m.system.codename.toLowerCase() === item.system.codename.toLowerCase())) { - allContentItems.push(item); - } - } - // process main items - this.linkItemsInRte(allContentItems); - } -} diff --git a/lib/query/item/single-item-query.class.ts b/lib/query/item/single-item-query.class.ts deleted file mode 100644 index c00be6c2..00000000 --- a/lib/query/item/single-item-query.class.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - IContentItem, - IItemQueryConfig, - IDeliveryNetworkResponse, - Responses, - Parameters, - ClientTypes -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseQuery } from '../common/base-query.class'; - -export class SingleItemQuery< - TClientTypes extends ClientTypes, - TContentItem extends IContentItem = IContentItem -> extends BaseQuery< - TClientTypes, - Responses.IViewContentItemResponse, - IItemQueryConfig, - Contracts.IViewContentItemContract -> { - protected _queryConfig: IItemQueryConfig = {}; - - constructor( - protected config: IDeliveryClientConfig, - protected queryService: QueryService, - private codename: string - ) { - super(config, queryService); - - if (!codename) { - throw Error(`'codename' has to be configured for 'SingleItemQuery' query`); - } - } - - /** - * Indicates depth of query that affects loading of nested linked items. - * @param depth Depth of the query (> 0) - */ - depthParameter(depth: number): this { - this.parameters.push(new Parameters.DepthParameter(depth)); - return this; - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: IItemQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - /** - * Language codename - * @param languageCodename Codename of the language - */ - languageParameter(languageCodename: TClientTypes['languageCodenames']): this { - this.parameters.push(new Parameters.LanguageParameter(languageCodename)); - return this; - } - - /** - * Used to limit the number of elements returned by query. - * @param elementCodenames Array of element codenames to fetch - */ - elementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ElementsParameter(elementCodenames)); - return this; - } - - /** - * Used to exclude elements returned by query. - * @param elementCodenames Array of element codenames to exclude - */ - excludeElementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ExcludeElementsParameter(elementCodenames)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IViewContentItemResponse, - Contracts.IViewContentItemContract - > - > { - return this.queryService.getSingleItemAsync(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/items/' + this.codename; - - // add default language is necessry - this.processDefaultLanguageParameter(); - - //process client level archived item exclusion - this.processExcludeArchivedItemsParameter(); - - return super.resolveUrlInternal(action); - } - - map(json: any): Responses.IViewContentItemResponse { - return this.queryService.mappingService.viewContentItemResponse(json); - } -} diff --git a/lib/query/items-feed/items-feed-query.class.ts b/lib/query/items-feed/items-feed-query.class.ts deleted file mode 100644 index c0319611..00000000 --- a/lib/query/items-feed/items-feed-query.class.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - Filters, - IContentItem, - IDeliveryNetworkResponse, - Parameters, - Responses, - IItemFeedQueryConfig, - ClientTypes -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseItemListingQuery } from '../common/base-item-listing-query.class'; - -export class ItemsFeedQuery< - TClientTypes extends ClientTypes, - TContentItem extends IContentItem = IContentItem -> extends BaseItemListingQuery< - TClientTypes, - Responses.IListItemsFeedResponse, - Responses.IListItemsFeedAllResponse, - IItemFeedQueryConfig, - Contracts.IItemsFeedContract -> { - protected _queryConfig: IItemFeedQueryConfig = {}; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Gets only item of given type - * @param type Codename of type to get - */ - type(type: TClientTypes['contentTypeCodenames']): this { - this.parameters.push(new Filters.TypeFilter(type)); - return this; - } - - /** - * Gets items of given types (logical or) - * I.e. get items of either 'Actor' or 'Movie' type - * @param types Types to get - */ - types(types: TClientTypes['contentTypeCodenames'][]): this { - this.parameters.push(new Filters.TypeFilter(types)); - return this; - } - - /** - * Gets only item from given collection - * @param collection Codename of collection to get - */ - collection(collection: TClientTypes['collectionCodenames']): this { - this.parameters.push(new Filters.CollectionFilter(collection)); - return this; - } - - /** - * Gets items from given collections (logical or) - * I.e. get items of either 'default' or 'christmas-campaign' collection - * @param collections Collections to get - */ - collections(collections: TClientTypes['collectionCodenames'][]): this { - this.parameters.push(new Filters.CollectionFilter(collections)); - return this; - } - - /** - * Language codename - * @param languageCodename Codename of the language - */ - languageParameter(languageCodename: TClientTypes['languageCodenames']): this { - this.parameters.push(new Parameters.LanguageParameter(languageCodename)); - return this; - } - - /** - * Used to limit the number of elements returned by query. - * @param elementCodenames Array of element codenames to fetch - */ - elementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ElementsParameter(elementCodenames)); - return this; - } - - /** - * Used to exclude elements returned by query. - * @param elementCodenames Array of element codenames to exclude - */ - excludeElementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ExcludeElementsParameter(elementCodenames)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IListItemsFeedResponse, - Contracts.IItemsFeedContract - > - > { - return this.queryService.getItemsFeed(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/items-feed'; - - // add default language is necessary - this.processDefaultLanguageParameter(); - - //process client level archived item exclusion - this.processExcludeArchivedItemsParameter(); - - return super.resolveUrlInternal(action); - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: IItemFeedQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - map(json: any): Responses.IListItemsFeedResponse { - return this.queryService.mappingService.itemsFeedResponse(json); - } - - protected allResponseFactory( - items: TContentItem[], - responses: IDeliveryNetworkResponse< - Responses.IListItemsFeedResponse, - Contracts.IItemsFeedContract - >[] - ): Responses.IListItemsFeedAllResponse { - if (this.canLinkItems()) { - this.linkFeedItems(items, responses); - } - - return { - items: items, - responses: responses - }; - } - - private linkFeedItems( - items: TContentItem[], - responses: IDeliveryNetworkResponse< - Responses.IListItemsFeedResponse, - Contracts.IItemsFeedContract - >[] - ): void { - // prepare all available items (including components) for linking - const allAvailableContentItems: IContentItem[] = []; - - // process linked items (modular_content part of the response) - for (const response of responses) { - allAvailableContentItems.push( - ...Object.values(response.data.linkedItems) - .filter((m) => m !== undefined) - .map((m) => m as TClientTypes['contentItemType']) - ); - } - - // add standard items - for (const item of items) { - if ( - !allAvailableContentItems.find( - (m) => m.system.codename.toLowerCase() === item.system.codename.toLowerCase() - ) - ) { - allAvailableContentItems.push(item); - } - } - // process main items - this.linkItemsInRte(allAvailableContentItems); - } - - private canLinkItems(): boolean { - if (this.config.linkedItemsReferenceHandler === 'ignore') { - return false; - } - - if (this._queryConfig.disableItemLinking === true) { - return false; - } - - return true; - } -} diff --git a/lib/query/language/languages-query.class.ts b/lib/query/language/languages-query.class.ts deleted file mode 100644 index 99887ffa..00000000 --- a/lib/query/language/languages-query.class.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - ClientTypes, - IDeliveryNetworkResponse, - ILanguage, - ILanguagesQueryConfig, - Parameters, - Responses -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseListingQuery } from '../common/base-listing-query.class'; - -export class LanguagesQuery extends BaseListingQuery< - TClientTypes, - ILanguage, - Responses.IListLanguagesResponse, - Responses.IListLanguagesAllResponse, - ILanguagesQueryConfig, - Contracts.IListLanguagesContract -> { - /** - * Endpoint - */ - protected readonly endpoint: string = 'languages'; - - protected _queryConfig: ILanguagesQueryConfig = {}; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Limits the number of taxonomies returned by query - * @param limit Number of taxonomies to load - */ - limitParameter(limit: number): this { - this.parameters.push(new Parameters.LimitParameter(limit)); - return this; - } - - /** - * Skips the selected number of taxonomies - * @param skip Number of taxonomies to skip - */ - skipParameter(skip: number): this { - this.parameters.push(new Parameters.SkipParameter(skip)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IListLanguagesResponse, - Contracts.IListLanguagesContract - > - > { - return this.queryService.getLanguages(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/' + this.endpoint; - - return super.resolveUrlInternal(action); - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: ILanguagesQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - map(json: any): Responses.IListLanguagesResponse { - return this.queryService.mappingService.listLanguagesResponse(json); - } - - protected allResponseFactory( - items: ILanguage[], - responses: IDeliveryNetworkResponse< - Responses.IListLanguagesResponse, - Contracts.IListLanguagesContract - >[] - ): Responses.IListLanguagesAllResponse { - return { - items: items, - responses: responses - }; - } -} diff --git a/lib/query/sync/initialize-sync-query.class.ts b/lib/query/sync/initialize-sync-query.class.ts deleted file mode 100644 index d704b31a..00000000 --- a/lib/query/sync/initialize-sync-query.class.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - ClientTypes, - Filters, - IDeliveryNetworkResponse, - ILanguagesQueryConfig, - ISyncInitQueryConfig, - Parameters, - Responses -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseQuery } from '../common/base-query.class'; - -export class InitializeSyncQuery extends BaseQuery< - TClientTypes, - Responses.IInitializeSyncResponse, - ISyncInitQueryConfig, - Contracts.IInitializeSyncContract -> { - protected readonly endpoint: string = 'sync/init'; - - protected _queryConfig: ILanguagesQueryConfig = {}; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Gets only item of given type - * @param type Codename of type to get - */ - type(type: string): this { - this.parameters.push(new Filters.TypeFilter(type)); - return this; - } - - /** - * Gets only item from given collection - * @param collection Codename of collection to get - */ - collection(collection: string): this { - this.parameters.push(new Filters.CollectionFilter(collection)); - return this; - } - - /** - * Language codename - * @param languageCodename Codename of the language - */ - languageParameter(languageCodename: string): this { - this.parameters.push(new Parameters.LanguageParameter(languageCodename)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse - > { - console.warn( - `Sync Api v1 is deprecated. Please use the new Sync Api v2. https://kontent.ai/learn/docs/apis/openapi/sync-api-v2/` - ); - return this.queryService.initializeSync(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/' + this.endpoint; - - return super.resolveUrlInternal(action); - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: ISyncInitQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - map(json: any): Responses.IInitializeSyncResponse { - return this.queryService.mappingService.initializeContentSync(json); - } -} diff --git a/lib/query/sync/sync-changes-query.class.ts b/lib/query/sync/sync-changes-query.class.ts deleted file mode 100644 index 17356850..00000000 --- a/lib/query/sync/sync-changes-query.class.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { IItemQueryConfig, IDeliveryNetworkResponse, Responses, ClientTypes, IContentItemDelta } from '../../models'; -import { QueryService } from '../../services'; -import { BaseListingQuery } from '../common/base-listing-query.class'; - -export class SyncChangesQuery extends BaseListingQuery< - TClientTypes, - IContentItemDelta, - Responses.ISyncChangesResponse, - Responses.ISyncChangesAllResponse, - IItemQueryConfig, - Contracts.ISyncChangesContract -> { - protected _queryConfig: IItemQueryConfig = {}; - - private readonly action: string = '/sync'; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - toPromise(): Promise> { - console.warn( - `Sync Api v1 is deprecated. Please use the new Sync Api v2. https://kontent.ai/learn/docs/apis/openapi/sync-api-v2/` - ); - return this.queryService.syncChanges(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - return super.resolveUrlInternal(this.action); - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: IItemQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - map(json: any): Responses.ISyncChangesResponse { - return this.queryService.mappingService.syncChanges(json); - } - - protected allResponseFactory( - items: IContentItemDelta[], - responses: IDeliveryNetworkResponse[] - ): Responses.ISyncChangesAllResponse { - return { - items: items, - responses: responses - }; - } -} diff --git a/lib/query/taxonomy/taxonomies-query.class.ts b/lib/query/taxonomy/taxonomies-query.class.ts deleted file mode 100644 index 346af79b..00000000 --- a/lib/query/taxonomy/taxonomies-query.class.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - ClientTypes, - IDeliveryNetworkResponse, - ITaxonomyGroup, - ITaxonomyQueryConfig, - Parameters, - Responses -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseListingQuery } from '../common/base-listing-query.class'; - -export class TaxonomiesQuery extends BaseListingQuery< - TClientTypes, - ITaxonomyGroup, - Responses.IListTaxonomiesResponse, - Responses.IListTaxonomiesAllResponse, - ITaxonomyQueryConfig, - Contracts.IListTaxonomyGroupsContract -> { - /** - * Taxonomies endpoint URL action - */ - protected readonly taxonomiesEndpoint: string = 'taxonomies'; - - protected _queryConfig: ITaxonomyQueryConfig = {}; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Limits the number of taxonomies returned by query - * @param limit Number of taxonomies to load - */ - limitParameter(limit: number): this { - this.parameters.push(new Parameters.LimitParameter(limit)); - return this; - } - - /** - * Skips the selected number of taxonomies - * @param skip Number of taxonomies to skip - */ - skipParameter(skip: number): this { - this.parameters.push(new Parameters.SkipParameter(skip)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IListTaxonomiesResponse, - Contracts.IListTaxonomyGroupsContract - > - > { - return this.queryService.getTaxonomies(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/' + this.taxonomiesEndpoint; - - return super.resolveUrlInternal(action); - } - - map(json: any): Responses.IListTaxonomiesResponse { - return this.queryService.mappingService.listTaxonomiesResponse(json); - } - - protected allResponseFactory( - items: ITaxonomyGroup[], - responses: IDeliveryNetworkResponse< - Responses.IListTaxonomiesResponse, - Contracts.IListTaxonomyGroupsContract - >[] - ): Responses.IListTaxonomiesAllResponse { - return { - items: items, - responses: responses - }; - } -} diff --git a/lib/query/taxonomy/taxonomy-query.class.ts b/lib/query/taxonomy/taxonomy-query.class.ts deleted file mode 100644 index 4cac7fa6..00000000 --- a/lib/query/taxonomy/taxonomy-query.class.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { ClientTypes, IDeliveryNetworkResponse, ITaxonomyQueryConfig, Responses } from '../../models'; -import { QueryService } from '../../services'; -import { BaseQuery } from '../common/base-query.class'; - -export class TaxonomyQuery extends BaseQuery< - TClientTypes, - Responses.IViewTaxonomyResponse, - ITaxonomyQueryConfig, - Contracts.IViewTaxonomyGroupContract -> { - /** - * Taxonomies endpoint URL action - */ - protected readonly taxonomiesEndpoint: string = 'taxonomies'; - - protected _queryConfig: ITaxonomyQueryConfig = {}; - - constructor( - protected config: IDeliveryClientConfig, - protected queryService: QueryService, - private taxonomyCodename: string - ) { - super(config, queryService); - - if (!taxonomyCodename) { - throw Error(`Cannot create taxonomy query without codename of the taxonomy`); - } - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IViewTaxonomyResponse, - Contracts.IViewTaxonomyGroupContract - > - > { - return this.queryService.getTaxonomy(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/' + this.taxonomiesEndpoint + '/' + this.taxonomyCodename; - - return super.resolveUrlInternal(action); - } - - map(json: any): Responses.IViewTaxonomyResponse { - return this.queryService.mappingService.viewTaxonomyResponse(json); - } -} diff --git a/lib/query/type/multiple-type-query.class.ts b/lib/query/type/multiple-type-query.class.ts deleted file mode 100644 index ad8a4828..00000000 --- a/lib/query/type/multiple-type-query.class.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - ClientTypes, - IContentType, - IContentTypeQueryConfig, - IDeliveryNetworkResponse, - Parameters, - Responses -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseListingQuery } from '../common/base-listing-query.class'; - -export class MultipleTypeQuery extends BaseListingQuery< - TClientTypes, - IContentType, - Responses.IListContentTypesResponse, - Responses.IListContentTypesAllResponse, - IContentTypeQueryConfig, - Contracts.IListContentTypeContract -> { - protected _queryConfig: IContentTypeQueryConfig = {}; - - constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService) { - super(config, queryService); - } - - /** - * Used to limit the number of elements returned by query. - * @param elementCodenames Array of element codenames to fetch - */ - elementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ElementsParameter(elementCodenames)); - return this; - } - - /** - * Used to exclude elements returned by query. - * @param elementCodenames Array of element codenames to exclude - */ - excludeElementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this { - this.parameters.push(new Parameters.ExcludeElementsParameter(elementCodenames)); - return this; - } - - /** - * Limits the number of taxonomies returned by query - * @param limit Number of taxonomies to load - */ - limitParameter(limit: number): this { - this.parameters.push(new Parameters.LimitParameter(limit)); - return this; - } - - /** - * Skips the selected number of taxonomies - * @param skip Number of taxonomies to skip - */ - skipParameter(skip: number): this { - this.parameters.push(new Parameters.SkipParameter(skip)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IListContentTypesResponse, - Contracts.IListContentTypeContract - > - > { - return this.queryService.getMultipleTypes(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/types'; - - return super.resolveUrlInternal(action); - } - - map(json: any): Responses.IListContentTypesResponse { - return this.queryService.mappingService.listContentTypesResponse(json); - } - - protected allResponseFactory( - items: IContentType[], - responses: IDeliveryNetworkResponse< - Responses.IListContentTypesResponse, - Contracts.IListContentTypeContract - >[] - ): Responses.IListContentTypesAllResponse { - return { - items: items, - responses: responses - }; - } -} diff --git a/lib/query/type/single-type-query.class.ts b/lib/query/type/single-type-query.class.ts deleted file mode 100644 index 8f3e685c..00000000 --- a/lib/query/type/single-type-query.class.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { ClientTypes, IContentTypeQueryConfig, IDeliveryNetworkResponse, Responses } from '../../models'; -import { QueryService } from '../../services'; -import { BaseQuery } from '../common/base-query.class'; - -export class SingleTypeQuery extends BaseQuery< - TClientTypes, - Responses.IViewContentTypeResponse, - IContentTypeQueryConfig, - Contracts.IViewContentTypeContract -> { - protected _queryConfig: IContentTypeQueryConfig = {}; - - constructor( - protected config: IDeliveryClientConfig, - protected queryService: QueryService, - private typeCodename: string - ) { - super(config, queryService); - - if (!typeCodename) { - throw Error(`Cannot create type query without the codename of the type`); - } - } - - toPromise(): Promise< - IDeliveryNetworkResponse< - Responses.IViewContentTypeResponse, - Contracts.IViewContentTypeContract - > - > { - return this.queryService.getSingleType(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = '/types/' + this.typeCodename; - - return super.resolveUrlInternal(action); - } - - map(json: any): Responses.IViewContentTypeResponse { - return this.queryService.mappingService.viewContentTypeResponse(json); - } -} diff --git a/lib/query/used-in/used-in-query.class.ts b/lib/query/used-in/used-in-query.class.ts deleted file mode 100644 index 0f8390de..00000000 --- a/lib/query/used-in/used-in-query.class.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Contracts } from '../../contracts'; -import { IDeliveryClientConfig } from '../../config'; -import { - Filters, - IDeliveryNetworkResponse, - Parameters, - Responses, - IItemFeedQueryConfig, - ClientTypes, - IUsedInItemRecord, - IQueryConfig -} from '../../models'; -import { QueryService } from '../../services'; -import { BaseListingQuery } from '../common/base-listing-query.class'; - -export type UsedInSetup = { - readonly entity: 'asset' | 'contentItem'; - readonly codename: string; -}; - -export class UsedInQuery extends BaseListingQuery< - TClientTypes, - IUsedInItemRecord, - Responses.IUsedInResponse, - Responses.IUsedInAllResponse, - IQueryConfig, - Contracts.IUsedInItemsContract -> { - protected _queryConfig: IQueryConfig = {}; - - constructor( - protected readonly config: IDeliveryClientConfig, - protected readonly queryService: QueryService, - protected readonly setup: UsedInSetup - ) { - super(config, queryService); - } - - /** - * Gets only item of given type - * @param type Codename of type to get - */ - type(type: TClientTypes['contentTypeCodenames']): this { - this.parameters.push(new Filters.TypeFilter(type)); - return this; - } - - /** - * Gets items of given types (logical or) - * I.e. get items of either 'Actor' or 'Movie' type - * @param types Types to get - */ - types(types: TClientTypes['contentTypeCodenames'][]): this { - this.parameters.push(new Filters.TypeFilter(types)); - return this; - } - - /** - * Gets only item from given collection - * @param collection Codename of collection to get - */ - collection(collection: TClientTypes['collectionCodenames']): this { - this.parameters.push(new Filters.CollectionFilter(collection)); - return this; - } - - /** - * Gets items from given collections (logical or) - * I.e. get items of either 'default' or 'christmas-campaign' collection - * @param collections Collections to get - */ - collections(collections: TClientTypes['collectionCodenames'][]): this { - this.parameters.push(new Filters.CollectionFilter(collections)); - return this; - } - - /** - * Language codename - * @param languageCodename Codename of the language - */ - languageParameter(languageCodename: TClientTypes['languageCodenames']): this { - this.parameters.push(new Parameters.LanguageParameter(languageCodename)); - return this; - } - - toPromise(): Promise< - IDeliveryNetworkResponse, Contracts.IUsedInItemsContract> - > { - return this.queryService.getUsedIn(this.getUrl(), this._queryConfig ?? {}); - } - - getUrl(): string { - const action = `/${this.setup.entity === 'asset' ? 'assets' : 'items'}/${this.setup.codename}/used-in`; - - // add default language is necessary - this.processDefaultLanguageParameter(); - - //process client level archived item exclusion - this.processExcludeArchivedItemsParameter(); - - return super.resolveUrlInternal(action); - } - - /** - * Used to configure query - * @param queryConfig Query configuration - */ - queryConfig(queryConfig: IItemFeedQueryConfig): this { - this._queryConfig = queryConfig; - return this; - } - - map(json: any): Responses.IUsedInResponse { - return this.queryService.mappingService.usedInResponse(json); - } - - protected allResponseFactory( - items: IUsedInItemRecord[], - responses: IDeliveryNetworkResponse, Contracts.IUsedInItemsContract>[] - ): Responses.IUsedInAllResponse { - return { - items: items, - responses: responses - }; - } -} diff --git a/lib/sdk-info.generated.ts b/lib/sdk-info.generated.ts deleted file mode 100644 index 69d07da7..00000000 --- a/lib/sdk-info.generated.ts +++ /dev/null @@ -1,7 +0,0 @@ - -import { ISDKInfo } from '@kontent-ai/core-sdk'; -export const sdkInfo: ISDKInfo = { - host: 'npmjs.com', - version: '16.4.0', - name: '@kontent-ai/delivery-sdk' -}; diff --git a/lib/services/base-delivery-query.service.ts b/lib/services/base-delivery-query.service.ts deleted file mode 100644 index 25e2c4ca..00000000 --- a/lib/services/base-delivery-query.service.ts +++ /dev/null @@ -1,375 +0,0 @@ -import { IResponse, IHeader, IHttpService, IQueryParameter, urlHelper } from '@kontent-ai/core-sdk'; -import { AxiosError } from 'axios'; -import { - waitForLoadingNewContentHeader, - IQueryConfig, - ISDKInfo, - IDeliveryErrorRaw, - DeliveryError, - sdkVersionHeader, - staleContentHeaderName, - continuationTokenHeaderName, - IDeliveryNetworkResponse, - ClientTypes -} from '../models'; - -import { IDeliveryClientConfig } from '../config'; -import { IMappingService } from './mapping.service'; - -export abstract class BaseDeliveryQueryService { - /** - * Default base Url to Kontent.ai Delivery API - */ - private readonly defaultBaseDeliveryApiUrl: string = 'https://deliver.kontent.ai'; - - /** - * Default preview url to Kontent.ai Delivery API - */ - private readonly defaultPreviewDeliveryApiUrl: string = 'https://preview-deliver.kontent.ai'; - - constructor( - /** - * Delivery client configuration - */ - public readonly config: IDeliveryClientConfig, - /** - * Http service for fetching data - */ - public readonly httpService: IHttpService, - /** - * Information about the SDK - */ - public readonly sdkInfo: ISDKInfo, - /** - * Mapping service - */ - public readonly mappingService: IMappingService - ) {} - - /** - * Gets url based on the action, query configuration and options (parameters) - * @param action Action (= url part) that will be hit - * @param queryConfig Query configuration - * @param options Query options - */ - getUrl(action: string, queryConfig: IQueryConfig, options?: IQueryParameter[]): string { - if (!this.config.proxy || !this.config.proxy.advancedProxyUrlResolver) { - return urlHelper.addOptionsToUrl(this.getBaseUrl(queryConfig) + action, options); - } - return this.config.proxy.advancedProxyUrlResolver({ - queryParameters: options ? options : [], - queryString: urlHelper.addOptionsToUrl('', options), - action: action, - domain: this.getDomain(queryConfig), - queryConfig: queryConfig, - environmentId: this.config.environmentId - }); - } - - /** - * Gets proper set of headers for given request. - * @param queryConfig Query configuration - * @param additionalHeaders Custom headers - */ - getHeaders(queryConfig: IQueryConfig, additionalHeaders?: IHeader[]): IHeader[] { - const headers: IHeader[] = []; - - if (additionalHeaders) { - headers.push(...additionalHeaders); - } - - // add SDK Id header for monitoring SDK usage - headers.push(this.getSdkIdHeader()); - - // add headers from global config - if (this.config.globalHeaders) { - headers.push(...this.config.globalHeaders(queryConfig)); - } - - // add query / global headers from query config - headers.push(...this.getQueryHeaders(queryConfig)); - - if (this.isPreviewModeEnabled(queryConfig) && this.isSecuredModeEnabled(queryConfig)) { - throw Error(`Preview & secured modes cannot be used at the same time.`); - } - - // add preview header is required - if (this.isPreviewModeEnabled(queryConfig) && this.config.previewApiKey) { - headers.push(this.getAuthorizationHeader(this.config.previewApiKey)); - } - - // add secured mode header is required - if (this.isSecuredModeEnabled(queryConfig) && this.config.secureApiKey) { - headers.push(this.getAuthorizationHeader(this.config.secureApiKey)); - } - - // add 'X-KC-Wait-For-Loading-New-Content' header if required - if (this.shouldAddWaitForLoadingNewContentHeader(queryConfig)) { - headers.push({ - header: waitForLoadingNewContentHeader, - value: 'true' - }); - } - - return headers; - } - - /** - * Http POST response - * @param url Url of request - * @param queryConfig Query config configuration - */ - protected async postResponseAsync( - url: string, - body: any, - queryConfig?: IQueryConfig, - serviceConfig?: { - headers?: IHeader[]; - } - ): Promise> { - if (!queryConfig) { - queryConfig = {}; - } - - if (!serviceConfig) { - serviceConfig = {}; - } - - try { - return await this.httpService.postAsync( - { - url: url, - body: body - }, - { - cancelToken: queryConfig?.cancelToken, - responseType: 'json', - retryStrategy: this.config.retryStrategy, - headers: this.getHeaders(queryConfig, serviceConfig.headers ? serviceConfig.headers : []) - } - ); - } catch (error) { - throw this.mapDeliveryError(error); - } - } - - /** - * Http GET response - * @param url Url of request - * @param queryConfig Query config configuration - */ - protected async getResponseAsync( - url: string, - queryConfig?: IQueryConfig, - serviceConfig?: { - headers?: IHeader[]; - } - ): Promise> { - if (!queryConfig) { - queryConfig = {}; - } - - if (!serviceConfig) { - serviceConfig = {}; - } - - try { - return await this.httpService.getAsync( - { - url: url - }, - { - cancelToken: queryConfig?.cancelToken, - responseType: 'json', - retryStrategy: this.config.retryStrategy, - headers: this.getHeaders(queryConfig, serviceConfig.headers ? serviceConfig.headers : []) - } - ); - } catch (error) { - throw this.mapDeliveryError(error); - } - } - - /** - * Gets base URL of the request including the environment Id - * @param queryConfig Query configuration - */ - protected getBaseUrl(queryConfig: IQueryConfig): string { - return this.getDomain(queryConfig) + '/' + this.config.environmentId; - } - - protected mapNetworkResponse( - data: TData, - response: IResponse - ): IDeliveryNetworkResponse { - return { - data: data, - response: response, - hasStaleContent: this.getHasStaleContent(response.headers), - xContinuationToken: this.getContinuationToken(response.headers) - }; - } - - /** - * Indicates if current query should use preview mode - * @param queryConfig Query configuration - */ - private isPreviewModeEnabled(queryConfig: IQueryConfig): boolean { - if (queryConfig.usePreviewMode !== undefined) { - return queryConfig.usePreviewMode; - } - - if (!this.config.defaultQueryConfig) { - return false; - } - - if (this.config.defaultQueryConfig.usePreviewMode === true) { - return true; - } - - return false; - } - - private getQueryHeaders(queryConfig: IQueryConfig): IHeader[] { - if (queryConfig.customHeaders) { - return queryConfig.customHeaders; - } - - if (this.config.defaultQueryConfig?.customHeaders) { - return this.config.defaultQueryConfig.customHeaders; - } - - return []; - } - - private shouldAddWaitForLoadingNewContentHeader(queryConfig: IQueryConfig): boolean { - if (queryConfig.waitForLoadingNewContent !== undefined) { - return queryConfig.waitForLoadingNewContent; - } - - if (!this.config.defaultQueryConfig) { - return false; - } - - if (this.config.defaultQueryConfig.waitForLoadingNewContent === true) { - return true; - } - - return false; - } - - /** - * Indicates if current query should use secured mode - * @param queryConfig Query configuration - */ - private isSecuredModeEnabled(queryConfig: IQueryConfig): boolean { - if (queryConfig.useSecuredMode !== undefined) { - return queryConfig.useSecuredMode; - } - - if (!this.config.defaultQueryConfig) { - return false; - } - - if (this.config.defaultQueryConfig.useSecuredMode === true) { - return true; - } - - return false; - } - - /** - * Gets preview or standard URL based on client and query configuration - * @param queryConfig Query configuration - */ - private getDomain(queryConfig: IQueryConfig): string { - if (this.isPreviewModeEnabled(queryConfig)) { - if (!this.config.previewApiKey) { - throw Error(`Preview API key is not configured.`); - } - - // check custom preview url - if (this.config.proxy && this.config.proxy.basePreviewUrl) { - return this.config.proxy.basePreviewUrl; - } - - // use default preview url - return this.defaultPreviewDeliveryApiUrl; - } - - // check custom base url - if (this.config.proxy && this.config.proxy.baseUrl) { - return this.config.proxy.baseUrl; - } - return this.defaultBaseDeliveryApiUrl; - } - - /** - * Gets authorization header. This is used for 'preview' functionality - */ - private getAuthorizationHeader(key?: string): IHeader { - if (!key) { - throw Error(`Cannot get authorization header because key is invalid`); - } - // authorization header required for preview mode - return { - header: 'authorization', - value: `bearer ${key}` - }; - } - - /** - * Header identifying SDK type & version for internal purposes of Kontent.ai - */ - private getSdkIdHeader(): IHeader { - return { - header: sdkVersionHeader, - value: `${this.sdkInfo.host};${this.sdkInfo.name};${this.sdkInfo.version}` - }; - } - - private mapDeliveryError(error: any): any { - let axiosError: AxiosError | undefined; - - if (error.error) { - axiosError = error.error; - } else { - axiosError = error; - } - - if (!axiosError || !axiosError.isAxiosError) { - return error; - } - - const deliveryErrorData = axiosError.response?.data as IDeliveryErrorRaw; - - if (!deliveryErrorData || !deliveryErrorData.error_code) { - return error; - } - - return new DeliveryError({ - errorCode: deliveryErrorData.error_code, - message: deliveryErrorData.message, - specificCode: deliveryErrorData.specific_code, - requestId: deliveryErrorData.request_id - }); - } - - private getHasStaleContent(headers: IHeader[]): boolean { - const hasStaleContentHeader = headers.find( - (m) => m.header.toLowerCase() === staleContentHeaderName.toLowerCase() - ); - - if (hasStaleContentHeader) { - if (hasStaleContentHeader.value.toString() === '1') { - return true; - } - } - return false; - } - - private getContinuationToken(headers: IHeader[]): string | undefined { - const header = headers.find((m) => m.header.toLowerCase() === continuationTokenHeaderName.toLowerCase()); - return header ? header.value : undefined; - } -} diff --git a/lib/services/delivery-query.service.ts b/lib/services/delivery-query.service.ts deleted file mode 100644 index 19fd7a80..00000000 --- a/lib/services/delivery-query.service.ts +++ /dev/null @@ -1,336 +0,0 @@ -import { IHttpService } from '@kontent-ai/core-sdk'; -import { IDeliveryClientConfig } from '../config'; -import { Contracts } from '../contracts'; -import { - Responses, - IContentItem, - IContentTypeQueryConfig, - IGroupedNetworkResponse, - IItemQueryConfig, - IDeliveryNetworkResponse, - ILanguagesQueryConfig, - ITaxonomyQueryConfig, - ISyncInitQueryConfig, - ClientTypes -} from '../models'; -import { - IKontentListAllResponse, - IKontentListResponse, - IListAllQueryConfig, - ISDKInfo -} from '../models/common/common-models'; -import { BaseDeliveryQueryService } from './base-delivery-query.service'; -import { IMappingService } from './mapping.service'; - -export class QueryService extends BaseDeliveryQueryService { - constructor( - config: IDeliveryClientConfig, - httpService: IHttpService, - sdkInfo: ISDKInfo, - mappingService: IMappingService - ) { - super(config, httpService, sdkInfo, mappingService); - } - - /** - * Gets single item from given url - * @param url Url used to get single item - * @param queryConfig Query configuration - */ - async getSingleItemAsync( - url: string, - queryConfig: IItemQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IViewContentItemResponse, - Contracts.IViewContentItemContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse< - Responses.IViewContentItemResponse, - Contracts.IViewContentItemContract - >(this.mappingService.viewContentItemResponse(response.data), response); - } - - /** - * Gets single feed response. Might not contain all items in your environment. - * @param url Url - * @param queryConfig Query configuration - */ - async getItemsFeed( - url: string, - queryConfig: IItemQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IListItemsFeedResponse, - Contracts.IItemsFeedContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.itemsFeedResponse(response.data), response); - } - - /** - * Gets single used in response. Might not contain all used in references. - * @param url Url - * @param queryConfig Query configuration - */ - async getUsedIn( - url: string, - queryConfig: IItemQueryConfig - ): Promise, Contracts.IUsedInItemsContract>> { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.usedInResponse(response.data), response); - } - - /** - * Gets multiple items from given url - * @param url Url used to get multiple items - * @param queryConfig Query configuration - */ - async getMultipleItems( - url: string, - queryConfig: IItemQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IListContentItemsResponse, - Contracts.IListContentItemsContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.listContentItemsResponse(response.data), response); - } - - /** - * Gets single content type from given url - * @param url Url used to get single type - * @param queryConfig Query configuration - */ - async getSingleType( - url: string, - queryConfig: IContentTypeQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IViewContentTypeResponse, - Contracts.IViewContentTypeContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.viewContentTypeResponse(response.data), response); - } - - /** - * Gets multiple content types from given url - * @param url Url used to get multiple types - * @param queryConfig Query configuration - */ - async getMultipleTypes( - url: string, - queryConfig: IContentTypeQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IListContentTypesResponse, - Contracts.IListContentTypeContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.listContentTypesResponse(response.data), response); - } - - /** - * Initializes synchronization of changes in content items based on the specified parameters. After the initialization, - * you'll get an X-Continuation token in the response. - * Use the token to synchronize changes in the content items matching the initialization criteria. - * @param url Url - * @param queryConfig Query configuration - */ - async initializeSync( - url: string, - queryConfig: ISyncInitQueryConfig - ): Promise> { - const response = await this.postResponseAsync(url, {}, queryConfig); - - return this.mapNetworkResponse(this.mappingService.initializeContentSync(response.data), response); - } - - /** - * Retrieve a list of delta updates to recently changed content items in the specified environment. - * The types of items you get is determined by the X-Continuation token you use. - * @param url Url used to get multiple types - * @param queryConfig Query configuration - */ - async syncChanges( - url: string, - queryConfig: IContentTypeQueryConfig - ): Promise> { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.syncChanges(response.data), response); - } - - /** - * Gets languages - * @param url Url - * @param queryConfig Query configuration - */ - async getLanguages( - url: string, - queryConfig: ILanguagesQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IListLanguagesResponse, - Contracts.IListLanguagesContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.listLanguagesResponse(response.data), response); - } - - /** - * Gets single taxonomy from given url - * @param url Url used to get single taxonomy - * @param queryConfig Query configuration - */ - async getTaxonomy( - url: string, - queryConfig: ITaxonomyQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IViewTaxonomyResponse, - Contracts.IViewTaxonomyGroupContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.viewTaxonomyResponse(response.data), response); - } - - /** - * Gets multiple taxonomies from given url - * @param url Url used to get multiple taxonomies - * @param queryConfig Query configuration - */ - async getTaxonomies( - url: string, - queryConfig: ITaxonomyQueryConfig - ): Promise< - IDeliveryNetworkResponse< - Responses.IListTaxonomiesResponse, - Contracts.IListTaxonomyGroupsContract - > - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.listTaxonomiesResponse(response.data), response); - } - - /** - * Gets single content type element from given url - * @param url Url used to get single content type element - * @param queryConfig Query configuration - */ - async getElementAsync( - url: string, - queryConfig: ITaxonomyQueryConfig - ): Promise< - IDeliveryNetworkResponse - > { - const response = await this.getResponseAsync(url, queryConfig); - - return this.mapNetworkResponse(this.mappingService.viewContentTypeElementResponse(response.data), response); - } - - async getListAllResponse< - TResponse extends IKontentListResponse, - TAllResponse extends IKontentListAllResponse, - TContract - >(data: { - page: number; - getResponse: ( - nextPageUrl?: string, - continuationToken?: string - ) => Promise>; - allResponseFactory: ( - items: any[], - responses: IDeliveryNetworkResponse[] - ) => IGroupedNetworkResponse; - listQueryConfig?: IListAllQueryConfig; - }): Promise> { - const responses = await this.getListAllResponseInternalAsync({ - page: data.page, - resolvedResponses: [], - getResponse: data.getResponse, - nextPageUrl: undefined, - continuationToken: undefined, - listQueryConfig: data.listQueryConfig - }); - - return data.allResponseFactory( - responses.reduce((prev: any[], current) => { - prev.push(...current.data.items); - return prev; - }, []), - responses - ); - } - - private async getListAllResponseInternalAsync(data: { - page: number; - nextPageUrl?: string; - continuationToken?: string; - getResponse: ( - nextPageUrl?: string, - continuationToken?: string - ) => Promise>; - resolvedResponses: IDeliveryNetworkResponse[]; - listQueryConfig?: IListAllQueryConfig; - }): Promise[]> { - if (data.listQueryConfig?.pages) { - if (data.page > data.listQueryConfig.pages) { - // page limit reached, return result - return data.resolvedResponses; - } - } - - const response = await data.getResponse(data.nextPageUrl, data.continuationToken); - - if (data.listQueryConfig?.delayBetweenRequests) { - await this.sleep(data.listQueryConfig.delayBetweenRequests); - } - - data.resolvedResponses.push(response); - - if (data.listQueryConfig?.responseFetched) { - data.listQueryConfig.responseFetched(response, data.nextPageUrl, data.continuationToken); - } - - const nextPage = response.data.pagination?.nextPage; - const continuationToken = response.xContinuationToken; - - if (nextPage || continuationToken) { - // recursively fetch next page data - return await this.getListAllResponseInternalAsync({ - page: data.page + 1, - nextPageUrl: nextPage, - continuationToken: continuationToken, - listQueryConfig: data.listQueryConfig, - getResponse: data.getResponse, - resolvedResponses: data.resolvedResponses - }); - } - - return data.resolvedResponses; - } - - private sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); - } -} diff --git a/lib/services/index.ts b/lib/services/index.ts deleted file mode 100644 index c65825b1..00000000 --- a/lib/services/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './delivery-query.service'; -export * from './mapping.service'; diff --git a/lib/services/mapping.service.ts b/lib/services/mapping.service.ts deleted file mode 100644 index e64c9ff5..00000000 --- a/lib/services/mapping.service.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { IDeliveryClientConfig } from '../config'; -import { Contracts } from '../contracts'; -import { - SyncMapper, - GenericElementMapper, - ItemMapper, - LanguageMapper, - TaxonomyMapper, - TypeMapper, - UsedInMapper -} from '../mappers'; -import { Responses, IContentItem, IPagination, ClientTypes } from '../models'; - -export interface IMappingService { - listContentTypesResponse( - data: Contracts.IListContentTypeContract - ): Responses.IListContentTypesResponse; - - itemsFeedResponse( - data: Contracts.IItemsFeedContract - ): Responses.IListItemsFeedResponse; - - usedInResponse(data: Contracts.IUsedInItemsContract): Responses.IUsedInResponse; - - viewContentTypeResponse( - data: Contracts.IViewContentTypeContract - ): Responses.IViewContentTypeResponse; - - viewContentItemResponse( - data: Contracts.IViewContentItemContract - ): Responses.IViewContentItemResponse; - - listContentItemsResponse( - data: Contracts.IListContentItemsContract - ): Responses.IListContentItemsResponse; - - viewTaxonomyResponse( - data: Contracts.IViewTaxonomyGroupContract - ): Responses.IViewTaxonomyResponse; - - listTaxonomiesResponse( - data: Contracts.IListTaxonomyGroupsContract - ): Responses.IListTaxonomiesResponse; - - viewContentTypeElementResponse( - data: Contracts.IViewContentTypeElementContract - ): Responses.IViewContentTypeElementResponse; - - listLanguagesResponse( - data: Contracts.IListLanguagesContract - ): Responses.IListLanguagesResponse; - initializeContentSync(data: Contracts.IInitializeSyncContract): Responses.IInitializeSyncResponse; - syncChanges(data: Contracts.ISyncChangesContract): Responses.ISyncChangesResponse; -} - -export class MappingService implements IMappingService { - private readonly typeMapper: TypeMapper; - private readonly languageMapper: LanguageMapper; - private readonly itemMapper: ItemMapper; - private readonly taxonomyMapper: TaxonomyMapper; - private readonly usedInMapper: UsedInMapper; - private readonly genericElementMapper: GenericElementMapper; - private readonly syncMapper: SyncMapper; - - constructor(readonly config: IDeliveryClientConfig) { - this.typeMapper = new TypeMapper(); - this.languageMapper = new LanguageMapper(); - this.itemMapper = new ItemMapper(config); - this.taxonomyMapper = new TaxonomyMapper(); - this.usedInMapper = new UsedInMapper(); - this.genericElementMapper = new GenericElementMapper(); - this.syncMapper = new SyncMapper(); - } - - usedInResponse(data: Contracts.IUsedInItemsContract): Responses.IUsedInResponse { - return { - items: data.items.map((m) => this.usedInMapper.mapUsedInItem(m)) - }; - } - - /** - * Gets response for list of languages - * @param data Response data - */ - listLanguagesResponse( - data: Contracts.IListLanguagesContract - ): Responses.IListLanguagesResponse { - return { - items: this.languageMapper.mapMultipleLanguages(data), - pagination: this.mapPagination(data.pagination) - }; - } - - /** - * Gets response for getting a multiple type - * @param data Response data - */ - listContentTypesResponse( - data: Contracts.IListContentTypeContract - ): Responses.IListContentTypesResponse { - return { - items: this.typeMapper.mapMultipleTypes(data), - pagination: this.mapPagination(data.pagination) - }; - } - - /** - * Gets response for single type - * @param data Response data - * @param options Options - */ - viewContentTypeResponse( - data: Contracts.IViewContentTypeContract - ): Responses.IViewContentTypeResponse { - return { - type: this.typeMapper.mapSingleType(data) - }; - } - - itemsFeedResponse( - data: Contracts.IItemsFeedContract - ): Responses.IListItemsFeedResponse { - const itemsResult = this.itemMapper.mapItems({ - linkedItems: Object.values(data.modular_content), - mainItems: data.items - }); - - return { - items: itemsResult.items, - linkedItems: itemsResult.linkedItems - }; - } - - /** - * Gets response for getting single item - * @param data Response data - * @param queryConfig Query configuration - */ - viewContentItemResponse( - data: Contracts.IViewContentItemContract - ): Responses.IViewContentItemResponse { - const itemResult = this.itemMapper.mapSingleItemFromResponse(data); - - return { - item: itemResult.item, - linkedItems: itemResult.linkedItems - }; - } - - /** - * Gets response for getting multiple items - * @param data Response data - * @param queryConfig Query configuration - */ - listContentItemsResponse( - data: Contracts.IListContentItemsContract - ): Responses.IListContentItemsResponse { - const itemsResult = this.itemMapper.mapMultipleItemsFromResponse(data); - - return { - items: itemsResult.items, - pagination: this.mapPagination(data.pagination), - linkedItems: itemsResult.linkedItems - }; - } - - /** - * Gets response for getting single taxonomy item - * @param data Response data - */ - viewTaxonomyResponse( - data: Contracts.IViewTaxonomyGroupContract - ): Responses.IViewTaxonomyResponse { - return { - taxonomy: this.taxonomyMapper.mapTaxonomy(data.system, data.terms) - }; - } - - /** - * Gets response for getting multiples taxonomies - * @param data Response data - */ - listTaxonomiesResponse( - data: Contracts.IListTaxonomyGroupsContract - ): Responses.IListTaxonomiesResponse { - return { - items: this.taxonomyMapper.mapTaxonomies(data.taxonomies), - pagination: this.mapPagination(data.pagination) - }; - } - - /** - * Gets response for getting single content type element - * @param data Response data - */ - viewContentTypeElementResponse( - data: Contracts.IViewContentTypeElementContract - ): Responses.IViewContentTypeElementResponse { - return this.genericElementMapper.mapElement(data); - } - - initializeContentSync(data: Contracts.IInitializeSyncContract): Responses.IInitializeSyncResponse { - return { - items: data.items.map((m) => this.syncMapper.mapContentItemDelta(m)) - }; - } - - syncChanges(data: Contracts.ISyncChangesContract): Responses.ISyncChangesResponse { - return { - items: data.items.map((m) => this.syncMapper.mapContentItemDelta(m)) - }; - } - - private mapPagination(paginationContract: Contracts.IPaginationContract): IPagination { - return { - skip: paginationContract.skip, - count: paginationContract.count, - limit: paginationContract.limit, - nextPage: paginationContract.next_page, - totalCount: paginationContract.total_count ?? null - }; - } -} diff --git a/lib/transforms/content-item-transforms.ts b/lib/transforms/content-item-transforms.ts new file mode 100644 index 00000000..99c88e08 --- /dev/null +++ b/lib/transforms/content-item-transforms.ts @@ -0,0 +1,91 @@ +import { isDefined } from "@kontent-ai/core-sdk"; +import type { DeliveryClientSchema } from "../models/core.models.js"; +import type { ContentItemPayload, ContentItemPayloadExtended } from "../queries/content-items/models/content-item.models.js"; +import type { ContentItemElementPayload, ContentItemElementPayloadExtended } from "../queries/content-items/models/element.models.js"; + +export function mapToExtendedItem({ + allItems, + item, +}: { + readonly allItems: Readonly | undefined>>; + readonly item: ContentItemPayload; +}): ContentItemPayloadExtended { + for (const [key, element] of Object.entries(item.elements)) { + // the item.elements is readonly, but we do want to mutate it here rather then creating new object + (item.elements as Record)[key] = resolveExtendedElement(element, allItems); + } + + // we know that for each element we have it's extended version + return item as ContentItemPayloadExtended; +} + +export function mapToExtendedModularContent({ + modularContents, + allItems, +}: { + readonly modularContents: Readonly | undefined>>; + readonly allItems: Readonly | undefined>>; +}): Readonly | undefined>> { + for (const modularContent of Object.values(modularContents).filter(isDefined)) { + mapToExtendedItem({ allItems, item: modularContent }); + } + + // We know that for each item we have its extended version + return modularContents as Readonly | undefined>>; +} + +export function joinItems({ + items, + modularContent, +}: { + readonly items: readonly ContentItemPayload[]; + readonly modularContent: readonly Readonly | undefined>>[]; +}): Readonly>> { + const joinedItems: Record> = {}; + for (const content of modularContent) { + Object.assign(joinedItems, content); + } + + for (const item of items) { + joinedItems[item.system.codename] = item; + } + + return joinedItems; +} + +function resolveCodenamesToItems( + codenames: readonly string[], + allItems: Readonly | undefined>>, +): readonly ContentItemPayload[] { + return codenames.reduce[]>((preparedItems, codename) => { + const record = allItems[codename]; + if (record) { + preparedItems.push(record); + } + return preparedItems; + }, []); +} + +/** + * We intentionally mutate element here rather then creating new object + */ +function resolveExtendedElement( + element: ContentItemElementPayload, + allItems: Readonly | undefined>>, +): ContentItemElementPayloadExtended { + // Note - intentionally not using ts-pattern here for perf. reasons + // also intentionally not using switch because biome cant infer the source types correctly here and reports false positives + if (element.type === "modular_content") { + return { + ...element, + items: resolveCodenamesToItems(element.value, allItems), + }; + } + if (element.type === "rich_text") { + return { + ...element, + items: resolveCodenamesToItems(element.modular_content, allItems), + }; + } + return element; +} diff --git a/lib/utilities/codename.helper.ts b/lib/utilities/codename.helper.ts deleted file mode 100644 index 1afabacb..00000000 --- a/lib/utilities/codename.helper.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class CodenameHelper { - /** - * This is used to prevent errors caused by reserved names in content item codename (e.g. 'constructor') - */ - escapeCodenameInCodenameIndexer(codename: string): string { - return `_${codename}`; - } -} - -export const codenameHelper = new CodenameHelper(); diff --git a/lib/utilities/delivery-url.helper.ts b/lib/utilities/delivery-url.helper.ts deleted file mode 100644 index 60c6688b..00000000 --- a/lib/utilities/delivery-url.helper.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class DeliveryUrlHelper { - replaceAssetDomain(originalAssetUrl: string, customDomain: string): string { - return `${customDomain}${this.getPathname(originalAssetUrl)}`; - } - - getPathname(url: string): string { - return new URL(url).pathname; - } -} - -export const deliveryUrlHelper = new DeliveryUrlHelper(); diff --git a/lib/utilities/enum.helper.ts b/lib/utilities/enum.helper.ts deleted file mode 100644 index e314f38f..00000000 --- a/lib/utilities/enum.helper.ts +++ /dev/null @@ -1,38 +0,0 @@ -export class EnumHelper { - getAllValues(T: any): string[] { - const allEnumValues: string[] = Object.keys(T).map((key) => T[key]); - return allEnumValues; - } - - getEnumFromValue(T: any, value: string | number): T | undefined { - try { - if (!value) { - return undefined; - } - - // we can map back from index number directly - if (this.isNumeric(value)) { - return T[value]; - } - - // for strings, we need to compare each value separately - const allEnumValues = this.getAllValues(T); - - const result = allEnumValues.find((m) => m.toLowerCase() === value.toString().toLowerCase()); - - if (!result) { - return undefined; - } - - return result as T; - } catch (err) { - return undefined; - } - } - - private isNumeric(value: any): boolean { - return !isNaN(parseFloat(value)) && isFinite(value); - } -} - -export const enumHelper = new EnumHelper(); diff --git a/lib/utilities/index.ts b/lib/utilities/index.ts deleted file mode 100644 index f54bdf0e..00000000 --- a/lib/utilities/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './codename.helper'; -export * from './delivery-url.helper'; -export * from './enum.helper'; diff --git a/lib/utils/error.utils.ts b/lib/utils/error.utils.ts new file mode 100644 index 00000000..0aa8c1ae --- /dev/null +++ b/lib/utils/error.utils.ts @@ -0,0 +1,6 @@ +import type { KontentSdkError } from "@kontent-ai/core-sdk"; +import { DeliverySdkError } from "../models/error.models.js"; + +export function mapDeliveryError(error: KontentSdkError): DeliverySdkError { + return new DeliverySdkError(error); +} diff --git a/lib/utils/paging.utils.ts b/lib/utils/paging.utils.ts new file mode 100644 index 00000000..4ab85c7f --- /dev/null +++ b/lib/utils/paging.utils.ts @@ -0,0 +1,21 @@ +import { extractContinuationToken, type GetNextPageData, type JsonValue } from "@kontent-ai/core-sdk"; +import type { PaginationPayload } from "../models/pagination.models.js"; + +export function getNextPageByUrl(): GetNextPageData { + return (response) => { + const nextPageUrl = response.payload.pagination.next_page; + return { + continuationToken: undefined, + nextPageUrl: nextPageUrl.length ? nextPageUrl : undefined, + }; + }; +} + +export function getNextPageByContinuationToken(): GetNextPageData { + return (response) => { + return { + continuationToken: extractContinuationToken(response.meta.responseHeaders), + nextPageUrl: undefined, + }; + }; +} diff --git a/lib/utils/url.utils.ts b/lib/utils/url.utils.ts new file mode 100644 index 00000000..711d6d28 --- /dev/null +++ b/lib/utils/url.utils.ts @@ -0,0 +1,133 @@ +import { type BaseUrl, getEndpointUrl } from "@kontent-ai/core-sdk"; +import { match } from "ts-pattern"; +import type { ApiMode, DeliveryClientConfig, DeliveryEndpoint } from "../models/core.models.js"; +import { + type EmptyRichTextFilter, + emptyRichTextOperators, + emptyRichTextToFilterOperator, + type Filter, + type ObjectFilter, +} from "../models/filter.models.js"; +import type { QueryParameterRecord } from "../models/request.models.js"; + +export function getDeliveryUrl({ + environmentId, + path, + baseUrl, + apiMode, +}: { readonly path: DeliveryEndpoint } & Pick): string { + return getEndpointUrl({ + environmentId, + path, + baseUrl: baseUrl ?? getDefaultBaseUrlForApiMode(apiMode), + }); +} + +export function addQueryParametersToUrl( + url: string, + query: QueryParameterRecord | undefined, + filters: readonly Filter[] | undefined, +): string { + if (!query && !filters) { + return url; + } + + const searchParams = getUrlSearchParams(query, filters); + + if (searchParams.size === 0) { + return url; + } + + return `${url}${url.includes("?") ? "&" : "?"}${searchParams.toString()}`; +} + +export function isEmptyRichTextFilter(value: unknown): value is EmptyRichTextFilter { + if (typeof value !== "object" || value === null || value === undefined) { + return false; + } + + if (!(("operator" satisfies keyof EmptyRichTextFilter) in value)) { + return false; + } + + return emptyRichTextOperators.some((operator) => operator === value.operator); +} + +function getDefaultBaseUrlForApiMode(apiMode: ApiMode): BaseUrl { + if (apiMode === "preview") { + return { protocol: "https", host: "preview-deliver.kontent.ai" }; + } + + // Both "public" and "secure" modes use the same base URL. + // Secure mode is distinguished by the Authorization header, not a different endpoint. + return { protocol: "https", host: "deliver.kontent.ai" }; +} + +function getUrlSearchParams( + query: QueryParameterRecord | undefined, + filters: readonly Filter[] | undefined, +): URLSearchParams { + return new URLSearchParams(getQueryParams(query).concat(getFilterParams(filters))); +} + +function filterHasDefinedValue( + filter: ObjectFilter, +): filter is ObjectFilter & { readonly value: NonNullable } { + return filter.value !== undefined && filter.value !== null; +} + +function queryHasDefinedValue(item: [Key, Value | undefined]): item is [Key, Value] { + const [, value] = item; + return value !== undefined && value !== null; +} + +function isQueryFilter(value: unknown): value is ObjectFilter { + return typeof value === "object" && value !== null && "property" in value && "operator" in value && "value" in value; +} + +function getQueryParams(query: QueryParameterRecord | undefined): readonly string[][] { + if (!query) { + return []; + } + return Object.entries(query) + .filter(queryHasDefinedValue) + .map(([key, value]) => [key, value.toString()]); +} + +function getFilterParams(filters: readonly Filter[] | undefined): readonly string[][] { + if (!filters) { + return []; + } + return filters.flatMap((filter) => { + return ( + match(filter) + .returnType() + // Special case for "isEmptyRichText" operator + .when(isEmptyRichTextFilter, (filter) => [ + [`${filter.property}[${emptyRichTextToFilterOperator[filter.operator]}]`, "


"], + ]) + .when(isQueryFilter, (filter) => { + if (!filterHasDefinedValue(filter)) { + return []; + } + + // Special case for "=" operator which we can just omit from the property definition + if (filter.operator === "=") { + return [[filter.property, filter.value.toString()]]; + } + + // Special case for "!=" operator which we need to convert to "neq" + if (filter.operator === "!=") { + return [[`${filter.property}[neq]`, filter.value.toString()]]; + } + + return [[`${filter.property}[${filter.operator}]`, filter.value.toString()]]; + }) + .otherwise((stringFilter) => { + // Split the filter string into property and value + const separatorIndex = stringFilter.indexOf("="); + return [[stringFilter.slice(0, separatorIndex), stringFilter.slice(separatorIndex + 1)]]; + }) + ); + }); +} diff --git a/migration.md b/migration.md new file mode 100644 index 00000000..fb43a447 --- /dev/null +++ b/migration.md @@ -0,0 +1,635 @@ +# Migration Guide: v16 → v17 + +This guide covers the breaking changes when upgrading from `@kontent-ai/delivery-sdk` v16 to v17, with +side-by-side v16/v17 examples for every part of the API. + +v17 is a ground-up rewrite. The biggest conceptual shifts: + +- The fluent query builder (`.items().type().limitParameter()...toPromise()`) is replaced by **request + objects** passed to renamed methods (`client.listContentItems({ query, filters })`). +- Queries no longer throw by default — they expose **safe** execution methods that return + `{ success, response, error }` alongside throwing ones. +- Responses are the **raw API payload** (snake_case), wrapped as `{ payload, meta }`. Linked items are + still resolved for you, but onto each element's `items` array rather than a separate `linkedItems` bag. +- Strong typing moves from the `ClientTypes` generic + `IContentItem` to a `DeliveryClientSchema` + + `ContentItemOf`, and responses can be validated at runtime with Zod schemas. + +## At a glance + +| Concept | v16 | v17 | +|---|---|---| +| Create client | `createDeliveryClient({ environmentId, previewApiKey })` | `createDeliveryClient({ apiMode, environmentId, deliveryApiKey })` | +| List items | `client.items().type("movie").toPromise()` | `client.listContentItems({ filters: [...] }).fetchPageSafe()` | +| Single item | `client.item("x").toPromise()` | `client.fetchContentItem({ codename: "x" }).fetchSafe()` | +| Strong typing | `ClientTypes` generic + `IContentItem<{...Elements.*}>` | `DeliveryClientSchema` + `ContentItemOf` | +| Response data | `response.data.items` | `response.payload.items` | +| Linked items | `element.linkedItems` | `element.items` (resolved) | +| Errors | `try/catch` (`DeliveryError`) | `{ success, error }` (`DeliverySdkError`) | + +--- + +## Installation + +v17 requires Node.js ≥ 22 and has three peer dependencies that were previously bundled: +`@kontent-ai/core-sdk`, `zod`, and `ts-pattern`. + +**npm** installs peer dependencies automatically: + +```bash +npm install @kontent-ai/delivery-sdk +``` + +**pnpm** does not, so install them explicitly alongside the package: + +```bash +pnpm add @kontent-ai/delivery-sdk @kontent-ai/core-sdk zod ts-pattern +``` + +--- + +## Client creation + +API access mode is now an explicit `apiMode` discriminant instead of optional API-key fields. + +**v16** +```typescript +import { createDeliveryClient } from "@kontent-ai/delivery-sdk"; + +const client = createDeliveryClient({ + environmentId: "", + previewApiKey: "", // preview mode + // secureApiKey: "", // OR secure mode + defaultQueryConfig: { usePreviewMode: true }, +}); +``` + +**v17** +```typescript +import { createDeliveryClient } from "@kontent-ai/delivery-sdk"; + +// Public +const client = createDeliveryClient({ apiMode: "public", environmentId: "" }); + +// Preview +const client = createDeliveryClient({ + apiMode: "preview", + environmentId: "", + deliveryApiKey: "", +}); + +// Secure +const client = createDeliveryClient({ + apiMode: "secure", + environmentId: "", + deliveryApiKey: "", +}); +``` + +`usePreviewMode`/`useSecuredMode` query config is gone — the mode is fixed when the client is created. + +### Removed / relocated config options + +| v16 property | v17 | +|---|---| +| `previewApiKey` / `secureApiKey` | Replaced by `apiMode` + `deliveryApiKey` | +| `defaultQueryConfig` (`usePreviewMode` / `useSecuredMode`) | Decided by `apiMode` at client creation | +| `elementResolver` | Removed — elements are returned as typed discriminated-union values, not remapped | +| `linkedItemsReferenceHandler` | Removed — linked items are resolved onto `element.items` (see [Linked items](#linked-items--rich-text)) | +| `proxy` / `basePreviewUrl` | Use `baseUrl` from the `@kontent-ai/core-sdk` config | +| `globalHeaders` | Pass headers per request (`config.customHeaders`) | +| `defaultLanguage` | Pass `query.language` per request | +| `retryStrategy` | Configured in `@kontent-ai/core-sdk` | +| `httpService` | Still supported (from `@kontent-ai/core-sdk`) | +| `assetsDomain` / `defaultRenditionPreset` | Removed | +| `excludeArchivedItems` | Removed | + +--- + +## TypeScript schema (replaces the `ClientTypes` generic) + +v16 narrowed codenames with a `ClientTypes` generic. v17 uses `DeliveryClientSchema<...>`, where content +types and taxonomies are **maps** (so elements/terms are tied to their parent). + +**v16** +```typescript +import type { ClientTypes } from "@kontent-ai/delivery-sdk"; + +type MyClientTypes = ClientTypes & { + languageCodenames: "en-US" | "cs-CZ"; + contentTypeCodenames: "article" | "movie"; + collectionCodenames: "default"; + workflowCodenames: "default"; + workflowStepCodenames: "published" | "draft"; + taxonomyCodenames: "genre"; + elementCodenames: "title" | "summary"; +}; + +const client = createDeliveryClient({ environmentId: "..." }); +``` + +**v17** +```typescript +import { createDeliveryClient, type DeliveryClientSchema } from "@kontent-ai/delivery-sdk"; + +type MySchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["en-US", "cs-CZ"]; + readonly collectionCodenames: readonly ["default"]; + readonly workflowCodenames: readonly ["default"]; + readonly workflowStepCodenames: readonly ["published", "draft"]; + readonly taxonomies: { + readonly genre: readonly ["action", "comedy", "drama"]; + }; + readonly contentTypes: { + readonly article: readonly ["title", "summary"]; + readonly movie: readonly ["title", "release_date"]; + }; +}>; + +const client = createDeliveryClient({ apiMode: "public", environmentId: "..." }); +``` + +The schema is type-only — it narrows codenames at compile time and is not passed as a runtime value. + +> **`taxonomyCodenames` → `taxonomies` map.** Each key is a taxonomy codename; its value lists that +> taxonomy's term codenames. This lets `fetchTaxonomy` narrow the returned term codenames to the queried +> taxonomy — `client.fetchTaxonomy({ codename: "genre" })` types `terms[].codename` as +> `"action" | "comedy" | "drama"` at every nesting level. The taxonomy codenames are derived from the map's +> keys, so no separate `taxonomyCodenames` field is needed. + +> **`contentTypeCodenames` + `elementCodenames` → `contentTypes` map.** Each key is a content type +> codename; its value lists that type's element codenames. Single-type queries narrow elements to the +> queried type — `client.fetchContentTypeElement({ typeCodename: "article", elementCodename: "title" })` +> accepts only `article`'s elements, and `client.fetchContentType({ codename: "article" })` narrows its +> `elements` selection the same way. Cross-type queries (`listContentItems`, `itemsFeed`, +> `fetchContentItem`, `listContentTypes`) accept any element codename across all types. + +> Generated schemas from `@kontent-ai/model-generator` emit this shape, so you normally won't hand-write it. + +--- + +## Typed content models + +v16 modeled an item with `IContentItem<{...}>` and the `Elements.*` wrapper types. v17 uses +`ContentItemOf` with the `Elements.*` namespace. The element shape's +keys are validated against the type's element codenames in your schema. + +**v16** +```typescript +import type { IContentItem, Elements } from "@kontent-ai/delivery-sdk"; + +type Actor = IContentItem<{ + readonly first_name: Elements.TextElement; + readonly last_name: Elements.TextElement; +}>; + +type Movie = IContentItem<{ + readonly title: Elements.TextElement; + readonly plot: Elements.RichTextElement; + readonly released: Elements.DateTimeElement; + readonly length: Elements.NumberElement; + readonly poster: Elements.AssetsElement; + readonly category: Elements.MultipleChoiceElement; + readonly stars: Elements.LinkedItemsElement; + readonly seoname: Elements.UrlSlugElement; + readonly releasecategory: Elements.TaxonomyElement; +}>; +``` + +**v17** +```typescript +import type { ContentItemOf, Elements } from "@kontent-ai/delivery-sdk"; + +type Actor = ContentItemOf; + +type Movie = ContentItemOf; + readonly released: Elements.DateTime; + readonly length: Elements.Number; + readonly poster: Elements.Asset; + readonly category: Elements.MultipleChoice<"action" | "drama">; + readonly stars: Elements.LinkedItems; + readonly seoname: Elements.UrlSlug; + readonly releasecategory: Elements.Taxonomy<"action" | "comedy" | "drama">; +}>; +``` + +### Element type mapping + +| v16 | v17 | +|---|---| +| `Elements.TextElement` | `Elements.Text` | +| `Elements.NumberElement` | `Elements.Number` | +| `Elements.RichTextElement` | `Elements.RichText` | +| `Elements.MultipleChoiceElement` | `Elements.MultipleChoice` | +| `Elements.DateTimeElement` | `Elements.DateTime` | +| `Elements.AssetsElement` | `Elements.Asset` | +| `Elements.TaxonomyElement` | `Elements.Taxonomy` | +| `Elements.UrlSlugElement` | `Elements.UrlSlug` | +| `Elements.CustomElement` | `Elements.Custom` | +| `Elements.LinkedItemsElement` | `Elements.LinkedItems` | + +The generic arguments (``, `<"action" | "drama">`, …) are compile-time hints that power +autocomplete and narrowing; at runtime the value is whatever the API returns. + +--- + +## Query methods + +| v16 | v17 | +|---|---| +| `client.items()` | `client.listContentItems()` | +| `client.item(codename)` | `client.fetchContentItem({ codename })` | +| `client.itemsFeed()` | `client.itemsFeed()` | +| `client.types()` | `client.listContentTypes()` | +| `client.type(codename)` | `client.fetchContentType({ codename })` | +| `client.taxonomies()` | `client.listTaxonomies()` | +| `client.taxonomy(codename)` | `client.fetchTaxonomy({ codename })` | +| `client.languages()` | `client.listLanguages()` | +| `client.element(type, element)` | `client.fetchContentTypeElement({ typeCodename, elementCodename })` | +| `client.assetUsedIn(codename)` | `client.itemsReferencingAsset({ codename })` | +| `client.itemUsedIn(codename)` | `client.itemsReferencingItem({ codename })` | +| `client.mappingService` | Removed (see [Removed APIs](#removed-apis)) | +| `client.initializeSync()` / `client.syncChanges()` | Removed (see [Removed APIs](#removed-apis)) | + +### Fluent builder → request object + +v16 chained builder methods; v17 passes a single request object. Query parameters live under `query`, +content filtering under `filters`. + +**v16** +```typescript +const response = await client + .items() + .type("movie") + .languageParameter("en-US") + .depthParameter(2) + .limitParameter(10) + .skipParameter(20) + .elementsParameter(["title", "plot"]) + .orderByAscending("system.name") + .toPromise(); + +console.log(response.data.items); +``` + +**v17** +```typescript +const { response } = await client + .listContentItems({ + query: { + language: "en-US", + depth: 2, + limit: 10, + skip: 20, + elements: ["title", "plot"], + order: "system.name[asc]", + }, + filters: [{ property: "system.type", operator: "eq", value: "movie" }], + }) + .fetchPageSafe(); + +console.log(response?.payload.items); +``` + +| v16 builder method | v17 | +|---|---| +| `.type(c)` / `.types([...])` | `filters: [{ property: "system.type", operator: "eq" / "in", value }]` | +| `.collection(c)` / `.collections([...])` | `filters: [{ property: "system.collection", operator: "eq" / "in", value }]` | +| `.languageParameter(c)` | `query.language` | +| `.depthParameter(n)` | `query.depth` | +| `.limitParameter(n)` / `.skipParameter(n)` | `query.limit` / `query.skip` | +| `.elementsParameter([...])` / `.excludeElementsParameter([...])` | `query.elements` / `query.excludeElements` | +| `.includeTotalCountParameter()` | `query.includeTotalCount: true` | +| `.orderByAscending(x)` / `.orderByDescending(x)` / `.orderParameter(x, dir)` | `query.order: "[asc|desc]"` | + +### Execution methods + +| v16 | v17 | Behaviour | +|---|---|---| +| `.toPromise()` | `.fetchSafe()` (single) / `.fetchPageSafe()` (paged) | Returns `{ success, response, error }`, never throws | +| `.toPromise()` | `.fetch()` / `.fetchPage()` | Throws on error | +| `.toAllPromise()` | `.fetchAllPagesSafe()` | All pages, returns `{ success, responses, error }` | +| `.toAllPromise()` | `.fetchAllPages()` | All pages, throws on error | +| — | `.pages()` / `.pagesSafe()` | Async iterators over pages | + +--- + +## Error handling + +v16 queries threw `DeliveryError`. v17 prefers the safe variants, which return a result object with a +`DeliverySdkError` instead of throwing (the throwing `fetch()`/`fetchPage()` variants still exist). + +**v16** +```typescript +import { DeliveryError } from "@kontent-ai/delivery-sdk"; + +try { + const response = await client.item("invalid").toPromise(); + console.log(response.data.item); +} catch (error) { + if (error instanceof DeliveryError) { + console.error(error.message, error.errorCode); + } +} +``` + +**v17** +```typescript +const { success, response, error } = await client.fetchContentItem({ codename: "invalid" }).fetchSafe(); + +if (!success) { + console.error(error.message); + console.error(error.details.reason); // e.g. "parsingFailed" + return; +} + +console.log(response.payload.item); +``` + +Every query exports a matching response type for annotating results: +`FetchContentItemResponse`, `ListContentItemsResponse`, `ItemsFeedResponse`, `FetchContentTypeResponse`, +`ListContentTypesResponse`, `FetchContentTypeElementResponse`, `FetchTaxonomyResponse`, +`ListTaxonomiesResponse`, `ListLanguagesResponse`, `ItemsReferencingAssetResponse`, +`ItemsReferencingItemResponse`. + +> `modular_content` is a record keyed by codename whose values are `item | undefined` — index access can +> return `undefined`, so guard before use. + +### System property names + +System properties are now snake_case to match the raw API: + +| v16 | v17 | +|---|---| +| `system.lastModified` | `system.last_modified` | +| `system.workflowStep` | `system.workflow_step` | +| `system.sitemapLocations` | `system.sitemap_locations` | +| `system.id` / `name` / `codename` / `type` / `language` / `collection` / `workflow` | unchanged | + +--- + +## Linked items & rich text + +This is the biggest behavioural change to be aware of. v16 resolved linked items into a separate +`linkedItems` bag and onto `element.linkedItems`. **v17 still resolves them for you** — but onto each +element's **`items`** array, directly on the default (resolved) response. Call `.raw()` on the query if you +want the unresolved payload instead. + +**v16** +```typescript +const movie = response.data.item; +const stars = movie.elements.stars.linkedItems; // resolved Actor[] +const plotItems = movie.elements.plot.linkedItems; // items referenced from rich text +``` + +**v17** +```typescript +// Linked-items element: `.value` holds codenames, `.items` holds the resolved items +const stars = movie.elements.stars.items; // resolved Actor[] +const starCodenames = movie.elements.stars.value; // string[] + +// Rich-text element: `.value` is the HTML string, `.modular_content` is codenames, `.items` is resolved +const plotHtml = movie.elements.plot.value; // string (HTML) +const plotItems = movie.elements.plot.items; // resolved items +const plotItemCodenames = movie.elements.plot.modular_content; + +// Need the raw, unresolved payload? Use .raw() +const raw = await client.fetchContentItem({ codename: "warrior" }).raw().fetch(); +``` + +> v17 does **not** ship a rich-text-to-HTML resolver or portable-text transformer. `element.value` is the +> raw HTML the API returns; resolve embedded components/links yourself from `modular_content` / `links`. + +--- + +## Content item type guards + +When a query returns items of mixed types (e.g. `listContentItems`), narrow each item to its typed model +with a type guard on `system.type`. This replaces v16's `response.item as Movie` casting and gives you +fully-typed `elements` inside the branch. + +```typescript +import type { ContentItemPayload } from "@kontent-ai/delivery-sdk"; + +function isMovie(item: ContentItemPayload): item is Movie { + return item.system.type === "movie"; +} + +function isActor(item: ContentItemPayload): item is Actor { + return item.system.type === "actor"; +} + +const { response } = await client.listContentItems().fetchPageSafe(); + +for (const item of response?.payload.items ?? []) { + if (isMovie(item)) { + const title: string = item.elements.title.value; + const stars = item.elements.stars.items; // resolved Actor[] + } else if (isActor(item)) { + const name: string = item.elements.first_name.value; + } +} +``` + +> You don't need to write these by hand — `@kontent-ai/model-generator` emits a type guard +> (`isMovie`, `isActor`, …) for every content type alongside the typed models and schema. + +--- + +## Filters + +v16 exposed filters as builder methods; v17 uses an explicit `filters` array. + +**v16** +```typescript +const response = await client + .items() + .equalsFilter("system.type", "movie") + .allFilter("elements.genre", ["action", "drama"]) + .greaterThanOrEqualFilter("elements.release_date", "2020-01-01") + .toPromise(); +``` + +**v17** +```typescript +const { response } = await client + .listContentItems({ + filters: [ + { property: "system.type", operator: "eq", value: "movie" }, + { property: "elements.genre", operator: "all", value: ["action", "drama"] }, + { property: "elements.release_date", operator: "gte", value: "2020-01-01" }, + ], + }) + .fetchPageSafe(); +``` + +Filters may also be raw query strings: `filters: ["system.type[eq]=movie", "elements.genre[all]=action,drama"]`. + +| v16 method | v17 operator | +|---|---| +| `equalsFilter` | `"eq"` | +| `notEqualsFilter` | `"neq"` | +| `emptyFilter` | `"empty"` | +| `notEmptyFilter` | `"nempty"` | +| `greaterThanFilter` | `"gt"` | +| `greaterThanOrEqualFilter` | `"gte"` | +| `lessThanFilter` | `"lt"` | +| `lessThanOrEqualFilter` | `"lte"` | +| `rangeFilter` | `"range"` | +| `anyFilter` | `"any"` | +| `allFilter` | `"all"` | +| `containsFilter` | `"contains"` | +| `inFilter` | `"in"` | +| `notInFilter` | `"nin"` | + +--- + +## Ordering + +**v16** +```typescript +client.items().orderByAscending("system.name").toPromise(); +client.items().orderByDescending("elements.release_date").toPromise(); +client.items().orderParameter("elements.title", "desc").toPromise(); +``` + +**v17** +```typescript +client.listContentItems({ query: { order: "system.name[asc]" } }).fetchPageSafe(); +client.listContentItems({ query: { order: "elements.release_date[desc]" } }).fetchPageSafe(); +``` + +--- + +## Paging + +### URL paging (skip / limit) + +**v16** +```typescript +const response = await client + .items() + .limitParameter(10) + .skipParameter(20) + .includeTotalCountParameter() + .toPromise(); + +console.log(response.data.pagination.skip, response.data.pagination.totalCount); +``` + +**v17** +```typescript +const { response } = await client + .listContentItems({ query: { limit: 10, skip: 20, includeTotalCount: true } }) + .fetchPageSafe(); + +console.log(response?.payload.pagination.skip, response?.payload.pagination.total_count); +``` + +### Continuation-token paging (items feed) + +**v16** +```typescript +const response = await client + .itemsFeed() + .withContinuationToken("token-from-previous-response") + .toPromise(); +``` + +**v17** +```typescript +const { response } = await client + .itemsFeed({ headers: { "X-Continuation": "token-from-previous-response" } }) + .fetchPageSafe(); + +console.log(response?.meta.continuationToken); // next token +``` + +### Fetching all pages + +**v16** +```typescript +const response = await client.items().limitParameter(5).toAllPromise({ pages: 3 }); +console.log(response.data.items); +``` + +**v17** +```typescript +const { success, responses } = await client.listContentItems({ query: { limit: 5 } }).fetchAllPagesSafe(); +if (success) { + const allItems = responses.flatMap((r) => r.payload.items); +} + +// or iterate page-by-page +for await (const page of client.itemsFeed().pages()) { + console.log(page.payload.items.length); +} +``` + +--- + +## Runtime validation (new in v17) + +v17 can validate API responses against the Zod schemas the types are derived from, catching unexpected +payload shapes immediately. It is opt-in: + +```typescript +const client = createDeliveryClient({ + apiMode: "public", + environmentId: "...", + runtimeValidation: { validateResponses: true }, +}); +``` + +When validation fails, the safe result carries a `parsingFailed` error reason with the underlying +`ZodError`: + +```typescript +const { success, error } = await client.listLanguages().fetchPageSafe(); + +if (!success && error.details.reason === "parsingFailed") { + console.error(error.details.zodError); +} +``` + +--- + +## Removed APIs + +### `mappingService` + +The `client.mappingService` property for remapping stored JSON responses is removed. Parse responses with +the exported Zod schemas directly. The schemas live on the dedicated `@kontent-ai/delivery-sdk/schemas` +subpath — a separate entry point that is **not** part of the main bundle, so it's only pulled in when you +import from it: + +```typescript +import { listContentItemsSchema } from "@kontent-ai/delivery-sdk/schemas"; + +const result = await listContentItemsSchema().safeParseAsync(storedJson); +``` + +### `transformImageUrl` + +The image-transformation builder is removed. Use the +[Kontent.ai Image Transformation API](https://kontent.ai/learn/docs/apis/image-transformation) URL +parameters directly, or a third-party image URL builder. + +### `.getUrl()` / `.withUrl()` + +Query URL inspection/override builder methods are removed. Inspect a query's request via `query.inspect()`, +set a custom host through the `baseUrl` config, and express ad-hoc query strings via raw-string `filters`. + +### Sync API + +`client.initializeSync()` and `client.syncChanges()` are removed. Use the dedicated +[`@kontent-ai/sync-sdk`](https://github.com/kontent-ai/sync-sdk-js) package, which provides type-safe +synchronization with the Kontent.ai Sync API v2: + +```bash +npm install @kontent-ai/sync-sdk +``` diff --git a/misc/set-sdk-version.ts b/misc/set-sdk-version.ts deleted file mode 100644 index d75a79fd..00000000 --- a/misc/set-sdk-version.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { version, name } from '../package.json'; -import { createSdkVersionFile } from './version-helper'; - -createSdkVersionFile('./lib/sdk-info.generated.ts', version, name, '@kontent-ai/core-sdk'); diff --git a/misc/verify-sdk-version.ts b/misc/verify-sdk-version.ts deleted file mode 100644 index 994efd47..00000000 --- a/misc/verify-sdk-version.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { sdkInfo } from '../lib/sdk-info.generated'; -import { version } from '../package.json'; -import { verifySdkVersion } from './version-helper'; - -verifySdkVersion(sdkInfo, version); diff --git a/misc/version-helper.ts b/misc/version-helper.ts deleted file mode 100644 index 6f570d5b..00000000 --- a/misc/version-helper.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ISDKInfo } from '@kontent-ai/core-sdk'; -import { cyan, green, red, yellow } from 'colors'; -import { writeFileSync } from 'fs'; - -export const verifySdkVersion = (sdkInfo: ISDKInfo, versionInPackage: string) => { - if (sdkInfo.version !== versionInPackage) { - const msg = `Versions of '${sdkInfo.name}' SDK don't match. Lib version is '${sdkInfo.version}' while package version is '${versionInPackage}'. - Please make sure to use identical versions.`; - throw Error(red(msg)); - } else { - console.log(`Version check successful for '${yellow(sdkInfo.version)}' and package '${yellow(sdkInfo.name)}'`); - } -}; - -export const createSdkVersionFile = (filePath: string, appVersion: string, packageName: string, importFrom: string) => { - console.log(cyan('\nCreating SDK version file')); - - const src = ` -import { ISDKInfo } from '${importFrom}'; -export const sdkInfo: ISDKInfo = { - host: 'npmjs.com', - version: '${appVersion}', - name: '${packageName}' -}; -`; - - // ensure version module pulls value from package.json - writeFileSync(filePath, src); - console.log(green(`Updating application version ${yellow(appVersion)}`)); - console.log(`${green('Writing version module to ')}${yellow(filePath)}\n`); -}; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6aba0c8d..00000000 --- a/package-lock.json +++ /dev/null @@ -1,11524 +0,0 @@ -{ - "name": "@kontent-ai/delivery-sdk", - "version": "16.4.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@kontent-ai/delivery-sdk", - "version": "16.4.0", - "license": "MIT", - "dependencies": { - "@kontent-ai/core-sdk": "10.12.1" - }, - "devDependencies": { - "@types/jasmine": "5.1.12", - "@types/node": "24.10.0", - "@typescript-eslint/eslint-plugin": "8.39.0", - "@typescript-eslint/parser": "8.39.0", - "colors": "1.4.0", - "eslint": "9.32.0", - "jasmine-core": "5.12.1", - "jasmine-spec-reporter": "7.0.0", - "karma": "6.4.4", - "karma-chrome-launcher": "3.2.0", - "karma-cli": "2.0.0", - "karma-coverage-istanbul-reporter": "3.0.3", - "karma-jasmine": "5.1.0", - "karma-jasmine-html-reporter": "2.1.0", - "karma-sourcemap-loader": "0.4.0", - "karma-typescript": "5.5.4", - "karma-typescript-es6-transform": "5.5.4", - "lcov-parse": "1.0.0", - "mocha": "11.7.5", - "standard-version": "9.5.0", - "ts-loader": "9.5.4", - "tsx": "4.20.6", - "typescript": "5.2.2", - "typescript-eslint": "8.39.0", - "webpack": "5.102.1", - "webpack-bundle-analyzer": "4.10.2", - "webpack-cli": "6.0.1" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "regexpu-core": "^6.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", - "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.5", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.4", - "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.27.1", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.28.5", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.28.5", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.4", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.28.5", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.4", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@eslint/eslintrc/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", - "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.15.2", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "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, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@kontent-ai/core-sdk": { - "version": "10.12.1", - "resolved": "https://registry.npmjs.org/@kontent-ai/core-sdk/-/core-sdk-10.12.1.tgz", - "integrity": "sha512-6lD5gVloyqOVgdQhjnnMLBz2Hj3cD/nrXlqrosktWaD0nKCzzxp7h/9F7kOObknWDvxl+hH+yeBLHTGWUegJdg==", - "license": "MIT", - "dependencies": { - "axios": "1.13.2" - }, - "engines": { - "node": ">= 20" - } - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.5.tgz", - "integrity": "sha512-Dq1bqBdLaZ1Gb/l2e5/+o3B18+8TI9ANlA1SkejZqDgdU/jK/ThYaMPMJpVMMXy2uRHvGKbkz9vheVGdq3cJfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jasmine": { - "version": "5.1.12", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.12.tgz", - "integrity": "sha512-1BzPxNsFDLDfj9InVR3IeY0ZVf4o9XV+4mDqoCfyPkbsA7dYyKAPAb2co6wLFlHcvxPlt1wShm7zQdV7uTfLGA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", - "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz", - "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.39.0", - "@typescript-eslint/type-utils": "8.39.0", - "@typescript-eslint/utils": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.39.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz", - "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "8.39.0", - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz", - "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.39.0", - "@typescript-eslint/types": "^8.39.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz", - "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz", - "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz", - "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0", - "@typescript-eslint/utils": "8.39.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", - "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz", - "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.39.0", - "@typescript-eslint/tsconfig-utils": "8.39.0", - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/visitor-keys": "8.39.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz", - "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.39.0", - "@typescript-eslint/types": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz", - "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.39.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", - "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", - "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", - "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/add-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5", - "core-js-compat": "^3.43.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.8.25", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz", - "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.17.0" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true, - "license": "ISC" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", - "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^5.2.1", - "randombytes": "^2.1.0", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz", - "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==", - "dev": true, - "license": "ISC", - "dependencies": { - "bn.js": "^5.2.2", - "browserify-rsa": "^4.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.6.1", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.9", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-sign/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/browserify-sign/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", - "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "node_modules/combine-source-map/node_modules/convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "dev": true, - "license": "MIT" - }, - "node_modules/combine-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/conventional-changelog": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", - "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "conventional-changelog-angular": "^5.0.12", - "conventional-changelog-atom": "^2.0.8", - "conventional-changelog-codemirror": "^2.0.8", - "conventional-changelog-conventionalcommits": "^4.5.0", - "conventional-changelog-core": "^4.2.1", - "conventional-changelog-ember": "^2.0.9", - "conventional-changelog-eslint": "^3.0.9", - "conventional-changelog-express": "^2.0.6", - "conventional-changelog-jquery": "^3.0.11", - "conventional-changelog-jshint": "^2.0.9", - "conventional-changelog-preset-loader": "^2.3.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", - "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-atom": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", - "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", - "dev": true, - "license": "ISC", - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-codemirror": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", - "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", - "dev": true, - "license": "ISC", - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-config-spec": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", - "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", - "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", - "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0", - "lodash": "^4.17.15", - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", - "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "add-stream": "^1.0.0", - "conventional-changelog-writer": "^5.0.0", - "conventional-commits-parser": "^3.2.0", - "dateformat": "^3.0.0", - "get-pkg-repo": "^4.0.0", - "git-raw-commits": "^2.0.8", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^4.1.1", - "lodash": "^4.17.15", - "normalize-package-data": "^3.0.0", - "q": "^1.5.1", - "read-pkg": "^3.0.0", - "read-pkg-up": "^3.0.0", - "through2": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-ember": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", - "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", - "dev": true, - "license": "ISC", - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-eslint": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", - "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", - "dev": true, - "license": "ISC", - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-express": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", - "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-jquery": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", - "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", - "dev": true, - "license": "ISC", - "dependencies": { - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-jshint": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", - "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", - "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-preset-loader": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", - "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-writer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", - "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "conventional-commits-filter": "^2.0.7", - "dateformat": "^3.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^4.0.0" - }, - "bin": { - "conventional-changelog-writer": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-writer/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/conventional-commits-filter": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", - "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-commits-parser": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", - "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.0.4", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "conventional-commits-parser": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-recommended-bump": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", - "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^2.3.4", - "conventional-commits-filter": "^2.0.7", - "conventional-commits-parser": "^3.2.0", - "git-raw-commits": "^2.0.8", - "git-semver-tags": "^4.1.1", - "meow": "^8.0.0", - "q": "^1.5.1" - }, - "bin": { - "conventional-recommended-bump": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/core-js-compat": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", - "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.26.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", - "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-cipher": "^1.0.1", - "browserify-sign": "^4.2.3", - "create-ecdh": "^4.0.4", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "diffie-hellman": "^5.0.3", - "hash-base": "~3.0.4", - "inherits": "^2.0.4", - "pbkdf2": "^3.1.2", - "public-encrypt": "^4.0.3", - "randombytes": "^2.1.0", - "randomfill": "^1.0.4" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true, - "license": "MIT" - }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true, - "license": "MIT" - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "node_modules/domain-browser": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", - "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", - "dev": true, - "license": "Artistic-2.0", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotgitignore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", - "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", - "dev": true, - "license": "ISC", - "dependencies": { - "find-up": "^3.0.0", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/dotgitignore/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/dotgitignore/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dotgitignore/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.250", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz", - "integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==", - "dev": true, - "license": "ISC" - }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/engine.io": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", - "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.7.2", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", - "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "punycode": "^1.4.1", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/envinfo": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.20.0.tgz", - "integrity": "sha512-+zUomDcLXsVkQ37vUqWBvQwLaLlj8eZPSi61llaEFAVBY5mhcXdaSw1pSJVl4yTYD5g/gEfpNl28YYk4IPvrrg==", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", - "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.32.0", - "@eslint/plugin-kit": "^0.3.4", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" - }, - "bin": { - "get-pkg-repo": "src/cli.js" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-pkg-repo/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-pkg-repo/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/get-pkg-repo/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-pkg-repo/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/get-pkg-repo/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", - "dev": true, - "license": "MIT", - "dependencies": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" - }, - "bin": { - "git-raw-commits": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-semver-tags": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", - "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "meow": "^8.0.0", - "semver": "^6.0.0" - }, - "bin": { - "git-semver-tags": "cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/git-semver-tags/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/gitconfiglocal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", - "dev": true, - "license": "BSD", - "dependencies": { - "ini": "^1.3.2" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", - "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/inline-source-map": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.3.tgz", - "integrity": "sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "~0.5.3" - } - }, - "node_modules/inline-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "text-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jasmine-core": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.12.1.tgz", - "integrity": "sha512-P/UbRZ0LKwXe7wEpwDheuhunPwITn4oPALhrJEQJo6756EwNGnsK/TSQrWojBB4cQDQ+VaxWYws9tFNDuiMh2Q==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/jasmine-spec-reporter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", - "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "colors": "1.4.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/karma": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", - "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.7.2", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "which": "^1.2.1" - } - }, - "node_modules/karma-chrome-launcher/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/karma-cli": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/karma-cli/-/karma-cli-2.0.0.tgz", - "integrity": "sha512-1Kb28UILg1ZsfqQmeELbPzuEb5C6GZJfVIk0qOr8LNYQuYWmAaqP16WpbpKEjhejDrDYyYOwwJXSZO6u7q5Pvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.3.3" - }, - "bin": { - "karma": "bin/karma" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/karma-coverage-istanbul-reporter": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", - "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", - "dev": true, - "license": "MIT", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^3.0.2", - "minimatch": "^3.0.4" - }, - "funding": { - "url": "https://github.com/sponsors/mattlewis92" - } - }, - "node_modules/karma-coverage-istanbul-reporter/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma-coverage-istanbul-reporter/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/karma-jasmine": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", - "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jasmine-core": "^4.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "karma": "^6.0.0" - } - }, - "node_modules/karma-jasmine-html-reporter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", - "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "jasmine-core": "^4.0.0 || ^5.0.0", - "karma": "^6.0.0", - "karma-jasmine": "^5.0.0" - } - }, - "node_modules/karma-jasmine/node_modules/jasmine-core": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", - "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/karma-sourcemap-loader": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz", - "integrity": "sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.10" - } - }, - "node_modules/karma-typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/karma-typescript/-/karma-typescript-5.5.4.tgz", - "integrity": "sha512-D7nQ96xu/UekuqCmiPimnCuOFqp8+BxiND6MU6IJVN37E7DgXzr7SUeTzwuTHtKSYpgxKv4iOTUteYTxpeZL9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2", - "assert": "^2.0.0", - "async": "^3.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^5.4.3", - "combine-source-map": "^0.8.0", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "convert-source-map": "^1.7.0", - "crypto-browserify": "^3.12.0", - "diff": "^4.0.1", - "domain-browser": "^4.16.0", - "events": "^3.2.0", - "glob": "^7.1.6", - "https-browserify": "^1.0.0", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.19", - "log4js": "^6.3.0", - "minimatch": "^3.0.4", - "os-browserify": "^0.3.0", - "pad": "^3.2.0", - "path-browserify": "^1.0.0", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.1.1", - "source-map": "^0.7.3", - "stream-browserify": "^3.0.0", - "stream-http": "^3.1.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.11", - "tmp": "^0.2.1", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.1", - "vm-browserify": "^1.1.2" - }, - "peerDependencies": { - "karma": "1 || 2 || 3 || 4 || 5 || 6", - "typescript": "1 || 2 || 3 || 4 || 5" - } - }, - "node_modules/karma-typescript-es6-transform": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/karma-typescript-es6-transform/-/karma-typescript-es6-transform-5.5.4.tgz", - "integrity": "sha512-SKUNU4cAxNgmJnF/zCAzMRnBaciQjFumSDrsf1j8TTJvAtwAk/tLM+hru88Dr4Q4SmFUFa+PzIK8NJmykQ2F7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2", - "log4js": "^6.3.0", - "magic-string": "^0.25.7" - } - }, - "node_modules/karma-typescript/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma-typescript/node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/karma-typescript/node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/karma-typescript/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/karma-typescript/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/karma-typescript/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/karma/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma/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, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "lcov-parse": "bin/cli.js" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/meow/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/meow/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true, - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "11.7.5", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", - "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", - "dev": true, - "license": "MIT", - "dependencies": { - "browser-stdout": "^1.3.1", - "chokidar": "^4.0.1", - "debug": "^4.3.5", - "diff": "^7.0.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^10.4.5", - "he": "^1.2.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^9.0.5", - "ms": "^2.1.3", - "picocolors": "^1.1.1", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^9.2.0", - "yargs": "^17.7.2", - "yargs-parser": "^21.1.1", - "yargs-unparser": "^2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/mocha/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/mocha/node_modules/diff": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", - "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/pad": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/pad/-/pad-3.3.0.tgz", - "integrity": "sha512-2/G2Q8J/lbkJ3Zf595U9jattrUkM1rwTr3s4n9smp3+ALe66V+t3I75SG0qjWzuQgmXOgiUS0/qE97S+0hP7Cw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">= 4.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-linux-x64-gnu": "4.9.5" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true, - "license": "(MIT AND Zlib)" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz", - "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "pbkdf2": "^3.1.5", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", - "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "ripemd160": "^2.0.3", - "safe-buffer": "^5.2.1", - "sha.js": "^2.4.12", - "to-buffer": "^1.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.9" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", - "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexpu-core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", - "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.2", - "regjsgen": "^0.8.0", - "regjsparser": "^0.13.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.2.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/regjsparser": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~3.1.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", - "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.1.2", - "inherits": "^2.0.4" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ripemd160/node_modules/hash-base": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", - "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ripemd160/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ripemd160/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/ripemd160/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/ripemd160/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/ripemd160/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true, - "license": "MIT" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, - "license": "ISC" - }, - "node_modules/sha.js": { - "version": "2.4.12", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", - "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", - "dev": true, - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.0" - }, - "bin": { - "sha.js": "bin.js" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/socket.io": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", - "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.6.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "node_modules/socket.io-adapter/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true, - "license": "MIT" - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "license": "ISC", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/standard-version": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", - "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "chalk": "^2.4.2", - "conventional-changelog": "3.1.25", - "conventional-changelog-config-spec": "2.1.0", - "conventional-changelog-conventionalcommits": "4.6.3", - "conventional-recommended-bump": "6.1.0", - "detect-indent": "^6.0.0", - "detect-newline": "^3.1.0", - "dotgitignore": "^2.1.0", - "figures": "^3.1.0", - "find-up": "^5.0.0", - "git-semver-tags": "^4.0.0", - "semver": "^7.1.1", - "stringify-package": "^1.0.1", - "yargs": "^16.0.0" - }, - "bin": { - "standard-version": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/standard-version/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/standard-version/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/standard-version/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/standard-version/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/standard-version/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "license": "MIT", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stringify-package": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", - "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", - "deprecated": "This module is not used anymore, and has been replaced by @npmcli/package-json", - "dev": true, - "license": "ISC" - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser": { - "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, - "node_modules/to-buffer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "^2.0.5", - "safe-buffer": "^5.2.1", - "typed-array-buffer": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/ts-loader": { - "version": "9.5.4", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", - "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/tsx": { - "version": "4.20.6", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", - "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.25.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true, - "license": "MIT" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.39.0.tgz", - "integrity": "sha512-lH8FvtdtzcHJCkMOKnN73LIn6SLTpoojgJqDAxPm1jCR14eWSGPX8ul/gggBdPMk/d5+u9V854vTYQ8T5jF/1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.39.0", - "@typescript-eslint/parser": "8.39.0", - "@typescript-eslint/typescript-estree": "8.39.0", - "@typescript-eslint/utils": "8.39.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/ua-parser-js": { - "version": "0.7.41", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz", - "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], - "license": "MIT", - "bin": { - "ua-parser-js": "script/cli.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, - "license": "MIT" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webpack": { - "version": "5.102.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", - "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.26.3", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.3", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.4", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", - "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.6.1", - "@webpack-cli/configtest": "^3.0.1", - "@webpack-cli/info": "^3.0.1", - "@webpack-cli/serve": "^3.0.1", - "colorette": "^2.0.14", - "commander": "^12.1.0", - "cross-spawn": "^7.0.3", - "envinfo": "^7.14.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^6.0.1" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.82.0" - }, - "peerDependenciesMeta": { - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", - "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.17.0" - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/workerpool": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", - "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/package.json b/package.json index 85bd466a..77c6e6e8 100644 --- a/package.json +++ b/package.json @@ -1,95 +1,74 @@ { - "name": "@kontent-ai/delivery-sdk", - "version": "16.4.0", - "repository": { - "type": "git", - "url": "https://github.com/kontent-ai/delivery-sdk-js" - }, - "private": false, - "author": "richard sustek", - "license": "MIT", - "description": "Official Kontent.AI Delivery API SDK", - "keywords": [ - "Kontent", - "Kontent.ai", - "Kontent SDK", - "Kontent API", - "Kontent Delivery", - "Kontent Javascript", - "Kontent Node.js", - "Kontent Typescript" - ], - "engines": { - "node": ">= 20" - }, - "main": "./dist/cjs/index.js", - "module": "./dist/es6/index.js", - "es2015": "./dist/es6/index.js", - "types": "./dist/cjs/index.d.ts", - "standard-version": { - "scripts": { - "postchangelog": "npm run set-sdk-version" - } - }, - "scripts": { - "release": "npm run lint:check && standard-version", - "release:major": "npm run lint:check && standard-version --release-as major", - "release:major:beta": "npm run lint:check && standard-version --prerelease --release-as major", - "release:beta": "standard-version --prerelease", - "lint:check": "npx eslint lib", - "test:browser": "karma start karma.conf.js", - "test:gh-actions": "karma start karma-gh-actions.conf.js", - "test:node": "npm run build:commonjs && npx mocha --timeout 15s -- \"test/node/**/*.js\"", - "test:all": "npm run test:node && npm run test:gh-actions", - "new-patch": "npm version patch && npm run set-sdk-version && npm run check-version ", - "new-minor": "npm version minor && npm run set-sdk-version && npm run check-version ", - "new-major": "npm version major && npm run set-sdk-version && npm run check-version ", - "prepublishOnly": "npm run lint:check && npm run check-version && npm run build:all && npm run test:all && npm run push:tags", - "set-sdk-version": "tsx ./misc/set-sdk-version.ts", - "check-version": "tsx ./misc/verify-sdk-version.ts", - "webpack:dev": "webpack -- --mode development --config webpack.config.js --progress", - "webpack:prod": "webpack -- --mode production --config webpack.config.js --progress", - "publish:beta": "npm publish --tag=next", - "build:umd": "npm run webpack:dev && npm run webpack:prod", - "build:es6": "tsc -m es6 --outDir dist/es6 --p tsconfig.prod.json", - "build:esnext": "tsc -m esnext --outDir dist/esnext --p tsconfig.prod.json", - "build:commonjs": "tsc -m commonjs --outDir dist/cjs --p tsconfig.prod.json", - "build:all": "npm run clean && npm run lint:check && npm run build:umd && npm run build:es6 && npm run build:esnext && npm run build:commonjs", - "bundle-stats:min": "npm run build:umd && webpack-bundle-analyzer dist/bundles/stats.min.json", - "bundle-stats": "npm run build:umd && webpack-bundle-analyzer dist/bundles/stats.json", - "push:tags": "git push --tags", - "clean": "tsx clean.ts" - }, - "dependencies": { - "@kontent-ai/core-sdk": "10.12.1" - }, - "devDependencies": { - "@types/jasmine": "5.1.12", - "@types/node": "24.10.0", - "colors": "1.4.0", - "jasmine-core": "5.12.1", - "jasmine-spec-reporter": "7.0.0", - "karma": "6.4.4", - "karma-chrome-launcher": "3.2.0", - "karma-cli": "2.0.0", - "karma-coverage-istanbul-reporter": "3.0.3", - "karma-jasmine": "5.1.0", - "karma-jasmine-html-reporter": "2.1.0", - "karma-sourcemap-loader": "0.4.0", - "karma-typescript": "5.5.4", - "karma-typescript-es6-transform": "5.5.4", - "lcov-parse": "1.0.0", - "mocha": "11.7.5", - "standard-version": "9.5.0", - "ts-loader": "9.5.4", - "tsx": "4.20.6", - "@typescript-eslint/eslint-plugin": "8.39.0", - "@typescript-eslint/parser": "8.39.0", - "eslint": "9.32.0", - "typescript": "5.2.2", - "webpack": "5.102.1", - "webpack-bundle-analyzer": "4.10.2", - "webpack-cli": "6.0.1", - "typescript-eslint": "8.39.0" - } + "name": "@kontent-ai/delivery-sdk", + "version": "17.0.0-preview.2", + "repository": { + "type": "git", + "url": "https://github.com/kontent-ai/delivery-sdk-js" + }, + "private": false, + "author": "richard sustek", + "license": "MIT", + "description": "Official Kontent.AI Delivery API SDK", + "keywords": [ + "Kontent", + "Kontent.ai", + "Kontent SDK", + "Kontent API", + "Kontent Delivery", + "Kontent Javascript", + "Kontent Node.js", + "Kontent Typescript" + ], + "engines": { + "node": ">= 22" + }, + "packageManager": "pnpm@11.7.0", + "exports": { + ".": { + "types": "./dist/public_api.d.ts", + "default": "./dist/public_api.js" + }, + "./schemas": { + "types": "./dist/public_schemas.d.ts", + "default": "./dist/public_schemas.js" + } + }, + "types": "./dist/public_api.d.ts", + "type": "module", + "sideEffects": false, + "scripts": { + "prepublishOnly": "pnpm run build", + "eslint": "eslint -c eslint.config.mjs .", + "lint": "pnpm run biome:check && pnpm run eslint", + "build": "pnpm run lint && pnpm run clean && pnpm run build:ts && pnpm run update:version", + "build:ts": "tsgo -p tsconfig.build.json", + "test": "vitest run --config=vitest.config.ts --coverage", + "test:unit": "vitest run --config=vitest-unit.config.ts", + "test:integration": "vitest run --config=vitest-integration.config.ts", + "test:types": "tsgo -p sample/tsconfig.json", + "biome:check": "biome check", + "biome:fix": "biome check --write", + "biome:fix:unsafe": "biome check --write --unsafe", + "clean": "tsx scripts/clean.ts", + "update:version": "tsx ./scripts/update-version.ts", + "bundle:size": "tsx scripts/measure-bundle.ts", + "bundle:create": "tsx scripts/create-bundles.ts" + }, + "peerDependencies": { + "@kontent-ai/core-sdk": "^12.0.0-preview.40", + "ts-pattern": "^5", + "zod": "^4" + }, + "devDependencies": { + "@kontent-ai/biome-config": "0.7.3", + "@kontent-ai/eslint-config": "2.4.1", + "eslint": "10.6.0", + "@biomejs/biome": "2.5.3", + "@types/node": "26.1.1", + "vitest": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "tsx": "4.23.0", + "@typescript/native-preview": "7.0.0-dev.20260707.2", + "esbuild": "0.28.1" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..855638ea --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3630 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@kontent-ai/core-sdk': + specifier: ^12.0.0-preview.40 + version: 12.0.0-preview.40(ts-pattern@5.9.0)(zod@4.4.3) + ts-pattern: + specifier: ^5 + version: 5.9.0 + zod: + specifier: ^4 + version: 4.4.3 + devDependencies: + '@biomejs/biome': + specifier: 2.5.3 + version: 2.5.3 + '@kontent-ai/biome-config': + specifier: 0.7.3 + version: 0.7.3(@biomejs/biome@2.5.3) + '@kontent-ai/eslint-config': + specifier: 2.4.1 + version: 2.4.1(typescript@6.0.3) + '@types/node': + specifier: 26.1.1 + version: 26.1.1 + '@typescript/native-preview': + specifier: 7.0.0-dev.20260707.2 + version: 7.0.0-dev.20260707.2 + '@vitest/coverage-v8': + specifier: 4.1.10 + version: 4.1.10(vitest@4.1.10) + esbuild: + specifier: 0.28.1 + version: 0.28.1 + eslint: + specifier: 10.6.0 + version: 10.6.0 + tsx: + specifier: 4.23.0 + version: 4.23.0 + vitest: + specifier: 4.1.10 + version: 4.1.10(@types/node@26.1.1)(@vitest/coverage-v8@4.1.10)(vite@8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0)) + +packages: + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@biomejs/biome@2.5.3': + resolution: {integrity: sha512-MrJswFdei9EfDwwUy2tQrPDpK0AO+RmMFvBoaaJ6ayBc3sUbHdCE+XG5N8vp+5So41ZupZJQm0roHFFhMGVD7A==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.5.3': + resolution: {integrity: sha512-QhYP9muVQ0nUO5zztFuPbEwi4+94sJWVjaZds9aMi1l/KNZBiUjdiSUrGHsTaMGDXrYl+r4AS2sUKfgH3w+V3g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.5.3': + resolution: {integrity: sha512-NC1Ss13UaW7QZX+y8j44bF7AP0jSJdBl6iRhe0MAkvaSqZy+mWg3GaXsrb+eSoHoGDBtaXWEbMVV0iVN2cZ7cQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.5.3': + resolution: {integrity: sha512-fccix0w6xp6csCXgxeC0dU/3ecgRQal0y+cv2SP9ajNlhe7Yrk2Ug7UDe2j9AT9ZDYitkXpvUKgZjjuoYeP4Vg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-arm64@2.5.3': + resolution: {integrity: sha512-ksx1KWeyYW18ILL04msF/J4ZBtBDN33znYK8Z/aNv/vlBVxL9/g3mGP+omgHJKy4+KWbK87vcmmpmurfNjSgiA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-linux-x64-musl@2.5.3': + resolution: {integrity: sha512-O/yU9YKRUiHhmcjF2f38PSjseVk3G4VLWYc0G2HWpzdBVREV6G8IGWIVEFf7MFPfWIzNUIvPsEjeAZQIOgnLcQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-x64@2.5.3': + resolution: {integrity: sha512-yMkJtilsgvILDcVkh187aVLTb64xYsrxYajx5kym+r1ULkO5HUOfu9AYKLGQbOVLwJtT2utNw7hhFNg+17mUYA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-win32-arm64@2.5.3': + resolution: {integrity: sha512-cX5z+GYwRcqEok0AH3KSfQGgqYd0Nomfp6Fbe1uiTtELE38hdH2k842wQ9wLNaF/JJ7r4rjJQ4VR+ce+fRmQbw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.5.3': + resolution: {integrity: sha512-ExSaJWi4/u6+GXCszlSKpWSjKNbDseAYqqkCznsCsZ/4uidZ/BEqsCc5/3ctlq6dfIubdIIRSVLC/PG9xPl70Q==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.6.0': + resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@kontent-ai/biome-config@0.7.3': + resolution: {integrity: sha512-4Gi29ZkI4+F3e0+haJi4oBY7vy08ajb991LY+wNrBC5D+0Wc4RJheHRRrutrVUt5TfIEj1YG0p2Lc5V40gb1vg==} + peerDependencies: + '@biomejs/biome': ^2.5.0 + + '@kontent-ai/core-sdk@12.0.0-preview.40': + resolution: {integrity: sha512-W8k5iijCvknnzHGX7q7VD0zzk2dh7W5elml2P76iroPj48OvxZuscR9Fzyg2W/Scefpe5Yy70ek4k/uw+RN77A==} + engines: {node: '>=22'} + peerDependencies: + ts-pattern: ^5 + zod: ^4 + + '@kontent-ai/eslint-config@2.4.1': + resolution: {integrity: sha512-4tIyNDDIxeYaPK17lMN00Ch1kqNbayLmrV+/tcia62XzCejR/cHcXcsWVGhmxS1RjyVpqhstnTWbUrcvmXge2Q==} + + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@26.1.1': + resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==} + + '@typescript-eslint/eslint-plugin@8.61.0': + resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.61.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.61.0': + resolution: {integrity: sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.61.0': + resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.61.0': + resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.61.0': + resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.61.0': + resolution: {integrity: sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.61.0': + resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.61.0': + resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.61.0': + resolution: {integrity: sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.61.0': + resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-wny2pgKjGbiZtnOIHVa3tXC1UfDqxNEFzyPGmiqybedG8hipG2Nfp0l5UxbaKCjkLacUpH/W5bP2hBOMVhCOzg==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-Afc7M5zOwo+GpfcYwz5Z8HMB2tPVsui7nNIqEuuFB73MPdVqNn/Wmpe4tP4MRri0AtJnJknoHBaTJ/VDAp/Jhw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-iITBa2WjjTI5N9t5l7Z4KoOSI+2zBlhbvFzsD/f8qX8QoKjz/Y4DPyBDgezYi8nkqjjksbgSOJ3/ykzhwrB9cg==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-hJm/UOqZTr9FHmR7uNm8VGX4oKtfWk0Jem0zPeJFNC8ckGUfSBueyiEYMZB+XmRc1aG4x1E46y3CplP4CLHvGQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-du0dzi6y97Po5vDNdPJTyyijHCpaS22JLRnKZEJXBDaO9gCIymOv/5QQokFRuOlQm0bWl3i9PF4OVdGP6uAOQA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-SsAwfhyHJ1akgBc+99z4+hwdbHsdWaKB8EwCNIMA6JfSLMeUjffrYvxu+vfMyxVtOVOz7RrRXRoiDiu4a2sCtg==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-DL4u27stv0fo71sVhOzHSwE+YMZsbBijVI+kg5dLDLilSH79WFTJ8RSQ46vJrCMt+Gjlv/JOZP1PuLJDfioYeQ==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@typescript/native-preview@7.0.0-dev.20260707.2': + resolution: {integrity: sha512-oUGp+Rep/hqMhPunyinsALUwSlzHINSxitifPiSaeqoKOKD2OlR9NE3TaPqwsl4NlGslsOSUXI1JotWQzpYCPg==} + engines: {node: '>=16.20.0'} + hasBin: true + + '@vitest/coverage-v8@4.1.10': + resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==} + peerDependencies: + '@vitest/browser': 4.1.10 + vitest: 4.1.10 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} + + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} + + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} + + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} + + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} + + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + brace-expansion@1.1.15: + resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.3.3: + resolution: {integrity: sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.6.0: + resolution: {integrity: sha512-6lVbcqSodALYo+4ELD0heG6lFiFxnLMuLkiMi2qV8LMp54N8tE8FT1GMH+ev4Ti00nFjNze2+Su6DsV5OQW3Dg==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.2.0: + resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-document.all@1.0.0: + resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@2.0.0-next.7: + resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==} + engines: {node: '>= 0.4'} + hasBin: true + + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.11: + resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.10: + resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-pattern@5.9.0: + resolution: {integrity: sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.23.0: + resolution: {integrity: sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.8: + resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==} + engines: {node: '>= 0.4'} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite@8.0.16: + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.18 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + +snapshots: + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + + '@babel/types@7.29.7': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@bcoe/v8-coverage@1.0.2': {} + + '@biomejs/biome@2.5.3': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.5.3 + '@biomejs/cli-darwin-x64': 2.5.3 + '@biomejs/cli-linux-arm64': 2.5.3 + '@biomejs/cli-linux-arm64-musl': 2.5.3 + '@biomejs/cli-linux-x64': 2.5.3 + '@biomejs/cli-linux-x64-musl': 2.5.3 + '@biomejs/cli-win32-arm64': 2.5.3 + '@biomejs/cli-win32-x64': 2.5.3 + + '@biomejs/cli-darwin-arm64@2.5.3': + optional: true + + '@biomejs/cli-darwin-x64@2.5.3': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.5.3': + optional: true + + '@biomejs/cli-linux-arm64@2.5.3': + optional: true + + '@biomejs/cli-linux-x64-musl@2.5.3': + optional: true + + '@biomejs/cli-linux-x64@2.5.3': + optional: true + + '@biomejs/cli-win32-arm64@2.5.3': + optional: true + + '@biomejs/cli-win32-x64@2.5.3': + optional: true + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.28.1': + optional: true + + '@esbuild/android-arm64@0.28.1': + optional: true + + '@esbuild/android-arm@0.28.1': + optional: true + + '@esbuild/android-x64@0.28.1': + optional: true + + '@esbuild/darwin-arm64@0.28.1': + optional: true + + '@esbuild/darwin-x64@0.28.1': + optional: true + + '@esbuild/freebsd-arm64@0.28.1': + optional: true + + '@esbuild/freebsd-x64@0.28.1': + optional: true + + '@esbuild/linux-arm64@0.28.1': + optional: true + + '@esbuild/linux-arm@0.28.1': + optional: true + + '@esbuild/linux-ia32@0.28.1': + optional: true + + '@esbuild/linux-loong64@0.28.1': + optional: true + + '@esbuild/linux-mips64el@0.28.1': + optional: true + + '@esbuild/linux-ppc64@0.28.1': + optional: true + + '@esbuild/linux-riscv64@0.28.1': + optional: true + + '@esbuild/linux-s390x@0.28.1': + optional: true + + '@esbuild/linux-x64@0.28.1': + optional: true + + '@esbuild/netbsd-arm64@0.28.1': + optional: true + + '@esbuild/netbsd-x64@0.28.1': + optional: true + + '@esbuild/openbsd-arm64@0.28.1': + optional: true + + '@esbuild/openbsd-x64@0.28.1': + optional: true + + '@esbuild/openharmony-arm64@0.28.1': + optional: true + + '@esbuild/sunos-x64@0.28.1': + optional: true + + '@esbuild/win32-arm64@0.28.1': + optional: true + + '@esbuild/win32-ia32@0.28.1': + optional: true + + '@esbuild/win32-x64@0.28.1': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@10.6.0)': + dependencies: + eslint: 10.6.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/config-helpers@0.6.0': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.2.0 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@eslint/plugin-kit@0.7.2': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@kontent-ai/biome-config@0.7.3(@biomejs/biome@2.5.3)': + dependencies: + '@biomejs/biome': 2.5.3 + + '@kontent-ai/core-sdk@12.0.0-preview.40(ts-pattern@5.9.0)(zod@4.4.3)': + dependencies: + ts-pattern: 5.9.0 + zod: 4.4.3 + + '@kontent-ai/eslint-config@2.4.1(typescript@6.0.3)': + dependencies: + '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@10.6.0)(typescript@6.0.3) + eslint: 9.39.4 + eslint-plugin-react: 7.37.5(eslint@9.39.4) + transitivePeerDependencies: + - jiti + - supports-color + - typescript + + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@oxc-project/types@0.133.0': {} + + '@rolldown/binding-android-arm64@1.0.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.3': + optional: true + + '@rolldown/binding-darwin-x64@1.0.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.3': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.3': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.3': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@standard-schema/spec@1.1.0': {} + + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@26.1.1': + dependencies: + undici-types: 8.3.0 + + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.61.0(eslint@10.6.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.61.0(eslint@10.6.0)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 + debug: 4.4.3 + eslint: 10.6.0 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + debug: 4.4.3 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.61.0': + dependencies: + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 + + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 + + '@typescript-eslint/type-utils@8.61.0(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4)(typescript@6.0.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.61.0': {} + + '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': + dependencies: + '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.4 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.61.0(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + eslint: 9.39.4 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.61.0': + dependencies: + '@typescript-eslint/types': 8.61.0 + eslint-visitor-keys: 5.0.1 + + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260707.2': + optional: true + + '@typescript/native-preview@7.0.0-dev.20260707.2': + optionalDependencies: + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260707.2 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260707.2 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260707.2 + + '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.10 + ast-v8-to-istanbul: 1.0.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.3 + obug: 2.1.3 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.10(@types/node@26.1.1)(@vitest/coverage-v8@4.1.10)(vite@8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0)) + + '@vitest/expect@4.1.10': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.10(vite@8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0) + + '@vitest/pretty-format@4.1.10': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.10': + dependencies: + '@vitest/utils': 4.1.10 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.10': {} + + '@vitest/utils@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + assertion-error@2.0.1: {} + + ast-v8-to-istanbul@1.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + brace-expansion@1.1.15: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + chai@6.2.2: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + detect-libc@2.1.2: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.2.0 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.11 + string.prototype.trimend: 1.0.10 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.8 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.22 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.3.3: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + + es-module-lexer@2.1.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.4 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react@7.37.5(eslint@9.39.4): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.3 + eslint: 9.39.4 + estraverse: 5.3.0 + hasown: 2.0.4 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.7 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.6.0: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.6.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.2 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + eslint-visitor-keys: 4.2.1 + + espree@11.2.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + eslint-visitor-keys: 5.0.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + esutils@2.0.3: {} + + expect-type@1.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.2.0: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + es-define-property: 1.0.1 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + hasown: 2.0.4 + is-callable: 1.2.7 + is-document.all: 1.0.0 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.4 + side-channel: 1.1.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.4 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-document.all@1.0.0: + dependencies: + call-bound: 1.0.4 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.22 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + js-tokens@10.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.2.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.3: + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.8.4 + + math-intrinsics@1.1.0: {} + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.15 + + ms@2.1.3: {} + + nanoid@3.3.12: {} + + natural-compare@1.4.0: {} + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + obug@2.1.3: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.5.15: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + punycode@2.3.1: {} + + react-is@16.13.1: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve@2.0.0-next.7: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + rolldown@1.0.3: + dependencies: + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + semver@6.3.1: {} + + semver@7.8.4: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@4.1.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.1 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.trim@1.2.11: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + has-property-descriptors: 1.0.2 + safe-regex-test: 1.1.0 + + string.prototype.trimend@1.0.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tinybench@2.9.0: {} + + tinyexec@1.2.4: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinyrainbow@3.1.0: {} + + ts-api-utils@2.5.0(typescript@6.0.3): + dependencies: + typescript: 6.0.3 + + ts-pattern@5.9.0: {} + + tslib@2.8.1: + optional: true + + tsx@4.23.0: + dependencies: + esbuild: 0.28.1 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.8: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@6.0.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@8.3.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite@8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.1.1 + esbuild: 0.28.1 + fsevents: 2.3.3 + tsx: 4.23.0 + + vitest@4.1.10(@types/node@26.1.1)(@vitest/coverage-v8@4.1.10)(vite@8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@26.1.1)(esbuild@0.28.1)(tsx@4.23.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 26.1.1 + '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) + transitivePeerDependencies: + - msw + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.2.0 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.22 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.22: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + yocto-queue@0.1.0: {} + + zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..c3bb3d58 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,23 @@ +allowBuilds: + esbuild: true +ignoredBuiltDependencies: + - esbuild +minimumReleaseAgeExclude: + - '@kontent-ai/biome-config@0.7.3' + - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260615.1' + - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260615.1' + - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260615.1' + - '@typescript/native-preview-linux-arm@7.0.0-dev.20260615.1' + - '@typescript/native-preview-linux-x64@7.0.0-dev.20260615.1' + - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260615.1' + - '@typescript/native-preview-win32-x64@7.0.0-dev.20260615.1' + - '@typescript/native-preview@7.0.0-dev.20260615.1' + - '@vitest/coverage-v8@4.1.9' + - '@vitest/expect@4.1.9' + - '@vitest/mocker@4.1.9' + - '@vitest/pretty-format@4.1.9' + - '@vitest/runner@4.1.9' + - '@vitest/snapshot@4.1.9' + - '@vitest/spy@4.1.9' + - '@vitest/utils@4.1.9' + - vitest@4.1.9 diff --git a/readme.md b/readme.md deleted file mode 100644 index 86c2a40c..00000000 --- a/readme.md +++ /dev/null @@ -1,531 +0,0 @@ -[![npm version](https://badge.fury.io/js/%40kontent-ai%2Fdelivery-sdk.svg)](https://badge.fury.io/js/%40kontent-ai%2Fdelivery-sdk) -[![Build](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/test.yml/badge.svg)](https://github.com/kontent-ai/delivery-sdk-js/actions/workflows/test.yml) -[![npm](https://img.shields.io/npm/dt/@kontent-ai/delivery-sdk.svg)](https://www.npmjs.com/package/@kontent-ai/delivery-sdk) -[![Known Vulnerabilities](https://snyk.io/test/github/kontent-ai/delivery-sdk-js/badge.svg)](https://snyk.io/test/github/kontent-ai/delivery-sdk-js) -[![GitHub license](https://img.shields.io/github/license/kontent-ai/delivery-sdk-js.svg)](https://github.com/kontent-ai/delivery-sdk-js) -![Gzip browser bundle](https://img.badgesize.io/https:/cdn.jsdelivr.net/npm/@kontent-ai/delivery-sdk/dist/bundles/kontent-delivery.umd.min.js?compression=gzip) -[![Discord](https://img.shields.io/discord/821885171984891914?label=Discord&logo=Discord&logoColor=white)](https://discord.gg/SKCxwPtevJ) - -# JavaScript Delivery SDK Documentation - -This library is build for fetching [Kontent.ai](https://kontent.ai/) data with `Delivery API`. Works in browser & node. - -> [!TIP] -> It's **highly recommended** to use this library in combination with -> [Model Generator](https://www.npmjs.com/package/@kontent-ai/model-generator). Generating models will greatly increase -> type safety of your code and offer you an advanced intellisense. - -# Kontent.ai Delivery SDK - -## Installation - -```bash -npm i @kontent-ai/delivery-sdk --save -``` - -## Getting started - -```typescript -import { type IContentItem, type Elements, createDeliveryClient } from '@kontent-ai/delivery-sdk'; - -/** - * Generate models with @kontent-ai/model-generator - */ -export type Movie = IContentItem<{ - readonly title: Elements.TextElement; - readonly plot: Elements.RichTextElement; - readonly released: Elements.DateTimeElement; - readonly length: Elements.NumberElement; - readonly poster: Elements.AssetsElement; - readonly category: Elements.MultipleChoiceElement; - readonly stars: Elements.LinkedItemsElement; - readonly seoname: Elements.UrlSlugElement; - readonly releasecategory: Elements.TaxonomyElement; -}>; - -// Both `CoreDeliveryClient` and `CoreClientTypes` are types generated by @kontent-ai/model-generator -// By using the generated types you will get access to advanced intellisense & type safety -const deliveryClient: CoreDeliveryClient = createDeliveryClient({ - environmentId: '' -}); - -// fetch items -const response = await deliveryClient.items().type('').toPromise(); - -// read data of first item -const movieText = response.data.items[0].elements.title.value; -``` - -## Configuration - -| Property | type | description | -| ---------------------------- | :--------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| environmentId | string | environmentId of your Kontent.ai project | -| elementResolver? | ElementResolver | Element resolver used to map custom elements | -| previewApiKey? | string | Preview API key used to get unpublished content items | -| defaultLanguage? | string | Sets default language that will be used for all queries unless overridden with query parameters | -| proxy? | IDeliveryClientProxyConfig | Can be used to configure custom URLs. Useful when you use reverse proxy or have a need to transform URL - e.g. to remove 'environmentId' | -| secureApiKey? | string | Secured API key: Use secured API only when running on Node.JS server, otherwise you can expose your key | -| defaultQueryConfig? | IQueryConfig | Default configuration for all queries. Can be overridden by individual queries | -| httpService ? | IHttpService | Can be used to inject custom http service for performing requests | -| globalHeaders? | (queryConfig: IQueryConfig) => IHeader[] | Adds ability to add extra headers to each http request | -| retryStrategy? | IRetryStrategyOptions | Retry strategy configuration | -| linkedItemsReferenceHandler? | LinkedItemsReferenceHandler | Indicates if content items are automatically mapped. Available values: 'map' or 'ignore' | -| assetsDomain? | string | Custom domain for assets. Changes url of assets in both asset & rich text elements | -| defaultRenditionPreset? | string | Codename of rendition preset to be applied by default to the base asset URL path when present. When set, the SDK will provide the URL of customized images by default. Right now the only supported preset codename is `default`. | -| excludeArchivedItems? | boolean | Can be used to exclude archived items from all queries by default. Only applicable when preview API is used. | - -### Querying - -The SDK supports the following query parameters: `depthParameter`, `elementsParameter`, `excludeElementsParameter`, -`limitParameter`, `orderParameter`, `skipParameter` and `languageParameter`. For more information about the parameters, -see the [SDK query methods](#filter-content) below. You can also head over to -[Delivery API reference](https://kontent.ai/learn/docs/apis/openapi/delivery-api/#tag/Filtering-parameters). - -```typescript -// Gets 5 items based on the Movie type -deliveryClient.items().type('movie').limitParameter(5).skipParameter(2).toPromise(); -``` - -| Filter | -| -------------------------- | -| `depthParameter` | -| `elementsParameter` | -| `excludeElementsParameter` | -| `limitParameter` | -| `orderParameter` | -| `skipParameter` | -| `languageParameter` | - -#### Filtering - -Filters are also considered query parameters and can be combined. See -[Content filtering in API reference](https://kontent.ai/learn/docs/apis/openapi/delivery-api/#tag/Filtering-parameters) -for more examples. - -```typescript -// Gets items based on the Movie type with 'Warrior' in their 'Title' element -deliveryClient.items().type('movie').equalsFilter('elements.title', 'Warrior').toPromise(); -``` - -| Filter | -| -------------------------- | -| `type` | -| `types` | -| `allFilter` | -| `anyFilter` | -| `containsFilter` | -| `equalsFilter` | -| `greaterThanFilter` | -| `greaterThanOrEqualFilter` | -| `inFilter` | -| `lessThanFilter` | -| `lessThanOrEqualFilter` | -| `rangeFilter` | -| `emptyFilter` | -| `NotEmptyFilter` | -| `notEqualsFilter` | -| `notInFilter` | - -#### Soring - -You can sort data by using any of the following methods: - -```typescript -deliveryClient.items().type('movie').orderByDescending('elements.title').toPromise(); -deliveryClient.items().type('movie').orderByAscending('elements.title').toPromise(); -deliveryClient.items().type('movie').orderParameter('elements.title', 'desc').toPromise(); -``` - -### Execute queries with a custom URL - -When you have an URL (i.e. for `next page` in paging, for testing purposes or just if you prefer to build it on your -own) and still want to leverage SDK functionality such as type mapping, property resolving etc., use `withUrl` parameter -on any query such as: - -```typescript -deliveryClient - .items() - .withUrl('https://deliver.kontent.ai/da5abe9f-fdad-4168-97cd-b3464be2ccb9/items?system.type=movie') - .toPromise(); -``` - -### Custom parameters - -In case you need to use custom parameters to build up an URL, use `withParameter` method: - -```typescript -deliveryClient.items().withParameter('name', 'value').toPromise(); -``` - -### Get localized items - -You can specify [language of items](https://kontent.ai/learn/tutorials/manage-kontent/projects/set-up-languages) with -`languageParameter` of a particular query. You can also define default language that will be used if `languageParameter` -is not used during the initialization of delivery client. - -```typescript -import { createDeliveryClient } from '@kontent-ai/delivery-sdk'; - -var deliveryClient = new createDeliveryClient({ - environmentId: '', - defaultLanguage: 'es' -}); - -// Gets items in 'es' language because it is marked as default -deliveryClient.item('warrior').toPromise(); - -// Gets items in 'en' language because language parameter has priority over the default one -deliveryClient.item('warrior').languageParameter(`en`).toPromise(); -``` - -### Preview mode - -You can enable the preview mode either globally (when [initializing the DeliveryClient](#how-to-use-deliveryclient)) or -per query. In each case, you need to set `previewApiKey` in the delivery client global configuration. - -#### Enable preview mode globally - -```typescript -import { createDeliveryClient } from '@kontent-ai/delivery-sdk'; - -const deliveryClient = createDeliveryClient({ - environmentId: ''; - previewApiKey: '', - defaultQueryConfig: { - usePreviewMode: true - } -}); -``` - -#### Enable preview mode per query - -```typescript -deliveryClient - .items() - .queryConfig({ - usePreviewMode: true - }) - .toPromise(); -``` - -### Secure Delivery API - -Using the Delivery API with -[secure access](https://kontent.ai/learn/tutorials/develop-apps/build-strong-foundation/restrict-public-access) enabled -is recommend only when the request is not being executed on the client (browser) because otherwise you will expose the -API key publicly. - -```typescript -import { createDeliveryClient } from '@kontent-ai/delivery-sdk'; - -const deliveryClient = createDeliveryClient({ - environmentId: ''; - secureApiKey: '', - defaultQueryConfig: { - // Enabled secure access for all queries - useSecuredMode: true - } -}); -``` - -As with [preview mode](#preview-mode), you can also override global settings on query level. - -```typescript -deliveryClient - .items() - .queryConfig({ - // Enables secure access only for this query - useSecuredMode: true - }) - .toPromise(); -``` - -### Image transformation - -Use `ImageUrlBuilder` for your [image transformations](https://kontent.ai/learn/reference/image-transformation) on asset -URLs. - -```typescript -import { transformImageUrl } from '@kontent-ai/delivery-sdk'; - -// Sample asset URL; You'll find URLs like these in asset and rich text elements -const assetUrl = `https://assets-eu-01.kc-usercontent.com/ede994d8-bb05-01b5-9c33-8b65e7372306/4f45e0a8-4fc3-4143-a81f-55b7e4ce7daa/warrior.jpg`; - -const transformedUrl = transformImageUrl(assetUrl) - .withDpr(2) - .withCompression('lossless') - .withQuality(4) - .withHeight(200) - .withWidth(100) - .getUrl(); -``` - -### Paging - -All listing queries support automatic paging. To use automatic paging, use `toAllPromise` extension method: - -```typescript -// this executed multiple HTTP requests until it gets all items -const response = await deliveryClient.items().limitParameter(5).toAllPromise(); - -// only gets 3 pages at maximum -const response = await deliveryClient.items().limitParameter(5).toAllPromise({ - pages: 3 -}); -``` - -### Resolving rich text elements - -[Rich text elements](https://kontent.ai/learn/reference/delivery-api#section/Rich-text-element) in Kontent.ai may -contain linked items and components. For example, if you write a blog post, you might want to insert a video or -testimonial to a specific place in your article. - -To learn how to work with Rich text element have a look at -[@kontent-ai/rich-text-resolver](https://www.npmjs.com/package/@kontent-ai/rich-text-resolver) library. - -## Get content types - -```typescript -deliveryClient.type('movie').toPromise(); -deliveryClient.types().toPromise(); -deliveryClient.types().toAllPromise(); -``` - -## Get taxonomies - -```typescript -deliveryClient.taxonomy('taxonomyGroupName').toPromise(); -deliveryClient.taxonomies().toPromise(); -deliveryClient.taxonomies().toAllPromise(); -``` - -## Proxy configuration - -If you want to use a proxy server, you need to use a different domain or otherwise transform the URL. By using `proxy` -configuration option you can define your own base domains as well as URL format. This is useful if you need to for -example hide the `environmentId` from the URL. - -`IDeliveryClientProxyConfig` offers 3 ways of configuring proxy URL: - -1. `baseUrl` - Base URL used for all requests. Defaults to 'deliver.kontent.ai' -2. `basePreviewUrl` - Base url used for preview requests. Defaults to 'preview-deliver.kontent.ai' -3. `advancedProxyUrlResolver` - Resolver function where you get `IProxyUrlData` context data (includes domain, action, - query parameters..) and can fully customize the final URL. - -Examples: - -```typescript -const client = createDeliveryClient({ - environmentId: '', - // Will be used instead of 'https://deliver.kontent.ai' for all requests. - // Parameters, filters, project Id and other parts of the URL will use default values. - proxy: { - baseUrl: 'http://my-proxy.io' - } -}); -``` - -```typescript -const client = createDeliveryClient({ - environmentId: '', - proxy: { - advancedProxyUrlResolver: (data) => { - const action = data.action; // /items - const domain = data.domain; // https://deliver.kontent.ai - const environmentId = data.environmentId; // xxx - const queryString = data.queryString; // e.g. ?depth=1&elements=xElement - const queryParameters = data.queryParameters; // array with query parameters parameters - const queryConfig = data.queryConfig; // query configuration - return `http://my-proxy.io${action}${queryString}`; // proxy URL with omitted project Id - } - } -}); -``` - -## Error handling - -If the error originates in Kontent.ai (see -[error responses](https://kontent.ai/learn/reference/delivery-api#section/SDKs)), you will get a `DeliveryError` object -instance with more specific information. Otherwise, you will get the original error. - -```typescript -import { DeliveryError } from '@kontent-ai/delivery-sdk'; - -try { - await deliveryClient.item('invalid_codename').toPromise(); -} catch (error) { - if (error instanceof DeliveryError) { - // delivery specific error (e.g. item with codename not found...) - console.log(err.message, err.errorCode); - } else { - // some other error - console.log(error); - } -} -``` - -### Remapping json responses - -In some scenarios, you might want to store `json` response for later use and use SDK to map the response for you. There -are 2 ways you can map previously stored `json`: - -```typescript -const result = await deliveryClient.item('codename').toPromise(); -const json = result.response.data; - -// approach #1 -const remappedData = deliveryClient.mappingService.viewContentItemResponse(json); - -// approach #2 -const remappedData = deliveryClient.item(movieCodename).map(json); -``` - -### Handling circular references - -By default, the SDK automatically maps content items present in `linked items` & `rich text` elements. Linked items can -reference other linked items in their tree (e.g. child item referencing parent) which may cause infinite nesting -(circular reference). This behavior is not an issue for most scenarios, in fact it is beneficial as you can easily -access all linked items. However, you cannot easily serialize such model. Using e.g. `JSON.stringify` would fail if -there are circular references. - -For this reason, you may disable mapping of linked items with `linkedItemsReferenceHandler` configuration option. - -```typescript -const client = getTestDeliveryClient({ - environmentId: '', - linkedItemsReferenceHandler: 'ignore' // or 'map' -}); -``` - -### Using custom HTTP service - -The SDK allows you to inject your own instance of a class implementing the `IHttpService` interface. This way you can -easily mock responses, implement your own http service, or modify the requests in some other way. - -Sample of a test `HttpService` implementation can be found at https://github.com/kontent-ai/core-sdk-js - -Once you have your `HttpService`, use it in delivery client initialization: - -```typescript -const deliveryClient = createDeliveryClient({ - environmentId: '', - httpService: YourHttpServiceImplementation -}); -``` - -### Use custom models for Custom elements - -You can register an `ElementResolver` to map custom elements into dedicated element models and work with data more -effectively. - -For example, if you have a custom `color` element in your Kontent.ai project with json data like: - -```json - "color": { - "type": "custom", - "name": "Color", - "value": "{\"red\":167,\"green\":96,\"blue\":197}" - } -``` - -You can create a `ColorElement` type with strongly typed properties for `red`, `green` & `blue` values that you will -parse from the json. - -```typescript -import { ElementModels, Elements, createDeliveryClient } from '@kontent-ai/delivery-sdk'; - -type ColorElement = Elements.CustomElement<{ - red: number; - green: number; - blue: number; -}>; -``` - -To resolve your custom element into `ColorElement`, use the `ElementResolver` in your delivery client config: - -```typescript -const client = createDeliveryClient({ - environmentId: '', - elementResolver: (elementWrapper) => { - if (elementWrapper.rawElement.type === 'color') { - const parsed = JSON.parse(elementWrapper.rawElement.value); - - return { - red: parsed.red, - green: parsed.green, - blue: parsed.blue - }; - } - - return undefined; - } -}); -``` - -You can then use this custom element type in your models: - -```typescript -type Movie = IContentItem<{ - color: ColorElement; - title: Elements.TextElement; -}>; -``` - -## UMD bundles - -When using UMD bundle and including this library in `script` tag on your `html` page, you can find it under the -`kontentDelivery` global variable. - -Bundles are distributed in `dist/bundles` folder: - -- `dist/bundles/kontent-delivery.umd.js` -- `dist/bundles/kontent-delivery.umd.min.js` - -## Debugging - -### Accessing request data - -Every response from this SDK contains additional debug data you can use to inspect when something is not right or if you -need to access response headers or other network related properties. - -```typescript -const deliveryResponse = await createDeliveryClient({ environmentId: 'environmentId' }) - .item('itemCodename') - .toPromise(); -const rawResponseData = deliveryResponse.response; // contains raw response data, headers, status etc.. -const responseHeaders = deliveryResponse.response.headers; -``` - -### Getting URL of a query - -In case you need to get the raw URL of a request before calling it, use the `getUrl()` method on any query. - -```typescript -const queryText = deliveryClient - .items() - .type('movie') - .limitParameter(10) - .orderParameter('system.codename', 'desc') - .getUrl(); - -console.log(queryText); -// outputs: -// https://deliver.kontent.ai/b52fa0db-84ec-4310-8f7c-3b94ed06644d/items?limit=10&order=system.codename[desc]&system.type=movie -``` - -## Testing - -Note: You need to have `Chrome` installed in order to run tests via Karma. - -- `npm run test:browser` Runs tests in Chrome -- `npm run test:node` Runs tests in node.js -- `npm run test:all` Runs all test - -> If you want to mock http responses, it is possible to use -> [custom Http Service](https://github.com/kontent-ai/core-sdk-js#testing) as a part of the -> [delivery client configuration](#client-configuration). - -## Feedback & Contribution - -Feedback & Contributions are welcomed. Feel free to take/start an issue & submit PR. diff --git a/sample/safe-vs-unsafe-queries.ts b/sample/safe-vs-unsafe-queries.ts new file mode 100644 index 00000000..58d4e436 --- /dev/null +++ b/sample/safe-vs-unsafe-queries.ts @@ -0,0 +1,93 @@ +/** biome-ignore-all lint/correctness/noUnusedVariables: Disabled for clarity of the sample */ +/** + * Sample: safe vs unsafe queries. + * + * Every query the SDK exposes comes in two flavors: + * - unsafe (`fetchPage`, `fetchAllPages`, `pages`): throws on error. + * - safe (`fetchPageSafe`, `fetchAllPagesSafe`, `pagesSafe`): returns a + * discriminated `{ success, response | error }` result and never throws. + * + * The only difference is how a failure is delivered to your code. + * + * `listLanguages` is used here as a representative paged query. The same + * pattern applies to every other query on the delivery client. + */ + +import { createDeliveryClient } from "../lib/client/delivery-client.js"; + +// Minimal client setup. A real consumer would supply their own environmentId +// and (optionally) a typed schema generic; both are irrelevant to the topic here. +const client = createDeliveryClient({ + apiMode: "public", + environmentId: "x", +}); + +/** + * 1. Unsafe single page + * + * `fetchPage()` throws on any failure, regardless of cause (transport, + * validation, anything else). Wrap at the call boundary if you want the + * error to propagate to your framework. + */ +export async function listLanguagesUnsafe(): Promise { + try { + const response = await client.listLanguages().fetchPage(); + + // response.payload is the validated, fully typed languages page. + const firstLanguageCodename: string | undefined = response.payload.languages[0]?.system.codename; + } catch (error) { + console.error("listLanguages failed:", error); + } +} + +/** + * 2. Safe single page + * + * `fetchPageSafe()` never throws. Branch on `result.success` to access + * either the validated payload or the error. + */ +export async function listLanguagesSafe(): Promise { + const result = await client.listLanguages().fetchPageSafe(); + + if (result.success) { + // Same payload shape as the unsafe path, reached via `result.response`. + const firstLanguageCodename: string | undefined = result.response.payload.languages[0]?.system.codename; + } else { + // `result.error` is always a `DeliverySdkError` regardless of the underlying cause. + console.error("listLanguages failed:", result.error); + } +} + +/** + * 3. All pages, unsafe + * + * `fetchAllPages()` walks the entire result set and throws on the first + * failure. Any pages already fetched before the failure are lost. + */ +export async function listAllLanguagesUnsafe(): Promise { + try { + const response = await client.listLanguages().fetchAllPages(); + + // response.responses is one entry per page. + const totalLanguages = response.responses.flatMap((page) => page.payload.languages).length; + } catch (error) { + console.error("listLanguages paging failed:", error); + } +} + +/** + * 4. All pages, safe + * + * `fetchAllPagesSafe()` is the strongest reason to reach for the safe API: + * on failure, `partialResponses` still contains the pages fetched before + * the error - you can recover whatever progress was made. + */ +export async function listAllLanguagesSafe(): Promise { + const result = await client.listLanguages().fetchAllPagesSafe(); + + if (result.success) { + const totalLanguages = result.responses.flatMap((page) => page.payload.languages).length; + } else { + console.error("listLanguages paging failed", result.error); + } +} diff --git a/sample/sample-schema.ts b/sample/sample-schema.ts new file mode 100644 index 00000000..645a76e0 --- /dev/null +++ b/sample/sample-schema.ts @@ -0,0 +1,245 @@ +/** biome-ignore-all lint/correctness/noUnusedVariables: Disabled for clarity of the sample */ +/** + * Sample: defining a strongly typed Kontent.ai delivery model. + * + * Top to bottom: + * 1. Declare your project's codename schema. + * 2. Define content-type element shapes and their payload types. + * 4. Create a typed delivery client. + * 5. See how response values narrow at the call site. + * + * In a real consumer project, imports below would come from + * `@kontent-ai/delivery-sdk`. This sample lives in the SDK repo, + * so it imports from the in-tree source instead. + */ + +import type { QueryResponse } from "@kontent-ai/core-sdk"; +import { createDeliveryClient } from "../lib/client/delivery-client.js"; +import type { DeliveryMetadata } from "../lib/models/core.models.js"; +import type { + ContentItemOf, + ContentItemPayload, + DeliveryClient, + DeliveryClientSchema, + ElementCodenamesOf, + Elements, + FetchContentItemResponse, + TaxonomyPayload, +} from "../lib/public_api.js"; +import type { SnippetOf } from "../lib/queries/content-items/models/content-item.models.js"; + +/** + * 1. Schema declaration + * + * `DeliveryClientSchema` lists every codename your project uses so queries, + * payloads, and element accessors are checked against it. + * + * `contentTypes` is a map: each key is a content type codename, and its value + * lists that type's element codenames. Elements therefore belong to a type, + * which lets single-type queries narrow elements to the queried type (see + * `typedContentTypeElement` below). `taxonomies` follows the same shape, with + * each taxonomy mapping to its term codenames. + */ +export type SampleProjectSchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["en-us", "es-es"]; + readonly taxonomies: { + readonly category: readonly ["term1", "term2"]; + readonly tag: readonly ["news", "featured"]; + }; + readonly contentTypes: { + readonly movie: readonly [ + "title", + "rating", + "synopsis", + "genre", + "release_date", + "poster", + "categories", + "url_slug", + "custom_id", + "actors", + "metadata__internal_id", + ]; + readonly actor: readonly ["first_name", "last_name", "role", "relatedActors", "metadata__internal_id"]; + }; + readonly collectionCodenames: readonly ["movies", "tv-shows"]; + readonly workflowCodenames: readonly ["published", "draft"]; + readonly workflowStepCodenames: readonly ["published", "draft"]; +}>; + +export type MetadataElements = { + readonly metadata__internal_id: Elements.Text; +}; + +/** + * 2. Content type: Actor + * + * Each property on `ActorElements` maps an element codename to its element type. + * Codename generics on `MultipleChoice<...>` and `Taxonomy<...>` are TypeScript + * hints only: they power autocomplete and narrowing, but the runtime schema + * still accepts any string codename the API returns. + */ +export type ActorElements = { + readonly first_name: Elements.Text; + readonly last_name: Elements.Text; + readonly role: Elements.MultipleChoice<"opt1" | "opt2" | "opt3">; + readonly relatedActors: Elements.LinkedItems; +} & MetadataElements; + +// Fully-typed Actor item payload (system metadata + elements). +export type Actor = ContentItemOf; + +/** + * 3. Content type: Movie + * + * Movie exercises every element type the SDK supports. `LinkedItems` + * tells the SDK that the resolved `items[i]` of `actors` should be typed as + * `Actor`, so consumers get full element narrowing on referenced items. + */ +export type MovieElements = { + readonly title: Elements.Text; + readonly rating: Elements.Number; + readonly synopsis: Elements.RichText; + readonly genre: Elements.MultipleChoice<"genre1" | "genre2">; + readonly release_date: Elements.DateTime; + readonly poster: Elements.Asset; + readonly categories: Elements.Taxonomy<"term1" | "term2">; + readonly url_slug: Elements.UrlSlug; + readonly custom_id: Elements.Custom; + readonly actors: Elements.LinkedItems; +} & MetadataElements; + +// Fully-typed Movie item payload. +export type Movie = ContentItemOf; + +/** + * The element shape is validated against the schema: every key must be an element codename declared + * for the content type. You may type a subset of the type's elements, but unknown codenames are rejected. + */ +// @ts-expect-error "titel" is not an element codename declared for "movie" in the schema. +export type BadMovie = ContentItemOf; + +// A partial shape (only some of the type's elements) is still allowed. +export type PartialMovie = ContentItemOf; + +/** + * 4. Typed delivery client + * + * Pass `SampleProjectSchema` as the generic to `createDeliveryClient` and + * every query is narrowed against your schema. + */ +export type SampleDeliveryClient = DeliveryClient; + +export const client: SampleDeliveryClient = createDeliveryClient({ + apiMode: "public", + environmentId: "x", +}); + +/** + * 5. Demonstration: query typing + * + * Each annotated `const` shows what the SDK narrows a response value to. + */ +export async function queries(): Promise { + const languageResponse = await client.listLanguages().fetchPage(); + + // Languages are typed to the schema codenames. + const responseLanguageCodenames: readonly ("en-us" | "es-es")[] = languageResponse.payload.languages.map( + (language) => language.system.codename, + ); + + // `fetchContentItem` returns a fully typed item payload. Annotate it with `FetchContentItemResponse` + // instead of hand-assembling the response type from `@kontent-ai/core-sdk`. + const response: FetchContentItemResponse = await client.fetchContentItem({ codename: "itemCodename" }).fetch(); + + const movieItem = response.payload.item; + if (isMovie(movieItem)) { + const title: string = movieItem.elements.title.value; + const releaseDate: string | null = movieItem.elements.release_date.value; + const actors: readonly Actor[] = movieItem.elements.actors.items; + } +} + +/** + * 6. Demonstration: element value narrowing + * + * Annotations below are the types the SDK gives you at compile time. They + * produce a compile error if the public types drift. Narrowed codenames are + * TypeScript hints; the runtime value can be any string the API returns. + */ +export function typedActor(actor: Actor): void { + const firstName: string = actor.elements.first_name.value; + + // `value[0]?.codename` is narrowed to one of the declared literals (or undefined when empty). + const roleCodename: "opt1" | "opt2" | "opt3" | undefined = actor.elements.role.value[0]?.codename; + + // `relatedActors.value` holds the codenames of the referenced items. + const firstRelatedActorCodename: string | undefined = actor.elements.relatedActors.value[0]; +} + +export function typedMovie(movie: Movie): void { + const title: string = movie.elements.title.value; + const rating: number | null = movie.elements.rating.value; + const synopsis: string = movie.elements.synopsis.value; + const synopsisActors: readonly Actor[] = movie.elements.synopsis.items; + const genreCodename: "genre1" | "genre2" | undefined = movie.elements.genre.value[0]?.codename; + const releaseDate: string | null = movie.elements.release_date.value; + const displayTimezone: string | null = movie.elements.release_date.display_timezone; + const posterUrl: string | undefined = movie.elements.poster.value[0]?.url; + const categoryCodename: "term1" | "term2" | undefined = movie.elements.categories.value[0]?.codename; + const urlSlug: string = movie.elements.url_slug.value; + const customId: string | null = movie.elements.custom_id.value; + const movieActorCodename: string | undefined = movie.elements.actors.value[0]; + const firstMovieActor: Actor | undefined = movie.elements.actors.items[0]; + const actors: readonly Actor[] = movie.elements.actors.items; +} + +export async function typedTaxonomy(): Promise { + const categoryTaxonomy: QueryResponse, DeliveryMetadata> = await client + .fetchTaxonomy({ codename: "category" }) + .fetch(); + + // Term codenames are narrowed to the terms declared for the "category" taxonomy in the schema. + const termCodename: "term1" | "term2" | undefined = categoryTaxonomy.payload.terms[0]?.codename; + + // Narrowing applies at every nesting level (the term tree shares one flat codename union). + const nestedTermCodename: "term1" | "term2" | undefined = categoryTaxonomy.payload.terms[0]?.terms[0]?.codename; + + // A different taxonomy narrows to its own terms. + const tagTaxonomy = await client.fetchTaxonomy({ codename: "tag" }).fetch(); + const tagCodename: "news" | "featured" | undefined = tagTaxonomy.payload.terms[0]?.codename; +} + +/** + * 7. Demonstration: per-content-type element codenames + * + * Because elements live under their content type in the schema, single-type + * queries narrow element codenames to the queried type — exactly how + * `fetchTaxonomy` narrows term codenames to the queried taxonomy. + */ +export async function typedContentTypeElement(): Promise { + // `elementCodename` is narrowed to the elements declared for the "movie" type. + await client.fetchContentTypeElement({ typeCodename: "movie", elementCodename: "title" }).fetch(); + + // A different type narrows to its own elements. + await client.fetchContentTypeElement({ typeCodename: "actor", elementCodename: "first_name" }).fetch(); + + // @ts-expect-error "first_name" belongs to "actor", not "movie". + await client.fetchContentTypeElement({ typeCodename: "movie", elementCodename: "first_name" }).fetch(); + + // `fetchContentType` narrows its element selection to the queried type too. + await client.fetchContentType({ codename: "movie", query: { elements: ["title", "rating"] } }).fetch(); + + // The element codenames of a single type can be derived directly from the schema. + const movieElement: ElementCodenamesOf = "synopsis"; +} + +function isMovie(item: ContentItemPayload): item is Movie { + return item.system.codename === ("movie" as keyof SampleProjectSchema["contentTypes"]); +} + +function isMetadata( + item: ContentItemPayload, +): item is SnippetOf { + return ["actor", "movie"].includes(item.system.type); +} diff --git a/sample/tsconfig.json b/sample/tsconfig.json new file mode 100644 index 00000000..8cd5b443 --- /dev/null +++ b/sample/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "noEmit": true, + "noUnusedLocals": false, + "noUnusedParameters": false + }, + "include": ["**/*"] +} diff --git a/scripts/clean.ts b/scripts/clean.ts new file mode 100644 index 00000000..1a0e42dc --- /dev/null +++ b/scripts/clean.ts @@ -0,0 +1,5 @@ +import { deleteFolderRecursive } from "@kontent-ai/core-sdk/devkit"; + +for (const path of ["dist", "bundles"]) { + deleteFolderRecursive(path); +} diff --git a/scripts/create-bundles.ts b/scripts/create-bundles.ts new file mode 100644 index 00000000..1c1d9b4b --- /dev/null +++ b/scripts/create-bundles.ts @@ -0,0 +1,15 @@ +import { fileURLToPath } from "node:url"; +import { formatBytes, scenarios, writeBundles } from "./utils/measure-bundle-utils.js"; + +const repoRoot = fileURLToPath(new URL("..", import.meta.url)); +const outDir = `${repoRoot}bundles`; + +const [minified, unminified] = await Promise.all([ + writeBundles(scenarios, { resolveDir: repoRoot, outDir, minify: true }), + writeBundles(scenarios, { resolveDir: repoRoot, outDir, minify: false }), +]); + +console.log(`Wrote ${minified.length + unminified.length} bundles to ${outDir}:`); +for (const { path, bytes } of [...unminified, ...minified]) { + console.log(` ${path} (${formatBytes(bytes)})`); +} diff --git a/scripts/measure-bundle.ts b/scripts/measure-bundle.ts new file mode 100644 index 00000000..be612189 --- /dev/null +++ b/scripts/measure-bundle.ts @@ -0,0 +1,6 @@ +import { fileURLToPath } from "node:url"; +import { measureScenarios, printSizeTable, scenarios } from "./utils/measure-bundle-utils.js"; + +const repoRoot = fileURLToPath(new URL("..", import.meta.url)); + +printSizeTable(await measureScenarios(scenarios, { resolveDir: repoRoot })); diff --git a/scripts/update-version.ts b/scripts/update-version.ts new file mode 100644 index 00000000..6ffaab6b --- /dev/null +++ b/scripts/update-version.ts @@ -0,0 +1,5 @@ +import { replaceSdkVersionPlaceholder } from "@kontent-ai/core-sdk/devkit"; +// biome-ignore lint/correctness/useImportExtensions: package.json is a JSON file +import packageJson from "../package.json" with { type: "json" }; + +replaceSdkVersionPlaceholder("./dist/delivery-sdk-info.js", packageJson.version); diff --git a/scripts/utils/measure-bundle-utils.ts b/scripts/utils/measure-bundle-utils.ts new file mode 100644 index 00000000..07800910 --- /dev/null +++ b/scripts/utils/measure-bundle-utils.ts @@ -0,0 +1,132 @@ +import { mkdir, writeFile } from "node:fs/promises"; +import { brotliCompressSync, gzipSync } from "node:zlib"; +import { build } from "esbuild"; + +export type Scenario = { + readonly name: TName; + readonly entryContents: string; + readonly thresholdKb: number; +}; + +export type SizeResult = { + readonly scenario: TName; + readonly raw: number; + readonly min: number; + readonly gzip: number; + readonly brotli: number; +}; + +export type ScenarioName = "public_api (full)" | "public_schemas (full)"; + +export const scenarios: readonly Scenario[] = [ + { + name: "public_api (full)", + entryContents: `export * from "./lib/public_api.ts";`, + thresholdKb: 20, + }, + { + name: "public_schemas (full)", + entryContents: `export * from "./lib/public_schemas.ts";`, + thresholdKb: 11, + }, +]; + +const bundleScenario = async ( + scenario: Scenario, + { resolveDir, minify }: { readonly resolveDir: string; readonly minify: boolean }, +): Promise => { + const result = await build({ + stdin: { + contents: scenario.entryContents, + resolveDir, + loader: "ts", + }, + bundle: true, + format: "esm", + platform: "neutral", + target: "es2022", + treeShaking: true, + minify, + write: false, + legalComments: "none", + logLevel: "silent", + }); + + const output = result.outputFiles?.[0]; + if (!output) { + throw new Error(`esbuild produced no output for scenario "${scenario.name}"`); + } + return output.contents; +}; + +export const measureScenarios = async ( + scenarios: readonly Scenario[], + options: { readonly resolveDir: string }, +): Promise[]> => + Promise.all( + scenarios.map(async (scenario): Promise> => { + const [rawBytes, minBytes] = await Promise.all([ + bundleScenario(scenario, { resolveDir: options.resolveDir, minify: false }), + bundleScenario(scenario, { resolveDir: options.resolveDir, minify: true }), + ]); + return { + scenario: scenario.name, + raw: rawBytes.byteLength, + min: minBytes.byteLength, + gzip: gzipSync(minBytes).byteLength, + brotli: brotliCompressSync(minBytes).byteLength, + }; + }), + ); + +const toSafeFileName = (name: string): string => + name + .replaceAll(/[^a-z0-9]+/gi, "-") + .replace(/^-+|-+$/g, "") + .toLowerCase(); + +export type WrittenBundle = { + readonly scenario: TName; + readonly path: string; + readonly bytes: number; +}; + +export const writeBundles = async ( + scenarios: readonly Scenario[], + options: { readonly resolveDir: string; readonly outDir: string; readonly minify?: boolean }, +): Promise[]> => { + await mkdir(options.outDir, { recursive: true }); + const minify = options.minify ?? true; + return Promise.all( + scenarios.map(async (scenario): Promise> => { + const bytes = await bundleScenario(scenario, { resolveDir: options.resolveDir, minify }); + const suffix = minify ? ".min.js" : ".js"; + const path = `${options.outDir}/${toSafeFileName(scenario.name)}${suffix}`; + await writeFile(path, bytes); + return { scenario: scenario.name, path, bytes: bytes.byteLength }; + }), + ); +}; + +export const formatBytes = (n: number): string => { + if (n < 1024) { + return `${n} B`; + } + const kb = n / 1024; + return `${kb.toFixed(1)} kB`; +}; + +const columns = ["scenario", "raw", "min", "gzip", "brotli"] as const; + +export const printSizeTable = (rows: readonly SizeResult[]): void => { + const cell = (row: SizeResult, col: (typeof columns)[number]): string => + col === "scenario" ? row.scenario : formatBytes(row[col]); + const widths = columns.map((col) => Math.max(col.length, ...rows.map((row) => cell(row, col).length))); + const renderRow = (cells: readonly string[]): string => cells.map((value, i) => value.padEnd(widths[i] ?? 0)).join(" "); + + console.log(renderRow([...columns])); + console.log(renderRow(widths.map((w) => "-".repeat(w)))); + for (const row of rows) { + console.log(renderRow(columns.map((col) => cell(row, col)))); + } +}; diff --git a/test/browser/client/delivery-client.spec.ts b/test/browser/client/delivery-client.spec.ts deleted file mode 100644 index c77b98b1..00000000 --- a/test/browser/client/delivery-client.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DeliveryClient } from '../../../lib'; - -describe('Delivery Client initialization', () => { - it(`initialization DeliveryClient without config should throw error`, () => { - expect(() => new DeliveryClient(null as any)).toThrowError(); - expect(() => new DeliveryClient(undefined as any)).toThrowError(); - }); -}); diff --git a/test/browser/isolated-tests/core/base-url.spec.ts b/test/browser/isolated-tests/core/base-url.spec.ts deleted file mode 100644 index 2fb37a18..00000000 --- a/test/browser/isolated-tests/core/base-url.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Base URL', () => { - - const context = new Context(); - setup(context); - - let itemsUrl: string; - let parsedUrl: URL; - - beforeAll(() => { - itemsUrl = context.deliveryClient.items().getUrl(); - - parsedUrl = new URL(itemsUrl); - }); - - it(`url should be defined`, () => expect(itemsUrl).toBeDefined()); - - it(`protocol should be 'https:'`, () => expect(parsedUrl.protocol).toEqual('https:')); - - it(`host should be 'deliver.kontent.ai'`, () => expect(parsedUrl.host).toEqual('deliver.kontent.ai')); - - it(`origin should be 'https://deliver.kontent.ai'`, () => expect(parsedUrl.origin).toEqual('https://deliver.kontent.ai')); - - it(`pathname should contain environment id'`, () => expect(itemsUrl).toContain(context.environmentId)); - - it(`custom base URL should be used'`, () => { - const baseUrl = 'http://custombase.com'; - const contextCustom = new Context({baseUrl: baseUrl}); - setup(contextCustom); - expect(contextCustom.deliveryClient.items().getUrl()).toContain(baseUrl); - }); - - it(`custom preview URL should be used'`, () => { - const previewUrl = 'http://custompreview.com'; - const contextCustom = new Context({basePreviewUrl: previewUrl, defaultQueryConfig: { usePreviewMode: true}}); - setup(contextCustom); - expect(contextCustom.deliveryClient.items().getUrl()).toContain(previewUrl); - }); - -}); - diff --git a/test/browser/isolated-tests/core/core-headers.spec.ts b/test/browser/isolated-tests/core/core-headers.spec.ts deleted file mode 100644 index 923b0bff..00000000 --- a/test/browser/isolated-tests/core/core-headers.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { sdkInfo } from '../../../../lib'; -import { Context, setup } from '../../setup'; -import { IHeader } from '@kontent-ai/core-sdk'; - -describe('Core headers', () => { - - const context = new Context(); - - setup(context); - - it(`SDK Id version header should be set`, () => { - const headers = context.deliveryClient.items().getHeaders(); - const header = headers.find(m => m.header === 'X-KC-SDKID'); - expect(header).toBeDefined(); - }); - - it(`Verifies SDK Id version format`, () => { - const headers = context.deliveryClient.items().getHeaders(); - const header = headers.find(m => m.header === 'X-KC-SDKID') as IHeader; - const expectedValue = `${sdkInfo.host};${sdkInfo.name};${sdkInfo.version}`; - expect(header.value).toEqual(expectedValue); - }); - -}); - diff --git a/test/browser/isolated-tests/core/global-headers.spec.ts b/test/browser/isolated-tests/core/global-headers.spec.ts deleted file mode 100644 index b268aec7..00000000 --- a/test/browser/isolated-tests/core/global-headers.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { IHeader } from '@kontent-ai/core-sdk'; - -import { IQueryConfig } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Global headers', () => { - let headers: IHeader[] = []; - const context = new Context(); - let queryConfig: IQueryConfig | undefined; - context.globalHeaders = (xQueryConfig) => { - queryConfig = xQueryConfig; - return [ - { - header: 'gl1', - value: 'vl1', - }, - { - header: 'gl2', - value: 'vl2', - } - ]; - }; - - setup(context); - - beforeAll((done) => { - headers = context.deliveryClient.items().queryConfig({ - usePreviewMode: true - }).getHeaders(); - - done(); - }); - - it(`Global headers should be set`, () => { - const header1 = headers.find(m => m.header === 'gl1') as IHeader; - const header2 = headers.find(m => m.header === 'gl2') as IHeader; - expect(header1).toBeDefined(); - expect(header2).toBeDefined(); - - expect(header1.value).toEqual('vl1'); - expect(header2.value).toEqual('vl2'); - }); - - - it(`Query config should be set and preview mode enabled`, () => { - expect(queryConfig).toBeDefined(); - - if (queryConfig) { - expect(queryConfig.usePreviewMode).toBeTruthy(); - - } - }); - -}); - diff --git a/test/browser/isolated-tests/core/global-query-headers.spec.ts b/test/browser/isolated-tests/core/global-query-headers.spec.ts deleted file mode 100644 index e6ab5a65..00000000 --- a/test/browser/isolated-tests/core/global-query-headers.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Global query headers', () => { - - it(`globally defined header should stay in headers when query config defines empty header array`, () => { - const context = new Context({ - globalHeaders: (config) => [ - { - header: 'xHeader', - value: 'x' - } - ], - defaultQueryConfig: { - customHeaders: [] - } - }); - - setup(context); - const headers = context.deliveryClient.items().getHeaders(); - const xHeader = headers.find(m => m.header === 'xHeader'); - expect(xHeader).toBeDefined(); - }); - - it(`globally defined header should stay in headers along with headers defined by query config`, () => { - const context = new Context({ - globalHeaders: (config) => [ - { - header: 'xHeader', - value: 'x' - } - ], - defaultQueryConfig: { - customHeaders: [{ - header: 'yHeader', - value: 'y' - }] - } - }); - - setup(context); - const headers = context.deliveryClient.items().getHeaders(); - const xHeader = headers.find(m => m.header === 'xHeader'); - const yHeader = headers.find(m => m.header === 'yHeader'); - expect(xHeader).toBeDefined(); - expect(yHeader).toBeDefined(); - }); - -}); - diff --git a/test/browser/isolated-tests/core/preview-headers.spec.ts b/test/browser/isolated-tests/core/preview-headers.spec.ts deleted file mode 100644 index 3fdecb35..00000000 --- a/test/browser/isolated-tests/core/preview-headers.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Context, setup } from '../../setup'; -import { IHeader } from '@kontent-ai/core-sdk'; - -describe('Preview headers', () => { - - const context = new Context({ - defaultQueryConfig: { - usePreviewMode: true - } - }); - - setup(context); - - it(`preview authorization header should be defined when getting items (global config)'`, () => { - const headers = context.deliveryClient.items().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization'); - expect(authorizationHeader).toBeDefined(); - }); - - it(`preview authorization header should be defined when getting taxonomies (global config)'`, () => { - const headers = context.deliveryClient.types().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization'); - expect(authorizationHeader).toBeDefined(); - }); - - it(`preview authorization header should be defined for getting types (global config)'`, () => { - const headers = context.deliveryClient.taxonomies().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization'); - expect(authorizationHeader).toBeDefined(); - }); - - it(`preview authorization header should contain preview API key (global config)'`, () => { - const headers = context.deliveryClient.items().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization') as IHeader; - const expectedValue = 'bearer ' + context.previewApiKey; - expect(authorizationHeader.value).toEqual(expectedValue); - }); - - it(`preview authorization header should NOT be defined when QueryConfig specifically disables it'`, () => { - const headers = context.deliveryClient.items().queryConfig({ - usePreviewMode: false - }).getHeaders(); - - const authorizationHeader = headers.find(m => m.header === 'authorization'); - - expect(authorizationHeader).toBeUndefined(); - }); -}); - diff --git a/test/browser/isolated-tests/core/preview-url.spec.ts b/test/browser/isolated-tests/core/preview-url.spec.ts deleted file mode 100644 index cade624a..00000000 --- a/test/browser/isolated-tests/core/preview-url.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Preview URL', () => { - - const context = new Context({ - defaultQueryConfig: { - usePreviewMode: true - } - }); - - setup(context); - - it(`origin should be 'https://preview-deliver.kontent.ai'`, () => { - const url = new URL(context.deliveryClient.items().getUrl()); - expect(url.origin).toEqual('https://preview-deliver.kontent.ai'); - }); - - it(`preview pathname should contain environment id'`, () => { - const url = context.deliveryClient.items().getUrl(); - expect(url).toContain(context.environmentId); - }); -}); - diff --git a/test/browser/isolated-tests/core/preview-with-secured-mode.spec.ts b/test/browser/isolated-tests/core/preview-with-secured-mode.spec.ts deleted file mode 100644 index 00c50027..00000000 --- a/test/browser/isolated-tests/core/preview-with-secured-mode.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Using secured with preview mode', () => { - - const context = new Context({ - defaultQueryConfig: { - usePreviewMode: true, - useSecuredMode: true - } - }); - - setup(context); - - it(`using secured API in combination with preview mode should thrown an Exception`, () => { - expect(() => context.deliveryClient.items().getHeaders()).toThrowError(); - }); -}); - diff --git a/test/browser/isolated-tests/core/proxy-url-spec.ts b/test/browser/isolated-tests/core/proxy-url-spec.ts deleted file mode 100644 index 8be65fdd..00000000 --- a/test/browser/isolated-tests/core/proxy-url-spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { DeliveryClient, IProxyUrlData } from '../../../../lib'; - -describe('Proxy URL #1', () => { - - let proxyData: IProxyUrlData | undefined; - - const client = new DeliveryClient({ - environmentId: 'xxx', - proxy: { - advancedProxyUrlResolver: (data) => { - proxyData = data; - return 'http://custom-proxy.io'; - } - } - }); - - const itemsUrl: string = client - .item('xCodename') - .depthParameter(1) - .elementsParameter(['xElement']) - .queryConfig({ - useSecuredMode: true - }) - .getUrl(); - - it(`Custom proxy should be applied as request URL`, () => expect(itemsUrl).toEqual('http://custom-proxy.io')); - - it(`Proxy data should be assigned correctly`, () => { - if (!proxyData) { - throw Error(`Proxy data is invalid`); - } - expect(proxyData.action).toEqual('/items/xCodename'); - expect(proxyData.queryParameters.length).toEqual(2); - expect(proxyData.environmentId).toEqual('xxx'); - expect(proxyData.queryString).toEqual('?depth=1&elements=xElement'); - expect(proxyData.queryConfig.useSecuredMode).toBeTruthy(); - expect(proxyData.domain).toEqual('https://deliver.kontent.ai'); - }); -}); - - diff --git a/test/browser/isolated-tests/core/secured-api-headers.spec.ts b/test/browser/isolated-tests/core/secured-api-headers.spec.ts deleted file mode 100644 index 94996569..00000000 --- a/test/browser/isolated-tests/core/secured-api-headers.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Context, setup } from '../../setup'; -import { IHeader } from '@kontent-ai/core-sdk'; - -describe('Secured headers', () => { - - const context = new Context({ - defaultQueryConfig: { - useSecuredMode: true - } - }); - - setup(context); - - it(`secured authorization header should be defined when getting items (global config)'`, () => { - const headers = context.deliveryClient.items().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization'); - expect(authorizationHeader).toBeDefined(); - }); - - it(`secured authorization header should be defined when getting taxonomies (global config)'`, () => { - const headers = context.deliveryClient.types().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization'); - expect(authorizationHeader).toBeDefined(); - }); - - it(`secured authorization header should be defined for getting types (global config)'`, () => { - const headers = context.deliveryClient.taxonomies().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization'); - expect(authorizationHeader).toBeDefined(); - }); - - it(`secured authorization header should contain secured API key (global config)'`, () => { - const headers = context.deliveryClient.items().getHeaders(); - const authorizationHeader = headers.find(m => m.header === 'authorization') as IHeader; - const expectedValue = 'bearer ' + context.securedApiKey; - expect(authorizationHeader.value).toEqual(expectedValue); - }); - - it(`secured authorization header should NOT be defined when QueryConfig specifically disables it'`, () => { - const headers = context.deliveryClient.items().queryConfig({ - useSecuredMode: false - }).getHeaders(); - - const authorizationHeader = headers.find(m => m.header === 'authorization'); - - expect(authorizationHeader).toBeUndefined(); - }); -}); - diff --git a/test/browser/isolated-tests/core/wait-for-loading-new-content-header.spec.ts b/test/browser/isolated-tests/core/wait-for-loading-new-content-header.spec.ts deleted file mode 100644 index 52dd8422..00000000 --- a/test/browser/isolated-tests/core/wait-for-loading-new-content-header.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Wait for loading new content header', () => { - - it(`defaultQueryConfig header should be present in headers`, () => { - const context = new Context({ - defaultQueryConfig: { - waitForLoadingNewContent: true - } - }); - - setup(context); - const headers = context.deliveryClient.items().getHeaders(); - const waitForLoadingNewContentHeader = headers.find(m => m.header === 'X-KC-Wait-For-Loading-New-Content'); - expect(waitForLoadingNewContentHeader).toBeDefined(); - }); - - it(`defaultQueryConfig header should not be present in headers`, () => { - const context = new Context({ - defaultQueryConfig: { - waitForLoadingNewContent: false - } - }); - - setup(context); - const headers = context.deliveryClient.items().getHeaders(); - const waitForLoadingNewContentHeader = headers.find(m => m.header === 'X-KC-Wait-For-Loading-New-Content'); - expect(waitForLoadingNewContentHeader).toBeUndefined(); - }); - - it(`defaultQueryConfig header should be present in headers`, () => { - const context = new Context({ - defaultQueryConfig: { - waitForLoadingNewContent: false - } - }); - - setup(context); - const headers = context.deliveryClient.items().queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - const waitForLoadingNewContentHeader = headers.find(m => m.header === 'X-KC-Wait-For-Loading-New-Content'); - expect(waitForLoadingNewContentHeader).toBeDefined(); - }); - - it(`defaultQueryConfig header should not be present in headers`, () => { - const context = new Context({ - defaultQueryConfig: { - waitForLoadingNewContent: true - } - }); - - setup(context); - const headers = context.deliveryClient.items().queryConfig({ waitForLoadingNewContent: false }).getHeaders(); - const waitForLoadingNewContentHeader = headers.find(m => m.header === 'X-KC-Wait-For-Loading-New-Content'); - expect(waitForLoadingNewContentHeader).toBeUndefined(); - }); - -}); - diff --git a/test/browser/isolated-tests/elements/assets/asset-rendition.spec.json b/test/browser/isolated-tests/elements/assets/asset-rendition.spec.json deleted file mode 100644 index 79981782..00000000 --- a/test/browser/isolated-tests/elements/assets/asset-rendition.spec.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "item": { - "system": { - "id": "335d17ac-b6ba-4c6a-ae31-23c1193215cb", - "collection": "default", - "name": "My article", - "codename": "my_article", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "last_modified": "2019-03-27T13:21:11.38Z", - "workflow_step": "published" - }, - "elements": { - "assetWithRenditionInDefaultPreset": { - "type": "asset", - "name": "Teaser image", - "value": [ - { - "name": "sources.jpg", - "type": "image/jpeg", - "size": 45376, - "description": "Description of what the asset represents.", - "url": "https://assets-us-01.kc-usercontent.com/975bf280-fd91-488c-994c-2f04416e5ee3/3e76909f-599f-4742-b472-77fd4b510e92/sources.jpg", - "width": 640, - "height": 457, - "renditions": { - "default": { - "rendition_id": "b447ca6c-8020-4e8f-be57-1d110721e535", - "preset_id": "a6d98cd5-8b2c-4e50-99c9-15192bce2490", - "width": 1280, - "height": 1024, - "query": "w=1280&h=1024&fit=clip&rect=2396,169,1280,1024" - } - } - } - ] - }, - "assetWithRenditionInMobilePreset": { - "type": "asset", - "name": "Teaser image", - "value": [ - { - "name": "sources.jpg", - "type": "image/jpeg", - "size": 45376, - "description": "Description of what the asset represents.", - "url": "https://assets-us-01.kc-usercontent.com/975bf280-fd91-488c-994c-2f04416e5ee3/3e76909f-599f-4742-b472-77fd4b510e92/sources.jpg", - "width": 640, - "height": 457, - "renditions": { - "mobile": { - "rendition_id": "b447ca6c-8020-4e8f-be57-1d110721e535", - "preset_id": "a6d98cd5-8b2c-4e50-99c9-15192bce2490", - "width": 1280, - "height": 1024, - "query": "w=1280&h=1024&fit=clip&rect=2396,169,1280,1024" - } - } - } - ] - }, - "assetWithoutRendition": { - "type": "asset", - "name": "Teaser image", - "value": [ - { - "name": "sources.jpg", - "type": "image/jpeg", - "size": 45376, - "description": "Description of what the asset represents.", - "url": "https://assets-us-01.kc-usercontent.com/975bf280-fd91-488c-994c-2f04416e5ee3/3e76909f-599f-4742-b472-77fd4b510e92/sources.jpg", - "width": 640, - "height": 457 - } - ] - } - } - }, - "modular_content": {} -} diff --git a/test/browser/isolated-tests/elements/assets/asset-rendition.spec.ts b/test/browser/isolated-tests/elements/assets/asset-rendition.spec.ts deleted file mode 100644 index 1767a971..00000000 --- a/test/browser/isolated-tests/elements/assets/asset-rendition.spec.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { Elements, IContentItem } from '../../../../../lib'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './asset-rendition.spec.json'; - -describe('Asset renditions', () => { - let item: IContentItem; - - describe('renditions are correctly set', () => { - beforeAll(async () => { - const response = (await getDeliveryClientWithJson(responseJson).item('xx').toPromise()); - - item = response.data.item; - }); - - it(`Asset element without rendition - renditions are null`, () => { - const asset = item.elements.assetWithoutRendition as Elements.AssetsElement; - const image = asset.value[0]; - const renditions = image.renditions; - - expect(renditions).toBeNull(); - }); - - it(`Asset element with rendition in default preset - renditions should be accessible`, () => { - const asset = item.elements.assetWithRenditionInDefaultPreset as Elements.AssetsElement; - const image = asset.value[0]; - const rendition = image.renditions?.default; - - const rawImage = responseJson.item.elements.assetWithRenditionInDefaultPreset.value[0]; - const rawRendition = rawImage.renditions.default; - expect(rendition?.rendition_id).toEqual(rawRendition.rendition_id); - expect(rendition?.height).toEqual(rawRendition.height); - expect(rendition?.preset_id).toEqual(rawRendition.preset_id); - expect(rendition?.query).toEqual(rawRendition.query); - expect(rendition?.width).toEqual(rawRendition.width); - expect(rendition?.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - }); - - it(`Asset element with rendition in mobile preset - renditions should be accessible`, () => { - const asset = item.elements.assetWithRenditionInMobilePreset as Elements.AssetsElement; - const image = asset.value[0]; - const rendition = image.renditions?.mobile; - - const rawImage = responseJson.item.elements.assetWithRenditionInMobilePreset.value[0]; - const rawRendition = rawImage.renditions.mobile; - expect(rendition?.height).toEqual(rawRendition.height); - expect(rendition?.preset_id).toEqual(rawRendition.preset_id); - expect(rendition?.query).toEqual(rawRendition.query); - expect(rendition?.width).toEqual(rawRendition.width); - expect(rendition?.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - }); - }); - - describe('no default profile specified in config', () => { - beforeAll(async () => { - const response = (await getDeliveryClientWithJson(responseJson).item('xx').toPromise()); - - item = response.data.item; - }); - - it(`Asset element without rendition - renditions are null`, () => { - const asset = item.elements.assetWithoutRendition as Elements.AssetsElement; - const image = asset.value[0]; - const renditions = image.renditions; - - const rawImage = responseJson.item.elements.assetWithoutRendition.value[0]; - expect(image.url).toEqual(rawImage.url); - expect(renditions).toBeNull(); - }); - - it(`Asset element with rendition in default preset - URL of original asset`, () => { - const asset = item.elements.assetWithRenditionInDefaultPreset as Elements.AssetsElement; - const image = asset.value[0]; - const rendition = image.renditions?.default; - - const rawImage = responseJson.item.elements.assetWithRenditionInDefaultPreset.value[0]; - const rawRendition = rawImage.renditions.default; - expect(image.url).toEqual(rawImage.url); - expect(rendition?.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - }); - - it(`Asset element with rendition in mobile preset - URL of original asset`, () => { - const asset = item.elements.assetWithRenditionInMobilePreset as Elements.AssetsElement; - const image = asset.value[0]; - const rendition = image.renditions?.mobile; - - const rawImage = responseJson.item.elements.assetWithRenditionInMobilePreset.value[0]; - const rawRendition = rawImage.renditions.mobile; - expect(image.url).toEqual(rawImage.url); - expect(rendition?.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - }); - }); - - describe('with default preset specified in config', () => { - beforeAll(async () => { - const response = (await getDeliveryClientWithJson(responseJson, { - defaultRenditionPreset: 'default', - environmentId: 'x' - }).item('xx').toPromise()); - - item = response.data.item; - }); - - it(`Asset element without rendition - URL of original asset`, () => { - const asset = item.elements.assetWithoutRendition as Elements.AssetsElement; - const image = asset.value[0]; - const renditions = image.renditions; - - const rawImage = responseJson.item.elements.assetWithoutRendition.value[0]; - expect(image.url).toEqual(rawImage.url); - expect(renditions).toBeNull(); - }); - - it(`Asset element with rendition in default preset - URL including rendition query string`, () => { - const asset = item.elements.assetWithRenditionInDefaultPreset as Elements.AssetsElement; - const image = asset.value[0]; - const rendition = image.renditions?.default; - - const rawImage = responseJson.item.elements.assetWithRenditionInDefaultPreset.value[0]; - const rawRendition = rawImage.renditions.default; - - expect(image.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - expect(rendition?.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - }); - - it(`Asset element with rendition in mobile preset - URL of original asset`, () => { - const asset = item.elements.assetWithRenditionInMobilePreset as Elements.AssetsElement; - const image = asset.value[0]; - const rendition = image.renditions?.mobile; - - const rawImage = responseJson.item.elements.assetWithRenditionInMobilePreset.value[0]; - const rawRendition = rawImage.renditions.mobile; - expect(image.url).toEqual(rawImage.url); - expect(rendition?.url).toEqual(`${rawImage.url}?${rawRendition.query}`); - }); - }); -}); diff --git a/test/browser/isolated-tests/elements/assets/custom-assets-domain.spec.ts b/test/browser/isolated-tests/elements/assets/custom-assets-domain.spec.ts deleted file mode 100644 index 88b2f5e6..00000000 --- a/test/browser/isolated-tests/elements/assets/custom-assets-domain.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { deliveryUrlHelper } from '../../../../../lib'; -import { getDeliveryClientWithJson, Movie } from '../../../setup'; -import * as responseJson from '../../fake-data/fake-warrior-response.json'; - -describe('Custom assets domain', () => { - let item: Movie; - const customDomain: string = 'https://custom.com'; - - beforeAll(async () => { - const response = await getDeliveryClientWithJson(responseJson, { - assetsDomain: customDomain, - environmentId: 'x' - }) - .item('xx') - .toPromise(); - - item = response.data.item; - }); - - it(`Custom asset domain should be set in asset element`, () => { - const assetElement = item.elements.poster.value[0]; - - expect(assetElement.url).toEqual( - `${customDomain}/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg` - ); - }); - - it(`Custom asset domain should be set for rendition URL in asset element`, () => { - const assetElement = item.elements.poster.value[0]; - - expect(assetElement.renditions?.['default'].url).toEqual( - `${customDomain}/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg?w=1280&h=1024&fit=clip&rect=2396,169,1280,1024` - ); - }); - - it(`Custom asset domain should be set in Rich Text element`, () => { - const richTextElement = item.elements.plot; - - for (const image of richTextElement.images) { - const imagePathname = deliveryUrlHelper.getPathname(image.url); - expect(image.url).toEqual(`${customDomain}${imagePathname}`); - } - }); - - it(`Custom asset domain should be set in HTML of Rich Text elements`, () => { - const richTextElement = item.elements.plot; - - for (const image of richTextElement.images) { - expect(richTextElement.value).toContain(image.url); - } - }); -}); diff --git a/test/browser/isolated-tests/elements/custom-element/custom-element-with-custom-model.spec.ts b/test/browser/isolated-tests/elements/custom-element/custom-element-with-custom-model.spec.ts deleted file mode 100644 index 0e1dfa3e..00000000 --- a/test/browser/isolated-tests/elements/custom-element/custom-element-with-custom-model.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { IContentItem, ElementType, Elements } from '../../../../../lib'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './custom-element.spec.json'; - - -type ColorElement = Elements.CustomElement<{ - red: number; - green: number; - blue: number; -}>; - -type MarkdownElement = Elements.CustomElement<{ - isMarkdown: boolean; - -}>; - -type ItemWithCustomElements = IContentItem<{ - color: ColorElement; - markdown: MarkdownElement; -}>; - -describe('Custom element with custom model', () => { - let item: ItemWithCustomElements; - - beforeAll(async () => { - const response = await getDeliveryClientWithJson(responseJson, { - environmentId: '', - elementResolver: (elementWrapper) => { - const responseItem = responseJson.items[0]; - const colorElement = responseJson.items[0].elements.color; - const markdownElement = responseJson.items[0].elements.markdown; - - if ( - elementWrapper.system.type === responseItem.system.type && - elementWrapper.rawElement.name === colorElement.name - ) { - const parsed = JSON.parse(elementWrapper.rawElement.value); - - return { - red: parsed.red, - green: parsed.green, - blue: parsed.blue - }; - } - - if ( - elementWrapper.system.type === responseItem.system.type && - elementWrapper.rawElement.name === markdownElement.name - ) { - return { - isMarkdown: true - }; - } - return undefined; - } - }) - .items() - .toPromise(); - - item = response.data.items[0]; - }); - - it(`Color element should be mapped to ColorElement`, () => { - const element = item.elements.color; - const rawElement = responseJson.items[0].elements.color; - - expect(element.value.red).toEqual(167); - expect(element.value.green).toEqual(96); - expect(element.value.blue).toEqual(197); - - expect(element.name).toEqual(rawElement.name); - expect(element.type).toEqual(ElementType.Custom); - }); - - it(`Markdown element should be mapped to MarkdownElement`, () => { - const element = item.elements.markdown; - const rawElement = responseJson.items[0].elements.markdown; - - expect(element.value.isMarkdown).toEqual(true); - expect(element.name).toEqual(rawElement.name); - expect(element.type).toEqual(ElementType.Custom); - }); -}); diff --git a/test/browser/isolated-tests/elements/custom-element/custom-element.spec.json b/test/browser/isolated-tests/elements/custom-element/custom-element.spec.json deleted file mode 100644 index 9ad29b73..00000000 --- a/test/browser/isolated-tests/elements/custom-element/custom-element.spec.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "a3dde145-2456-445d-ac33-3d3f6a092da8", - "name": "Color item", - "codename": "color_item", - "language": "default", - "type": "with_color_picker", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "rich": { - "type": "rich_text", - "name": "Rich", - "images": {}, - "links": {}, - "modular_content": [], - "value": "


" - }, - "color": { - "type": "custom", - "name": "Color", - "value": "{\"red\":167,\"green\":96,\"blue\":197}" - }, - "markdown": { - "type": "custom", - "name": "markdown", - "value": "**Super value**" - }, - "simple_text": { - "type": "text", - "name": "Simple text", - "value": "simple text" - } - } - } - ], - "modular_content": {}, - "pagination": { - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } - } diff --git a/test/browser/isolated-tests/elements/custom-element/custom-element.spec.ts b/test/browser/isolated-tests/elements/custom-element/custom-element.spec.ts deleted file mode 100644 index 74c09cdb..00000000 --- a/test/browser/isolated-tests/elements/custom-element/custom-element.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { IContentItem, Elements, ElementType } from '../../../../../lib'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './custom-element.spec.json'; - -describe('Custom element', () => { - let item: IContentItem; - beforeAll(async () => { - const response = (await getDeliveryClientWithJson(responseJson).items().toPromise()).data; - - item = response.items[0]; - }); - - it(`Color element should be mapped to DefaultCustomElement`, () => { - const element = item.elements.color as Elements.CustomElement; - const rawElement = responseJson.items[0].elements.color; - - expect(element.name).toEqual(rawElement.name); - expect(element.type).toEqual(ElementType.Custom); - expect(element.value).toEqual(rawElement.value); - }); - - it(`Markdown element should be mapped to DefaultCustomElement`, () => { - const element = item.elements.markdown as Elements.CustomElement; - const rawElement = responseJson.items[0].elements.markdown; - - expect(element.name).toEqual(rawElement.name); - expect(element.type).toEqual(ElementType.Custom); - expect(element.value).toEqual(rawElement.value); - }); -}); diff --git a/test/browser/isolated-tests/elements/rich-text/rich-text.spec.json b/test/browser/isolated-tests/elements/rich-text/rich-text.spec.json deleted file mode 100644 index 73f62764..00000000 --- a/test/browser/isolated-tests/elements/rich-text/rich-text.spec.json +++ /dev/null @@ -1,160 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "a3dde145-2456-445d-ac33-3d3f6a092da7", - "name": "Rich Text Item (Unordered)", - "codename": "rich_text_item_unordered", - "language": "default", - "type": "item", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "rich": { - "type": "rich_text", - "name": "Rich", - "images": { - "66d73245-10e5-4478-93e7-5609fee3cdf7": { - "image_id": "66d73245-10e5-4478-93e7-5609fee3cdf7", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/38af179c-40ba-42e7-a5ca-33b8cdcc0d45/66d73245-10e5-4478-93e7-5609fee3cdf7/image.jpg", - "width": 600, - "height": 457 - } - }, - "links": { - "ef23e568-6aa2-42cd-a120-7823c0ef19f7": { - "codename": "article_codename", - "type": "article", - "url_slug": "my-article" - } - }, - "modular_content": ["n2", "n4", "n3", "n1"], - "value": "

Basic formatted text: plain text, bold, italics, monospace, subscript, superscript.

Links: link to a content item, link to web URL, email link, phone link, link to asset.

Table

ABC
DEF
GHI

Image

\"\"

Component

Inserted content item

" - } - } - }, - { - "system": { - "id": "a3dde145-2456-445d-ac33-3d3f6a092da8", - "name": "Rich Text Item (Ordered)", - "codename": "rich_text_item_ordered", - "language": "default", - "type": "item", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "rich": { - "type": "rich_text", - "name": "Rich", - "images": { - "66d73245-10e5-4478-93e7-5609fee3cdf7": { - "image_id": "66d73245-10e5-4478-93e7-5609fee3cdf7", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/38af179c-40ba-42e7-a5ca-33b8cdcc0d45/66d73245-10e5-4478-93e7-5609fee3cdf7/image.jpg", - "width": 600, - "height": 457 - } - }, - "links": { - "ef23e568-6aa2-42cd-a120-7823c0ef19f7": { - "codename": "n4", - "type": "article", - "url_slug": "my-article" - } - }, - "modular_content": ["n1", "n2", "n3", "n4"], - "value": "

Basic formatted text: plain text, bold, italics, monospace, subscript, superscript.

Links: link to a content item, link to web URL, email link, phone link, link to asset.

Table

ABC
DEF
GHI

Image

\"\"

Component

Inserted content item

" - } - } - } - ], - "modular_content": { - "n1": { - "system": { - "id": "a3dde145-2456-445d-ac33-3d3f6a092da8-n1", - "name": "Modular Content 1", - "codename": "n1", - "language": "default", - "type": "modular_item", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "text": { - "type": "text", - "name": "Text", - "value": "Text 1" - } - } - }, - "n2": { - "system": { - "id": "a3dde245-2456-445d-ac33-3d3f6a092da8-n2", - "name": "Modular Content 2", - "codename": "n2", - "language": "default", - "type": "modular_item", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "text": { - "type": "text", - "name": "Text", - "value": "Text 2" - } - } - }, - "n3": { - "system": { - "id": "a3dde345-2456-445d-ac33-3d3f6a092da8-n3", - "name": "Modular Content 3", - "codename": "n3", - "language": "default", - "type": "modular_item", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "text": { - "type": "text", - "name": "Text", - "value": "Text 3" - } - } - }, - "n4": { - "system": { - "id": "a3dde345-2456-445d-ac33-3d3f6a092da8-n4", - "name": "Modular Content 4", - "codename": "n4", - "language": "default", - "type": "modular_item", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "text": { - "type": "text", - "name": "Text", - "value": "Text 4" - } - } - } - }, - "pagination": { - "skip": 0, - "limit": 0, - "count": 3, - "next_page": "" - } -} diff --git a/test/browser/isolated-tests/elements/rich-text/rich-text.spec.ts b/test/browser/isolated-tests/elements/rich-text/rich-text.spec.ts deleted file mode 100644 index 9d57e0ae..00000000 --- a/test/browser/isolated-tests/elements/rich-text/rich-text.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Responses, Elements, ElementType, IContentItem } from '../../../../../lib'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './rich-text.spec.json'; - -describe('Rich-text element', () => { - let response: Responses.IListContentItemsResponse; - beforeAll(async () => { - response = (await getDeliveryClientWithJson(responseJson).items().toPromise()).data; - }); - - it(`Rich-text linked items should be re-ordered if not ordered in raw response`, async () => { - const rawItem = responseJson.items.find(({ system: { codename } }) => codename === 'rich_text_item_unordered'); - const item = response.items.find( - ({ system: { codename } }) => codename === 'rich_text_item_unordered' - ) as IContentItem; - const element = item.elements.rich as Elements.RichTextElement; - - expect(element.type).toEqual(ElementType.RichText); - expect(rawItem?.elements.rich.modular_content).toEqual(['n2', 'n4', 'n3', 'n1']); - expect(element.linkedItemCodenames).toEqual(['n1', 'n2', 'n3', 'n4']); - for (let i = 0; i < element.linkedItems.length; ++i) { - expect(element.linkedItems[i].system.codename).toBe(`n${i + 1}`); - } - }); - - it(`Rich-text linked items order should be maintained if already ordered in raw response`, () => { - const rawItem = responseJson.items.find(({ system: { codename } }) => codename === 'rich_text_item_ordered'); - const item = response.items.find( - ({ system: { codename } }) => codename === 'rich_text_item_ordered' - ) as IContentItem; - const element = item.elements.rich as Elements.RichTextElement; - - expect(element.type).toEqual(ElementType.RichText); - expect(rawItem?.elements.rich.modular_content).toEqual(['n1', 'n2', 'n3', 'n4']); - expect(element.linkedItemCodenames).toEqual(['n1', 'n2', 'n3', 'n4']); - for (let i = 0; i < element.linkedItems.length; ++i) { - expect(element.linkedItems[i].system.codename).toBe(`n${i + 1}`); - } - }); -}); diff --git a/test/browser/isolated-tests/elements/unknown-element/unknown-element.spec.json b/test/browser/isolated-tests/elements/unknown-element/unknown-element.spec.json deleted file mode 100644 index 9e47369c..00000000 --- a/test/browser/isolated-tests/elements/unknown-element/unknown-element.spec.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "a3dde145-2456-445d-ac33-3d3f6a092da8", - "name": "Color item", - "codename": "color_item", - "language": "default", - "type": "with_color_picker", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-01-04T09:56:04.372261Z" - }, - "elements": { - "ufo": { - "type": "ufo", - "name": "Simple text", - "value": "simple text" - } - } - } - ], - "modular_content": {}, - "pagination": { - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } - } diff --git a/test/browser/isolated-tests/elements/unknown-element/unknown-element.spec.ts b/test/browser/isolated-tests/elements/unknown-element/unknown-element.spec.ts deleted file mode 100644 index 5ffa5dd2..00000000 --- a/test/browser/isolated-tests/elements/unknown-element/unknown-element.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Elements, ElementType, IContentItem } from '../../../../../lib'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './unknown-element.spec.json'; - -describe('Unknown element', () => { - let item: IContentItem; - - beforeAll(async () => { - const response = (await getDeliveryClientWithJson(responseJson).items().toPromise()).data; - - item = response.items[0]; - }); - - it(`Ufo element should be mapped to UnknownElement`, () => { - const element = item.elements.ufo as Elements.UnknownElement; - const rawElement = responseJson.items[0].elements.ufo; - - expect(element.name).toEqual(rawElement.name); - expect(element.type).toEqual(ElementType.Unknown); - expect(element.value).toEqual(rawElement.value); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items-feed/items-feed-all.spec.json b/test/browser/isolated-tests/endpoints/items-feed/items-feed-all.spec.json deleted file mode 100644 index a08a775a..00000000 --- a/test/browser/isolated-tests/endpoints/items-feed/items-feed-all.spec.json +++ /dev/null @@ -1,245 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "325e2acb-1c14-47f6-af9a-27bc8b6c16fe", - "name": "Warrior", - "codename": "warrior", - "language": "en", - "type": "movie", - "sitemap_locations": ["main_sitemap"], - "collection": "default", - "last_modified": "2019-09-05T10:51:15.6555984Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Warrior" - }, - "plot": { - "type": "rich_text", - "name": "Plot", - "images": { - "22504ba8-2075-48fa-9d4f-8fce3de1754a": { - "image_id": "22504ba8-2075-48fa-9d4f-8fce3de1754a", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - }, - "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5": { - "image_id": "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - }, - "links": { - "3294e4b0-e58b-49d7-85fa-5bc9a86556ec": { - "codename": "joel_edgerton", - "type": "actor", - "url_slug": "joel-edgerton" - }, - "d1557cb1-d7ec-4d04-9742-f86b52bc34fc": { - "codename": "tom_hardy", - "type": "actor", - "url_slug": "tom-hardy" - } - }, - "modular_content": ["tom_hardy", "joel_edgerton", "ec9813f6_194d_018f_e20c_36855fb6e600"], - "value": "

The youngest son of an alcoholic former boxer returns home, where he's trained by his father for competition in a mixed martial arts tournament - a path that puts the fighter on a collision course with his estranged, older brother.

\n

Stars: 

\n\n\n


\n

See more in profile of Joel Edgerton and Tom Hardy

\n

And here are some images: 

\n
\"\"
\n
\"\"
\n


\n

Also, why not include content component in the mix?

\n" - }, - "released": { - "type": "date_time", - "name": "Released", - "value": "2011-09-09T00:00:00Z" - }, - "length": { - "type": "number", - "name": "Length", - "value": 151 - }, - "poster": { - "type": "asset", - "name": "Poster", - "value": [ - { - "name": "warrior.jpg", - "description": null, - "type": "image/jpeg", - "size": 111004, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - } - ] - }, - "category": { - "type": "multiple_choice", - "name": "Category", - "value": [ - { - "name": "Action", - "codename": "action" - }, - { - "name": "Drama", - "codename": "drama" - } - ] - }, - "stars": { - "type": "modular_content", - "name": "Stars", - "value": ["tom_hardy", "joel_edgerton"] - }, - "seoname": { - "type": "url_slug", - "name": "SeoName", - "value": "warrior" - }, - "releasecategory": { - "type": "taxonomy", - "name": "releasecategory", - "taxonomy_group": "releasecategory", - "value": [ - { - "name": "Global release", - "codename": "global_release" - }, - { - "name": "US only", - "codename": "us_only" - } - ] - } - } - } - ], - "modular_content": { - "ec9813f6_194d_018f_e20c_36855fb6e600": { - "system": { - "id": "ec9813f6-194d-018f-e20c-36855fb6e600", - "name": "ec9813f6-194d-018f-e20c-36855fb6e600", - "codename": "ec9813f6_194d_018f_e20c_36855fb6e600", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-09-05T10:51:15.6555984Z" - }, - "elements": { - "first_name": { - "type": "text", - "name": "First name", - "value": "Jennifer " - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Morrison" - }, - "url": { - "type": "url_slug", - "name": "Url", - "value": "component-actor-url" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [] - } - } - }, - "joel_edgerton": { - "system": { - "id": "3294e4b0-e58b-49d7-85fa-5bc9a86556ec", - "name": "Joel Edgerton", - "codename": "joel_edgerton", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2017-08-03T09:21:21.3857294Z" - }, - "elements": { - "url": { - "type": "url_slug", - "name": "Url", - "value": "joel-edgerton" - }, - "first_name": { - "type": "text", - "name": "First name", - "value": "Joel" - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Edgerton" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [ - { - "name": "joel_edgerton.jpg", - "description": null, - "type": "image/jpeg", - "size": 6460, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/2855720a-4ca4-4687-826a-29f9635088e0/joel_edgerton.jpg", - "width": 211, - "height": 317 - } - ] - } - } - }, - "tom_hardy": { - "system": { - "id": "d1557cb1-d7ec-4d04-9742-f86b52bc34fc", - "name": "Tom Hardy", - "codename": "tom_hardy", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2018-02-09T13:11:32.5769383Z" - }, - "elements": { - "url": { - "type": "url_slug", - "name": "Url", - "value": "tom-hardy" - }, - "first_name": { - "type": "text", - "name": "First name", - "value": "Tom" - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Hardy" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [ - { - "name": "tom_hardy.jpg", - "description": null, - "type": "image/jpeg", - "size": 8091, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - ] - } - } - } - } -} diff --git a/test/browser/isolated-tests/endpoints/items-feed/items-feed-all.spec.ts b/test/browser/isolated-tests/endpoints/items-feed/items-feed-all.spec.ts deleted file mode 100644 index 4f74424c..00000000 --- a/test/browser/isolated-tests/endpoints/items-feed/items-feed-all.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { IContentItem, IGroupedNetworkResponse, Responses } from '../../../../../lib'; -import { Context, Movie, setup } from '../../../setup'; -import { getDeliveryClientWithJsonAndHeaders } from '../../../setup'; -import * as responseJson from './items-feed-all.spec.json'; - -describe('Items feed all', () => { - const context = new Context(); - setup(context); - - let response: IGroupedNetworkResponse>; - - beforeAll(async () => { - response = await getDeliveryClientWithJsonAndHeaders( - responseJson, - { - environmentId: 'x' - }, - [] - ) - .itemsFeed() - .queryConfig({ - disableItemLinking: false - }) - .toAllPromise(); - }); - - it(`Validate responses counts`, () => { - expect(response.responses.length).toEqual(1); - }); - - it(`Validate items count`, () => { - expect(response.data.items.length).toEqual(responseJson.items.length); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items-feed/items-feed.spec.json b/test/browser/isolated-tests/endpoints/items-feed/items-feed.spec.json deleted file mode 100644 index a08a775a..00000000 --- a/test/browser/isolated-tests/endpoints/items-feed/items-feed.spec.json +++ /dev/null @@ -1,245 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "325e2acb-1c14-47f6-af9a-27bc8b6c16fe", - "name": "Warrior", - "codename": "warrior", - "language": "en", - "type": "movie", - "sitemap_locations": ["main_sitemap"], - "collection": "default", - "last_modified": "2019-09-05T10:51:15.6555984Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Warrior" - }, - "plot": { - "type": "rich_text", - "name": "Plot", - "images": { - "22504ba8-2075-48fa-9d4f-8fce3de1754a": { - "image_id": "22504ba8-2075-48fa-9d4f-8fce3de1754a", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - }, - "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5": { - "image_id": "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - }, - "links": { - "3294e4b0-e58b-49d7-85fa-5bc9a86556ec": { - "codename": "joel_edgerton", - "type": "actor", - "url_slug": "joel-edgerton" - }, - "d1557cb1-d7ec-4d04-9742-f86b52bc34fc": { - "codename": "tom_hardy", - "type": "actor", - "url_slug": "tom-hardy" - } - }, - "modular_content": ["tom_hardy", "joel_edgerton", "ec9813f6_194d_018f_e20c_36855fb6e600"], - "value": "

The youngest son of an alcoholic former boxer returns home, where he's trained by his father for competition in a mixed martial arts tournament - a path that puts the fighter on a collision course with his estranged, older brother.

\n

Stars: 

\n\n\n


\n

See more in profile of Joel Edgerton and Tom Hardy

\n

And here are some images: 

\n
\"\"
\n
\"\"
\n


\n

Also, why not include content component in the mix?

\n" - }, - "released": { - "type": "date_time", - "name": "Released", - "value": "2011-09-09T00:00:00Z" - }, - "length": { - "type": "number", - "name": "Length", - "value": 151 - }, - "poster": { - "type": "asset", - "name": "Poster", - "value": [ - { - "name": "warrior.jpg", - "description": null, - "type": "image/jpeg", - "size": 111004, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - } - ] - }, - "category": { - "type": "multiple_choice", - "name": "Category", - "value": [ - { - "name": "Action", - "codename": "action" - }, - { - "name": "Drama", - "codename": "drama" - } - ] - }, - "stars": { - "type": "modular_content", - "name": "Stars", - "value": ["tom_hardy", "joel_edgerton"] - }, - "seoname": { - "type": "url_slug", - "name": "SeoName", - "value": "warrior" - }, - "releasecategory": { - "type": "taxonomy", - "name": "releasecategory", - "taxonomy_group": "releasecategory", - "value": [ - { - "name": "Global release", - "codename": "global_release" - }, - { - "name": "US only", - "codename": "us_only" - } - ] - } - } - } - ], - "modular_content": { - "ec9813f6_194d_018f_e20c_36855fb6e600": { - "system": { - "id": "ec9813f6-194d-018f-e20c-36855fb6e600", - "name": "ec9813f6-194d-018f-e20c-36855fb6e600", - "codename": "ec9813f6_194d_018f_e20c_36855fb6e600", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-09-05T10:51:15.6555984Z" - }, - "elements": { - "first_name": { - "type": "text", - "name": "First name", - "value": "Jennifer " - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Morrison" - }, - "url": { - "type": "url_slug", - "name": "Url", - "value": "component-actor-url" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [] - } - } - }, - "joel_edgerton": { - "system": { - "id": "3294e4b0-e58b-49d7-85fa-5bc9a86556ec", - "name": "Joel Edgerton", - "codename": "joel_edgerton", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2017-08-03T09:21:21.3857294Z" - }, - "elements": { - "url": { - "type": "url_slug", - "name": "Url", - "value": "joel-edgerton" - }, - "first_name": { - "type": "text", - "name": "First name", - "value": "Joel" - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Edgerton" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [ - { - "name": "joel_edgerton.jpg", - "description": null, - "type": "image/jpeg", - "size": 6460, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/2855720a-4ca4-4687-826a-29f9635088e0/joel_edgerton.jpg", - "width": 211, - "height": 317 - } - ] - } - } - }, - "tom_hardy": { - "system": { - "id": "d1557cb1-d7ec-4d04-9742-f86b52bc34fc", - "name": "Tom Hardy", - "codename": "tom_hardy", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2018-02-09T13:11:32.5769383Z" - }, - "elements": { - "url": { - "type": "url_slug", - "name": "Url", - "value": "tom-hardy" - }, - "first_name": { - "type": "text", - "name": "First name", - "value": "Tom" - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Hardy" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [ - { - "name": "tom_hardy.jpg", - "description": null, - "type": "image/jpeg", - "size": 8091, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - ] - } - } - } - } -} diff --git a/test/browser/isolated-tests/endpoints/items-feed/items-feed.spec.ts b/test/browser/isolated-tests/endpoints/items-feed/items-feed.spec.ts deleted file mode 100644 index 12715fe5..00000000 --- a/test/browser/isolated-tests/endpoints/items-feed/items-feed.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { IDeliveryNetworkResponse, Responses } from '../../../../../lib'; -import { Context, Movie, setup } from '../../../setup'; -import { getDeliveryClientWithJsonAndHeaders } from '../../../setup'; -import * as responseJson from './items-feed.spec.json'; - -describe('Items feed', () => { - const context = new Context(); - setup(context); - - let response: IDeliveryNetworkResponse, any>; - - beforeAll(async () => { - response = await getDeliveryClientWithJsonAndHeaders( - responseJson, - { - environmentId: 'x', - }, - [ - { - value: 'TokenX', - header: 'X-Continuation' - } - ] - ) - .itemsFeed() - .toPromise(); - }); - - it(`Continuation token should be set`, () => { - expect(response.xContinuationToken).toEqual('TokenX'); - }); - -}); diff --git a/test/browser/isolated-tests/endpoints/items/circular-referenced-linked-items-mapping.spec.json b/test/browser/isolated-tests/endpoints/items/circular-referenced-linked-items-mapping.spec.json deleted file mode 100644 index a47120a7..00000000 --- a/test/browser/isolated-tests/endpoints/items/circular-referenced-linked-items-mapping.spec.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "item": { - "system": { - "id": "117cdfae-52cf-4885-b271-66aef6825612", - "name": "Coffee processing techniques", - "codename": "coffee_processing_techniques", - "language": "en-US", - "type": "article", - "sitemap_locations": [ - "articles" - ], - "collection": "default", - "last_modified": "2018-07-17T08:12:03.07Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Coffee processing techniques" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": [ - "on_roasts", - "which_brewing_fits_you_" - ] - } - } - }, - "modular_content": { - "on_roasts": { - "system": { - "id": "f4b3fc05-e988-4dae-9ac1-a94aba566474", - "name": "On Roasts", - "codename": "on_roasts", - "language": "en-US", - "type": "article", - "sitemap_locations": [ - "articles" - ], - "collection": "default", - "last_modified": "2017-12-08T08:49:53.603Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "On Roasts" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": [ - "on_roasts", - "which_brewing_fits_you_" - ] - } - } - }, - "which_brewing_fits_you_": { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "Which brewing fits you?", - "codename": "which_brewing_fits_you_", - "language": "en-US", - "type": "article", - "sitemap_locations": [ - "articles" - ], - "collection": "default", - "last_modified": "2018-10-11T08:45:56.917Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": [ - "coffee_processing_techniques", - "on_roasts" - ] - } - } - } - } -} diff --git a/test/browser/isolated-tests/endpoints/items/circular-referenced-linked-items-mapping.spec.ts b/test/browser/isolated-tests/endpoints/items/circular-referenced-linked-items-mapping.spec.ts deleted file mode 100644 index 9681ea6e..00000000 --- a/test/browser/isolated-tests/endpoints/items/circular-referenced-linked-items-mapping.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { getDeliveryClientWithJson } from '../../../setup'; -import { Responses, Elements } from '../../../../../lib'; -import * as responseJson from './circular-referenced-linked-items-mapping.spec.json'; - -describe('Circular references in linked items', () => { - let response: Responses.IViewContentItemResponse; - - const modularItemElement = 'related_articles'; - - beforeAll(async () => { - response = (await getDeliveryClientWithJson(responseJson).item('x').toPromise()).data; - }); - - it(`Response should be defines and there should be no stackoverflow exception logged`, () => { - expect(response).toBeDefined(); - }); - - it(`'coffee_processing_techniques' should have mapped items`, () => { - const linkedItem = response.item; - expect(linkedItem).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'which_brewing_fits_you_' - ) - ).toBeDefined(); - }); - - it(`'on_roasts' should have mapped items `, () => { - const linkedItemCodename = 'on_roasts'; - const linkedItem = response.linkedItems[linkedItemCodename]; - - expect(linkedItem).toBeDefined(); - - if (!linkedItem) { - throw Error(`Item with codename '${linkedItemCodename}' was not found`); - } - - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'which_brewing_fits_you_' - ) - ).toBeDefined(); - }); - - it(`'which_brewing_fits_you_' should have mapped items`, () => { - const linkedItemCodename = 'which_brewing_fits_you_'; - const linkedItem = response.linkedItems[linkedItemCodename]; - - expect(linkedItem).toBeDefined(); - - if (!linkedItem) { - throw Error(`Item with codename '${linkedItemCodename}' was not found`); - } - - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'coffee_processing_techniques' - ) - ).toBeDefined(); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items/items-list-response.spec.json b/test/browser/isolated-tests/endpoints/items/items-list-response.spec.json deleted file mode 100644 index 9aab6c3f..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-list-response.spec.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "Which brewing fits you?", - "codename": "which_brewing_fits_you_", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-03-27T13:24:54.042Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "We have put down three procedures with clearly written steps describing the process of making coffee. Read this article to convince yourself that brewing coffee is no science." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-10-27T00:00:00Z" - } - } - } - ], - "modular_content": {}, - "pagination": { - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } - } diff --git a/test/browser/isolated-tests/endpoints/items/items-list-response.spec.ts b/test/browser/isolated-tests/endpoints/items/items-list-response.spec.ts deleted file mode 100644 index 9cf111fc..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-list-response.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './items-list-response.spec.json'; - -describe('Items list response', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentItemsResponse; - const parameters: IQueryParameter[] = []; - - beforeAll(async () => { - const query = getDeliveryClientWithJson(responseJson).items().includeTotalCountParameter(); - parameters.push(...query.getParameters()); - response = (await query.toPromise()).data; - }); - - it(`Total count parameter should be set to true`, () => { - const totalCountParameter = parameters.find( - (m) => m.getParam().toLowerCase() === 'includeTotalCount=true'.toLowerCase() - ); - - expect(totalCountParameter).toBeDefined(); - }); - - it(`Response should have pagination`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`Response item should be mapped properly`, () => { - const item = response.items[0]; - const rawItem = responseJson.items[0]; - - expect(item).toBeDefined(); - expect(rawItem).toBeDefined(); - expect(item.system).toBeDefined(); - - expect(item.elements.title.value).toEqual(rawItem.elements.title.value); - expect(item.elements.summary.value).toEqual(rawItem.elements.summary.value); - expect(item.elements.post_date.value).toEqual(rawItem.elements.post_date.value); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-in-linked-items-response.spec.json b/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-in-linked-items-response.spec.json deleted file mode 100644 index 094cd611..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-in-linked-items-response.spec.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "Brewing", - "codename": "Brewing", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-03-27T13:24:54.042Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "We have put down three procedures with clearly written steps describing the process of making coffee. Read this article to convince yourself that brewing coffee is no science." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-10-27T00:00:00Z" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": ["constructor"] - } - } - } - ], - "modular_content": { - "constructor": { - "system": { - "id": "f4b3fc05-e988-4dae-9ac1-a94aba566474", - "name": "On Roasts", - "codename": "constructor", - "language": "en-US", - "type": "article", - "sitemap_locations": ["articles"], - "collection": "default", - "last_modified": "2017-12-08T08:49:53.603Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "constructor" - } - } - } - }, - "pagination": { - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } -} diff --git a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-in-linked-items-response.spec.ts b/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-in-linked-items-response.spec.ts deleted file mode 100644 index 9b3154c1..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-in-linked-items-response.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './items-list-with-reserved-names-in-linked-items-response.spec.json'; - -describe('Items list with reserved names in linked items', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentItemsResponse; - const parameters: IQueryParameter[] = []; - - beforeAll(async () => { - const query = getDeliveryClientWithJson(responseJson).items().includeTotalCountParameter(); - parameters.push(...query.getParameters()); - response = (await query.toPromise()).data; - }); - - it(`Total count parameter should be set to true`, () => { - const totalCountParameter = parameters.find( - (m) => m.getParam().toLowerCase() === 'includeTotalCount=true'.toLowerCase() - ); - - expect(totalCountParameter).toBeDefined(); - }); - - it(`Response should have pagination`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`Response item should be mapped properly`, () => { - const item = response.items[0]; - const rawItem = responseJson.items[0]; - - expect(item).toBeDefined(); - expect(rawItem).toBeDefined(); - expect(item.system).toBeDefined(); - - expect(item.elements.title.value).toEqual(rawItem.elements.title.value); - expect(item.elements.summary.value).toEqual(rawItem.elements.summary.value); - expect(item.elements.post_date.value).toEqual(rawItem.elements.post_date.value); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-response.spec.json b/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-response.spec.json deleted file mode 100644 index ab434f9d..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-response.spec.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "constructor", - "codename": "constructor", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-03-27T13:24:54.042Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "We have put down three procedures with clearly written steps describing the process of making coffee. Read this article to convince yourself that brewing coffee is no science." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-10-27T00:00:00Z" - } - } - } - ], - "modular_content": { - }, - "pagination": { - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } -} diff --git a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-response.spec.ts b/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-response.spec.ts deleted file mode 100644 index 302883b2..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-list-with-reserved-names-response.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './items-list-with-reserved-names-response.spec.json'; - -describe('Items list with reserved names', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentItemsResponse; - const parameters: IQueryParameter[] = []; - - beforeAll(async () => { - const query = getDeliveryClientWithJson(responseJson).items().includeTotalCountParameter(); - parameters.push(...query.getParameters()); - response = (await query.toPromise()).data; - }); - - it(`Total count parameter should be set to true`, () => { - const totalCountParameter = parameters.find( - (m) => m.getParam().toLowerCase() === 'includeTotalCount=true'.toLowerCase() - ); - - expect(totalCountParameter).toBeDefined(); - }); - - it(`Response should have pagination`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`Response item should be mapped properly`, () => { - const item = response.items[0]; - const rawItem = responseJson.items[0]; - - expect(item).toBeDefined(); - expect(rawItem).toBeDefined(); - expect(item.system).toBeDefined(); - - expect(item.elements.title.value).toEqual(rawItem.elements.title.value); - expect(item.elements.summary.value).toEqual(rawItem.elements.summary.value); - expect(item.elements.post_date.value).toEqual(rawItem.elements.post_date.value); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items/items-with-total-count.spec.json b/test/browser/isolated-tests/endpoints/items/items-with-total-count.spec.json deleted file mode 100644 index c18e9f7e..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-with-total-count.spec.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "Which brewing fits you?", - "codename": "which_brewing_fits_you_", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-03-27T13:24:54.042Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "We have put down three procedures with clearly written steps describing the process of making coffee. Read this article to convince yourself that brewing coffee is no science." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-10-27T00:00:00Z" - } - } - } - ], - "modular_content": {}, - "pagination": { - "total_count": 1, - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } - } diff --git a/test/browser/isolated-tests/endpoints/items/items-with-total-count.spec.ts b/test/browser/isolated-tests/endpoints/items/items-with-total-count.spec.ts deleted file mode 100644 index 17dbb5c9..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-with-total-count.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './items-with-total-count.spec.json'; - -describe('Items with total count', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentItemsResponse; - const parameters: IQueryParameter[] = []; - - beforeAll(async () => { - const query = getDeliveryClientWithJson(responseJson).items().includeTotalCountParameter(); - - parameters.push(...query.getParameters()); - - response = (await query.toPromise()).data; - }); - - it(`Total count parameter should be set to true`, () => { - const totalCountParameter = parameters.find( - (m) => m.getParam().toLowerCase() === 'includeTotalCount=true'.toLowerCase() - ); - - expect(totalCountParameter).toBeDefined(); - }); - - it(`Response should have total count parameter set`, () => { - expect(response.pagination.totalCount).toEqual(responseJson.pagination.total_count); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/items/items-without-total-count.spec.json b/test/browser/isolated-tests/endpoints/items/items-without-total-count.spec.json deleted file mode 100644 index 9aab6c3f..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-without-total-count.spec.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "Which brewing fits you?", - "codename": "which_brewing_fits_you_", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-03-27T13:24:54.042Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "We have put down three procedures with clearly written steps describing the process of making coffee. Read this article to convince yourself that brewing coffee is no science." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-10-27T00:00:00Z" - } - } - } - ], - "modular_content": {}, - "pagination": { - "skip": 0, - "limit": 0, - "count": 1, - "next_page": "" - } - } diff --git a/test/browser/isolated-tests/endpoints/items/items-without-total-count.spec.ts b/test/browser/isolated-tests/endpoints/items/items-without-total-count.spec.ts deleted file mode 100644 index 3871cddc..00000000 --- a/test/browser/isolated-tests/endpoints/items/items-without-total-count.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { IQueryParameter } from '@kontent-ai/core-sdk'; - -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './items-without-total-count.spec.json'; - -describe('Items without total count', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentItemsResponse; - const parameters: IQueryParameter[] = []; - - beforeAll(async () => { - const query = getDeliveryClientWithJson(responseJson).items(); - - parameters.push(...query.getParameters()); - - response = (await query.toPromise()).data; - }); - - it(`Total count parameter should not be set`, () => { - const totalCountParameter = parameters.find((m) => - m.getParam().toLowerCase().startsWith('includeTotalCount'.toLowerCase()) - ); - - expect(totalCountParameter).toBeUndefined(); - }); - - it(`Response should not have total count parameter set`, () => { - expect(response.pagination.totalCount).toEqual(null); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/languages/list-languages.spec.json b/test/browser/isolated-tests/endpoints/languages/list-languages.spec.json deleted file mode 100644 index 7e8dcd74..00000000 --- a/test/browser/isolated-tests/endpoints/languages/list-languages.spec.json +++ /dev/null @@ -1,423 +0,0 @@ -{ - "languages": [ - { - "system": { - "id": "a151379f-332e-4b1e-842b-7519e0c28d56", - "name": "German", - "codename": "de" - } - }, - { - "system": { - "id": "614d82f5-c16c-465b-a34b-a37a1b416d12", - "name": "German -- 11", - "codename": "de-DE---11" - } - }, - { - "system": { - "id": "de7bffee-659e-495f-b462-073974c88147", - "name": "German -- 131", - "codename": "de-DE---131" - } - }, - { - "system": { - "id": "b67aa235-4711-4f59-be02-6c2439fa3231", - "name": "German -- 161", - "codename": "de-DE---161" - } - }, - { - "system": { - "id": "560ef6e2-fa13-4cde-a2f2-7219e4f0be38", - "name": "German -- 31", - "codename": "de-DE---31" - } - }, - { - "system": { - "id": "7878060f-af11-4140-9cd8-64bf98bb4c32", - "name": "German -- 41", - "codename": "de-DE---41" - } - }, - { - "system": { - "id": "29d27691-256a-4707-aac2-58a4bcc2a146", - "name": "German -- 51", - "codename": "de-DE---51" - } - }, - { - "system": { - "id": "cff69077-dd72-436a-bd44-ec2161ebbf02", - "name": "German -- 61", - "codename": "de-DE---61" - } - }, - { - "system": { - "id": "e8089efe-fd5a-4675-a226-83e878a4ccd1", - "name": "German -- 71", - "codename": "de-DE---71" - } - }, - { - "system": { - "id": "869eabb8-3d9d-4581-8823-e499e400dbcf", - "name": "German -- 91", - "codename": "de-DE---91" - } - }, - { - "system": { - "id": "e7d462c9-3d02-49d2-8255-0d453b25351f", - "name": "German -- 121", - "codename": "de-DE---_121" - } - }, - { - "system": { - "id": "9a43bb60-7545-48ef-a3e4-3ba815de166c", - "name": "German -- 191", - "codename": "de-DE---_191" - } - }, - { - "system": { - "id": "0ff7adc4-c297-4d2b-97ec-d25e3c7e8e66", - "name": "German -- 21", - "codename": "de-DE---_21" - } - }, - { - "system": { - "id": "7106d69c-5b02-48b7-a88e-112a4ddd9100", - "name": "German -- 261", - "codename": "de-DE---_261" - } - }, - { - "system": { - "id": "85e9d0b7-09e6-497c-91e7-a949676c8cc1", - "name": "German -- 281", - "codename": "de-DE---_281" - } - }, - { - "system": { - "id": "13193a77-9684-4665-bfe7-751cf6e828d9", - "name": "German - 71", - "codename": "de-DE--71" - } - }, - { - "system": { - "id": "e4a3c739-69a3-4f3a-be2e-042464423ca5", - "name": "German - 81", - "codename": "de-DE--81" - } - }, - { - "system": { - "id": "9339dafc-6a64-45ca-bffd-d6ed1e9fa5da", - "name": "German - 0", - "codename": "de-DE-0" - } - }, - { - "system": { - "id": "83d2cf55-87a8-4f16-b645-27ed2d110918", - "name": "German - 101", - "codename": "de-DE-101" - } - }, - { - "system": { - "id": "09d573c6-976f-4ee3-88d6-5e8e2a921e80", - "name": "German - 11", - "codename": "de-DE-11" - } - }, - { - "system": { - "id": "7dcaa4e5-ec87-48b6-8e79-94863fe2e6dd", - "name": "German - 121", - "codename": "de-DE-121" - } - }, - { - "system": { - "id": "25a95f57-6d28-49b5-8ee3-ad45d05a7191", - "name": "German - 171", - "codename": "de-DE-171" - } - }, - { - "system": { - "id": "b52570c5-0d92-4526-a9d8-efa5107d1bf0", - "name": "German - 191", - "codename": "de-DE-191" - } - }, - { - "system": { - "id": "20f0fba0-9ee3-42a2-9502-0891dde37881", - "name": "German - 21", - "codename": "de-DE-21" - } - }, - { - "system": { - "id": "73bf2fc6-47f4-49b1-bbe0-bdd482a20d53", - "name": "German - 271", - "codename": "de-DE-271" - } - }, - { - "system": { - "id": "a2027e3a-eb07-420b-aebb-9536b80e0bdc", - "name": "German - 311", - "codename": "de-DE-311" - } - }, - { - "system": { - "id": "eeda27e1-0191-4c85-b205-4f6dba123d6b", - "name": "German - 321", - "codename": "de-DE-321" - } - }, - { - "system": { - "id": "1d28d836-24b8-4bad-8366-b5337449faa6", - "name": "German - 381", - "codename": "de-DE-381" - } - }, - { - "system": { - "id": "a5fd9f3c-b500-4531-abeb-c3a26dd49be7", - "name": "German - 441", - "codename": "de-DE-441" - } - }, - { - "system": { - "id": "699e94e5-05d7-47d0-8afb-b46769eb4c9a", - "name": "German - 491", - "codename": "de-DE-491" - } - }, - { - "system": { - "id": "f377ceee-efa0-4e6b-a384-8d94ee74da4a", - "name": "German - 51", - "codename": "de-DE-51" - } - }, - { - "system": { - "id": "85332170-baca-4925-a0e5-8ab1104ff829", - "name": "German - 61", - "codename": "de-DE-61" - } - }, - { - "system": { - "id": "0f6f50d4-e3f5-48e8-9407-a86a1eb5b3a1", - "name": "German - 91", - "codename": "de-DE-91" - } - }, - { - "system": { - "id": "79228548-6576-5a60-acad-53360bf23687", - "name": "German - ext", - "codename": "de-DE-ext" - } - }, - { - "system": { - "id": "9c295dde-9f56-489a-9869-f8bab454ebfd", - "name": "German_131", - "codename": "de-DE_131" - } - }, - { - "system": { - "id": "646bbcbe-bb5a-4aca-a513-9826d205a3df", - "name": "German_211", - "codename": "de-DE_211" - } - }, - { - "system": { - "id": "13f6c434-1652-4850-b874-207207f0cffa", - "name": "German_221", - "codename": "de-DE_221" - } - }, - { - "system": { - "id": "b87ebacc-1686-473a-ad56-ccb0b73ad0e4", - "name": "German_261", - "codename": "de-DE_261" - } - }, - { - "system": { - "id": "3d15c7d7-2b6d-41a5-ab52-d42138ec23af", - "name": "German_31", - "codename": "de-DE_31" - } - }, - { - "system": { - "id": "b800a209-1d0a-409c-8e3c-8fc8430257ad", - "name": "German_331", - "codename": "de-DE_331" - } - }, - { - "system": { - "id": "23eec871-d70a-4d68-9e55-dec481b92fe5", - "name": "German_351", - "codename": "de-DE_351" - } - }, - { - "system": { - "id": "251246ad-ca05-4e51-85e5-7c4a8a461e37", - "name": "German_401", - "codename": "de-DE_401" - } - }, - { - "system": { - "id": "4a3ea19a-26a8-4536-840e-1963a46c5179", - "name": "German_451", - "codename": "de-DE_451" - } - }, - { - "system": { - "id": "eed653b1-ecf4-41dc-b556-f9593f152dcf", - "name": "German_471", - "codename": "de-DE_471" - } - }, - { - "system": { - "id": "ae46bbfa-adb1-43af-9687-d2f80d250a81", - "name": "German_491", - "codename": "de-DE_491" - } - }, - { - "system": { - "id": "385077d2-ecc7-4483-b43f-d81626774cbe", - "name": "German_541", - "codename": "de-DE_541" - } - }, - { - "system": { - "id": "4f34b0c3-f2cf-4e9f-8fba-7db8083a3be3", - "name": "German_591", - "codename": "de-DE_591" - } - }, - { - "system": { - "id": "28ffafad-8b6c-4d41-a84b-2ed650f8aec2", - "name": "German_651", - "codename": "de-DE_651" - } - }, - { - "system": { - "id": "47671fa3-79ea-4810-96c7-513f5d05d58e", - "name": "German_681", - "codename": "de-DE_681" - } - }, - { - "system": { - "id": "1c35c688-8002-4201-b61c-70bc919e2c9c", - "name": "German_741", - "codename": "de-DE_741" - } - }, - { - "system": { - "id": "bef4ed3b-b82e-443d-b69d-6c6504302422", - "name": "German_781", - "codename": "de-DE_781" - } - }, - { - "system": { - "id": "5dfd9c2b-a0b4-4e21-9b52-6ec32840723e", - "name": "German_81", - "codename": "de-DE_81" - } - }, - { - "system": { - "id": "51c9e330-68b1-4a8c-9eb7-0811fde43de0", - "name": "German_811", - "codename": "de-DE_811" - } - }, - { - "system": { - "id": "7f9fda00-117e-48b9-8b64-ed6235162510", - "name": "German_861", - "codename": "de-DE_861" - } - }, - { - "system": { - "id": "f00d0eb3-d637-4cf3-8d4b-0974576f81d5", - "name": "German_951", - "codename": "de-DE_951" - } - }, - { - "system": { - "id": "00699ff5-8984-4d14-b8e8-ed74347bd97b", - "name": "German_961", - "codename": "de-DE_961" - } - }, - { - "system": { - "id": "00000000-0000-0000-0000-000000000000", - "name": "Default environment language", - "codename": "default" - } - }, - { - "system": { - "id": "8fab3c4c-2ba4-47a9-8e53-df8e6154054f", - "name": "looooooooooooooooooooong2", - "codename": "looooooooooooooooooooong2" - } - }, - { - "system": { - "id": "24d5aaa6-a0db-4e20-8c11-6eb272bbe168", - "name": "loooooooooooooooooooooong", - "codename": "loooooooooooooooooooooong" - } - } - ], - "pagination": { - "skip": 100, - "limit": 0, - "count": 59, - "next_page": "" - } -} \ No newline at end of file diff --git a/test/browser/isolated-tests/endpoints/languages/list-languages.spec.ts b/test/browser/isolated-tests/endpoints/languages/list-languages.spec.ts deleted file mode 100644 index c9630057..00000000 --- a/test/browser/isolated-tests/endpoints/languages/list-languages.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './list-languages.spec.json'; - -describe('List languages', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListLanguagesResponse; - - beforeAll(async () => { - response = (await getDeliveryClientWithJson(responseJson).languages().toPromise()).data; - }); - - it(`Response should have all properties assigned`, () => { - expect(response.items.length).toEqual(responseJson.languages.length); - - for (const item of response.items) { - const originalItem = responseJson.languages.find((m) => m.system.id === item.system.id); - - if (!originalItem) { - throw Error(`Invalid language '${item.system.id}'`); - } - - expect(item.system.id).toEqual(originalItem.system.id); - expect(item.system.name).toEqual(originalItem.system.name); - expect(item.system.codename).toEqual(originalItem.system.codename); - } - }); -}); diff --git a/test/browser/isolated-tests/endpoints/sync/initialize-sync.spec.json b/test/browser/isolated-tests/endpoints/sync/initialize-sync.spec.json deleted file mode 100644 index 8bb0cf75..00000000 --- a/test/browser/isolated-tests/endpoints/sync/initialize-sync.spec.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "items": [ - { - "change_type": "deleted_item", - "timestamp": "2022-10-20T13:03:06.1310204Z", - "data": { - "system": { - "id": "a35d17ac-b6ba-4c6a-ae31-23c1193215cb", - "collection": "default", - "name": "My article", - "codename": "my_article", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "last_modified": "2019-03-27T13:21:11.38Z", - "workflow_step": "published" - } - } - }, - { - "change_type": "changed_item", - "timestamp": "2022-10-20T13:03:06.1310204Z", - "data": { - "system": { - "id": "335d17ac-b6ba-4c6a-ae31-23c1193215cb", - "collection": "default", - "name": "My article", - "codename": "my_article", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "last_modified": "2019-03-27T13:21:11.38Z", - "workflow_step": "published" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Warrior" - } - } - } - } - ] -} diff --git a/test/browser/isolated-tests/endpoints/sync/initialize-sync.spec.ts b/test/browser/isolated-tests/endpoints/sync/initialize-sync.spec.ts deleted file mode 100644 index 3b263199..00000000 --- a/test/browser/isolated-tests/endpoints/sync/initialize-sync.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './initialize-sync.spec.json'; - -describe('Initialize sync', () => { - const context = new Context(); - setup(context); - - let response: Responses.IInitializeSyncResponse; - - beforeAll(async () => { - response = (await getDeliveryClientWithJson(responseJson).initializeSync().toPromise()).data; - }); - - it(`Response should have all properties assigned`, () => { - expect(response.items.length).toEqual(responseJson.items.length); - - for (const item of response.items) { - const originalItem = responseJson.items.find((m) => m.data.system.id === item.data.system.id); - - if (!originalItem) { - throw Error(`Invalid item '${item.data.system.id}'`); - } - - expect(item.timestamp).toEqual(originalItem.timestamp); - expect(item.changeType).toEqual(originalItem.change_type); - - expect(item.data.system.codename).toEqual(originalItem.data.system.codename); - expect(item.data.system.type).toEqual(originalItem.data.system.type); - expect(item.data.system.collection).toEqual(originalItem.data.system.collection); - expect(item.data.system.language).toEqual(originalItem.data.system.language); - expect(item.data.system.name).toEqual(originalItem.data.system.name); - expect(item.data.system.workflowStep).toEqual(originalItem.data.system.workflow_step); - expect(item.data.system.lastModified).toEqual(originalItem.data.system.last_modified); - - if (originalItem.data.elements) { - expect(item.data.elements).toEqual(originalItem.data.elements); - } else { - expect(item.data.elements).toEqual({}); - } - } - }); -}); diff --git a/test/browser/isolated-tests/endpoints/sync/sync-changes.spec.json b/test/browser/isolated-tests/endpoints/sync/sync-changes.spec.json deleted file mode 100644 index 9ca393d8..00000000 --- a/test/browser/isolated-tests/endpoints/sync/sync-changes.spec.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "items": [ - { - "change_type": "deleted_item", - "timestamp": "2022-10-20T13:03:06.1310204Z", - "data": { - "system": { - "id": "135d17ac-b6ba-4c6a-ae31-23c1193215cb", - "collection": "default", - "name": "My article", - "codename": "my_article", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "last_modified": "2019-03-27T13:21:11.38Z", - "workflow_step": "published" - } - } - }, - { - "change_type": "changed_item", - "timestamp": "2022-10-20T13:03:06.1310204Z", - "data": { - "system": { - "id": "335d17ac-b6ba-4c6a-ae31-23c1193215cb", - "collection": "default", - "name": "My article", - "codename": "my_article", - "language": "en-US", - "type": "article", - "sitemap_locations": [], - "last_modified": "2019-03-27T13:21:11.38Z", - "workflow_step": "published" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Warrior" - } - } - } - } - ] -} diff --git a/test/browser/isolated-tests/endpoints/sync/sync-changes.spec.ts b/test/browser/isolated-tests/endpoints/sync/sync-changes.spec.ts deleted file mode 100644 index af2ab114..00000000 --- a/test/browser/isolated-tests/endpoints/sync/sync-changes.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJson } from '../../../setup'; -import * as responseJson from './sync-changes.spec.json'; - -describe('Sync changes', () => { - const context = new Context(); - setup(context); - - let response: Responses.ISyncChangesResponse; - - beforeAll(async () => { - response = (await getDeliveryClientWithJson(responseJson).syncChanges().toPromise()).data; - }); - - it(`Response should have all properties assigned`, () => { - expect(response.items.length).toEqual(responseJson.items.length); - - for (const item of response.items) { - const originalItem = responseJson.items.find((m) => m.data.system.id === item.data.system.id); - - if (!originalItem) { - throw Error(`Invalid item '${item.data.system.id}'`); - } - - expect(item.timestamp).toEqual(originalItem.timestamp); - expect(item.changeType).toEqual(originalItem.change_type); - - expect(item.data.system.codename).toEqual(originalItem.data.system.codename); - expect(item.data.system.type).toEqual(originalItem.data.system.type); - expect(item.data.system.collection).toEqual(originalItem.data.system.collection); - expect(item.data.system.language).toEqual(originalItem.data.system.language); - expect(item.data.system.name).toEqual(originalItem.data.system.name); - expect(item.data.system.workflowStep).toEqual(originalItem.data.system.workflow_step); - expect(item.data.system.lastModified).toEqual(originalItem.data.system.last_modified); - - if (originalItem.data.elements) { - expect(item.data.elements).toEqual(originalItem.data.elements); - } else { - expect(item.data.elements).toEqual({}); - } - } - }); -}); diff --git a/test/browser/isolated-tests/endpoints/used-in/used-in-all.spec.json b/test/browser/isolated-tests/endpoints/used-in/used-in-all.spec.json deleted file mode 100644 index 10e3c799..00000000 --- a/test/browser/isolated-tests/endpoints/used-in/used-in-all.spec.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "e27603e9-49e7-4d73-ba9f-843017d460db", - "name": "Product", - "codename": "product", - "language": "default", - "type": "product_example_content_type", - "collection": "default", - "workflow": "default", - "workflow_step": "published", - "last_modified": "2019-09-16T09:30:06.1123998Z" - } - } - ] -} diff --git a/test/browser/isolated-tests/endpoints/used-in/used-in-all.spec.ts b/test/browser/isolated-tests/endpoints/used-in/used-in-all.spec.ts deleted file mode 100644 index 1ed93048..00000000 --- a/test/browser/isolated-tests/endpoints/used-in/used-in-all.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { IGroupedNetworkResponse, Responses } from '../../../../../lib'; -import { Context, setup } from '../../../setup'; -import { getDeliveryClientWithJsonAndHeaders } from '../../../setup'; -import * as responseJson from './used-in-all.spec.json'; - -describe('Used in', () => { - const context = new Context(); - setup(context); - - let response: IGroupedNetworkResponse>; - - beforeAll(async () => { - response = await getDeliveryClientWithJsonAndHeaders( - responseJson, - { - environmentId: 'x' - }, - [] - ) - .itemUsedIn('x') - .queryConfig({ - disableItemLinking: false - }) - .toAllPromise(); - }); - - it(`Validate responses counts`, () => { - expect(response.responses.length).toEqual(1); - }); - - it(`Validate items count`, () => { - expect(response.data.items.length).toEqual(responseJson.items.length); - }); - - it(`Validates mapped item`, () => { - const item = response.data.items[0]; - const sourceItem = responseJson.items[0]; - - expect(item.system.id).toEqual(sourceItem.system.id); - expect(item.system.name).toEqual(sourceItem.system.name); - expect(item.system.codename).toEqual(sourceItem.system.codename); - expect(item.system.language).toEqual(sourceItem.system.language); - expect(item.system.type).toEqual(sourceItem.system.type); - expect(item.system.collection).toEqual(sourceItem.system.collection); - expect(item.system.lastModified).toEqual(sourceItem.system.last_modified); - expect(item.system.workflow).toEqual(sourceItem.system.workflow); - expect(item.system.workflowStep).toEqual(sourceItem.system.workflow_step); - }); -}); diff --git a/test/browser/isolated-tests/endpoints/used-in/used-in.spec.json b/test/browser/isolated-tests/endpoints/used-in/used-in.spec.json deleted file mode 100644 index 10e3c799..00000000 --- a/test/browser/isolated-tests/endpoints/used-in/used-in.spec.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "e27603e9-49e7-4d73-ba9f-843017d460db", - "name": "Product", - "codename": "product", - "language": "default", - "type": "product_example_content_type", - "collection": "default", - "workflow": "default", - "workflow_step": "published", - "last_modified": "2019-09-16T09:30:06.1123998Z" - } - } - ] -} diff --git a/test/browser/isolated-tests/endpoints/used-in/used-in.spec.ts b/test/browser/isolated-tests/endpoints/used-in/used-in.spec.ts deleted file mode 100644 index ab7ddb4f..00000000 --- a/test/browser/isolated-tests/endpoints/used-in/used-in.spec.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { IDeliveryNetworkResponse, Responses } from '../../../../../lib'; -import { Context, getTestDeliveryClient, setup } from '../../../setup'; -import { getDeliveryClientWithJsonAndHeaders } from '../../../setup'; -import * as responseJson from './used-in.spec.json'; - -describe('Used in', () => { - const context = new Context(); - setup(context); - - const query = getDeliveryClientWithJsonAndHeaders( - responseJson, - { - environmentId: 'x' - }, - [ - { - value: 'TokenX', - header: 'X-Continuation' - } - ] - ).itemUsedIn('product'); - - let response: IDeliveryNetworkResponse, any>; - - beforeAll(async () => { - response = await query.toPromise(); - }); - - it(`Validates asset used in url`, () => { - expect(getTestDeliveryClient().assetUsedIn('x').getUrl()).toEqual( - 'https://deliver.kontent.ai/delivery-environment-id/assets/x/used-in' - ); - }); - - it(`Validates content item used in url`, () => { - expect(getTestDeliveryClient().itemUsedIn('x').getUrl()).toEqual( - 'https://deliver.kontent.ai/delivery-environment-id/items/x/used-in' - ); - }); - - it(`Continuation token should be set`, () => { - expect(response.xContinuationToken).toEqual('TokenX'); - }); - - it(`Validates mapped item`, () => { - const item = response.data.items[0]; - const sourceItem = responseJson.items[0]; - - expect(item.system.id).toEqual(sourceItem.system.id); - expect(item.system.name).toEqual(sourceItem.system.name); - expect(item.system.codename).toEqual(sourceItem.system.codename); - expect(item.system.language).toEqual(sourceItem.system.language); - expect(item.system.type).toEqual(sourceItem.system.type); - expect(item.system.collection).toEqual(sourceItem.system.collection); - expect(item.system.lastModified).toEqual(sourceItem.system.last_modified); - expect(item.system.workflow).toEqual(sourceItem.system.workflow); - expect(item.system.workflowStep).toEqual(sourceItem.system.workflow_step); - }); -}); diff --git a/test/browser/isolated-tests/fake-data/fake-warrior-response.json b/test/browser/isolated-tests/fake-data/fake-warrior-response.json deleted file mode 100644 index eacf378d..00000000 --- a/test/browser/isolated-tests/fake-data/fake-warrior-response.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "item": { - "system": { - "id": "325e2acb-1c14-47f6-af9a-27bc8b6c16fe", - "name": "Warrior", - "codename": "warrior", - "language": "en", - "type": "movie", - "sitemap_locations": ["main_sitemap"], - "collection": "christmas-campaign", - "last_modified": "2019-09-05T10:51:15.6555984Z", - "workflow_step": "published", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Warrior" - }, - "plot": { - "type": "rich_text", - "name": "Plot", - "images": { - "22504ba8-2075-48fa-9d4f-8fce3de1754a": { - "image_id": "22504ba8-2075-48fa-9d4f-8fce3de1754a", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - }, - "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5": { - "image_id": "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - }, - "links": { - "3294e4b0-e58b-49d7-85fa-5bc9a86556ec": { - "codename": "joel_edgerton", - "type": "actor", - "url_slug": "joel-edgerton" - }, - "d1557cb1-d7ec-4d04-9742-f86b52bc34fc": { - "codename": "tom_hardy", - "type": "actor", - "url_slug": "tom-hardy" - } - }, - "modular_content": ["tom_hardy", "joel_edgerton", "ec9813f6_194d_018f_e20c_36855fb6e600"], - "value": "

The youngest son of an alcoholic former boxer returns home, where he's trained by his father for competition in a mixed martial arts tournament - a path that puts the fighter on a collision course with his estranged, older brother.

\n

Stars: 

\n\n\n


\n

See more in profile of Joel Edgerton and Tom Hardy

\n

And here are some images: 

\n
\"\"
\n
\"\"
\n


\n

Also, why not include content component in the mix?

\n" - }, - "released": { - "type": "date_time", - "name": "Released", - "value": "2011-09-09T00:00:00Z", - "display_timezone": "Europe/London" - }, - "length": { - "type": "number", - "name": "Length", - "value": 151 - }, - "poster": { - "type": "asset", - "name": "Poster", - "value": [ - { - "name": "warrior.jpg", - "description": null, - "type": "image/jpeg", - "size": 111004, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000, - "renditions": { - "default": { - "rendition_id": "b447ca6c-8020-4e8f-be57-1d110721e535", - "preset_id": "a6d98cd5-8b2c-4e50-99c9-15192bce2490", - "width": 1280, - "height": 1024, - "query": "w=1280&h=1024&fit=clip&rect=2396,169,1280,1024" - } - } - } - ] - }, - "category": { - "type": "multiple_choice", - "name": "Category", - "value": [ - { - "name": "Action", - "codename": "action" - }, - { - "name": "Drama", - "codename": "drama" - } - ] - }, - "stars": { - "type": "modular_content", - "name": "Stars", - "value": ["tom_hardy", "joel_edgerton"] - }, - "seoname": { - "type": "url_slug", - "name": "SeoName", - "value": "warrior" - }, - "releasecategory": { - "type": "taxonomy", - "name": "releasecategory", - "taxonomy_group": "releasecategory", - "value": [ - { - "name": "Global release", - "codename": "global_release" - }, - { - "name": "US only", - "codename": "us_only" - } - ] - } - } - }, - "modular_content": { - "ec9813f6_194d_018f_e20c_36855fb6e600": { - "system": { - "id": "ec9813f6-194d-018f-e20c-36855fb6e600", - "name": "ec9813f6-194d-018f-e20c-36855fb6e600", - "codename": "ec9813f6_194d_018f_e20c_36855fb6e600", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2019-09-05T10:51:15.6555984Z" - }, - "elements": { - "first_name": { - "type": "text", - "name": "First name", - "value": "Jennifer " - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Morrison" - }, - "url": { - "type": "url_slug", - "name": "Url", - "value": "component-actor-url" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [] - } - } - }, - "joel_edgerton": { - "system": { - "id": "3294e4b0-e58b-49d7-85fa-5bc9a86556ec", - "name": "Joel Edgerton", - "codename": "joel_edgerton", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2017-08-03T09:21:21.3857294Z" - }, - "elements": { - "url": { - "type": "url_slug", - "name": "Url", - "value": "joel-edgerton" - }, - "first_name": { - "type": "text", - "name": "First name", - "value": "Joel" - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Edgerton" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [ - { - "name": "joel_edgerton.jpg", - "description": null, - "type": "image/jpeg", - "size": 6460, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/2855720a-4ca4-4687-826a-29f9635088e0/joel_edgerton.jpg", - "width": 211, - "height": 317 - } - ] - } - } - }, - "tom_hardy": { - "system": { - "id": "d1557cb1-d7ec-4d04-9742-f86b52bc34fc", - "name": "Tom Hardy", - "codename": "tom_hardy", - "language": "en", - "type": "actor", - "sitemap_locations": [], - "collection": "default", - "last_modified": "2018-02-09T13:11:32.5769383Z" - }, - "elements": { - "url": { - "type": "url_slug", - "name": "Url", - "value": "tom-hardy" - }, - "first_name": { - "type": "text", - "name": "First name", - "value": "Tom" - }, - "last_name": { - "type": "text", - "name": "Last name", - "value": "Hardy" - }, - "photo": { - "type": "asset", - "name": "Photo", - "value": [ - { - "name": "tom_hardy.jpg", - "description": null, - "type": "image/jpeg", - "size": 8091, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - ] - } - } - } - } -} diff --git a/test/browser/isolated-tests/fake-data/fake-warrior-without-modular-data-response.json b/test/browser/isolated-tests/fake-data/fake-warrior-without-modular-data-response.json deleted file mode 100644 index 68ae3c93..00000000 --- a/test/browser/isolated-tests/fake-data/fake-warrior-without-modular-data-response.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "item": { - "system": { - "id": "325e2acb-1c14-47f6-af9a-27bc8b6c16fe", - "name": "Warrior", - "codename": "warrior", - "language": "en", - "type": "movie", - "sitemap_locations": ["main_sitemap"], - "collection": "default", - "last_modified": "2019-09-05T10:51:15.6555984Z" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Warrior" - }, - "plot": { - "type": "rich_text", - "name": "Plot", - "images": { - "22504ba8-2075-48fa-9d4f-8fce3de1754a": { - "image_id": "22504ba8-2075-48fa-9d4f-8fce3de1754a", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - }, - "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5": { - "image_id": "bb0899cf-2c3a-4e3f-8962-60e5a54fcca5", - "description": null, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/bb0899cf-2c3a-4e3f-8962-60e5a54fcca5/tom_hardy.jpg", - "width": 214, - "height": 317 - } - }, - "links": { - "3294e4b0-e58b-49d7-85fa-5bc9a86556ec": { - "codename": "joel_edgerton", - "type": "actor", - "url_slug": "joel-edgerton" - }, - "d1557cb1-d7ec-4d04-9742-f86b52bc34fc": { - "codename": "tom_hardy", - "type": "actor", - "url_slug": "tom-hardy" - } - }, - "modular_content": ["tom_hardy", "joel_edgerton", "ec9813f6_194d_018f_e20c_36855fb6e600"], - "value": "

The youngest son of an alcoholic former boxer returns home, where he's trained by his father for competition in a mixed martial arts tournament - a path that puts the fighter on a collision course with his estranged, older brother.

\n

Stars: 

\n\n\n


\n

See more in profile of Joel Edgerton and Tom Hardy

\n

And here are some images: 

\n
\"\"
\n
\"\"
\n


\n

Also, why not include content component in the mix?

\n" - }, - "released": { - "type": "date_time", - "name": "Released", - "value": "2011-09-09T00:00:00Z" - }, - "length": { - "type": "number", - "name": "Length", - "value": 151 - }, - "poster": { - "type": "asset", - "name": "Poster", - "value": [ - { - "name": "warrior.jpg", - "description": null, - "type": "image/jpeg", - "size": 111004, - "url": "https://assets-us-01.kc-usercontent.com:443/da5abe9f-fdad-4168-97cd-b3464be2ccb9/22504ba8-2075-48fa-9d4f-8fce3de1754a/warrior.jpg", - "width": 648, - "height": 1000 - } - ] - }, - "category": { - "type": "multiple_choice", - "name": "Category", - "value": [ - { - "name": "Action", - "codename": "action" - }, - { - "name": "Drama", - "codename": "drama" - } - ] - }, - "stars": { - "type": "modular_content", - "name": "Stars", - "value": ["tom_hardy", "joel_edgerton"] - }, - "seoname": { - "type": "url_slug", - "name": "SeoName", - "value": "warrior" - }, - "releasecategory": { - "type": "taxonomy", - "name": "releasecategory", - "taxonomy_group": "releasecategory", - "value": [ - { - "name": "Global release", - "codename": "global_release" - }, - { - "name": "US only", - "codename": "us_only" - } - ] - } - } - }, - "modular_content": {} -} diff --git a/test/browser/isolated-tests/http/custom-http-service.spec.ts b/test/browser/isolated-tests/http/custom-http-service.spec.ts deleted file mode 100644 index f35ad196..00000000 --- a/test/browser/isolated-tests/http/custom-http-service.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - IResponse, - IHttpDeleteQueryCall, - IHttpGetQueryCall, - IHttpPatchQueryCall, - IHttpPostQueryCall, - IHttpPutQueryCall, - IHttpQueryOptions, - IHttpService, - IHttpCancelRequestToken -} from '@kontent-ai/core-sdk'; - -import { DeliveryClient } from '../../../../lib'; - -class CustomHttpService implements IHttpService { - getAsync(call: IHttpGetQueryCall, options?: IHttpQueryOptions): Promise> { - return this.resolveTestCall(); - } - - postAsync( - call: IHttpPostQueryCall, - options?: IHttpQueryOptions - ): Promise> { - return this.resolveTestCall(); - } - - putAsync(call: IHttpPutQueryCall, options?: IHttpQueryOptions): Promise> { - return this.resolveTestCall(); - } - - patchAsync( - call: IHttpPatchQueryCall, - options?: IHttpQueryOptions - ): Promise> { - return this.resolveTestCall(); - } - - deleteAsync( - call: IHttpDeleteQueryCall, - options?: IHttpQueryOptions - ): Promise> { - return this.resolveTestCall(); - } - - createCancelToken(): IHttpCancelRequestToken { - return { - cancel: () => {}, - token: undefined - }; - } - - private resolveTestCall(): Promise> { - const promise = new Promise>((resolve, reject) => { - resolve({ - data: {}, - headers: [], - rawResponse: {}, - retryStrategy: { - options: {}, - retryAttempts: 3 - }, - status: 200 - }); - }); - return promise; - } -} - -describe('Custom Http service', () => { - const client = new DeliveryClient({ - environmentId: 'xxx', - httpService: new CustomHttpService() - }); - - it(`Should use custom http service`, () => { - // this is fragile, but we don't want to expose these properties for now - const httpService = client['queryService']['httpService']; - expect(httpService).toEqual(jasmine.any(CustomHttpService)); - }); -}); diff --git a/test/browser/isolated-tests/images/image-url-builder.spec.ts b/test/browser/isolated-tests/images/image-url-builder.spec.ts deleted file mode 100644 index 5e3a33c6..00000000 --- a/test/browser/isolated-tests/images/image-url-builder.spec.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { transformImageUrl } from '../../../../lib'; - -describe('Image URL builder', () => { - const getImageBuilder = () => transformImageUrl('myimage.jpg'); - - it(`Checks complex query`, () => { - const ib = getImageBuilder(); - ib.withDpr(2).withCompression('lossless').withQuality(4).withHeight(200).withWidth(100); - - expect(ib.getUrl()).toContain('myimage.jpg'); - expect(ib.getUrl()).toContain('q=4'); - expect(ib.getUrl()).toContain('w=100'); - expect(ib.getUrl()).toContain('h=200'); - expect(ib.getUrl()).toContain('lossless=true'); - expect(ib.getUrl()).toContain('dpr=2'); - }); - - it(`Checks automatic format`, () => { - const ib = getImageBuilder(); - ib.withAutomaticFormat(); - expect(ib.getUrl()).toContain('auto=format'); - }); - - it(`Checks automatic format with backup`, () => { - const ib = getImageBuilder(); - ib.withAutomaticFormat('jpg'); - expect(ib.getUrl()).toContain('fm=jpg'); - expect(ib.getUrl()).toContain('auto=format'); - }); - - it(`Checks dpr`, () => { - const ib = getImageBuilder(); - ib.withDpr(9); - expect(ib.getUrl()).toContain('dpr=9'); - }); - - it(`Checks width`, () => { - const ib = getImageBuilder(); - ib.withWidth(250); - expect(ib.getUrl()).toContain('w=250'); - - ib.withWidth(0.5); - expect(ib.getUrl()).toContain('w=0.5'); - - ib.withWidth(97.012345678915); - expect(ib.getUrl()).toContain('w=97.012345678915'); - }); - - it(`Checks height`, () => { - const ib = getImageBuilder(); - ib.withHeight(100); - expect(ib.getUrl()).toContain('h=100'); - }); - - it(`Checks quality`, () => { - const ib = getImageBuilder(); - ib.withQuality(2); - expect(ib.getUrl()).toContain('q=2'); - }); - - it(`Checks format`, () => { - const ib = getImageBuilder(); - ib.withFormat('png'); - expect(ib.getUrl()).toContain('fm=png'); - - ib.withFormat('png8'); - expect(ib.getUrl()).toContain('fm=png8'); - }); - - it(`Checks compression`, () => { - const ib = getImageBuilder(); - ib.withCompression('lossless'); - expect(ib.getUrl()).toContain('lossless=true'); - - ib.withCompression('lossy'); - expect(ib.getUrl()).toContain('lossless=false'); - }); - - it(`Checks rectangle crop`, () => { - const ib = getImageBuilder(); - ib.withRectangleCrop(1, 2, 50, 90); - expect(ib.getUrl()).toContain('rect=1,2,50,90'); - }); - - it(`Checks focal point crop`, () => { - const ib = getImageBuilder(); - ib.withFocalPointCrop(2, 50, 3); - expect(ib.getUrl()).toContain('crop=focalpoint'); - expect(ib.getUrl()).toContain('fp-x=2'); - expect(ib.getUrl()).toContain('fp-y=50'); - expect(ib.getUrl()).toContain('fp-z=3'); - }); - - it(`Checks fit mode`, () => { - const ib = getImageBuilder(); - ib.withFitMode('crop'); - expect(ib.getUrl()).toContain('fit=crop'); - - ib.withFitMode('clip'); - expect(ib.getUrl()).toContain('fit=clip'); - - ib.withFitMode('scale'); - expect(ib.getUrl()).toContain('fit=scale'); - }); - - it(`Checks custom param`, () => { - const ib = getImageBuilder(); - ib.withCustomParam('x=y'); - expect(ib.getUrl()).toContain('x=y'); - }); -}); diff --git a/test/browser/isolated-tests/query/custom-headers.spec.ts b/test/browser/isolated-tests/query/custom-headers.spec.ts deleted file mode 100644 index bbb9f6c1..00000000 --- a/test/browser/isolated-tests/query/custom-headers.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Custom query headers', () => { - const context = new Context(); - setup(context); - - it(`Item query initialization with invalid codename should throw Error`, () => { - expect(() => context.deliveryClient.item(null as any)).toThrowError(); - }); - - it(`Header should be present in result`, () => { - const headers = context.deliveryClient - .items() - .queryConfig({ - customHeaders: [ - { - header: 'xHeader', - value: 'yValue' - } - ] - }) - .getHeaders(); - - const itemHeader = headers.find( - m => m.header === 'xHeader' && m.value === 'yValue' - ); - - expect(itemHeader).toBeDefined(); - }); -}); diff --git a/test/browser/isolated-tests/query/query-config.spec.ts b/test/browser/isolated-tests/query/query-config.spec.ts deleted file mode 100644 index 77e77e2a..00000000 --- a/test/browser/isolated-tests/query/query-config.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { IQueryConfig, IItemQueryConfig } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Query configurations', () => { - - const context = new Context(); - setup(context); - - it(`QueryConfig should set values properly`, () => { - let queryConfig: IQueryConfig = { usePreviewMode: true, waitForLoadingNewContent: true }; - expect(queryConfig.usePreviewMode).toEqual(true); - expect(queryConfig.waitForLoadingNewContent).toEqual(true); - - queryConfig = ({ usePreviewMode: false, waitForLoadingNewContent: false }); - expect(queryConfig.usePreviewMode).toEqual(false); - expect(queryConfig.waitForLoadingNewContent).toEqual(false); - }); - - it(`ItemQuerConfig should set values properly`, () => { - let queryConfig: IItemQueryConfig = { usePreviewMode: true, waitForLoadingNewContent: true }; - expect(queryConfig.usePreviewMode).toEqual(true); - expect(queryConfig.waitForLoadingNewContent).toEqual(true); - - queryConfig = { usePreviewMode: false, waitForLoadingNewContent: false }; - expect(queryConfig.usePreviewMode).toEqual(false); - expect(queryConfig.waitForLoadingNewContent).toEqual(false); - }); -}); - diff --git a/test/browser/isolated-tests/query/query-custom-parameter.spec.ts b/test/browser/isolated-tests/query/query-custom-parameter.spec.ts deleted file mode 100644 index fb3e3ff4..00000000 --- a/test/browser/isolated-tests/query/query-custom-parameter.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Query custom parameter', () => { - - const context = new Context(); - setup(context); - - it(`Url should contain the custom parameter with value #1`, () => { - const url = context.deliveryClient.items().withCustomParameter('customParam', 'customVal').getUrl(); - expect(url).toContain(`customParam=customVal`); - }); - - it(`Url should contain the custom parameter with value #2`, () => { - const url = context.deliveryClient.element('el', 'cd').withCustomParameter('customParam', 'customVal').getUrl(); - expect(url).toContain(`customParam=customVal`); - }); - - it(`Custom param with invalid name should throw Error`, () => { - expect(() => context.deliveryClient.items().withCustomParameter(undefined as any, 'customVal')).toThrowError(); - expect(() => context.deliveryClient.items().withCustomParameter(null as any, 'customVal')).toThrowError(); - }); - -}); - diff --git a/test/browser/isolated-tests/query/query-initialization.spec.ts b/test/browser/isolated-tests/query/query-initialization.spec.ts deleted file mode 100644 index 956ebd0f..00000000 --- a/test/browser/isolated-tests/query/query-initialization.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Query initialization', () => { - - const context = new Context(); - setup(context); - - it(`Element query initialization with invalid type should throw Error`, () => { - expect(() => context.deliveryClient.element(null as any, 'title')).toThrowError(); - }); - - it(`Element query initialization with invalid type should throw Error`, () => { - expect(() => context.deliveryClient.element('movie', null as any)).toThrowError(); - }); - - it(`Item query initialization with invalid codename should throw Error`, () => { - expect(() => context.deliveryClient.item(null as any)).toThrowError(); - }); - - it(`Type query initialization with invalid codename should throw Error`, () => { - expect(() => context.deliveryClient.type(null as any)).toThrowError(); - }); - - it(`Taxonomy query initialization with invalid codename should throw Error`, () => { - expect(() => context.deliveryClient.taxonomy(null as any)).toThrowError(); - }); - -}); - diff --git a/test/browser/isolated-tests/query/query-url-debug.spec.ts b/test/browser/isolated-tests/query/query-url-debug.spec.ts deleted file mode 100644 index bab2508c..00000000 --- a/test/browser/isolated-tests/query/query-url-debug.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Query url debug', () => { - - const context = new Context(); - setup(context); - - it(`Item url`, () => { - const url = context.deliveryClient.item('warrior').getUrl(); - expect(url).toContain('items/warrior'); - }); - - it(`Items url`, () => { - const url = context.deliveryClient.items().getUrl(); - expect(url).toContain('items'); - }); - - it(`Taxonomy url`, () => { - const url = context.deliveryClient.taxonomy('taxonomy_element').getUrl(); - expect(url).toContain('taxonomies/taxonomy_element'); - }); - - it(`Taxonomies url`, () => { - const url = context.deliveryClient.taxonomies().getUrl(); - expect(url).toContain('taxonomies'); - }); - - it(`Type url`, () => { - const url = context.deliveryClient.type('movie').getUrl(); - expect(url).toContain('types/movie'); - }); - - it(`Types url`, () => { - const url = context.deliveryClient.types().getUrl(); - expect(url).toContain('types'); - }); - - it(`Element url`, () => { - const url = context.deliveryClient.element('movie', 'title').getUrl(); - expect(url).toContain('types/movie/elements/title'); - }); - -}); - diff --git a/test/browser/isolated-tests/query/wait-for-loading-new-content.spec.ts b/test/browser/isolated-tests/query/wait-for-loading-new-content.spec.ts deleted file mode 100644 index 95a60ee5..00000000 --- a/test/browser/isolated-tests/query/wait-for-loading-new-content.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Wait for loading new content', () => { - - const context = new Context(); - setup(context); - - const waitForLoadingNewContentHeader: string = 'X-KC-Wait-For-Loading-New-Content'; - - it(`'X-KC-Wait-For-Loading-New-Content' header should NOT be set when Query configuration does not set it`, () => { - const itemHeaders = context.deliveryClient.item('any').getHeaders(); - const itemsHeaders = context.deliveryClient.items().getHeaders(); - const taxonomyHeaders = context.deliveryClient.taxonomy('any').getHeaders(); - const taxonomiesHeaders = context.deliveryClient.taxonomies().getHeaders(); - const typeHeaders = context.deliveryClient.type('any').getHeaders(); - const typesHeaders = context.deliveryClient.types().getHeaders(); - - const itemHeader = itemHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const itemsHeader = itemsHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const taxonomyHeader = taxonomyHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const taxonomiesHeader = taxonomiesHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const typeHeader = typeHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const typesHeader = typesHeaders.find(m => m.header === waitForLoadingNewContentHeader); - - expect(itemHeader).toBeUndefined(); - expect(itemsHeader).toBeUndefined(); - expect(taxonomyHeader).toBeUndefined(); - expect(taxonomiesHeader).toBeUndefined(); - expect(typeHeader).toBeUndefined(); - expect(typesHeader).toBeUndefined(); - }); - - it(`'X-KC-Wait-For-Loading-New-Content' header should be be set when Query configuration enables it`, () => { - const itemHeaders = context.deliveryClient.item('any').queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - const itemsHeaders = context.deliveryClient.items().queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - const taxonomyHeaders = context.deliveryClient.taxonomy('any').queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - const taxonomiesHeaders = context.deliveryClient.taxonomies().queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - const typeHeaders = context.deliveryClient.type('any').queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - const typesHeaders = context.deliveryClient.types().queryConfig({ waitForLoadingNewContent: true }).getHeaders(); - - const itemHeader = itemHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const itemsHeader = itemsHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const taxonomyHeader = taxonomyHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const taxonomiesHeader = taxonomiesHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const typeHeader = typeHeaders.find(m => m.header === waitForLoadingNewContentHeader); - const typesHeader = typesHeaders.find(m => m.header === waitForLoadingNewContentHeader); - - expect(itemHeader).toBeDefined(); - expect(itemsHeader).toBeDefined(); - expect(taxonomyHeader).toBeDefined(); - expect(taxonomiesHeader).toBeDefined(); - expect(typeHeader).toBeDefined(); - expect(typesHeader).toBeDefined(); - }); -}); - - diff --git a/test/browser/isolated-tests/response/item.spec.ts b/test/browser/isolated-tests/response/item.spec.ts deleted file mode 100644 index c51cd74e..00000000 --- a/test/browser/isolated-tests/response/item.spec.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { Responses } from '../../../../lib'; -import { getDeliveryClientWithJson, Movie } from '../../setup'; -import * as warriorJson from '../fake-data/fake-warrior-response.json'; - -describe('Verifies mapping of delivery content item', () => { - let responseWithLinkedItems: Responses.IViewContentItemResponse; - let responseWithoutLinkedItems: Responses.IViewContentItemResponse; - - beforeAll(async () => { - responseWithLinkedItems = (await getDeliveryClientWithJson(warriorJson).item('x').toPromise()).data; - responseWithoutLinkedItems = ( - await getDeliveryClientWithJson(warriorJson, { - linkedItemsReferenceHandler: 'ignore', - environmentId: 'x' - }) - .item('x') - .toPromise() - ).data; - }); - - it(`checks system codename`, () => { - expect(responseWithLinkedItems.item.system.codename).toEqual(warriorJson.item.system.codename); - }); - - it(`checks system id`, () => { - expect(responseWithLinkedItems.item.system.id).toEqual(warriorJson.item.system.id); - }); - - it(`checks system type`, () => { - expect(responseWithLinkedItems.item.system.type).toEqual(warriorJson.item.system.type); - }); - - it(`checks system collection`, () => { - expect(responseWithLinkedItems.item.system.collection).toEqual(warriorJson.item.system.collection); - }); - - it(`checks last modified`, () => { - expect(responseWithLinkedItems.item.system.lastModified).toEqual(warriorJson.item.system.last_modified); - }); - - it(`checks workflow step`, () => { - expect(responseWithLinkedItems.item.system.workflowStep).toEqual(warriorJson.item.system.workflow_step); - }); - - it(`checks language`, () => { - expect(responseWithLinkedItems.item.system.language).toEqual(warriorJson.item.system.language); - }); - - it(`checks site map locations`, () => { - const locations: string[] = ['main_sitemap']; - expect(responseWithLinkedItems.item.system.sitemapLocations).toEqual(locations); - }); - - it(`checks taxonomy element value`, () => { - expect(responseWithLinkedItems.item.elements.releasecategory.value[0].codename).toEqual( - warriorJson.item.elements.releasecategory.value[0].codename - ); - }); - - it(`checks system workflow`, () => { - expect(responseWithLinkedItems.item.system.workflow).toEqual(warriorJson.item.system.workflow); - }); - - it(`checks system workflow step`, () => { - expect(responseWithLinkedItems.item.system.workflowStep).toEqual(warriorJson.item.system.workflow_step); - }); - - it(`checks strongly typed taxonomy`, () => { - const globalReleaseTaxonomy = responseWithLinkedItems.item.elements.releasecategory.value.find( - (m) => m.codename === 'global_release' - ); - const usReleaseTaxonomy = responseWithLinkedItems.item.elements.releasecategory.value.find( - (m) => m.codename === 'us_only' - ); - - expect(globalReleaseTaxonomy).toBeDefined(); - expect(usReleaseTaxonomy).toBeDefined(); - }); - - it(`checks text element`, () => { - expect(responseWithLinkedItems.item.elements.title.value).toEqual(warriorJson.item.elements.title.value); - }); - - it(`checks rich text element`, () => { - for (const linkedItemCodename of responseWithLinkedItems.item.elements.plot.linkedItemCodenames) { - const linkedItem = responseWithLinkedItems.item.elements.plot.linkedItems.find( - (m) => m.system.codename === linkedItemCodename - ); - - expect(linkedItem).toBeDefined(); - expect(linkedItem?.system.codename).toEqual(linkedItemCodename); - expect(linkedItem?.elements).toBeDefined(); - } - }); - - it(`checks datetime element`, () => { - expect(responseWithLinkedItems.item.elements.released.value).toEqual(warriorJson.item.elements.released.value); - expect(responseWithLinkedItems.item.elements.released.displayTimeZone).toEqual( - warriorJson.item.elements.released.display_timezone - ); - }); - - it(`checks number element`, () => { - expect(responseWithLinkedItems.item.elements.length.value).toEqual(warriorJson.item.elements.length.value); - }); - - it(`checks assets element`, () => { - expect(responseWithLinkedItems.item.elements.poster.value.length).toEqual( - warriorJson.item.elements.poster.value.length - ); - expect(responseWithLinkedItems.item.elements.poster.value[0].url).toEqual( - warriorJson.item.elements.poster.value[0].url - ); - }); - - it(`checks that correct number of linked items are created`, () => { - expect(responseWithLinkedItems.item.elements.stars.linkedItems.length).toEqual( - warriorJson.item.elements.stars.value.length - ); - }); - - it(`checks that text element in first linked item is set`, () => { - expect( - responseWithLinkedItems.item.elements.stars.linkedItems.find( - (m) => - m.elements.first_name.value === warriorJson.modular_content.joel_edgerton.elements.first_name.value - ) - ).toBeDefined(); - }); - - it(`checks that text element in second linked item is set`, () => { - expect( - responseWithLinkedItems.item.elements.stars.linkedItems.find( - (m) => m.elements.first_name.value === warriorJson.modular_content.tom_hardy.elements.first_name.value - ) - ).toBeDefined(); - }); - - describe('Checks disabled linked items mapping', () => { - it(`linked items should not be mapped`, () => { - expect(responseWithoutLinkedItems.item.elements.stars.linkedItems.length).toEqual(0); - }); - - it(`linked items should have empty array`, () => { - expect(responseWithoutLinkedItems.item.elements.plot.linkedItemCodenames.length).toEqual( - warriorJson.item.elements.plot.modular_content.length - ); - expect(responseWithoutLinkedItems.item.elements.plot.linkedItems.length).toEqual(0); - }); - }); -}); diff --git a/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping-disabled.spec.ts b/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping-disabled.spec.ts deleted file mode 100644 index b2d83156..00000000 --- a/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping-disabled.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Elements, Responses } from '../../../../../lib'; -import { getTestDeliveryClient } from '../../../setup'; -import * as responseJson from './linked-items-mapping.json'; - -describe('Linked items mapping disabled', () => { - const client = getTestDeliveryClient({ - environmentId: 'x', - linkedItemsReferenceHandler: 'ignore' - }); - - const response: Responses.IViewContentItemResponse = client.mappingService.viewContentItemResponse(responseJson); - const modularItemElement = 'related_articles'; - - it(`'coffee_processing_techniques' should have mapped items`, () => { - const linkedItem = response.item; - expect(linkedItem).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeUndefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'which_brewing_fits_you_' - ) - ).toBeUndefined(); - }); - - it(`'on_roasts' should not have parent object in its own linked items `, () => { - const linkedItemCodename = 'on_roasts'; - const linkedItem = response.linkedItems[linkedItemCodename]; - - expect(linkedItem).toBeDefined(); - - if (!linkedItem) { - throw Error(`Item with codename '${linkedItemCodename}' was not found`); - } - - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeUndefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'which_brewing_fits_you_' - ) - ).toBeUndefined(); - }); - - it(`'which_brewing_fits_you_' should not have parent object in its own linked items `, () => { - const linkedItemCodename = 'which_brewing_fits_you_'; - const linkedItem = response.linkedItems[linkedItemCodename]; - - expect(linkedItem).toBeDefined(); - - if (!linkedItem) { - throw Error(`Item with codename '${linkedItemCodename}' was not found`); - } - - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeUndefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'coffee_processing_techniques' - ) - ).toBeUndefined(); - }); -}); diff --git a/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping-enabled.spec.ts b/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping-enabled.spec.ts deleted file mode 100644 index daaca97b..00000000 --- a/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping-enabled.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Elements, Responses } from '../../../../../lib'; -import { getTestDeliveryClient } from '../../../setup'; -import * as responseJson from './linked-items-mapping.json'; - -describe('Linked items mapping enabled', () => { - const client = getTestDeliveryClient({ - environmentId: 'x', - linkedItemsReferenceHandler: 'map' - }); - - const response: Responses.IViewContentItemResponse = client.mappingService.viewContentItemResponse(responseJson); - const modularItemElement = 'related_articles'; - - it(`'coffee_processing_techniques' should have mapped items`, () => { - const linkedItem = response.item; - expect(linkedItem).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'which_brewing_fits_you_' - ) - ).toBeDefined(); - }); - - it(`'on_roasts' should have mapped items `, () => { - const linkedItemCodename = 'on_roasts'; - const linkedItem = response.linkedItems[linkedItemCodename]; - - expect(linkedItem).toBeDefined(); - - if (!linkedItem) { - throw Error(`Item with codename '${linkedItemCodename}' was not found`); - } - - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'which_brewing_fits_you_' - ) - ).toBeDefined(); - }); - - it(`'which_brewing_fits_you_' should have mapped items`, () => { - const linkedItemCodename = 'which_brewing_fits_you_'; - const linkedItem = response.linkedItems[linkedItemCodename]; - - expect(linkedItem).toBeDefined(); - - if (!linkedItem) { - throw Error(`Item with codename '${linkedItemCodename}' was not found`); - } - - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'on_roasts' - ) - ).toBeDefined(); - expect( - (linkedItem.elements[modularItemElement] as Elements.LinkedItemsElement).linkedItems.find( - (m) => m.system.codename === 'coffee_processing_techniques' - ) - ).toBeDefined(); - }); -}); diff --git a/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping.json b/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping.json deleted file mode 100644 index a16bb78c..00000000 --- a/test/browser/isolated-tests/response/linked-items-mapping/linked-items-mapping.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "item": { - "system": { - "id": "117cdfae-52cf-4885-b271-66aef6825612", - "name": "Coffee processing techniques", - "codename": "coffee_processing_techniques", - "language": "en-US", - "type": "article", - "sitemap_locations": [ - "articles" - ], - "collection": "default", - "last_modified": "2018-07-17T08:12:03.07Z", - "workflow_step": "x", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Coffee processing techniques" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": [ - "on_roasts", - "which_brewing_fits_you_" - ] - } - } - }, - "modular_content": { - "on_roasts": { - "system": { - "id": "f4b3fc05-e988-4dae-9ac1-a94aba566474", - "name": "On Roasts", - "codename": "on_roasts", - "language": "en-US", - "type": "article", - "sitemap_locations": ["articles"], - "collection": "default", - "last_modified": "2017-12-08T08:49:53.603Z", - "workflow_step": "x", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "On Roasts" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": [ - "on_roasts", - "which_brewing_fits_you_" - ] - } - } - }, - "which_brewing_fits_you_": { - "system": { - "id": "3120ec15-a4a2-47ec-8ccd-c85ac8ac5ba5", - "name": "Which brewing fits you?", - "codename": "which_brewing_fits_you_", - "language": "en-US", - "type": "article", - "sitemap_locations": ["articles"], - "collection": "default", - "last_modified": "2018-10-11T08:45:56.917Z", - "workflow_step": "x", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Which brewing fits you?" - }, - "related_articles": { - "type": "modular_content", - "name": "Related articles", - "value": [ - "coffee_processing_techniques", - "on_roasts" - ] - } - } - } - } -} \ No newline at end of file diff --git a/test/browser/isolated-tests/services/generic-element-mapper.spec.ts b/test/browser/isolated-tests/services/generic-element-mapper.spec.ts deleted file mode 100644 index fe1773f0..00000000 --- a/test/browser/isolated-tests/services/generic-element-mapper.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericElementMapper } from '../../../../lib/mappers'; - -describe('GenericElementMapper', () => { - - const genericElementMapper = new GenericElementMapper(); - - it(`should throw an Error when invalid response is given`, () => { - expect(() => genericElementMapper.mapElement(null as any)).toThrowError(); - expect(() => genericElementMapper.mapElement(undefined as any)).toThrowError(); - }); -}); - diff --git a/test/browser/isolated-tests/services/mapping-service.spec.json b/test/browser/isolated-tests/services/mapping-service.spec.json deleted file mode 100644 index bceffd34..00000000 --- a/test/browser/isolated-tests/services/mapping-service.spec.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "items": [ - { - "system": { - "id": "cf106f4e-30a4-42ef-b313-b8ea3fd3e5c5", - "name": "Coffee Beverages Explained", - "codename": "coffee_beverages_explained", - "language": "default", - "type": "article", - "sitemap_locations": ["articles"], - "collection": "default", - "last_modified": "2017-04-04T13:40:00.1102334Z", - "workflow_step": "published", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Coffee Beverages Explained" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "Espresso and filtered coffee are the two main categories of coffee, based on the method of preparation. Learn about individual types of coffee that fall under these categories." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-11-18T00:00:00Z" - }, - "teaser_image": { - "type": "asset", - "name": "Teaser image", - "value": [ - { - "name": "coffee-beverages-explained-1080px.jpg", - "type": "image/jpeg", - "size": 90895, - "description": null, - "url": "https://assets-us-01.kc-usercontent.com/975bf280-fd91-488c-994c-2f04416e5ee3/e700596b-03b0-4cee-ac5c-9212762c027a/coffee-beverages-explained-1080px.jpg" - } - ] - } - } - }, - { - "system": { - "id": "23f71096-fa89-4f59-a3f9-970e970944ec", - "name": "Donate with us", - "codename": "donate_with_us", - "language": "default", - "type": "article", - "sitemap_locations": ["articles"], - "collection": "default", - "last_modified": "2017-04-04T13:40:29.970377Z", - "workflow_step": "published", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Donate with us" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "Dancing Goat regularly donates money to Children in Africa, a foundation helping children with food, accommodation, education, and other essentials. Donate with us and create a better world." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-11-12T00:00:00Z" - }, - "teaser_image": { - "type": "asset", - "name": "Teaser image", - "value": [ - { - "name": "donate-with-us-1080px.jpg", - "type": "image/jpeg", - "size": 133239, - "description": null, - "url": "https://assets-us-01.kc-usercontent.com/975bf280-fd91-488c-994c-2f04416e5ee3/9b86141d-b667-4c35-82b1-826bc151d72a/donate-with-us-1080px.jpg" - } - ] - } - } - }, - { - "system": { - "id": "b2fea94c-73fd-42ec-a22f-f409878de187", - "name": "Origins of Arabica Bourbon", - "codename": "origins_of_arabica_bourbon", - "language": "default", - "type": "article", - "sitemap_locations": ["articles"], - "collection": "default", - "last_modified": "2017-04-04T13:45:44.1533096Z", - "workflow_step": "published", - "workflow": "default" - }, - "elements": { - "title": { - "type": "text", - "name": "Title", - "value": "Origins of Arabica Bourbon" - }, - "summary": { - "type": "text", - "name": "Summary", - "value": "This one particular type of coffee, the Arabica Bourbon, is now sold only in Japan. It has been brought back to life by enthusiasts after being almost forgotten for nearly sixty years." - }, - "post_date": { - "type": "date_time", - "name": "Post date", - "value": "2014-11-11T00:00:00Z" - }, - "teaser_image": { - "type": "asset", - "name": "Teaser image", - "value": [ - { - "name": "origins-of-arabica-bourbon-1080px.jpg", - "type": "image/jpeg", - "size": 132229, - "description": null, - "url": "https://assets.kenticocloud.com:443/975bf280-fd91-488c-994c-2f04416e5ee3/1cfcb6c9-1fe6-4013-a0bb-b26f8ada2ebf/origins-of-arabica-bourbon-1080px.jpg" - } - ] - } - } - } - ], - "modular_content": {}, - "pagination": { - "skip": 0, - "limit": 3, - "count": 3, - "next_page": "https://deliver.kontent.ai/975bf280-fd91-488c-994c-2f04416e5ee3/items?system.type=article&elements=title%2csummary%2cpost_date%2cteaser_image&order=elements.post_date%5bdesc%5d&depth=0&limit=3&skip=3" - } - } diff --git a/test/browser/isolated-tests/services/mapping-service.spec.ts b/test/browser/isolated-tests/services/mapping-service.spec.ts deleted file mode 100644 index 876ef53b..00000000 --- a/test/browser/isolated-tests/services/mapping-service.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Responses } from '../../../../lib'; -import { getTestDeliveryClient } from '../../setup'; -import * as responseJson from './mapping-service.spec.json'; - -describe('Mapping service', () => { - const client = getTestDeliveryClient({ - environmentId: 'x' - }); - - const listingResponse: Responses.IListContentItemsResponse = - client.mappingService.listContentItemsResponse(responseJson); - - it(`Listing response should be mapped correctly`, () => { - expect(listingResponse.items.length).toEqual(responseJson.items.length); - - for (const item of listingResponse.items) { - const rawItem = responseJson.items.find((m) => m.system.id === item.system.id); - if (!rawItem) { - throw Error(`Raw item with id '${item.system.id}' could not be found`); - } - - expect(item.system.id).toEqual(rawItem.system.id); - expect(item.system.codename).toEqual(rawItem.system.codename); - } - }); -}); diff --git a/test/browser/isolated-tests/services/taxonomy-mapper.spec.ts b/test/browser/isolated-tests/services/taxonomy-mapper.spec.ts deleted file mode 100644 index 94082ac2..00000000 --- a/test/browser/isolated-tests/services/taxonomy-mapper.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { TaxonomyMapper } from '../../../../lib/mappers'; - -describe('TaxonomyMapper', () => { - - const taxonomyMapper = new TaxonomyMapper(); - - it(`should throw an Error when invalid response is given`, () => { - expect(() => taxonomyMapper.mapTaxonomy(null as any, [])).toThrowError(); - expect(() => taxonomyMapper.mapTaxonomy(undefined as any, [])).toThrowError(); - - expect(() => taxonomyMapper.mapTaxonomy({} as any, null as any)).toThrowError(); - expect(() => taxonomyMapper.mapTaxonomy({} as any, undefined as any)).toThrowError(); - - expect(() => taxonomyMapper.mapTaxonomy({} as any, 'test' as any)).toThrowError(); - - expect(() => taxonomyMapper.mapTaxonomies(null as any)).toThrowError(); - expect(() => taxonomyMapper.mapTaxonomies(undefined as any)).toThrowError(); - - expect(() => taxonomyMapper.mapTaxonomies('test' as any)).toThrowError(); - - }); -}); - diff --git a/test/browser/isolated-tests/services/type-mapper.spec.ts b/test/browser/isolated-tests/services/type-mapper.spec.ts deleted file mode 100644 index 926236f6..00000000 --- a/test/browser/isolated-tests/services/type-mapper.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TypeMapper } from '../../../../lib/'; - -describe('TypeMapper', () => { - - const typeMapper = new TypeMapper(); - - it(`should throw an Error when invalid response is given`, () => { - expect(() => typeMapper.mapSingleType(null as any)).toThrowError(); - expect(() => typeMapper.mapSingleType(undefined as any)).toThrowError(); - - expect(() => typeMapper.mapSingleType({} as any)).toThrowError(); - - expect(() => typeMapper.mapMultipleTypes(null as any)).toThrowError(); - expect(() => typeMapper.mapMultipleTypes(undefined as any)).toThrowError(); - }); -}); - diff --git a/test/browser/isolated-tests/url/item-filters.ts b/test/browser/isolated-tests/url/item-filters.ts deleted file mode 100644 index c917c8cd..00000000 --- a/test/browser/isolated-tests/url/item-filters.ts +++ /dev/null @@ -1,274 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Item url filters', () => { - const context = new Context(); - setup(context); - - it(`empty filter should be set`, () => { - const url = new URL(context.deliveryClient.items().emptyFilter('x').getUrl()); - - const param = url.searchParams.get('x[empty]'); - - expect(param).toBeDefined(); - }); - - it(`notEmpty filter should be set`, () => { - const url = new URL(context.deliveryClient.items().notEmptyFilter('x').getUrl()); - - const param = url.searchParams.get('x[nempty]'); - - expect(param).toBeDefined(); - }); - - it(`type filter with single string should be set`, () => { - const type = 'TypeA'; - const url = new URL(context.deliveryClient.items().type(type).getUrl()); - - const param = url.searchParams.get('system.type'); - - expect(param).toEqual(type); - }); - - it(`type filter with multiple strings should be set`, () => { - const typeA = 'TypeA'; - const typeB = 'TypeB'; - - const types = [typeA, typeB]; - const url = new URL(context.deliveryClient.items().types(types).getUrl()); - - const param = url.searchParams.get('system.type[in]'); - - expect(param).toEqual(`${typeA},${typeB}`); - }); - - it(`collection filter with single string should be set`, () => { - const collection = 'CollectionA'; - const url = new URL(context.deliveryClient.items().collection(collection).getUrl()); - - const param = url.searchParams.get('system.collection'); - - expect(param).toEqual(collection); - }); - - it(`collection filter with multiple strings should be set`, () => { - const collectionA = 'CollectionA'; - const collectionB = 'CollectionB'; - - const collections = [collectionA, collectionB]; - const url = new URL(context.deliveryClient.items().collections(collections).getUrl()); - - const param = url.searchParams.get('system.collection[in]'); - - expect(param).toEqual(`${collectionA},${collectionB}`); - }); - - it(`inFilter with single value should be set`, () => { - const url = new URL(context.deliveryClient.items().inFilter('elem1', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[in]'); - - expect(param).toEqual('val1'); - }); - - it(`inFilter with multiple values should be set`, () => { - const url = new URL(context.deliveryClient.items().notInFilter('elem1', ['val1', 'val2']).getUrl()); - - const param = url.searchParams.get('elem1[nin]'); - - expect(param).toEqual('val1,val2'); - }); - - it(`notInFilter with single value should be set`, () => { - const url = new URL(context.deliveryClient.items().notInFilter('elem1', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[nin]'); - - expect(param).toEqual('val1'); - }); - - it(`notInFilter with multiple values should be set`, () => { - const url = new URL(context.deliveryClient.items().inFilter('elem1', ['val1', 'val2']).getUrl()); - - const param = url.searchParams.get('elem1[in]'); - - expect(param).toEqual('val1,val2'); - }); - - it(`anyFilter with single value should be set`, () => { - const url = new URL(context.deliveryClient.items().anyFilter('elem1', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[any]'); - - expect(param).toEqual('val1'); - }); - - it(`anyFilter with multiple values should be set`, () => { - const url = new URL(context.deliveryClient.items().anyFilter('elem1', ['val1', 'val2']).getUrl()); - - const param = url.searchParams.get('elem1[any]'); - - expect(param).toEqual('val1,val2'); - }); - - it(`containsFilter with single value should be set`, () => { - const url = new URL(context.deliveryClient.items().containsFilter('elem1', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[contains]'); - - expect(param).toEqual('val1'); - }); - - it(`containsFilter with multiple value should be set`, () => { - const url = new URL(context.deliveryClient.items().containsFilter('elem1', ['val1', 'val2']).getUrl()); - - const param = url.searchParams.get('elem1[contains]'); - - expect(param).toEqual('val1,val2'); - }); - - it(`equalsFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().equalsFilter('elem1', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[eq]'); - - expect(param).toEqual('val1'); - }); - - it(`notEqualsFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().notEqualsFilter('elem1', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[neq]'); - - expect(param).toEqual('val1'); - }); - - it(`greaterThanFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().greaterThanFilter('elem1', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[gt]'); - - expect(param).toEqual('val1'); - }); - - it(`greaterThanOrEqualFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().greaterThanOrEqualFilter('elem1', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[gte]'); - - expect(param).toEqual('val1'); - }); - - it(`lessThanFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().lessThanFilter('elem1', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[lt]'); - - expect(param).toEqual('val1'); - }); - - it(`lessThanOrEqualFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().lessThanOrEqualFilter('elem1', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[lte]'); - - expect(param).toEqual('val1'); - }); - - it(`allFilter with single value should be set`, () => { - const url = new URL(context.deliveryClient.items().allFilter('elem1', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[all]'); - - expect(param).toEqual('val1'); - }); - - it(`allFilter with multiple values should be set`, () => { - const url = new URL(context.deliveryClient.items().allFilter('elem1', ['val1', 'val2']).getUrl()); - - const param = url.searchParams.get('elem1[all]'); - - expect(param).toEqual('val1,val2'); - }); - - it(`rangeFilter should be set`, () => { - const url = new URL(context.deliveryClient.items().rangeFilter('elem1', 1, 10).getUrl()); - - const param = url.searchParams.get('elem1[range]'); - - expect(param).toEqual('1,10'); - }); - - // trim checks - - it(`inFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().inFilter(' elem1 ', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[in]'); - - expect(param).toEqual('val1'); - }); - - it(`allFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().allFilter(' elem1 ', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[all]'); - - expect(param).toEqual('val1'); - }); - - it(`anyFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().anyFilter(' elem1 ', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[any]'); - - expect(param).toEqual('val1'); - }); - - it(`containsFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().containsFilter(' elem1 ', ['val1']).getUrl()); - - const param = url.searchParams.get('elem1[contains]'); - - expect(param).toEqual('val1'); - }); - - it(`greaterThanFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().greaterThanFilter(' elem1 ', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[gt]'); - - expect(param).toEqual('val1'); - }); - - it(`greaterThanOrEqualFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().greaterThanOrEqualFilter(' elem1 ', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[gte]'); - - expect(param).toEqual('val1'); - }); - - it(`lessThanFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().lessThanFilter(' elem1 ', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[lt]'); - - expect(param).toEqual('val1'); - }); - - it(`lessThanOrEqualFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().lessThanOrEqualFilter(' elem1 ', 'val1').getUrl()); - - const param = url.searchParams.get('elem1[lte]'); - - expect(param).toEqual('val1'); - }); - - it(`rangeFilter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().rangeFilter(' elem1 ', 1, 10).getUrl()); - - const param = url.searchParams.get('elem1[range]'); - - expect(param).toEqual('1,10'); - }); -}); diff --git a/test/browser/isolated-tests/url/item-url-parameters.spec.ts b/test/browser/isolated-tests/url/item-url-parameters.spec.ts deleted file mode 100644 index 53a54032..00000000 --- a/test/browser/isolated-tests/url/item-url-parameters.spec.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Item url parameters', () => { - const context = new Context({ defaultLanguage: 'default', excludeArchivedItems: true }); - setup(context); - - it(`includeTotalCount parameter should be set to true when used`, () => { - const url = new URL(context.deliveryClient.items().includeTotalCountParameter().getUrl()) - - const param = url.searchParams.get('includeTotalCount'); - - expect(param).toEqual('true'); - }); - - it(`depth param should be set`, () => { - const url = new URL(context.deliveryClient.items().depthParameter(1).getUrl()); - - const param = url.searchParams.get('depth'); - - expect(param).toEqual('1'); - }); - - it(`negative depth parameter should throw error`, () => { - expect(() => context.deliveryClient.items().depthParameter(-1)).toThrowError(); - }); - - it(`multiple elements param should be set`, () => { - const url = new URL(context.deliveryClient.items().elementsParameter(['elem1', 'elem2']).getUrl()); - - const param = url.searchParams.get('elements'); - - expect(param).toEqual('elem1,elem2'); - }); - - it(`single elements param should be set`, () => { - const url = new URL(context.deliveryClient.items().elementsParameter(['elem1']).getUrl()); - - const param = url.searchParams.get('elements'); - - expect(param).toEqual('elem1'); - }); - - - it(`exclue elements param should be set`, () => { - const url = new URL(context.deliveryClient.items().excludeElementsParameter(['elem1', 'elem2']).getUrl()); - - const param = url.searchParams.get('excludeElements'); - - expect(param).toEqual('elem1,elem2'); - }); - - it(`limit parameter should be set`, () => { - const url = new URL(context.deliveryClient.items().limitParameter(1).getUrl()); - - const param = url.searchParams.get('limit'); - - expect(param).toEqual('1'); - }); - - it(`negative limit parameter should throw error`, () => { - expect(() => context.deliveryClient.items().limitParameter(-1)).toThrowError(); - }); - - it(`order (desc) parameter should be set`, () => { - const url = new URL(context.deliveryClient.items().orderParameter('elem1', 'desc').getUrl()); - - const param = url.searchParams.get('order'); - - expect(param).toEqual('elem1[desc]'); - }); - - it(`order (asc) parameter should be set`, () => { - const url = new URL(context.deliveryClient.items().orderParameter('elem1', 'asc').getUrl()); - - const param = url.searchParams.get('order'); - - expect(param).toEqual('elem1[asc]'); - }); - - it(`orderByDescending should be set`, () => { - const url = new URL(context.deliveryClient.items().orderByDescending('elem1').getUrl()); - - const param = url.searchParams.get('order'); - - expect(param).toEqual('elem1[desc]'); - }); - - it(`orderByAscending should be set`, () => { - const url = new URL(context.deliveryClient.items().orderByAscending('elem1').getUrl()); - - const param = url.searchParams.get('order'); - - expect(param).toEqual('elem1[asc]'); - }); - - it(`skip parameter should be set`, () => { - const url = new URL(context.deliveryClient.items().skipParameter(1).getUrl()); - - const param = url.searchParams.get('skip'); - - expect(param).toEqual('1'); - }); - - it(`skip parameter with negative skip should throw error`, () => { - expect(() => context.deliveryClient.items().skipParameter(-1)).toThrowError(); - }); - - it(`language parameter should be set`, () => { - const url = new URL(context.deliveryClient.items().languageParameter('en').getUrl()); - - const param = url.searchParams.get('language'); - - expect(param).toEqual('en'); - }); - - it('exclude archived items should apply workflow filter', () => { - const url = new URL(context.deliveryClient.items().getUrl()); - const param = url.searchParams.get('system.workflow_step[neq]'); - expect(param).toEqual('archived'); - }); - - // trim checks - - it(`elementsParameter should trim its element codenames`, () => { - const url = new URL(context.deliveryClient.items().elementsParameter([' elem1', 'elem2', ' elem3']).getUrl()); - - const param = url.searchParams.get('elements'); - - expect(param).toEqual('elem1,elem2,elem3'); - }); - - it(`orderParameter should trim its element`, () => { - const url = new URL(context.deliveryClient.items().orderParameter(' elem1 ', 'asc').getUrl()); - - const param = url.searchParams.get('order'); - - expect(param).toEqual('elem1[asc]'); - }); - - it('defaultLanguage should set language parameter', () => { - const url = new URL(context.deliveryClient.items().getUrl()); - const param = url.searchParams.get('language'); - expect(param).toEqual('default'); - }); - - it(`languageParameter should overwrite default language`, () => { - const url = new URL(context.deliveryClient.items().languageParameter('es_ES').getUrl()); - - const param = url.searchParams.get('language'); - expect(param).toEqual('es_ES'); - }); -}); diff --git a/test/browser/isolated-tests/url/item-url.spec.ts b/test/browser/isolated-tests/url/item-url.spec.ts deleted file mode 100644 index fc461894..00000000 --- a/test/browser/isolated-tests/url/item-url.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Item URL', () => { - - const context = new Context(); - setup(context); - - it(`item query should thrown error when item's codename is not set`, () => { - expect(() => context.deliveryClient.item(null as any)).toThrowError(); - }); - - it(`item query should thrown error when item's codename is empty`, () => { - expect(() => context.deliveryClient.item('')).toThrowError(); - }); - - it(`item url with 'kyle' codename should end with '/items/kyle`, () => { - const url = new URL(context.deliveryClient.item('kyle').getUrl()); - expect(url.toString()).toContain(`/items/kyle`); - }); - - it(`item url with 'arnold' codename should end with '/items/arnold'`, () => { - const url = new URL(context.deliveryClient.item('arnold').getUrl()); - expect(url.toString()).toContain(`/items/arnold`); - }); -}); - diff --git a/test/browser/isolated-tests/url/taxonomies-url.spec.ts b/test/browser/isolated-tests/url/taxonomies-url.spec.ts deleted file mode 100644 index d0125417..00000000 --- a/test/browser/isolated-tests/url/taxonomies-url.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Taxonomy url', () => { - - const context = new Context(); - setup(context); - - it(`taxonomies url should contain skip parameter`, () => { - const skip: number = 549228429; - const url = context.deliveryClient.taxonomies().skipParameter(skip).getUrl(); - expect(url).toContain('skip=' + skip.toString()); - }); -}); - diff --git a/test/browser/isolated-tests/url/type-url.spec.ts b/test/browser/isolated-tests/url/type-url.spec.ts deleted file mode 100644 index 71585dbc..00000000 --- a/test/browser/isolated-tests/url/type-url.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Context, setup } from '../../setup'; - -describe('Type url', () => { - - const context = new Context(); - setup(context); - - it(`type query should thrown error when types's codename is not set`, () => { - expect(() => context.deliveryClient.type(null as any)).toThrowError(); - }); - - it(`type url with 'movie' codename should contain '/types/movie`, () => { - const url = context.deliveryClient.type('movie').getUrl(); - expect(url).toContain(`/types/movie`); - }); - - it(`type url for all types should end with 'types'`, () => { - const url = context.deliveryClient.types().getUrl(); - expect(url).toContain(`/types`); - }); - - it(`type url should contain skip parameter`, () => { - const skip: number = 549228429; - const url = context.deliveryClient.types().skipParameter(skip).getUrl(); - expect(url).toContain('skip=' + skip.toString()); - }); - -}); - diff --git a/test/browser/live-tests/custom-url/custom-url.spec.ts b/test/browser/live-tests/custom-url/custom-url.spec.ts deleted file mode 100644 index 45726427..00000000 --- a/test/browser/live-tests/custom-url/custom-url.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Custom URL', () => { - const itemsUrl: string = 'https://deliver.kontent.ai/da5abe9f-fdad-4168-97cd-b3464be2ccb9/items?system.type=movie'; - - const context = new Context(); - setup(context); - - let responseItems: Responses.IListContentItemsResponse; - - beforeAll(async () => { - responseItems = (await context.deliveryClient.items().withCustomUrl(itemsUrl).toPromise()).data; - }); - - it(`items should be defined`, () => { - expect(responseItems).toBeDefined(); - }); -}); diff --git a/test/browser/live-tests/element/live-element.spec.ts b/test/browser/live-tests/element/live-element.spec.ts deleted file mode 100644 index a4dccb85..00000000 --- a/test/browser/live-tests/element/live-element.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Live element', () => { - const context = new Context(); - setup(context); - - const typeCodename: string = 'movie'; - - const multipleChoiceElementCodename: string = 'category'; - const taxonomyElementCodename: string = 'releasecategory'; - - let multipleChoiceElementResponse: Responses.IViewContentTypeElementResponse; - let taxonomyElementResponse: Responses.IViewContentTypeElementResponse; - - beforeAll(async () => { - multipleChoiceElementResponse = ( - await context.deliveryClient.element(typeCodename, multipleChoiceElementCodename).toPromise() - ).data; - - taxonomyElementResponse = ( - await context.deliveryClient.element(typeCodename, taxonomyElementCodename).toPromise() - ).data; - }); - - it(`element responses should be defined`, () => { - expect(multipleChoiceElementResponse).toBeDefined(); - expect(taxonomyElementResponse).toBeDefined(); - }); - - it(`element taxonomy element should contain valid taxonomy group property`, () => { - expect(taxonomyElementResponse.taxonomyGroup).toBeDefined(); - expect(taxonomyElementResponse.taxonomyGroup).toEqual(jasmine.any(String)); - }); - - it(`multiple choice element should contain options`, () => { - expect(multipleChoiceElementResponse.options).toBeDefined(); - expect(multipleChoiceElementResponse.options.length).toBeGreaterThan(0); - }); -}); diff --git a/test/browser/live-tests/errors/kontent-error.spec.ts b/test/browser/live-tests/errors/kontent-error.spec.ts deleted file mode 100644 index 6bb684f4..00000000 --- a/test/browser/live-tests/errors/kontent-error.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Context, setup } from '../../setup'; -import { DeliveryError } from '../../../../lib'; - -describe('Delivery errors', () => { - const context = new Context(); - setup(context); - - const invalidCodename: string = 'the_invalid_codename'; - let succeeded: boolean; - let error: unknown; - - beforeAll(async () => { - try { - await context.deliveryClient.item(invalidCodename).toPromise(); - succeeded = true; - } catch (err) { - error = err; - succeeded = false; - } - }); - - it(`Response shouldn't succeed because the item does not exists`, () => { - expect(succeeded).toEqual(false); - }); - - it(`Error should be an instance of DeliveryError`, () => { - expect(error).toEqual(jasmine.any(DeliveryError)); - }); - - it(`Error model should have all properties assigned`, () => { - const baseError = error as DeliveryError; - expect(baseError.errorCode).toBeGreaterThan(0); - expect(baseError.specificCode).toBeGreaterThanOrEqual(0); - expect(baseError.message).toBeDefined(); - expect(baseError.requestId).toBeDefined(); - }); -}); diff --git a/test/browser/live-tests/item/live-item-base-linked-items.spec.ts b/test/browser/live-tests/item/live-item-base-linked-items.spec.ts deleted file mode 100644 index c2092592..00000000 --- a/test/browser/live-tests/item/live-item-base-linked-items.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Live item - base linked items', () => { - const context = new Context(); - setup(context); - - const movieCodename: string = 'warrior'; - let response: Responses.IViewContentItemResponse; - - beforeAll(async () => { - response = (await context.deliveryClient.item(movieCodename).toPromise()).data; - }); - - it(`verify linked items included in response and are of 'ContentItem' type`, () => { - expect(Object.keys(response.linkedItems).length).toEqual(3); - - for (const key of Object.keys(response.linkedItems)) { - const linkedItem = response.linkedItems[key]; - expect(linkedItem).toBeDefined(); - } - }); -}); diff --git a/test/browser/live-tests/item/live-item.spec.ts b/test/browser/live-tests/item/live-item.spec.ts deleted file mode 100644 index 0a161579..00000000 --- a/test/browser/live-tests/item/live-item.spec.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Live item', () => { - const context = new Context(); - setup(context); - - const movieCodename: string = 'warrior'; - let response: Responses.IViewContentItemResponse; - - beforeAll(async () => { - response = (await context.deliveryClient.item(movieCodename).queryConfig({}).toPromise()).data; - }); - - it(`item response should be defined`, () => { - expect(response).toBeDefined(); - }); - - it(`item should be defined`, () => { - expect(response.item).toBeDefined(); - }); - - it(`title should be 'Warrior'`, () => { - expect(response.item.elements.title.value).toEqual('Warrior'); - }); - - it(`released date should be '2011-09-09T00:00:00Z'`, () => { - expect(response.item.elements.released.value).toEqual('2011-09-09T00:00:00Z'); - }); - - it(`poster asset should be defined`, () => { - expect(response.item.elements.poster).toBeDefined(); - }); - - it(`poster asset' url should be set`, () => { - const assetUrl = response.item.elements.poster.value[0].url; - expect(assetUrl).toBeDefined(); - expect(assetUrl).toContain('https://'); - }); - - it(`category options should be defined`, () => { - expect(response.item.elements.category.value).toBeDefined(); - }); - - it(`there should be 2 category options defined`, () => { - expect(response.item.elements.category.value.length).toEqual(2); - }); - - it(`checks codename of first category option`, () => { - expect(response.item.elements.category.value[0].codename).toEqual('action'); - }); - - it(`checks codename of second category option`, () => { - expect(response.item.elements.category.value[1].codename).toEqual('drama'); - }); - - it(`checks that category options are of proper type`, () => { - expect(response.item.elements.category.value[1]).toBeDefined(); - }); - - it(`stars linked items should be defined`, () => { - expect(response.item.elements.stars).toBeDefined(); - }); - - it(`check number of stars items`, () => { - expect(response.item.elements.stars.value.length).toEqual(2); - }); - - it(`checks that linkedItemCodenames element is mapped and container proper data`, () => { - expect(response.item.elements.plot.linkedItemCodenames).toBeDefined(); - expect(response.item.elements.plot.linkedItemCodenames).toContain('tom_hardy'); - expect(response.item.elements.plot.linkedItemCodenames).toContain('joel_edgerton'); - }); - - it(`check that linked item (Actor) has 'first_name' text properly assigned`, () => { - expect(response.item.elements.stars.linkedItems[0].elements.first_name.value).toEqual('Tom'); - }); - - it(`images should be mapped in plot rich text element`, () => { - const images = response.item.elements.plot.images; - - expect(images).toBeDefined(); - expect(images.length).toEqual(2); - }); - - it(`verify linked items included in response`, () => { - expect(Object.keys(response.linkedItems).length).toEqual(3); - for (const key of Object.keys(response.linkedItems)) { - const linkedItem = response.linkedItems[key]; - expect(linkedItem).toBeDefined(); - } - }); -}); diff --git a/test/browser/live-tests/items-feed/live-items-feed-all.spec.ts b/test/browser/live-tests/items-feed/live-items-feed-all.spec.ts deleted file mode 100644 index a58220d4..00000000 --- a/test/browser/live-tests/items-feed/live-items-feed-all.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { IDeliveryNetworkResponse, Contracts, Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Live items feed all', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListItemsFeedAllResponse; - const responses: IDeliveryNetworkResponse, Contracts.IItemsFeedContract>[] = []; - - beforeAll(async () => { - response = ( - await context.deliveryClient.itemsFeed().toAllPromise({ - responseFetched: (innerResponse, nextPage, continuationToken) => { - responses.push(innerResponse); - } - }) - ).data; - }); - - it(`items should be defined`, () => { - expect(response).toBeDefined(); - }); - - it(`items should have multiple responses`, () => { - expect(response.responses.length).toBeGreaterThan(0); - expect(response.responses.length).toEqual(responses.length); - - for (const innerResponse of response.responses) { - expect(innerResponse.data).toBeDefined(); - } - }); -}); diff --git a/test/browser/live-tests/items-feed/live-items-feed.spec.ts b/test/browser/live-tests/items-feed/live-items-feed.spec.ts deleted file mode 100644 index c86dfb87..00000000 --- a/test/browser/live-tests/items-feed/live-items-feed.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { IDeliveryNetworkResponse, Contracts, Responses } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Live items feed', () => { - const context = new Context(); - setup(context); - - let response: IDeliveryNetworkResponse; - - beforeAll(async () => { - response = await context.deliveryClient.itemsFeed().toPromise(); - }); - - it(`Response should have all properties assigned`, () => { - expect(response.data.items).toEqual(jasmine.any(Array)); - expect(response.data.items.length).toBeGreaterThan(0); - expect(response.xContinuationToken).toBeUndefined(); - expect(Object.keys(response.data.linkedItems).length).toBeGreaterThan(0); - - for (const item of response.data.items) { - expect(item.system).toBeDefined(); - expect(item.elements).toBeDefined(); - } - }); -}); diff --git a/test/browser/live-tests/items/live-items-all.spec.ts b/test/browser/live-tests/items/live-items-all.spec.ts deleted file mode 100644 index 835bd28d..00000000 --- a/test/browser/live-tests/items/live-items-all.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { IDeliveryNetworkResponse, Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Live items all', () => { - const context = new Context(); - setup(context); - - const type: string = 'movie'; - let response: Responses.IListContentItemsAllResponse; - const responses: IDeliveryNetworkResponse, any>[] = []; - - const pages: number = 2; - const limit: number = 2; - - beforeAll(async () => { - response = ( - await context.deliveryClient - .items() - .limitParameter(limit) - .type(type) - .toAllPromise({ - responseFetched: (innerResponse, nextPage, continuationToken) => { - responses.push(innerResponse); - }, - pages: pages - }) - ).data; - }); - - it(`items should be defined`, () => { - expect(response).toBeDefined(); - }); - - it(`check correct number of items`, () => { - expect(response.items.length).toEqual(pages * limit); - }); - - it(`items should have multiple responses`, () => { - expect(response.responses.length).toEqual(pages); - expect(response.responses.length).toEqual(responses.length); - - for (const innerResponse of response.responses) { - expect(innerResponse.data).toBeDefined(); - } - }); -}); diff --git a/test/browser/live-tests/items/live-items.spec.ts b/test/browser/live-tests/items/live-items.spec.ts deleted file mode 100644 index 64ce89d1..00000000 --- a/test/browser/live-tests/items/live-items.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Live items', () => { - const context = new Context(); - setup(context); - - const type: string = 'movie'; - let response: Responses.IListContentItemsResponse; - - beforeAll(async () => { - response = (await context.deliveryClient.items().type(type).toPromise()).data; - }); - - it(`items should be defined`, () => { - expect(response).toBeDefined(); - }); - - it(`check correct number of items`, () => { - expect(response.items.length).toEqual(6); - }); - - it(`items should have pagination`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`Linked items should be set`, () => { - expect(Object.keys(response.linkedItems).length).toBeGreaterThan(0); - }); -}); diff --git a/test/browser/live-tests/localization/localization-default-language.spec.ts b/test/browser/live-tests/localization/localization-default-language.spec.ts deleted file mode 100644 index d1847017..00000000 --- a/test/browser/live-tests/localization/localization-default-language.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Context, Movie, setup } from '../../setup'; - -describe('Language #1', () => { - const language = 'en'; - const context = new Context(); - context.defaultLanguage = language; - setup(context); - - const movieCodename: string = 'warrior'; - - const query = context.deliveryClient.item(movieCodename).languageParameter(language); - const queryLanguageParam = query.getParameters().find((m) => m.getParam() === `language=${language}`); - - it(`Language should be '${language}'`, () => { - expect(queryLanguageParam).toBeDefined(); - }); -}); - -describe('Language #2', () => { - const language = 'cz'; - const context = new Context(); - context.defaultLanguage = language; - setup(context); - - const newMovieCodename: string = 'warrior'; - - const query = context.deliveryClient.item(newMovieCodename).languageParameter(language); - const queryLanguageParam = query.getParameters().find((m) => m.getParam() === `language=${language}`); - - it(`language should be '${language}'`, () => { - expect(queryLanguageParam).toBeDefined(); - }); -}); diff --git a/test/browser/live-tests/localization/localized-item.spec.ts b/test/browser/live-tests/localization/localized-item.spec.ts deleted file mode 100644 index ec157edf..00000000 --- a/test/browser/live-tests/localization/localized-item.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Localized item', () => { - const context = new Context(); - setup(context); - - const language: string = 'cz'; - const movieCodename: string = 'warrior'; - let response: Responses.IViewContentItemResponse; - - beforeAll(async () => { - response = (await context.deliveryClient.item(movieCodename).languageParameter(language).toPromise()) - .data; - }); - - it(`language should be '${language}'`, () => { - expect(response.item.system.language).toEqual(language); - }); - - it(`title should be localized`, () => { - expect(response.item.elements.title.value).toEqual('Warrior-cz'); - }); -}); diff --git a/test/browser/live-tests/mapping/live-mapping.service.spec.ts b/test/browser/live-tests/mapping/live-mapping.service.spec.ts deleted file mode 100644 index 741fd166..00000000 --- a/test/browser/live-tests/mapping/live-mapping.service.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { IDeliveryNetworkResponse, Contracts, Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Live mapping service', () => { - const context = new Context(); - setup(context); - - const movieCodename: string = 'warrior'; - let response: IDeliveryNetworkResponse, Contracts.IViewContentItemContract>; - - beforeAll(async () => { - response = await context.deliveryClient.item(movieCodename).toPromise(); - }); - - it(`raw response should be available for mapping from stored json (with mapping service)`, () => { - const contractJson = response.response.data; - const reMappedResponse = context.deliveryClient.mappingService.viewContentItemResponse(contractJson); - expect(reMappedResponse).toBeDefined(); - expect(reMappedResponse.item.system.codename).toEqual(movieCodename); - expect(reMappedResponse.item.elements.title.value).toEqual('Warrior'); - }); - - it(`raw response should be available for mapping from stored json (with query)`, () => { - const contractJson = response.response.data; - const reMappedResponse = context.deliveryClient.item(movieCodename).map(contractJson); - expect(reMappedResponse).toBeDefined(); - expect(reMappedResponse.item.system.codename).toEqual(movieCodename); - expect(reMappedResponse.item.elements.title.value).toEqual('Warrior'); - }); -}); diff --git a/test/browser/live-tests/network-response/network-response.spec.ts b/test/browser/live-tests/network-response/network-response.spec.ts deleted file mode 100644 index cf1d1adf..00000000 --- a/test/browser/live-tests/network-response/network-response.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { IDeliveryNetworkResponse } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Network response', () => { - const context = new Context(); - setup(context); - - let response: IDeliveryNetworkResponse; - - beforeAll(async () => { - response = await context.deliveryClient - .itemsFeed() - .toPromise(); - }); - - it(`response should contain network response data`, () => { - expect(response.response.headers).toBeDefined(); - expect(response.response.data).toBeDefined(); - expect(response.response.rawResponse).toBeDefined(); - expect(response.response.retryStrategy).toBeDefined(); - expect(response.hasStaleContent).toEqual(false); - expect(response.xContinuationToken).toBeUndefined(); - expect(response.response.status).toEqual(200); - }); -}); diff --git a/test/browser/live-tests/pagination/pagination.spec.ts b/test/browser/live-tests/pagination/pagination.spec.ts deleted file mode 100644 index 51ad1ad8..00000000 --- a/test/browser/live-tests/pagination/pagination.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Pagination', () => { - const context = new Context(); - setup(context); - - const type: string = 'movie'; - let response: Responses.IListContentItemsResponse; - - beforeAll(async () => { - response = ( - await context.deliveryClient.items().type(type).limitParameter(5).skipParameter(1).toPromise() - ).data; - }); - - it(`pagination should be defined`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`check count`, () => { - expect(response.pagination.count).toEqual(5); - }); - - it(`check limit`, () => { - expect(response.pagination.limit).toEqual(5); - }); - - it(`check skip`, () => { - expect(response.pagination.skip).toEqual(1); - }); - - it(`check pagination count`, () => { - expect(response.pagination.nextPage).toEqual(''); - }); -}); diff --git a/test/browser/live-tests/promise/response-by-promise.spec.ts b/test/browser/live-tests/promise/response-by-promise.spec.ts deleted file mode 100644 index 464a43f8..00000000 --- a/test/browser/live-tests/promise/response-by-promise.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, Movie, setup } from '../../setup'; - -describe('Response with Promises', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentItemsResponse; - - beforeAll((done) => { - context.deliveryClient - .items() - .toPromise() - .then((xResponse) => { - response = xResponse.data; - done(); - }) - .catch((err) => { - throw err; - }); - }); - - it(`Response items should be retrieved and mapped just like with Promise`, () => { - expect(response).toBeDefined(); - }); -}); diff --git a/test/browser/live-tests/readme.md b/test/browser/live-tests/readme.md deleted file mode 100644 index 9649f9b1..00000000 --- a/test/browser/live-tests/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Live tests info - -Tests in this section depend on `live` environment diff --git a/test/browser/live-tests/taxonomy/live-taxonomies.spec.ts b/test/browser/live-tests/taxonomy/live-taxonomies.spec.ts deleted file mode 100644 index 1fb9a42c..00000000 --- a/test/browser/live-tests/taxonomy/live-taxonomies.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { ITaxonomyGroup, Responses, ITaxonomyTerms } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Live taxonomies', () => { - const context = new Context(); - setup(context); - - const termsWithNestedTermsCodename: string = 'film'; // codename of the taxonomy term that has nested terms - const numberOfNestedTerms: number = 3; // this is the number of nested terms defined by 'termsWithNestedTermsCodename' - const existingTaxonomyCodename: string = 'movietype'; // codename of some of the defined taxonomies - - let response: Responses.IListTaxonomiesResponse; - let taxonomy: ITaxonomyGroup; - - beforeAll(async () => { - response = (await context.deliveryClient.taxonomies().toPromise()).data; - - taxonomy = response.items.find((m) => m.system.codename === existingTaxonomyCodename) as ITaxonomyGroup; - }); - - it(`taxonomies should have pagination`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`taxonomies should be defined`, () => { - expect(response.items).toBeDefined(); - }); - - it(`taxonomy with codename '${existingTaxonomyCodename}' should be defined`, () => { - expect(taxonomy).toBeDefined(); - }); - - it(`taxomy system attributes should be defined`, () => { - if (!taxonomy) { - throw Error('undefined'); - } - expect(taxonomy.system).toBeDefined(); - expect(taxonomy.system.codename).toBeDefined(); - expect(taxonomy.system.id).toBeDefined(); - expect(taxonomy.system.lastModified).toBeDefined(); - expect(taxonomy.system.name).toBeDefined(); - }); - - it(`taxonomy group should match requested type`, () => { - if (!taxonomy) { - throw Error('undefined'); - } - expect(taxonomy.system.codename).toEqual(existingTaxonomyCodename); - }); - - it(`taxonomy group should have defined terms`, () => { - if (!taxonomy) { - throw Error('undefined'); - } - expect(taxonomy.terms).toBeDefined(); - }); - - it(`taxonomy group should have > 0 terms`, () => { - if (!taxonomy) { - throw Error('undefined'); - } - expect(taxonomy.terms.length).toBeGreaterThan(0); - }); - - it(`taxonomy group should contain nested taxonomies`, () => { - const termsWithNestedTerms = taxonomy.terms.find( - (m) => m.codename === termsWithNestedTermsCodename - ) as ITaxonomyTerms; - expect(termsWithNestedTerms).toBeDefined(); - - expect(termsWithNestedTerms.terms).toBeDefined(); - expect(termsWithNestedTerms.terms.length).toEqual(numberOfNestedTerms); - }); -}); diff --git a/test/browser/live-tests/taxonomy/live-taxonomy.spec.ts b/test/browser/live-tests/taxonomy/live-taxonomy.spec.ts deleted file mode 100644 index 042b7e6d..00000000 --- a/test/browser/live-tests/taxonomy/live-taxonomy.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Responses, ITaxonomyTerms } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Live taxonomy', () => { - const context = new Context(); - setup(context); - - const taxonomyCodename: string = 'movietype'; - const termsWithNestedTermsCodename: string = 'film'; // codename of the taxonomy term that has nested terms - const numberOfNestedTerms: number = 3; // this is the number of nested terms defined by 'termsWithNestedTermsCodename' - - let response: Responses.IViewTaxonomyResponse; - - beforeAll(async () => { - response = (await context.deliveryClient.taxonomy(taxonomyCodename).toPromise()).data; - }); - - it(`taxomy should be defined`, () => { - expect(response.taxonomy).toBeDefined(); - }); - - it(`taxomy system attributes should be defined`, () => { - expect(response.taxonomy.system).toBeDefined(); - expect(response.taxonomy.system.codename).toBeDefined(); - expect(response.taxonomy.system.id).toBeDefined(); - expect(response.taxonomy.system.lastModified).toBeDefined(); - expect(response.taxonomy.system.name).toBeDefined(); - }); - - it(`taxonomy group should match requested type`, () => { - expect(response.taxonomy.system.codename).toEqual(taxonomyCodename); - }); - - it(`taxonomy group should have defined terms`, () => { - expect(response.taxonomy.terms).toBeDefined(); - }); - - it(`taxonomy group should have > 0 terms`, () => { - expect(response.taxonomy.terms.length).toBeGreaterThan(0); - }); - - it(`taxonomy group should contain nested taxonomies`, () => { - const termsWithNestedTerms = response.taxonomy.terms.find( - (m) => m.codename === termsWithNestedTermsCodename - ) as ITaxonomyTerms; - expect(termsWithNestedTerms).toBeDefined(); - expect(termsWithNestedTerms.terms).toBeDefined(); - expect(termsWithNestedTerms.terms.length).toEqual(numberOfNestedTerms); - }); -}); diff --git a/test/browser/live-tests/types/live-type.spec.ts b/test/browser/live-tests/types/live-type.spec.ts deleted file mode 100644 index 5eb8cfa0..00000000 --- a/test/browser/live-tests/types/live-type.spec.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { IGenericElement, Responses } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Live type', () => { - const context = new Context(); - setup(context); - - const codename: string = 'movie'; - let response: Responses.IViewContentTypeResponse; - - const multipleChoiceElement: string = 'category'; - const taxonomyElement: string = 'releasecategory'; - - beforeAll(async () => { - response = (await context.deliveryClient.type(codename).toPromise()).data; - }); - - it(`type should be defined`, () => { - expect(response).toBeDefined(); - }); - - it(`elements should be defined`, () => { - expect(response.type.elements).toBeDefined(); - }); - - it(`system properties should be defined`, () => { - expect(response.type.system).toBeDefined(); - }); - - it(`proper type should be returned based on test config`, () => { - expect(response.type.system.codename).toEqual(codename); - }); - - it(`Verifies taxonomy element - '${taxonomyElement}'`, () => { - const releasecategoryElement = response.type.elements.find( - (m) => m.codename === taxonomyElement - ) as IGenericElement; - expect(releasecategoryElement).toBeDefined(); - expect(releasecategoryElement.taxonomyGroup).toBeDefined(); - expect(releasecategoryElement.taxonomyGroup).toEqual('releasecategory'); - }); - - it(`Verifies multiple_choice element - '${multipleChoiceElement}'`, () => { - const categoryElement = response.type.elements.find( - (m) => m.codename === multipleChoiceElement - ) as IGenericElement; - - expect(categoryElement).toBeDefined(); - expect(categoryElement.options).toBeDefined(); - expect(categoryElement.options.length).toBeGreaterThan(0); - expect(categoryElement.options[0].codename).toBeDefined(); - expect(categoryElement.options[0].name).toBeDefined(); - }); -}); diff --git a/test/browser/live-tests/types/live-types.spec.ts b/test/browser/live-tests/types/live-types.spec.ts deleted file mode 100644 index 79b2ae41..00000000 --- a/test/browser/live-tests/types/live-types.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Responses } from '../../../../lib'; -import { Context, setup } from '../../setup'; - -describe('Live types', () => { - const context = new Context(); - setup(context); - - let response: Responses.IListContentTypesResponse; - - beforeAll(async () => { - response = (await context.deliveryClient.types().toPromise()).data; - }); - - it(`types should be defined`, () => { - expect(response).toBeDefined(); - }); - - it(`types should have pagination`, () => { - expect(response.pagination).toBeDefined(); - }); - - it(`there should be at least 1 type`, () => { - expect(response.items.length).toBeGreaterThan(0); - }); - - it(`elements should be defined`, () => { - expect(response.items[0].elements).toBeDefined(); - }); - - it(`system properties should be defined`, () => { - expect(response.items[0].system).toBeDefined(); - }); - - it(`pagination should be defined`, () => { - expect(response.pagination).toBeDefined(); - }); -}); diff --git a/test/browser/setup/context.ts b/test/browser/setup/context.ts deleted file mode 100644 index 630aafd2..00000000 --- a/test/browser/setup/context.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { IHeader, IRetryStrategyOptions } from '@kontent-ai/core-sdk'; -import { DeliveryClient, IDeliveryClientConfig, IQueryConfig } from '../../../lib'; - -export class Context { - public deliveryClient!: DeliveryClient; - - public defaultQueryConfig?: IQueryConfig; - public environmentId!: string; - public previewApiKey?: string; - public securedApiKey?: string; - public usePreviewMode: boolean = false; - public useSecuredMode: boolean = false; - public defaultLanguage?: string; - public excludeArchivedItems?: boolean = false; - public baseUrl?: string; - public basePreviewUrl?: string; - public globalHeaders?: (queryConfig: IQueryConfig) => IHeader[]; - public retryStrategy?: IRetryStrategyOptions; - - constructor(options?: { - defaultQueryConfig?: IQueryConfig; - environmentId?: string; - previewApiKey?: string; - deliveryClient?: DeliveryClient; - defaultLanguage?: string; - excludeArchivedItems?: boolean; - baseUrl?: string; - basePreviewUrl?: string; - securedApiKey?: string; - globalHeaders?: (queryConfig: IQueryConfig) => IHeader[]; - retryStrategy?: IRetryStrategyOptions; - }) { - if (options) { - Object.assign(this, options); - } - } - - getConfig(): IDeliveryClientConfig { - return { - environmentId: this.environmentId, - previewApiKey: this.previewApiKey, - secureApiKey: this.securedApiKey, - defaultQueryConfig: this.defaultQueryConfig, - proxy: { - baseUrl: this.baseUrl, - basePreviewUrl: this.basePreviewUrl - }, - defaultLanguage: this.defaultLanguage, - globalHeaders: this.globalHeaders, - retryStrategy: this.retryStrategy, - excludeArchivedItems: this.excludeArchivedItems - }; - } -} diff --git a/test/browser/setup/delivery-test-client.ts b/test/browser/setup/delivery-test-client.ts deleted file mode 100644 index e95ffb12..00000000 --- a/test/browser/setup/delivery-test-client.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { IHeader, IResponse, TestHttpService } from '@kontent-ai/core-sdk'; - -import { createDeliveryClient, IDeliveryClient, IDeliveryClientConfig } from '../../../lib'; - -const testenvironmentId: string = 'delivery-environment-id'; - -export function toPromise(data: T): Promise { - return new Promise((resolve, reject) => { - resolve(data); - }); -} - -export function getTestDeliveryClient(config?: IDeliveryClientConfig): IDeliveryClient { - return createDeliveryClient( - config - ? config - : { - environmentId: testenvironmentId - } - ); -} - -export function getDeliveryClientWithError(errorJson: any): IDeliveryClient { - return createDeliveryClient({ - environmentId: testenvironmentId, - httpService: new TestHttpService({ - response: undefined, - error: errorJson - }) - }); -} - -export function getDeliveryClientWithJson( - json: any, - config?: IDeliveryClientConfig, - responseHeaders: IHeader[] = [] -): IDeliveryClient { - return getDeliveryClientWithJsonAndHeaders(json, config, responseHeaders); -} - -export function getDeliveryClientWithJsonAndHeaders( - json: any, - config?: IDeliveryClientConfig, - responseHeaders: IHeader[] = [] -): IDeliveryClient { - if (!config) { - return createDeliveryClient({ - environmentId: testenvironmentId, - httpService: new TestHttpService({ - response: getResponseFromJson(json, responseHeaders), - error: undefined - }) - }); - } - - // always set http service - config.httpService = new TestHttpService({ - response: getResponseFromJson(json, responseHeaders), - error: undefined - }); - - return createDeliveryClient(config); -} - -function getResponseFromJson(json: any, responseHeaders: IHeader[] = []): IResponse { - return { - data: json, - headers: responseHeaders, - rawResponse: json, - status: 999, - retryStrategy: { - retryAttempts: 1, - options: {} - } - }; -} diff --git a/test/browser/setup/index.ts b/test/browser/setup/index.ts deleted file mode 100644 index 0f65953b..00000000 --- a/test/browser/setup/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './models'; -export * from './context'; -export * from './setup'; -export * from './delivery-test-client'; diff --git a/test/browser/setup/models.ts b/test/browser/setup/models.ts deleted file mode 100644 index 9a4c24f0..00000000 --- a/test/browser/setup/models.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Elements, IContentItem } from '../../../lib'; - -type LanguageCodenames = 'default' | 'en'; -type CollectionCodenames = 'default'; -type WorkflowCodenames = 'default'; -type WorkflowStepCodenames = 'draft' | 'published' | 'review'; -type ActorElementCodenames = 'first_name' | 'last_name' | 'photo'; - -export type Actor = IContentItem< - { - readonly first_name: Elements.TextElement; - readonly last_name: Elements.TextElement; - readonly photo: Elements.AssetsElement; - }, - 'actor', - LanguageCodenames, - CollectionCodenames, - WorkflowCodenames, - WorkflowStepCodenames, - ActorElementCodenames ->; - -export type ReleaseCategoryTaxonomy = 'global_release' | 'us_only' | 'local_release'; -export type CategoryMultipleChoiceOptionCodenames = 'sci_fi' | 'action' | 'comedy' | 'drama' | 'romance' | 'animation'; - -type MovieElementCodenames = - | 'title' - | 'plot' - | 'released' - | 'length' - | 'poster' - | 'category' - | 'stars' - | 'seoname' - | 'releasecategory'; - -export type Movie = IContentItem< - { - readonly title: Elements.TextElement; - readonly plot: Elements.RichTextElement; - readonly released: Elements.DateTimeElement; - readonly length: Elements.NumberElement; - readonly category: Elements.MultipleChoiceElement; - readonly seoname: Elements.UrlSlugElement; - readonly poster: Elements.AssetsElement; - readonly stars: Elements.LinkedItemsElement; - readonly releasecategory: Elements.TaxonomyElement; - }, - 'movie', - LanguageCodenames, - CollectionCodenames, - WorkflowCodenames, - WorkflowStepCodenames, - MovieElementCodenames ->; diff --git a/test/browser/setup/setup.ts b/test/browser/setup/setup.ts deleted file mode 100644 index 5b3663e6..00000000 --- a/test/browser/setup/setup.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { DeliveryClient, IDeliveryClientConfig } from '../../../lib'; -import { Context } from './context'; - -const defaultenvironmentId = 'da5abe9f-fdad-4168-97cd-b3464be2ccb9'; - -// tslint:disable-next-line:max-line-length -const defaultPreviewApiKey = - 'ew0KICAiYWxnIjogIkhTMjU2IiwNCiAgInR5cCI6ICJKV1QiDQp9.ew0KICAidWlkIjogInVzcl8wdlFZQkNxQXZybm81cmlmSG5pWUVHIiwNCiAgImVtYWlsIjogInJpY2hhcmRzQGtlbnRpY28uY29tIiwNCiAgInByb2plY3RfaWQiOiAiZGE1YWJlOWYtZmRhZC00MTY4LTk3Y2QtYjM0NjRiZTJjY2I5IiwNCiAgImp0aSI6ICJpLXNFVWJlNmZPeUtBQmJOIiwNCiAgInZlciI6ICIxLjAuMCIsDQogICJnaXZlbl9uYW1lIjogIlJpY2hhcmQiLA0KICAiZmFtaWx5X25hbWUiOiAiU3VzdGVrIiwNCiAgImF1ZCI6ICJwcmV2aWV3LmRlbGl2ZXIua2VudGljb2Nsb3VkLmNvbSINCn0.jSq0owesXGAGf8l7e0Ue7wPkP28MT_--ZK5T02sO7yw'; - -const defaultSecuredApiKey = 'securedApiKey'; - -// ----------- setup function o------------ // -export function setup(context: Context) { - // get delivery client with given context - let environmentId: string = defaultenvironmentId; - let previewApiKey: string = defaultPreviewApiKey; - let securedApiKey: string = defaultSecuredApiKey; - - // context settings override default setup - if (context.environmentId) { - environmentId = context.environmentId; - } - - if (context.previewApiKey) { - previewApiKey = context.previewApiKey; - } - - if (context.securedApiKey) { - securedApiKey = context.securedApiKey; - } - - const deliveryClientConfig: IDeliveryClientConfig = { - environmentId: environmentId, - secureApiKey: securedApiKey, - previewApiKey: previewApiKey, - defaultQueryConfig: context.defaultQueryConfig, - defaultLanguage: context.defaultLanguage, - excludeArchivedItems: context.excludeArchivedItems, - proxy: { - baseUrl: context.baseUrl, - basePreviewUrl: context.basePreviewUrl - }, - retryStrategy: context.retryStrategy, - globalHeaders: context.globalHeaders - }; - - // set context - context.environmentId = environmentId; - context.previewApiKey = previewApiKey; - context.securedApiKey = securedApiKey; - - // set delivery client - context.deliveryClient = new DeliveryClient(deliveryClientConfig); -} diff --git a/test/node/base/base-node-test.js b/test/node/base/base-node-test.js deleted file mode 100644 index 6b6885b7..00000000 --- a/test/node/base/base-node-test.js +++ /dev/null @@ -1,30 +0,0 @@ -const KontentDelivery = require('../../../dist/cjs'); -const assert = require('assert'); -const environmentId = 'da5abe9f-fdad-4168-97cd-b3464be2ccb9'; - -const deliveryClient = new KontentDelivery.DeliveryClient({ - environmentId: environmentId, -}); - -describe('Base node.js test', () => { - - let response; - - before(async () => { - response = await deliveryClient.items() - .type('movie') - .limitParameter(10) - .toPromise(); - }); - - it('Response should be successful and should contain an item of defined type', () => { - var item = response.data.items[0]; - - assert.ok(item); - assert.ok(item.system.codename); - }); -}); - - - - diff --git a/tests/integration-tests.config.ts b/tests/integration-tests.config.ts new file mode 100644 index 00000000..db6f58e4 --- /dev/null +++ b/tests/integration-tests.config.ts @@ -0,0 +1,35 @@ +import { existsSync } from "node:fs"; +import path from "node:path"; +import { loadEnvFile } from "node:process"; +import { fileURLToPath } from "node:url"; +import type { BaseUrl } from "@kontent-ai/core-sdk"; +import { getEnvironmentOptionalValue, getEnvironmentRequiredValue } from "@kontent-ai/core-sdk/devkit"; + +export function getIntegrationTestConfig() { + loadEnvironmentVariables(); + + const host = getEnvironmentOptionalValue("INTEGRATION_DELIVERY_HOST"); + const protocol = getEnvironmentOptionalValue("INTEGRATION_DELIVERY_PROTOCOL"); + + const deliveryBaseUrl: BaseUrl | undefined = host ? { protocol: protocol === "http" ? "http" : "https", host } : undefined; + + const integrationEnv: { + readonly id: string; + readonly deliveryBaseUrl: BaseUrl | undefined; + } = { + id: getEnvironmentRequiredValue("INTEGRATION_ENVIRONMENT_ID"), + deliveryBaseUrl, + } as const; + + return { + env: integrationEnv, + }; +} + +function loadEnvironmentVariables(): void { + const envFilePath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", ".env"); + + if (existsSync(envFilePath)) { + loadEnvFile(envFilePath); + } +} diff --git a/tests/integration/models/integration-test.extra-tests.ts b/tests/integration/models/integration-test.extra-tests.ts new file mode 100644 index 00000000..7feb04d2 --- /dev/null +++ b/tests/integration/models/integration-test.extra-tests.ts @@ -0,0 +1,35 @@ +import { expect, it } from "vitest"; +import type { ContentTypeCodenameOf } from "../../../lib/public_api.js"; +import type { ContentItemPayloadExtended } from "../../../lib/queries/content-items/models/content-item.models.js"; +import { contentItemSchemaExtended } from "../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { type IntegrationTestProjectSchema, isMovie } from "./integration-test.schema.js"; + +export function registerExtendedItemsTests( + items: readonly ContentItemPayloadExtended[], + modularContent: Readonly>>, +): void { + const allItems = [...items, ...Object.values(modularContent)]; + + it("There should be > 0 items", () => { + expect(allItems.length).toBeGreaterThan(0); + }); + + for (const item of allItems) { + if (isMovie(item)) { + it(`Movie item with codename "${item.system.codename}" has resolved cast items matching extended content-item schema`, () => { + for (const linkedItem of item.elements.cast.items) { + const { success, error } = contentItemSchemaExtended().safeParse(linkedItem); + expect(success, error?.message).toBe(true); + expect(linkedItem.system.type).toBe>("star"); + } + }); + + it(`Movie item with codename "${item.system.codename}" has resolved rich-text description items matching extended content-item schema`, () => { + for (const linkedItem of item.elements.description.items) { + const { success, error } = contentItemSchemaExtended().safeParse(linkedItem); + expect(success, error?.message).toBe(true); + } + }); + } + } +} diff --git a/tests/integration/models/integration-test.schema.ts b/tests/integration/models/integration-test.schema.ts new file mode 100644 index 00000000..0a779286 --- /dev/null +++ b/tests/integration/models/integration-test.schema.ts @@ -0,0 +1,60 @@ +import type { ContentItemOf, DeliveryClientSchema, Elements, TaxonomyTermCodenamesOf } from "../../../lib/public_api.js"; +import type { ContentItemPayloadExtended } from "../../../lib/queries/content-items/models/content-item.models.js"; + +export type IntegrationTestProjectSchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["default"]; + readonly taxonomies: { + readonly movie_type: readonly ["drama", "comedy", "sitcom", "stand_up", "action"]; + }; + readonly contentTypes: { + readonly movie: readonly [ + "title", + "length_in_minutes", + "description", + "is_blockbuster", + "release_date", + "cover", + "category", + "url", + "metadata__metadata_description", + "cast", + "custom", + ]; + readonly star: readonly ["firstname", "lastname"]; + }; + readonly collectionCodenames: readonly ["default"]; + readonly workflowCodenames: readonly ["default"]; + readonly workflowStepCodenames: readonly ["published", "draft"]; +}>; + +export type StarElements = { + readonly firstname: Elements.Text; + readonly lastname: Elements.Text; +}; + +export type Star = ContentItemOf; + +export type MovieElements = { + readonly title: Elements.Text; + readonly length_in_minutes: Elements.Number; + readonly description: Elements.RichText; + readonly is_blockbuster: Elements.MultipleChoice<"yes">; + readonly release_date: Elements.DateTime; + readonly cover: Elements.Asset; + readonly category: Elements.Taxonomy; + readonly url: Elements.UrlSlug; + readonly metadata__metadata_description: Elements.Text; + readonly cast: Elements.LinkedItems; +}; + +export type Movie = ContentItemOf; + +export function isMovie(item: ContentItemPayloadExtended): item is Movie { + return item.system.type === "movie"; +} + +export function isStar(item: ContentItemPayloadExtended): item is Star { + return item.system.type === "star"; +} + +export type MovieTaxonomyTerms = TaxonomyTermCodenamesOf; diff --git a/tests/integration/queries/content-items/fetch-content-item-query.payload.ts b/tests/integration/queries/content-items/fetch-content-item-query.payload.ts new file mode 100644 index 00000000..aa23635e --- /dev/null +++ b/tests/integration/queries/content-items/fetch-content-item-query.payload.ts @@ -0,0 +1,169 @@ +import type { FetchContentItemPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + item: { + system: { + id: "21586dc9-9c04-4c9e-a9e4-83b8cd65baef", + name: "The Dark Knight", + codename: "the_dark_knight", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-05-04T10:30:48.5100633Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + just_a_number_and_required: { + type: "number", + name: "just a number and required", + value: null, + }, + title: { + type: "text", + name: "Title", + value: "The Dark Knight", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 152, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

Batman raises the stakes in his war on crime. With the help of Lt. Jim Gordon and District Attorney Harvey Dent, he sets out to dismantle the remaining criminal organizations that plague Gotham City. But the emergence of the Joker creates chaos.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2008-07-18T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [ + { + name: "The_Dark_Knight_(2008_film).jpg", + description: null, + type: "image/jpeg", + size: 52188, + url: "https://assets-eu-01.kc-usercontent.com:443/6bdd84fc-f71e-01a0-0ba6-79ce07af7f9b/1ee1e759-4af3-4f0a-acfc-b61a88c1eafe/The_Dark_Knight_%282008_film%29.jpg", + width: 259, + height: 383, + renditions: { + default: { + rendition_id: "467ed3c4-6c7a-4cb3-908b-f908f7b1e7dd", + preset_id: "a6d98cd5-8b2c-4e50-99c9-15192bce2490", + width: 150, + height: 150, + query: "w=150&h=150&fit=clip&rect=54,122,150,150", + }, + }, + }, + ], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "the-dark-knight", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Christopher Nolan's The Dark Knight is widely regarded as one of the greatest superhero films ever made.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["christian_bale", "gary_oldman"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + modular_content: { + christian_bale: { + system: { + id: "2630c0c1-f25a-46df-9dd2-f258ff0d3c60", + name: "Christian Bale", + codename: "christian_bale", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:23.6060976Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Christian", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Bale", + }, + }, + }, + gary_oldman: { + system: { + id: "55b225d8-9d62-4306-9a8f-16feea53a3ac", + name: "Gary Oldman", + codename: "gary_oldman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:57.9327818Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Gary", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Oldman", + }, + }, + }, + }, +} satisfies FetchContentItemPayload; diff --git a/tests/integration/queries/content-items/fetch-content-item-query.spec.ts b/tests/integration/queries/content-items/fetch-content-item-query.spec.ts new file mode 100644 index 00000000..d3ff763a --- /dev/null +++ b/tests/integration/queries/content-items/fetch-content-item-query.spec.ts @@ -0,0 +1,50 @@ +import { describe, expect, it } from "vitest"; +import type { + FetchContentItemPayload, + FetchContentItemPayloadExtended, +} from "../../../../lib/queries/content-items/models/content-item.models.js"; +import { + fetchContentItemSchema, + fetchContentItemSchemaExtended, +} from "../../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import { type IntegrationTestProjectSchema, isMovie, isStar } from "../../models/integration-test.schema.js"; +import rawPayload from "./fetch-content-item-query.payload.js"; + +describe("Fetch content item query", async () => { + const codename = rawPayload.item.system.codename; + await runQueryTestsAsync, IntegrationTestProjectSchema>({ + endpoint: `items/${codename}`, + rawPayload, + selectQuery: (client) => client.fetchContentItem({ codename }).raw(), + expectedSchema: fetchContentItemSchema(), + }); +}); + +describe("Fetch content item query - extended", async () => { + const codename = rawPayload.item.system.codename; + await runQueryTestsAsync, IntegrationTestProjectSchema>({ + endpoint: `items/${codename}`, + rawPayload: undefined, + selectQuery: (client) => client.fetchContentItem({ codename }), + expectedSchema: fetchContentItemSchemaExtended(), + extraTests: (response) => { + const item = response.item; + if (!isMovie(item)) { + throw new Error("Item is not a movie"); + } + + it("Star items should contain items with identical codenames as raw value", () => { + expect(item.elements.cast.items.map((m) => m.system.codename).sort()).toEqual(rawPayload.item.elements.cast.value.sort()); + }); + + it("Star items should be typed as Star and elements should be defined", () => { + for (const star of item.elements.cast.items) { + expect(isStar(star)).toBe(true); + expect(star.elements.firstname).toBeDefined(); + expect(star.elements.lastname).toBeDefined(); + } + }); + }, + }); +}); diff --git a/tests/integration/queries/content-items/items-feed-query.payload.ts b/tests/integration/queries/content-items/items-feed-query.payload.ts new file mode 100644 index 00000000..133d31e3 --- /dev/null +++ b/tests/integration/queries/content-items/items-feed-query.payload.ts @@ -0,0 +1,3159 @@ +import type { ItemsFeedPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + items: [ + { + system: { + id: "d56bff34-5ce8-4ac1-9cb8-547848b3a22b", + name: "Al Pacino", + codename: "al_pacino", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:25.6499619Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Al", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Pacino", + }, + }, + }, + { + system: { + id: "b25e6ed1-0a3f-4975-bb84-4c7efefa70d0", + name: "Amy Adams", + codename: "amy_adams", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:17.8650469Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Amy", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Adams", + }, + }, + }, + { + system: { + id: "114f4d17-936f-406d-8e59-e34c7eb5f200", + name: "Ana de Armas", + codename: "ana_de_armas", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:05.6615288Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Ana", + }, + lastname: { + type: "text", + name: "Lastname", + value: "de Armas", + }, + }, + }, + { + system: { + id: "19f8dbfa-46d8-4f0d-9afa-c88dc963ff96", + name: "Angelina Jolie", + codename: "angelina_jolie", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:16.1359703Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Angelina", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Jolie", + }, + }, + }, + { + system: { + id: "a0f01bd5-c1d1-4aad-92de-89e7835b561e", + name: "Anne Hathaway", + codename: "anne_hathaway", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:51.1280388Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Anne", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Hathaway", + }, + }, + }, + { + system: { + id: "68bc6cea-79ba-4748-92d8-fdbf33bd55ea", + name: "Anthony Hopkins", + codename: "anthony_hopkins", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:00.3600159Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Anthony", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Hopkins", + }, + }, + }, + { + system: { + id: "a7c0313e-0bb0-4dc3-9d5b-61f9f5757b5e", + name: "Antonio Banderas", + codename: "antonio_banderas", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:06.8102193Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Antonio", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Banderas", + }, + }, + }, + { + system: { + id: "f87989d8-ac15-4b87-b43a-37d85e0002f6", + name: "Avengers: Endgame", + codename: "avengers__endgame", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:39.8815857Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Avengers: Endgame", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 181, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

After the devastating events of Avengers: Infinity War, the remaining Avengers assemble one final time to undo Thanos' destruction and restore the universe. The epic conclusion to the Infinity Saga.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2019-04-26T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "avengers-endgame", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "The highest-grossing film of all time upon release, Avengers: Endgame is the culmination of 22 Marvel Cinematic Universe films.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["chris_evans", "scarlett_johansson", "robert_downey_jr_", "jeremy_renner"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "0f33b050-4cf3-41f4-9a9d-33bd1c7ba5ef", + name: "Benedict Cumberbatch", + codename: "benedict_cumberbatch", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:06.8688409Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Benedict", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Cumberbatch", + }, + }, + }, + { + system: { + id: "292468fe-ac5a-4505-b6f1-83cbbee89687", + name: "Black Panther", + codename: "black_panther", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:53.6784162Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Black Panther", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 134, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

T'Challa returns home to the African nation of Wakanda to take his rightful place as king. When a powerful enemy with ties to his past threatens to destroy the country, he must rally his allies and release the full power of the Black Panther.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2018-02-16T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "black-panther", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Marvel's Black Panther became a cultural phenomenon and was nominated for 7 Academy Awards including Best Picture.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["chadwick_boseman", "lupita_nyong_o"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "d7862a9a-0333-491c-9db9-ee91a7828a84", + name: "Brad Pitt", + codename: "brad_pitt", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:15.7816154Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Brad", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Pitt", + }, + }, + }, + { + system: { + id: "5d096ac1-fc8c-4275-b411-11a1de4b1fbf", + name: "Brie Larson", + codename: "brie_larson", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:15.552657Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Brie", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Larson", + }, + }, + }, + { + system: { + id: "863cf0b7-3ae8-4e77-8067-b9bd5b1f162e", + name: "Bryan Cranston", + codename: "bryan_cranston", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:11.6294243Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Bryan", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Cranston", + }, + }, + }, + { + system: { + id: "97468922-e32c-40ce-ad75-8ede3edd45d7", + name: "Cate Blanchett", + codename: "cate_blanchett", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:14.6089072Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Cate", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Blanchett", + }, + }, + }, + { + system: { + id: "831a6311-5e6a-40ee-bb2e-a1a51439b1e1", + name: "Chadwick Boseman", + codename: "chadwick_boseman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:12.1866334Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Chadwick", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Boseman", + }, + }, + }, + { + system: { + id: "8b6a70c2-cc79-40e1-a01a-fa5c6563d947", + name: "Charlize Theron", + codename: "charlize_theron", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:28.8990017Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Charlize", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Theron", + }, + }, + }, + { + system: { + id: "7a6f289c-3c2f-4b8d-a66e-f7361e8a2a6f", + name: "Chris Evans", + codename: "chris_evans", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:20.9296898Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Chris", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Evans", + }, + }, + }, + { + system: { + id: "921c1a57-2c05-4fa6-a876-7c3b799d3f1b", + name: "Chris Hemsworth", + codename: "chris_hemsworth", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:00.457889Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Chris", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Hemsworth", + }, + }, + }, + { + system: { + id: "2630c0c1-f25a-46df-9dd2-f258ff0d3c60", + name: "Christian Bale", + codename: "christian_bale", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:23.6060976Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Christian", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Bale", + }, + }, + }, + { + system: { + id: "1fcb9a45-ea77-47ed-9348-5bfba31e9278", + name: "Christoph Waltz", + codename: "christoph_waltz", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:57.7940706Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Christoph", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Waltz", + }, + }, + }, + { + system: { + id: "23c90ad1-6963-4c24-b7eb-6967967bd448", + name: "Cillian Murphy", + codename: "cillian_murphy", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:48.9787224Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Cillian", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Murphy", + }, + }, + }, + { + system: { + id: "7ea5e2a4-7715-47eb-9f54-55d3860289ed", + name: "Colin Firth", + codename: "colin_firth", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:52.3614325Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Colin", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Firth", + }, + }, + }, + { + system: { + id: "a8c19b2a-3f5c-4a1d-9cc8-1a06d83ab301", + name: "Daniel Craig", + codename: "daniel_craig", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:18.8005459Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Daniel", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Craig", + }, + }, + }, + { + system: { + id: "7f985920-fed5-4acc-98b2-044bae9bed69", + name: "Daniel Day-Lewis", + codename: "daniel_day_lewis", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:00.8239293Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Daniel", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Day-Lewis", + }, + }, + }, + { + system: { + id: "943f8fd8-91c2-4b87-8fec-98ad4e693697", + name: "Denzel Washington", + codename: "denzel_washington", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:17.4317276Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Denzel", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Washington", + }, + }, + }, + { + system: { + id: "41b167f9-79ef-4e48-ab01-8cd10f7303af", + name: "Dwayne Johnson", + codename: "dwayne_johnson", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:42.3374184Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Dwayne", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Johnson", + }, + }, + }, + { + system: { + id: "ebc99a0d-d44b-4599-a01a-2dfba273a531", + name: "Eddie Redmayne", + codename: "eddie_redmayne", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:55.5692481Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Eddie", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Redmayne", + }, + }, + }, + { + system: { + id: "952090fe-5409-49ae-9f0d-238afecab0ab", + name: "Emily Blunt", + codename: "emily_blunt", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:49.7782012Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Emily", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Blunt", + }, + }, + }, + { + system: { + id: "1621e70c-99be-455c-b93c-46f68eab6158", + name: "Emma Stone", + codename: "emma_stone", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:01.4684966Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Emma", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Stone", + }, + }, + }, + { + system: { + id: "d19f1d6c-52b8-4bf3-8fbc-b019431d3eb1", + name: "Emma Thompson", + codename: "emma_thompson", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:58.8051847Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Emma", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Thompson", + }, + }, + }, + { + system: { + id: "5db2ea89-5fb8-4187-9d7c-5389df88b248", + name: "Ethan Hawke", + codename: "ethan_hawke", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:08.7084469Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Ethan", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Hawke", + }, + }, + }, + { + system: { + id: "b5640463-7a4c-46c0-8b08-b3c2c0a3f90f", + name: "Felicity Jones", + codename: "felicity_jones", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:56.4897287Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Felicity", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Jones", + }, + }, + }, + { + system: { + id: "14622687-19bd-4362-90b3-de3898f7aa6d", + name: "Florence Pugh", + codename: "florence_pugh", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:03.2222014Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Florence", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Pugh", + }, + }, + }, + { + system: { + id: "81b0c4cf-37dc-476a-ab0b-d4b2ed8ebbf2", + name: "Forrest Gump", + codename: "forrest_gump", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:22.6154672Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Forrest Gump", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 142, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

The story of Forrest Gump, a man with a low IQ but good heart, who unwittingly influences several historical events in 20th century America while longing for his childhood sweetheart Jenny.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "1994-07-06T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Drama", + codename: "drama", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "forrest-gump", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Winner of 6 Academy Awards including Best Picture, Forrest Gump is a beloved American classic starring Tom Hanks.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["tom_hanks"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "b5365930-21db-4440-abfe-65735f9dac2a", + name: "Gal Gadot", + codename: "gal_gadot", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:59.0827865Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Gal", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Gadot", + }, + }, + }, + { + system: { + id: "55b225d8-9d62-4306-9a8f-16feea53a3ac", + name: "Gary Oldman", + codename: "gary_oldman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:57.9327818Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Gary", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Oldman", + }, + }, + }, + { + system: { + id: "e777df88-4411-4831-b660-c8d40f776234", + name: "George Clooney", + codename: "george_clooney", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:41.4431549Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "George", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Clooney", + }, + }, + }, + { + system: { + id: "9540ec1a-8e48-4036-a435-41defd8589e7", + name: "Gladiator", + codename: "gladiator", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:35.2485442Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Gladiator", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 155, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

A former Roman general is betrayed by the emperor's corrupt son, loses everything dear to him, and is forced to become a gladiator. He must use his arena popularity to seek revenge against the tyrannical emperor.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2000-05-05T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "gladiator", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Ridley Scott's Gladiator won 5 Academy Awards including Best Picture, with Russell Crowe delivering an iconic performance.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["russell_crowe"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "c329dea2-e6e4-4985-9ab1-2ec2db8b021b", + name: "Halle Berry", + codename: "halle_berry", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:08.1011475Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Halle", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Berry", + }, + }, + }, + { + system: { + id: "af27004b-150d-44d5-992d-7f1200be93e9", + name: "Harrison Ford", + codename: "harrison_ford", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:44.5871489Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Harrison", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Ford", + }, + }, + }, + { + system: { + id: "dcc060dc-ce0e-4b1f-af45-c3ef82a90422", + name: "Helen Mirren", + codename: "helen_mirren", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:59.1375839Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Helen", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Mirren", + }, + }, + }, + { + system: { + id: "f8543414-e7c2-4598-944b-b80b4b663642", + name: "Hugh Jackman", + codename: "hugh_jackman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:11.3590593Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Hugh", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Jackman", + }, + }, + }, + { + system: { + id: "96c9d600-a2b3-4339-b792-112629276dba", + name: "Ian McKellen", + codename: "ian_mckellen", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:59.7130962Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Ian", + }, + lastname: { + type: "text", + name: "Lastname", + value: "McKellen", + }, + }, + }, + { + system: { + id: "ff4bd7e5-40a7-4a0d-bb25-769b414bfdec", + name: "Idris Elba", + codename: "idris_elba", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:51.9478946Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Idris", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Elba", + }, + }, + }, + { + system: { + id: "23b4a456-9d2a-4e47-915d-589e41b7329b", + name: "Inception", + codename: "inception", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:44.4838819Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Inception", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 148, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

A skilled thief who steals secrets from within people's dreams is given a chance to have his criminal record erased if he can plant an idea into a target's subconscious — a process known as inception.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2010-07-16T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "inception", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Christopher Nolan's mind-bending sci-fi thriller Inception won 4 Academy Awards and is celebrated for its innovative storytelling.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["leonardo_dicaprio", "marion_cotillard"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "e1c9dde8-97dd-4604-8acc-bca0421d8e04", + name: "Jake Gyllenhaal", + codename: "jake_gyllenhaal", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:14.2302861Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jake", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Gyllenhaal", + }, + }, + }, + { + system: { + id: "26ddb3e5-46d3-451f-9774-bd68fe604c12", + name: "James McAvoy", + codename: "james_mcavoy", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:46.328842Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "James", + }, + lastname: { + type: "text", + name: "Lastname", + value: "McAvoy", + }, + }, + }, + { + system: { + id: "7427309c-b84a-4c47-9a51-44b3e259b46d", + name: "Jamie Foxx", + codename: "jamie_foxx", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:53.2123098Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jamie", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Foxx", + }, + }, + }, + { + system: { + id: "2a5142ec-c56b-44d8-bb86-80553d05f53e", + name: "Javier Bardem", + codename: "javier_bardem", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:53.6413359Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Javier", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Bardem", + }, + }, + }, + { + system: { + id: "caad3465-f88c-43db-8d24-f32331c2ac8e", + name: "Jeff Bridges", + codename: "jeff_bridges", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:58.5625601Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jeff", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Bridges", + }, + }, + }, + { + system: { + id: "b96c6cbc-fd7d-4a13-9a9a-52fdd425a27a", + name: "Jennifer Aniston", + codename: "jennifer_aniston", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:40.2064454Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jennifer", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Aniston", + }, + }, + }, + { + system: { + id: "6a8461ab-6948-4f91-93d1-5b36aaebd3ee", + name: "Jennifer Lawrence", + codename: "jennifer_lawrence", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:22.8329501Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jennifer", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Lawrence", + }, + }, + }, + { + system: { + id: "d87ce611-4f91-451e-8fa2-24f0922ba71c", + name: "Jeremy Renner", + codename: "jeremy_renner", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:55.7508643Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jeremy", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Renner", + }, + }, + }, + { + system: { + id: "35aba8b4-289b-42aa-82fe-29842ebbfc88", + name: "Jessica Chastain", + codename: "jessica_chastain", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:19.9987106Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jessica", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Chastain", + }, + }, + }, + { + system: { + id: "90e414bd-16f4-4644-8fdd-0c8553396b72", + name: "Joaquin Phoenix", + codename: "joaquin_phoenix", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:29.7797132Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Joaquin", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Phoenix", + }, + }, + }, + { + system: { + id: "f52c5bb9-7078-44ee-9bcd-404b8df000a5", + name: "John David Washington", + codename: "john_david_washington", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:06.4726897Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "John David", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Washington", + }, + }, + }, + { + system: { + id: "423efdd9-8624-4be1-9fa8-072ff75fed62", + name: "Joker", + codename: "joker", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:48.5786297Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Joker", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 122, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

Arthur Fleck, a failed stand-up comedian and part-time clown, is disregarded and mistreated by society. As he descends into madness, he adopts the alter ego of the Joker and becomes the catalyst for chaos in Gotham City.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2019-10-04T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Drama", + codename: "drama", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "joker", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Joaquin Phoenix won the Academy Award for Best Actor for his transformative portrayal of Arthur Fleck in Todd Phillips' Joker.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["joaquin_phoenix"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "9430c217-39d8-4ad3-91aa-2674acd981a2", + name: "Judi Dench", + codename: "judi_dench", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:50.2320048Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Judi", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Dench", + }, + }, + }, + { + system: { + id: "d468218a-e7c8-44cc-84d3-acb37e9dc9ee", + name: "Julia Roberts", + codename: "julia_roberts", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:18.3193199Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Julia", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Roberts", + }, + }, + }, + { + system: { + id: "7296fa14-b4d8-4585-8347-ebfe70b798ec", + name: "Julianne Moore", + codename: "julianne_moore", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:02.956359Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Julianne", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Moore", + }, + }, + }, + { + system: { + id: "e90e44e2-91f0-4203-857f-fd3faafd025d", + name: "Kate Winslet", + codename: "kate_winslet", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:05.6830624Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Kate", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Winslet", + }, + }, + }, + { + system: { + id: "d92f4584-34e9-40c5-baba-ca5d0fdd0b9f", + name: "Keanu Reeves", + codename: "keanu_reeves", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:08.9297582Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Keanu", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Reeves", + }, + }, + }, + { + system: { + id: "d4e90b88-679d-4d99-8159-cc0f89228b59", + name: "Keira Knightley", + codename: "keira_knightley", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:53.277714Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Keira", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Knightley", + }, + }, + }, + { + system: { + id: "691f96df-d9c3-4d69-95d8-eeb0eb1c65f6", + name: "La La Land", + codename: "la_la_land", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:30.7299534Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "La La Land", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 128, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

A jazz musician and an aspiring actress fall in love while each pursuing their dreams in Los Angeles. A modern musical celebrating the timeless Hollywood tradition of dreamers and lovers.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2016-12-09T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Drama", + codename: "drama", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "la-la-land", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Damien Chazelle's La La Land won 6 Academy Awards and revived the Hollywood musical genre.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["ryan_gosling", "emma_stone"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "62de95fa-4468-405a-bf0b-b0b791bdf9ce", + name: "Leonardo DiCaprio", + codename: "leonardo_dicaprio", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:14.1998292Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Leonardo", + }, + lastname: { + type: "text", + name: "Lastname", + value: "DiCaprio", + }, + }, + }, + { + system: { + id: "2c71df49-6390-453f-b2dd-12467406b350", + name: "Lupita Nyong'o", + codename: "lupita_nyong_o", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:13.5243957Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Lupita", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Nyong'o", + }, + }, + }, + { + system: { + id: "1aaa04e0-c5e9-4295-bfba-5af17e3be575", + name: "Mads Mikkelsen", + codename: "mads_mikkelsen", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:09.6094973Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Mads", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Mikkelsen", + }, + }, + }, + { + system: { + id: "736bc909-0049-42d0-9c33-f272f1f15248", + name: "Mahershala Ali", + codename: "mahershala_ali", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:08.9792264Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Mahershala", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Ali", + }, + }, + }, + { + system: { + id: "9437d4dd-69d4-4ce3-a57f-64d8a4c1e1bb", + name: "Margot Robbie", + codename: "margot_robbie", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:52.4340963Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Margot", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Robbie", + }, + }, + }, + { + system: { + id: "fda6870f-c881-4271-ba2a-2cbf209573c4", + name: "Marion Cotillard", + codename: "marion_cotillard", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:54.4864003Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Marion", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Cotillard", + }, + }, + }, + { + system: { + id: "aee262cf-866c-4d5a-8eb3-889457b2151c", + name: "Matt Damon", + codename: "matt_damon", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:02.2760641Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Matt", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Damon", + }, + }, + }, + { + system: { + id: "1c8eba11-646b-4f80-bedf-e7d23a665966", + name: "Meryl Streep", + codename: "meryl_streep", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:13.7111314Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Meryl", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Streep", + }, + }, + }, + { + system: { + id: "973aa0fa-311a-45fd-9adf-0ffc3c7df75a", + name: "Michael B. Jordan", + codename: "michael_b__jordan", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:47.5846647Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Michael B.", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Jordan", + }, + }, + }, + { + system: { + id: "f801888e-147d-4509-ad86-252f7918ab7b", + name: "Michael Fassbender", + codename: "michael_fassbender", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:16.7654414Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Michael", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Fassbender", + }, + }, + }, + { + system: { + id: "71c28bd9-3fe4-47fb-af29-9c882fb0b623", + name: "Michelle Yeoh", + codename: "michelle_yeoh", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:51.6922888Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Michelle", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Yeoh", + }, + }, + }, + { + system: { + id: "6dddc4e0-1425-44b5-8b4c-00a9690a2f90", + name: "Morgan Freeman", + codename: "morgan_freeman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:21.5555586Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Morgan", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Freeman", + }, + }, + }, + { + system: { + id: "45d594c5-b251-4d3d-864d-c78a3d2c285b", + name: "Movie with empty rich text", + codename: "movie_with_empty_rich_text", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-10T10:23:44.1265574Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "Movie with empty rich text", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 0, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "


", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "no", + codename: "no", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2026-04-09T22:00:00Z", + display_timezone: "Europe/Budapest", + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Drama", + codename: "drama", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "movie-with-empty-rich-text", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["joker"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "218a80d2-6787-4086-9728-5c06170d92ef", + name: "Naomi Watts", + codename: "naomi_watts", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:55.0766398Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Naomi", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Watts", + }, + }, + }, + { + system: { + id: "090807a7-c5a1-4d42-8987-d820c06bb6a9", + name: "Natalie Portman", + codename: "natalie_portman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:26.8476502Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Natalie", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Portman", + }, + }, + }, + { + system: { + id: "08271858-e58e-401b-9aa9-c13a86a54fdb", + name: "Nicole Kidman", + codename: "nicole_kidman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:31.0302744Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Nicole", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Kidman", + }, + }, + }, + { + system: { + id: "0b83b3dc-1849-4a8b-8e7f-222b581a0fff", + name: "Nora Lum", + codename: "nora_lum", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:07.7026459Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Nora", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Lum", + }, + }, + }, + { + system: { + id: "f51a15db-f5f5-4c2c-98b3-1d3918bd672f", + name: "Oscar Isaac", + codename: "oscar_isaac", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:07.5328891Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Oscar", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Isaac", + }, + }, + }, + { + system: { + id: "e2bc46cd-a7ea-4cde-8d4e-b56e30708bca", + name: "Pedro Pascal", + codename: "pedro_pascal", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:04.4430733Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Pedro", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Pascal", + }, + }, + }, + { + system: { + id: "e285cba4-294f-44a5-b76e-088cf89371be", + name: "Penélope Cruz", + codename: "penelope_cruz", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:05.4809267Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Penélope", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Cruz", + }, + }, + }, + { + system: { + id: "76a5c1fc-46bc-4274-8a19-07e74a0c801e", + name: "Rachel McAdams", + codename: "rachel_mcadams", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:56.9474259Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Rachel", + }, + lastname: { + type: "text", + name: "Lastname", + value: "McAdams", + }, + }, + }, + { + system: { + id: "03ef6927-eb79-4be2-85fa-44a9f5d01ae8", + name: "Ralph Fiennes", + codename: "ralph_fiennes", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:50.9985727Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Ralph", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Fiennes", + }, + }, + }, + { + system: { + id: "e5b44b09-572e-4768-9856-9f44e5df70aa", + name: "Reese Witherspoon", + codename: "reese_witherspoon", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:10.1223156Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Reese", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Witherspoon", + }, + }, + }, + { + system: { + id: "fbb9eb43-1405-4884-94bb-6ef230b87a65", + name: "Regina King", + codename: "regina_king", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:09.8875628Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Regina", + }, + lastname: { + type: "text", + name: "Lastname", + value: "King", + }, + }, + }, + { + system: { + id: "46663b41-3619-484e-a1f9-6e4cc9ca3ab0", + name: "Robert De Niro", + codename: "robert_de_niro", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:19.593274Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Robert", + }, + lastname: { + type: "text", + name: "Lastname", + value: "De Niro", + }, + }, + }, + { + system: { + id: "bbc14c55-9d5b-4c75-a968-6e17799987a7", + name: "Robert Downey Jr.", + codename: "robert_downey_jr_", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:45.6740229Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Robert", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Downey Jr.", + }, + }, + }, + { + system: { + id: "4c0f7928-a8c1-4b70-b2bd-62dc85722570", + name: "Rooney Mara", + codename: "rooney_mara", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:23:54.64466Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Rooney", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Mara", + }, + }, + }, + { + system: { + id: "906326c7-9d66-432a-b49d-2728f48e3825", + name: "Russell Crowe", + codename: "russell_crowe", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:56.2128676Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Russell", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Crowe", + }, + }, + }, + { + system: { + id: "dee9a365-71ee-4f1f-a430-d98f93bfe817", + name: "Ryan Gosling", + codename: "ryan_gosling", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:04.4007354Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Ryan", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Gosling", + }, + }, + }, + { + system: { + id: "94baa269-30cd-42b0-b54b-7be65b61fe0c", + name: "Salma Hayek", + codename: "salma_hayek", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:24:04.2441153Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Salma", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Hayek", + }, + }, + }, + { + system: { + id: "4cc3ccd6-8fc4-403f-a816-9ed97d302f82", + name: "Samuel L. Jackson", + codename: "samuel_l__jackson", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:53.7929068Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Samuel L.", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Jackson", + }, + }, + }, + { + system: { + id: "5409a321-144d-44b5-847e-4cfdab10a68b", + name: "Sandra Bullock", + codename: "sandra_bullock", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:24.8943758Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Sandra", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Bullock", + }, + }, + }, + { + system: { + id: "cb58900c-56fa-4331-a2d2-89d708c580ad", + name: "Saoirse Ronan", + codename: "saoirse_ronan", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:50.4309368Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Saoirse", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Ronan", + }, + }, + }, + { + system: { + id: "70c23859-845e-40d6-86f7-2c1865ff828d", + name: "Scarlett Johansson", + codename: "scarlett_johansson", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:20.2541643Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Scarlett", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Johansson", + }, + }, + }, + { + system: { + id: "3b8c25d3-fabe-4451-b0c1-c5b95ba15579", + name: "Sigourney Weaver", + codename: "sigourney_weaver", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:57.743072Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Sigourney", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Weaver", + }, + }, + }, + { + system: { + id: "21586dc9-9c04-4c9e-a9e4-83b8cd65baef", + name: "The Dark Knight", + codename: "the_dark_knight", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:36:42.4587906Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + title: { + type: "text", + name: "Title", + value: "The Dark Knight", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 152, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

Batman raises the stakes in his war on crime. With the help of Lt. Jim Gordon and District Attorney Harvey Dent, he sets out to dismantle the remaining criminal organizations that plague Gotham City. But the emergence of the Joker creates chaos.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2008-07-18T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [ + { + name: "The_Dark_Knight_(2008_film).jpg", + description: null, + type: "image/jpeg", + size: 52188, + url: "https://assets-eu-01.kc-usercontent.com:443/6bdd84fc-f71e-01a0-0ba6-79ce07af7f9b/1ee1e759-4af3-4f0a-acfc-b61a88c1eafe/The_Dark_Knight_%282008_film%29.jpg", + width: 259, + height: 383, + renditions: {}, + }, + ], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "the-dark-knight", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Christopher Nolan's The Dark Knight is widely regarded as one of the greatest superhero films ever made.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["christian_bale", "gary_oldman"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + ], + modular_content: {}, +} satisfies ItemsFeedPayload; diff --git a/tests/integration/queries/content-items/items-feed-query.spec.ts b/tests/integration/queries/content-items/items-feed-query.spec.ts new file mode 100644 index 00000000..8de2052a --- /dev/null +++ b/tests/integration/queries/content-items/items-feed-query.spec.ts @@ -0,0 +1,28 @@ +import { describe } from "vitest"; +import type { ItemsFeedPayloadExtended } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import { itemsFeedSchema, itemsFeedSchemaExtended } from "../../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import { registerExtendedItemsTests } from "../../models/integration-test.extra-tests.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; +import unitTestPayload from "./items-feed-query.payload.js"; + +describe("Items feed query", async () => { + await runQueryTestsAsync({ + endpoint: "items-feed", + rawPayload: unitTestPayload, + selectQuery: (client) => client.itemsFeed().raw(), + expectedSchema: itemsFeedSchema(), + }); +}); + +describe("Items feed query - extended", async () => { + await runQueryTestsAsync, IntegrationTestProjectSchema>({ + endpoint: "items-feed", + rawPayload: undefined, + selectQuery: (client) => client.itemsFeed(), + expectedSchema: itemsFeedSchemaExtended(), + extraTests: (payload) => { + registerExtendedItemsTests(payload.items, payload.modular_content); + }, + }); +}); diff --git a/tests/integration/queries/content-items/items-referencing-asset-query.payload.ts b/tests/integration/queries/content-items/items-referencing-asset-query.payload.ts new file mode 100644 index 00000000..252953b7 --- /dev/null +++ b/tests/integration/queries/content-items/items-referencing-asset-query.payload.ts @@ -0,0 +1,20 @@ +import type { ItemsReferencingAssetPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + items: [ + { + system: { + id: "21586dc9-9c04-4c9e-a9e4-83b8cd65baef", + name: "The Dark Knight", + codename: "the_dark_knight", + language: "default", + type: "movie", + collection: "default", + workflow: "default", + workflow_step: "published", + last_modified: "2026-04-07T10:36:42.4587906Z", + }, + }, + ], +} satisfies ItemsReferencingAssetPayload; diff --git a/tests/integration/queries/content-items/items-referencing-asset-query.spec.ts b/tests/integration/queries/content-items/items-referencing-asset-query.spec.ts new file mode 100644 index 00000000..ffe434f9 --- /dev/null +++ b/tests/integration/queries/content-items/items-referencing-asset-query.spec.ts @@ -0,0 +1,16 @@ +import { describe } from "vitest"; +import type { DeliveryClientSchema } from "../../../../lib/models/core.models.js"; +import type { ItemsReferencingAssetPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import { itemsReferencingAssetSchema } from "../../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./items-referencing-asset-query.payload.js"; + +describe("Items referencing asset query", async () => { + const assetCodename = "the_dark_knight__2008_film__jpg"; + await runQueryTestsAsync>({ + endpoint: `assets/${assetCodename}/used-in`, + rawPayload, + selectQuery: (client) => client.itemsReferencingAsset({ codename: assetCodename }), + expectedSchema: itemsReferencingAssetSchema(), + }); +}); diff --git a/tests/integration/queries/content-items/items-referencing-item-query.payload.ts b/tests/integration/queries/content-items/items-referencing-item-query.payload.ts new file mode 100644 index 00000000..46e48562 --- /dev/null +++ b/tests/integration/queries/content-items/items-referencing-item-query.payload.ts @@ -0,0 +1,20 @@ +import type { ItemsReferencingItemPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + items: [ + { + system: { + id: "21586dc9-9c04-4c9e-a9e4-83b8cd65baef", + name: "The Dark Knight", + codename: "the_dark_knight", + language: "default", + type: "movie", + collection: "default", + workflow: "default", + workflow_step: "published", + last_modified: "2026-04-07T10:36:42.4587906Z", + }, + }, + ], +} satisfies ItemsReferencingItemPayload; diff --git a/tests/integration/queries/content-items/items-referencing-item-query.spec.ts b/tests/integration/queries/content-items/items-referencing-item-query.spec.ts new file mode 100644 index 00000000..8fe0b7d7 --- /dev/null +++ b/tests/integration/queries/content-items/items-referencing-item-query.spec.ts @@ -0,0 +1,16 @@ +import { describe } from "vitest"; +import type { DeliveryClientSchema } from "../../../../lib/models/core.models.js"; +import type { ItemsReferencingItemPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import { itemsReferencingItemSchema } from "../../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./items-referencing-item-query.payload.js"; + +describe("Items referencing item query", async () => { + const itemCodename = "the_dark_knight"; + await runQueryTestsAsync>({ + endpoint: `items/${itemCodename}/used-in`, + rawPayload: rawPayload, + selectQuery: (client) => client.itemsReferencingItem({ codename: itemCodename }), + expectedSchema: itemsReferencingItemSchema(), + }); +}); diff --git a/tests/integration/queries/content-items/list-content-items-query.payload.ts b/tests/integration/queries/content-items/list-content-items-query.payload.ts new file mode 100644 index 00000000..b45fbf4f --- /dev/null +++ b/tests/integration/queries/content-items/list-content-items-query.payload.ts @@ -0,0 +1,353 @@ +import type { ListContentItemsPayload } from "../../../../lib/queries/content-items/models/content-item.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + items: [ + { + system: { + id: "f87989d8-ac15-4b87-b43a-37d85e0002f6", + name: "Avengers: Endgame", + codename: "avengers__endgame", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:39.8815857Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + just_a_number_and_required: { + type: "number", + name: "just a number and required", + value: null, + }, + title: { + type: "text", + name: "Title", + value: "Avengers: Endgame", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 181, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

After the devastating events of Avengers: Infinity War, the remaining Avengers assemble one final time to undo Thanos' destruction and restore the universe. The epic conclusion to the Infinity Saga.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2019-04-26T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "avengers-endgame", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "The highest-grossing film of all time upon release, Avengers: Endgame is the culmination of 22 Marvel Cinematic Universe films.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["chris_evans", "scarlett_johansson", "robert_downey_jr_", "jeremy_renner"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + { + system: { + id: "292468fe-ac5a-4505-b6f1-83cbbee89687", + name: "Black Panther", + codename: "black_panther", + language: "default", + type: "movie", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:25:53.6784162Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + just_a_number_and_required: { + type: "number", + name: "just a number and required", + value: null, + }, + title: { + type: "text", + name: "Title", + value: "Black Panther", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + value: 134, + }, + description: { + type: "rich_text", + name: "Description", + images: {}, + links: {}, + modular_content: [], + value: "

T'Challa returns home to the African nation of Wakanda to take his rightful place as king. When a powerful enemy with ties to his past threatens to destroy the country, he must rally his allies and release the full power of the Black Panther.

", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + value: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + value: "2018-02-16T00:00:00Z", + display_timezone: null, + }, + cover: { + type: "asset", + name: "Cover", + value: [], + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + value: [ + { + name: "Action", + codename: "action", + }, + ], + }, + url: { + type: "url_slug", + name: "Url", + value: "black-panther", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + value: "Marvel's Black Panther became a cultural phenomenon and was nominated for 7 Academy Awards including Best Picture.", + }, + cast: { + type: "modular_content", + name: "Cast", + value: ["chadwick_boseman", "lupita_nyong_o"], + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, + }, + ], + modular_content: { + chadwick_boseman: { + system: { + id: "831a6311-5e6a-40ee-bb2e-a1a51439b1e1", + name: "Chadwick Boseman", + codename: "chadwick_boseman", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:12.1866334Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Chadwick", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Boseman", + }, + }, + }, + chris_evans: { + system: { + id: "7a6f289c-3c2f-4b8d-a66e-f7361e8a2a6f", + name: "Chris Evans", + codename: "chris_evans", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:20.9296898Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Chris", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Evans", + }, + }, + }, + jeremy_renner: { + system: { + id: "d87ce611-4f91-451e-8fa2-24f0922ba71c", + name: "Jeremy Renner", + codename: "jeremy_renner", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:55.7508643Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Jeremy", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Renner", + }, + }, + }, + lupita_nyong_o: { + system: { + id: "2c71df49-6390-453f-b2dd-12467406b350", + name: "Lupita Nyong'o", + codename: "lupita_nyong_o", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:21:13.5243957Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Lupita", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Nyong'o", + }, + }, + }, + robert_downey_jr_: { + system: { + id: "bbc14c55-9d5b-4c75-a968-6e17799987a7", + name: "Robert Downey Jr.", + codename: "robert_downey_jr_", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:22:45.6740229Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Robert", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Downey Jr.", + }, + }, + }, + scarlett_johansson: { + system: { + id: "70c23859-845e-40d6-86f7-2c1865ff828d", + name: "Scarlett Johansson", + codename: "scarlett_johansson", + language: "default", + type: "star", + collection: "default", + sitemap_locations: [], + last_modified: "2026-04-07T10:20:20.2541643Z", + workflow: "default", + workflow_step: "published", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: "Scarlett", + }, + lastname: { + type: "text", + name: "Lastname", + value: "Johansson", + }, + }, + }, + }, + pagination: { + skip: 0, + limit: 2, + count: 2, + next_page: "", + }, +} satisfies ListContentItemsPayload; diff --git a/tests/integration/queries/content-items/list-content-items-query.spec.ts b/tests/integration/queries/content-items/list-content-items-query.spec.ts new file mode 100644 index 00000000..75c63cee --- /dev/null +++ b/tests/integration/queries/content-items/list-content-items-query.spec.ts @@ -0,0 +1,34 @@ +import { describe } from "vitest"; +import type { + ListContentItemsPayload, + ListContentItemsPayloadExtended, +} from "../../../../lib/queries/content-items/models/content-item.models.js"; +import { + listContentItemsSchema, + listContentItemsSchemaExtended, +} from "../../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import { registerExtendedItemsTests } from "../../models/integration-test.extra-tests.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; +import rawPayload from "./list-content-items-query.payload.js"; + +describe("List content items query", async () => { + await runQueryTestsAsync, IntegrationTestProjectSchema>({ + endpoint: "items", + rawPayload, + selectQuery: (client) => client.listContentItems().raw(), + expectedSchema: listContentItemsSchema(), + }); +}); + +describe("List content items query - extended", async () => { + await runQueryTestsAsync, IntegrationTestProjectSchema>({ + endpoint: "items", + rawPayload: undefined, + selectQuery: (client) => client.listContentItems(), + expectedSchema: listContentItemsSchemaExtended(), + extraTests: (response) => { + registerExtendedItemsTests(response.items, response.modular_content); + }, + }); +}); diff --git a/tests/integration/queries/content-types/fetch-content-type-element-query.payload.ts b/tests/integration/queries/content-types/fetch-content-type-element-query.payload.ts new file mode 100644 index 00000000..8c75d5e5 --- /dev/null +++ b/tests/integration/queries/content-types/fetch-content-type-element-query.payload.ts @@ -0,0 +1,61 @@ +import type { ContentTypeElementPayload } from "../../../../lib/queries/content-types/models/content-type.models.js"; + +export default [ + { + type: "text", + name: "Title", + codename: "title", + }, + { + type: "custom", + name: "Custom", + codename: "custom", + }, + { + type: "number", + name: "Length in minutes", + codename: "length_in_minutes", + }, + { + type: "rich_text", + name: "Description", + codename: "description", + }, + { + type: "multiple_choice", + name: "Is blockbuster", + options: [ + { + name: "yes", + codename: "yes", + }, + ], + codename: "is_blockbuster", + }, + { + type: "date_time", + name: "Release date", + codename: "release_date", + }, + { + type: "asset", + name: "Cover", + codename: "cover", + }, + { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + codename: "category", + }, + { + type: "text", + name: "Metadata description", + codename: "metadata__metadata_description", + }, + { + type: "modular_content", + name: "Cast", + codename: "cast", + }, +] satisfies readonly ContentTypeElementPayload[]; diff --git a/tests/integration/queries/content-types/fetch-content-type-element-query.spec.ts b/tests/integration/queries/content-types/fetch-content-type-element-query.spec.ts new file mode 100644 index 00000000..b2072be3 --- /dev/null +++ b/tests/integration/queries/content-types/fetch-content-type-element-query.spec.ts @@ -0,0 +1,20 @@ +import { describe } from "vitest"; +import type { ContentTypeElementPayload } from "../../../../lib/queries/content-types/models/content-type.models.js"; +import { contentTypeElementSchema } from "../../../../lib/queries/content-types/schemas/content-type.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./fetch-content-type-element-query.payload.js"; + +describe("Fetch content type element query", async () => { + const typeCodename = "movie"; + + const tests: readonly Promise[] = rawPayload.map(async (payload) => + runQueryTestsAsync({ + endpoint: `types/${typeCodename}/elements/${payload.codename}`, + rawPayload: payload, + selectQuery: (client) => client.fetchContentTypeElement({ typeCodename, elementCodename: payload.codename }), + expectedSchema: contentTypeElementSchema(), + }), + ); + + await Promise.all(tests); +}); diff --git a/tests/integration/queries/content-types/fetch-content-type-query.payload.ts b/tests/integration/queries/content-types/fetch-content-type-query.payload.ts new file mode 100644 index 00000000..bd6d6b67 --- /dev/null +++ b/tests/integration/queries/content-types/fetch-content-type-query.payload.ts @@ -0,0 +1,69 @@ +import type { ContentTypePayload } from "../../../../lib/queries/content-types/models/content-type.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + system: { + id: "445da25c-d991-4b0e-bece-c572124d91f5", + name: "Movie", + codename: "movie", + last_modified: "2026-04-10T10:23:30.2425214Z", + }, + elements: { + title: { + type: "text", + name: "Title", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + }, + description: { + type: "rich_text", + name: "Description", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + options: [ + { + name: "yes", + codename: "yes", + }, + { + name: "no", + codename: "no", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + }, + cover: { + type: "asset", + name: "Cover", + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + }, + url: { + type: "url_slug", + name: "Url", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + }, + cast: { + type: "modular_content", + name: "Cast", + }, + custom: { + type: "custom", + name: "Custom", + value: null, + }, + }, +} satisfies ContentTypePayload; diff --git a/tests/integration/queries/content-types/fetch-content-type-query.spec.ts b/tests/integration/queries/content-types/fetch-content-type-query.spec.ts new file mode 100644 index 00000000..42f04062 --- /dev/null +++ b/tests/integration/queries/content-types/fetch-content-type-query.spec.ts @@ -0,0 +1,83 @@ +import { describe, expect, it } from "vitest"; +import { contentTypeSchema } from "../../../../lib/queries/content-types/schemas/content-type.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./fetch-content-type-query.payload.js"; + +describe("Fetch content type query", async () => { + const codename = "movie"; + await runQueryTestsAsync({ + endpoint: `types/${codename}`, + rawPayload, + selectQuery: (client) => client.fetchContentType({ codename: codename }), + expectedSchema: contentTypeSchema(), + }); +}); + +describe("Fetch Content Type Query — Extra Field in Element", async () => { + const payload = { + system: { + id: "445da25c-d991-4b0e-bece-c572124d91f5", + name: "Movie", + codename: "movie", + last_modified: "2026-02-26T14:02:39.320664Z", + }, + elements: { + title: { + type: "text", + name: "Title", + extra: "Field", + }, + }, + }; + + const { success } = await contentTypeSchema().safeParseAsync(payload); + + it("parses successfully when extra fields are present in an element", () => { + expect(success).toBeTruthy(); + }); +}); + +describe("Fetch Content Type Query — Invalid Field Type in Element", async () => { + const payload = { + system: { + id: "445da25c-d991-4b0e-bece-c572124d91f5", + name: "Movie", + codename: "movie", + last_modified: "2026-02-26T14:02:39.320664Z", + }, + elements: { + title: { + type: "invalid_field", + name: "Title", + }, + }, + }; + + const { success } = await contentTypeSchema().safeParseAsync(payload); + + it("fails to parse when an invalid field type is present in element", () => { + expect(success).toBeFalsy(); + }); +}); + +describe("Fetch Content Type Query — Missing System Field", async () => { + const payload = { + system: { + id: "445da25c-d991-4b0e-bece-c572124d91f5", + name: "Movie", + codename: "movie", + }, + elements: { + title: { + type: "invalid_field", + name: "Title", + }, + }, + }; + + const { success } = await contentTypeSchema().safeParseAsync(payload); + + it("fails to parse when the system field is missing", () => { + expect(success).toBeFalsy(); + }); +}); diff --git a/tests/integration/queries/content-types/list-content-types-query.payload.ts b/tests/integration/queries/content-types/list-content-types-query.payload.ts new file mode 100644 index 00000000..a746c36a --- /dev/null +++ b/tests/integration/queries/content-types/list-content-types-query.payload.ts @@ -0,0 +1,88 @@ +import type { ListContentTypesPayload } from "../../../../lib/queries/content-types/models/content-type.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + types: [ + { + system: { + id: "445da25c-d991-4b0e-bece-c572124d91f5", + name: "Movie", + codename: "movie", + last_modified: "2026-02-26T14:02:39.320664Z", + }, + elements: { + title: { + type: "text", + name: "Title", + }, + length_in_minutes: { + type: "number", + name: "Length in minutes", + }, + description: { + type: "rich_text", + name: "Description", + }, + is_blockbuster: { + type: "multiple_choice", + name: "Is blockbuster", + options: [ + { + name: "yes", + codename: "yes", + }, + ], + }, + release_date: { + type: "date_time", + name: "Release date", + }, + cover: { + type: "asset", + name: "Cover", + }, + category: { + type: "taxonomy", + name: "Category", + taxonomy_group: "movie_type", + }, + url: { + type: "url_slug", + name: "Url", + }, + metadata__metadata_description: { + type: "text", + name: "Metadata description", + }, + cast: { + type: "modular_content", + name: "Cast", + }, + }, + }, + { + system: { + id: "068c2ea7-144f-4472-ac0a-70e6f53034bf", + name: "Star", + codename: "star", + last_modified: "2026-02-26T14:02:20.3307783Z", + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + }, + lastname: { + type: "text", + name: "Lastname", + }, + }, + }, + ], + pagination: { + skip: 0, + limit: 0, + count: 2, + next_page: "", + }, +} satisfies ListContentTypesPayload; diff --git a/tests/integration/queries/content-types/list-content-types-query.spec.ts b/tests/integration/queries/content-types/list-content-types-query.spec.ts new file mode 100644 index 00000000..9d7b5911 --- /dev/null +++ b/tests/integration/queries/content-types/list-content-types-query.spec.ts @@ -0,0 +1,15 @@ +import { describe } from "vitest"; +import type { DeliveryClientSchema } from "../../../../lib/models/core.models.js"; +import type { ListContentTypesPayload } from "../../../../lib/queries/content-types/models/content-type.models.js"; +import { listContentTypesSchema } from "../../../../lib/queries/content-types/schemas/content-type.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./list-content-types-query.payload.js"; + +describe("List content types query", async () => { + await runQueryTestsAsync>({ + endpoint: "types", + rawPayload, + selectQuery: (client) => client.listContentTypes(), + expectedSchema: listContentTypesSchema(), + }); +}); diff --git a/tests/integration/queries/languages/list-languages-query.payload.ts b/tests/integration/queries/languages/list-languages-query.payload.ts new file mode 100644 index 00000000..83647f83 --- /dev/null +++ b/tests/integration/queries/languages/list-languages-query.payload.ts @@ -0,0 +1,20 @@ +import type { ListLanguagesPayload } from "../../../../lib/queries/languages/models/language.models.js"; +import type { IntegrationTestProjectSchema } from "../../models/integration-test.schema.js"; + +export default { + languages: [ + { + system: { + id: "00000000-0000-0000-0000-000000000000", + name: "Default project language", + codename: "default", + }, + }, + ], + pagination: { + skip: 0, + limit: 0, + count: 1, + next_page: "", + }, +} satisfies ListLanguagesPayload; diff --git a/tests/integration/queries/languages/list-languages-query.spec.ts b/tests/integration/queries/languages/list-languages-query.spec.ts new file mode 100644 index 00000000..dce2baad --- /dev/null +++ b/tests/integration/queries/languages/list-languages-query.spec.ts @@ -0,0 +1,15 @@ +import { describe } from "vitest"; +import type { DeliveryClientSchema } from "../../../../lib/models/core.models.js"; +import type { ListLanguagesPayload } from "../../../../lib/queries/languages/models/language.models.js"; +import { listLanguagesSchema } from "../../../../lib/queries/languages/schemas/language.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./list-languages-query.payload.js"; + +describe("List languages query", async () => { + await runQueryTestsAsync>({ + endpoint: "languages", + rawPayload, + selectQuery: (client) => client.listLanguages(), + expectedSchema: listLanguagesSchema(), + }); +}); diff --git a/tests/integration/queries/taxonomies/fetch-taxonomy-query.payload.ts b/tests/integration/queries/taxonomies/fetch-taxonomy-query.payload.ts new file mode 100644 index 00000000..c10c0fa7 --- /dev/null +++ b/tests/integration/queries/taxonomies/fetch-taxonomy-query.payload.ts @@ -0,0 +1,39 @@ +import type { TaxonomyPayload } from "../../../../lib/queries/taxonomies/models/taxonomy.models.js"; +import type { IntegrationTestProjectSchema, MovieTaxonomyTerms } from "../../models/integration-test.schema.js"; + +export default { + system: { + id: "b7f516a3-36b9-4108-919f-ed83ea91926e", + name: "Movie type", + codename: "movie_type", + last_modified: "2026-02-26T10:12:41.5176081Z", + }, + terms: [ + { + name: "Drama", + codename: "drama", + terms: [], + }, + { + name: "Comedy", + codename: "comedy", + terms: [ + { + name: "Sitcom", + codename: "sitcom", + terms: [], + }, + { + name: "Stand-up", + codename: "stand_up", + terms: [], + }, + ], + }, + { + name: "Action", + codename: "action", + terms: [], + }, + ], +} satisfies TaxonomyPayload; diff --git a/tests/integration/queries/taxonomies/fetch-taxonomy-query.spec.ts b/tests/integration/queries/taxonomies/fetch-taxonomy-query.spec.ts new file mode 100644 index 00000000..84a1d3ed --- /dev/null +++ b/tests/integration/queries/taxonomies/fetch-taxonomy-query.spec.ts @@ -0,0 +1,16 @@ +import { describe } from "vitest"; +import type { DeliveryClientSchema } from "../../../../lib/models/core.models.js"; +import type { TaxonomyPayload } from "../../../../lib/queries/taxonomies/models/taxonomy.models.js"; +import { taxonomySchema } from "../../../../lib/queries/taxonomies/schemas/taxonomy.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./fetch-taxonomy-query.payload.js"; + +describe("Fetch taxonomy query", async () => { + const codename = "movie_type"; + await runQueryTestsAsync>({ + endpoint: `taxonomies/${codename}`, + rawPayload, + selectQuery: (client) => client.fetchTaxonomy({ codename: codename }), + expectedSchema: taxonomySchema(), + }); +}); diff --git a/tests/integration/queries/taxonomies/list-taxonomies-query.payload.ts b/tests/integration/queries/taxonomies/list-taxonomies-query.payload.ts new file mode 100644 index 00000000..42e3d8f6 --- /dev/null +++ b/tests/integration/queries/taxonomies/list-taxonomies-query.payload.ts @@ -0,0 +1,49 @@ +import type { ListTaxonomiesPayload } from "../../../../lib/queries/taxonomies/models/taxonomy.models.js"; +import type { IntegrationTestProjectSchema, MovieTaxonomyTerms } from "../../models/integration-test.schema.js"; + +export default { + taxonomies: [ + { + system: { + id: "b7f516a3-36b9-4108-919f-ed83ea91926e", + name: "Movie type", + codename: "movie_type", + last_modified: "2026-02-26T10:12:21.5095299Z", + }, + terms: [ + { + name: "Drama", + codename: "drama", + terms: [], + }, + { + name: "Comedy", + codename: "comedy", + terms: [ + { + name: "Sitcom", + codename: "sitcom", + terms: [], + }, + { + name: "Stand-up", + codename: "stand_up", + terms: [], + }, + ], + }, + { + name: "Action", + codename: "action", + terms: [], + }, + ], + }, + ], + pagination: { + skip: 0, + limit: 0, + count: 1, + next_page: "", + }, +} satisfies ListTaxonomiesPayload; diff --git a/tests/integration/queries/taxonomies/list-taxonomies-query.spec.ts b/tests/integration/queries/taxonomies/list-taxonomies-query.spec.ts new file mode 100644 index 00000000..33790676 --- /dev/null +++ b/tests/integration/queries/taxonomies/list-taxonomies-query.spec.ts @@ -0,0 +1,15 @@ +import { describe } from "vitest"; +import type { DeliveryClientSchema } from "../../../../lib/models/core.models.js"; +import type { ListTaxonomiesPayload } from "../../../../lib/queries/taxonomies/models/taxonomy.models.js"; +import { listTaxonomiesSchema } from "../../../../lib/queries/taxonomies/schemas/taxonomy.schemas.js"; +import { runQueryTestsAsync } from "../../../utils/integration-test.utils.js"; +import rawPayload from "./list-taxonomies-query.payload.js"; + +describe("List taxonomies query", async () => { + await runQueryTestsAsync>({ + endpoint: "taxonomies", + rawPayload, + selectQuery: (client) => client.listTaxonomies(), + expectedSchema: listTaxonomiesSchema(), + }); +}); diff --git a/tests/unit/api-mode/custom-base-url-api.spec.ts b/tests/unit/api-mode/custom-base-url-api.spec.ts new file mode 100644 index 00000000..a1afa283 --- /dev/null +++ b/tests/unit/api-mode/custom-base-url-api.spec.ts @@ -0,0 +1,30 @@ +import type { BaseUrl } from "@kontent-ai/core-sdk"; +import { getTestHttpServiceWithJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { describe, expect, it } from "vitest"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Custom base URL API", async () => { + const customBaseUrl: BaseUrl = { protocol: "https", host: "domain.com" }; + + const query = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: {}, + statusCode: 200, + }), + runtimeValidation: { + validateResponses: false, + }, + baseUrl: customBaseUrl, + }).listLanguages(); + + // execute query so that http service is called and request headers are captured + const { response } = await query.fetchPageSafe(); + + it("uses the custom base URL", () => { + const { origin } = new URL(response?.meta?.url ?? "n/a"); + expect(origin).toEqual(`${customBaseUrl.protocol}://${customBaseUrl.host}`); + }); +}); diff --git a/tests/unit/api-mode/deliver-api.spec.ts b/tests/unit/api-mode/deliver-api.spec.ts new file mode 100644 index 00000000..cace86e2 --- /dev/null +++ b/tests/unit/api-mode/deliver-api.spec.ts @@ -0,0 +1,54 @@ +import { getDefaultHttpAdapter, getDefaultHttpService, type Header, type KnownHeaderName } from "@kontent-ai/core-sdk"; +import { mockGlobalFetchJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Public deliver API", async () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + mockGlobalFetchJsonResponse({ + jsonResponse: {}, + statusCode: 200, + continuationToken: "x", + }); + + let requestHeaders: readonly Header[] = []; + + const query = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: false, + }, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: async (options) => { + requestHeaders = options.requestHeaders ?? []; + + return await getDefaultHttpAdapter().executeRequest(options); + }, + }, + }), + }).listLanguages(); + + // execute query so that http service is called and request headers are captured + const { success, error, response } = await query.fetchPageSafe(); + + it("returns a successful response", () => { + expect(success).toBeTruthy(); + expect(error).toBeUndefined(); + }); + + it("does not include an authorization header", () => { + const authorizationHeader = requestHeaders.find((header) => header.name === ("Authorization" satisfies KnownHeaderName)); + expect(authorizationHeader).toBeUndefined(); + }); + + it("uses the public deliver API URL", () => { + const { host } = new URL(response?.meta?.url ?? "n/a"); + expect(host).toEqual("deliver.kontent.ai"); + }); +}); diff --git a/tests/unit/api-mode/preview-api.spec.ts b/tests/unit/api-mode/preview-api.spec.ts new file mode 100644 index 00000000..ead46530 --- /dev/null +++ b/tests/unit/api-mode/preview-api.spec.ts @@ -0,0 +1,56 @@ +import { getDefaultHttpAdapter, getDefaultHttpService, type Header, type KnownHeaderName } from "@kontent-ai/core-sdk"; +import { mockGlobalFetchJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Preview API", async () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + mockGlobalFetchJsonResponse({ + jsonResponse: {}, + statusCode: 200, + continuationToken: "x", + }); + + let requestHeaders: readonly Header[] = []; + const previewApiKey = "y"; + + const query = createDeliveryClient({ + apiMode: "preview", + environmentId: unitEnvironmentId, + deliveryApiKey: previewApiKey, + runtimeValidation: { + validateResponses: false, + }, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: async (options) => { + requestHeaders = options.requestHeaders ?? []; + + return await getDefaultHttpAdapter().executeRequest(options); + }, + }, + }), + }).listLanguages(); + + // execute query so that http service is called and request headers are captured + const { success, error, response } = await query.fetchPageSafe(); + + it("returns a successful response", () => { + expect(success).toBeTruthy(); + expect(error).toBeUndefined(); + }); + + it("includes an authorization header with the delivery API key", () => { + const authorizationHeader = requestHeaders.find((header) => header.name === ("Authorization" satisfies KnownHeaderName)); + expect(authorizationHeader?.value).toEqual(`Bearer ${previewApiKey}`); + }); + + it("uses the preview API URL", () => { + const { host } = new URL(response?.meta?.url ?? "n/a"); + expect(host).toEqual("preview-deliver.kontent.ai"); + }); +}); diff --git a/tests/unit/api-mode/secure-api.spec.ts b/tests/unit/api-mode/secure-api.spec.ts new file mode 100644 index 00000000..21d20b18 --- /dev/null +++ b/tests/unit/api-mode/secure-api.spec.ts @@ -0,0 +1,55 @@ +import { getDefaultHttpAdapter, getDefaultHttpService, type Header, type KnownHeaderName } from "@kontent-ai/core-sdk"; +import { mockGlobalFetchJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Secure API", async () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + mockGlobalFetchJsonResponse({ + jsonResponse: {}, + statusCode: 200, + continuationToken: "x", + }); + + let requestHeaders: readonly Header[] = []; + const secureApiKey = "y"; + + const query = createDeliveryClient({ + apiMode: "secure", + environmentId: unitEnvironmentId, + deliveryApiKey: secureApiKey, + runtimeValidation: { + validateResponses: false, + }, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: async (options) => { + requestHeaders = options.requestHeaders ?? []; + + return await getDefaultHttpAdapter().executeRequest(options); + }, + }, + }), + }).listLanguages(); + + // execute query so that http service is called and request headers are captured + const { error, response } = await query.fetchPageSafe(); + + it("returns a successful response", () => { + expect(error).toBeUndefined(); + }); + + it("includes an authorization header with the secure API key", () => { + const authorizationHeader = requestHeaders.find((header) => header.name === ("Authorization" satisfies KnownHeaderName)); + expect(authorizationHeader?.value).toEqual(`Bearer ${secureApiKey}`); + }); + + it("uses the secure API URL", () => { + const { host } = new URL(response?.meta?.url ?? "n/a"); + expect(host).toEqual("deliver.kontent.ai"); + }); +}); diff --git a/tests/unit/bundle/bundle-size.spec.ts b/tests/unit/bundle/bundle-size.spec.ts new file mode 100644 index 00000000..cf434663 --- /dev/null +++ b/tests/unit/bundle/bundle-size.spec.ts @@ -0,0 +1,22 @@ +import { fileURLToPath } from "node:url"; +import { describe, expect, it } from "vitest"; +import { formatBytes, measureScenarios, scenarios } from "../../../scripts/utils/measure-bundle-utils.js"; + +const repoRoot = fileURLToPath(new URL("../../../", import.meta.url)); + +describe("bundle size", () => { + const resultsPromise = measureScenarios(scenarios, { resolveDir: repoRoot }); + + for (const scenario of scenarios) { + it(`${scenario.name} stays under ${scenario.thresholdKb} kB gzipped`, async () => { + const results = await resultsPromise; + const result = results.find((r) => r.scenario === scenario.name); + expect(result, `missing measurement for ${scenario.name}`).toBeDefined(); + const limitBytes = scenario.thresholdKb * 1024; + expect( + result?.gzip, + `${scenario.name} is ${formatBytes(result?.gzip ?? 0)} gzipped, limit is ${formatBytes(limitBytes)}`, + ).toBeLessThanOrEqual(limitBytes); + }); + } +}); diff --git a/tests/unit/delivery-query/create-delivery-fetch-query.spec.ts b/tests/unit/delivery-query/create-delivery-fetch-query.spec.ts new file mode 100644 index 00000000..9dfa6083 --- /dev/null +++ b/tests/unit/delivery-query/create-delivery-fetch-query.spec.ts @@ -0,0 +1,89 @@ +import type { JsonValue } from "@kontent-ai/core-sdk"; +import { describe, expect, it } from "vitest"; +import type { ZodMiniType } from "zod/mini"; +import * as z from "zod/mini"; +import type { DeliveryClientConfig } from "../../../lib/models/core.models.js"; +import type { Filter } from "../../../lib/models/filter.models.js"; +import type { DeliveryRequest } from "../../../lib/models/request.models.js"; +import { createDeliveryFetchQuery } from "../../../lib/queries/delivery-queries.js"; +import { getDeliveryUrl } from "../../../lib/utils/url.utils.js"; +import { isFetchQueryWithExpectedFunctions, unitEnvironmentId } from "../../utils/test.utils.js"; + +const clientConfig: DeliveryClientConfig = { + apiMode: "public", + environmentId: unitEnvironmentId, +}; + +const testSchema: () => Promise> = async () => z.object({}); + +describe("createDeliveryFetchQuery", () => { + it("returns a query with FetchQuery shape", () => { + const query = createDeliveryFetchQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items/my_item", + }); + expect(isFetchQueryWithExpectedFunctions(query)).toBeTruthy(); + }); + + it("resolves to the delivery URL for the configured endpoint", () => { + const endpoint = "items/my_item"; + const { inspect } = createDeliveryFetchQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint, + }); + expect(inspect().data?.url?.toString()).toEqual(new URL(getDeliveryUrl({ ...clientConfig, path: endpoint })).toString()); + }); + + it("has no query string when request is undefined", () => { + const { inspect } = createDeliveryFetchQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items/my_item", + }); + expect(inspect().data?.url?.toString()).not.toContain("?"); + }); + + it("has no query string when request has neither query nor filters", () => { + const { inspect } = createDeliveryFetchQuery({ + config: clientConfig, + request: {}, + schema: testSchema, + endpoint: "items/my_item", + }); + expect(inspect().data?.url?.toString()).not.toContain("?"); + }); + + it("includes query parameters when request.query is provided", () => { + const request: DeliveryRequest<{ readonly language: string; readonly depth: number }, never> = { + query: { language: "en-us", depth: 2 }, + }; + const { inspect } = createDeliveryFetchQuery({ + config: clientConfig, + request, + schema: testSchema, + endpoint: "items/my_item", + }); + + const url = inspect().data?.url; + expect(url?.searchParams.get("language")).toBe(request.query?.language); + expect(url?.searchParams.get("depth")).toBe(request.query?.depth.toString()); + }); + + it("includes filters when request.filters is provided", () => { + const request: DeliveryRequest[]> = { + filters: [{ property: "system.type", operator: "eq", value: "article" }], + }; + const { inspect } = createDeliveryFetchQuery({ + config: clientConfig, + request, + schema: testSchema, + endpoint: "items/my_item", + }); + expect(inspect().data?.url?.toString()).toContain(new URLSearchParams("system.type[eq]=article").toString()); + }); +}); diff --git a/tests/unit/delivery-query/create-delivery-paged-by-token-query.spec.ts b/tests/unit/delivery-query/create-delivery-paged-by-token-query.spec.ts new file mode 100644 index 00000000..ba6d3ac8 --- /dev/null +++ b/tests/unit/delivery-query/create-delivery-paged-by-token-query.spec.ts @@ -0,0 +1,189 @@ +import type { JsonValue } from "@kontent-ai/core-sdk"; +import { mockGlobalFetchJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import type { ZodMiniType } from "zod/mini"; +import * as z from "zod/mini"; +import type { DeliveryClientConfig } from "../../../lib/models/core.models.js"; +import type { Filter } from "../../../lib/models/filter.models.js"; +import type { DeliveryRequest } from "../../../lib/models/request.models.js"; +import { createDeliveryPagedByTokenQuery } from "../../../lib/queries/delivery-queries.js"; +import { getDeliveryUrl } from "../../../lib/utils/url.utils.js"; +import { isPagedFetchQueryWithExpectedFunctions, unitEnvironmentId } from "../../utils/test.utils.js"; + +const clientConfig: DeliveryClientConfig = { + apiMode: "public", + environmentId: unitEnvironmentId, +}; + +const testSchema: () => Promise> = async () => z.object({}); + +describe("createDeliveryPagedByTokenQuery", () => { + it("returns a query with PagedFetchQuery shape", () => { + const query = createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }); + expect(isPagedFetchQueryWithExpectedFunctions(query)).toBeTruthy(); + }); + + it("resolves to the delivery URL for the configured endpoint", () => { + const endpoint = "items-feed" as const; + const { inspect } = createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint, + }); + expect(inspect().data?.url?.toString()).toEqual(new URL(getDeliveryUrl({ ...clientConfig, path: endpoint })).toString()); + }); + + it("has no query string when request is undefined", () => { + const { inspect } = createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }); + expect(inspect().data?.url.toString()).not.toContain("?"); + }); + + it("has no query string when request has neither query nor filters", () => { + const request: DeliveryRequest = {}; + const { inspect } = createDeliveryPagedByTokenQuery({ + config: clientConfig, + request, + schema: testSchema, + endpoint: "items-feed", + }); + expect(inspect().data?.url.toString()).not.toContain("?"); + }); + + it("includes query parameters when request.query is provided", () => { + const request: DeliveryRequest<{ readonly language: string }, never> = { + query: { language: "en-us" }, + }; + const { inspect } = createDeliveryPagedByTokenQuery({ + config: clientConfig, + request, + schema: testSchema, + endpoint: "items-feed", + }); + expect(inspect().data?.url?.searchParams.get("language")).toBe("en-us"); + }); + + it("includes filters when request.filters is provided", () => { + const request: DeliveryRequest[]> = { + filters: [{ property: "system.type", operator: "eq", value: "blog" }], + }; + const { inspect } = createDeliveryPagedByTokenQuery({ + config: clientConfig, + request, + schema: testSchema, + endpoint: "items-feed", + }); + expect(inspect().data?.url?.toString()).toContain(new URLSearchParams("system.type[eq]=blog").toString()); + }); +}); + +describe("createDeliveryPagedByTokenQuery — continuationToken in meta", () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + it("meta.continuationToken equals the X-Continuation response header value", async () => { + const token = "abc-continuation-token"; + mockGlobalFetchJsonResponse({ jsonResponse: {}, statusCode: 200, continuationToken: token }); + + const { response } = await createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }).fetchPageSafe(); + + expect(response?.meta.continuationToken).toBe(token); + }); + + it("meta.continuationToken is undefined when the X-Continuation response header is absent", async () => { + mockGlobalFetchJsonResponse({ jsonResponse: {}, statusCode: 200 }); + + const { response } = await createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }).fetchPageSafe(); + + expect(response?.meta.continuationToken).toBeUndefined(); + }); +}); + +describe("createDeliveryPagedByTokenQuery — nextContinuationToken in fetchAllPagesSafe result", () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + it("nextContinuationToken equals the X-Continuation token of the last fetched page", async () => { + const token = "last-page-token"; + mockGlobalFetchJsonResponse({ jsonResponse: {}, statusCode: 200, continuationToken: token }); + + const { success, nextContinuationToken } = await createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }).fetchAllPagesSafe({ maxPagesCount: 1 }); + + expect(success).toBeTruthy(); + expect(nextContinuationToken).toBe(token); + }); + + it("nextContinuationToken is undefined when the last page has no X-Continuation header", async () => { + mockGlobalFetchJsonResponse({ jsonResponse: {}, statusCode: 200 }); + + const { success, nextContinuationToken } = await createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }).fetchAllPagesSafe(); + + expect(success).toBeTruthy(); + expect(nextContinuationToken).toBeUndefined(); + }); +}); + +describe("createDeliveryPagedByTokenQuery — nextContinuationToken in fetchAllPages result", () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + it("nextContinuationToken equals the X-Continuation token of the last fetched page", async () => { + const token = "last-page-token"; + mockGlobalFetchJsonResponse({ jsonResponse: {}, statusCode: 200, continuationToken: token }); + + const { nextContinuationToken } = await createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }).fetchAllPages({ maxPagesCount: 1 }); + + expect(nextContinuationToken).toBe(token); + }); + + it("nextContinuationToken is undefined when the last page has no X-Continuation header", async () => { + mockGlobalFetchJsonResponse({ jsonResponse: {}, statusCode: 200 }); + + const { nextContinuationToken } = await createDeliveryPagedByTokenQuery({ + config: clientConfig, + request: undefined, + schema: testSchema, + endpoint: "items-feed", + }).fetchAllPages(); + + expect(nextContinuationToken).toBeUndefined(); + }); +}); diff --git a/tests/unit/delivery-query/create-delivery-paged-by-url-query.spec.ts b/tests/unit/delivery-query/create-delivery-paged-by-url-query.spec.ts new file mode 100644 index 00000000..9bbbd2aa --- /dev/null +++ b/tests/unit/delivery-query/create-delivery-paged-by-url-query.spec.ts @@ -0,0 +1,146 @@ +import { mockGlobalFetchJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import type { DeliveryClientConfig } from "../../../lib/models/core.models.js"; +import type { Filter } from "../../../lib/models/filter.models.js"; +import { paginationSchema } from "../../../lib/models/pagination.schemas.js"; +import type { DeliveryRequest } from "../../../lib/models/request.models.js"; +import { createDeliveryPagedByUrlQuery } from "../../../lib/queries/delivery-queries.js"; +import { getDeliveryUrl } from "../../../lib/utils/url.utils.js"; +import { isPagedFetchQueryWithExpectedFunctions, unitEnvironmentId } from "../../utils/test.utils.js"; + +const clientConfig: DeliveryClientConfig = { + apiMode: "public", + environmentId: unitEnvironmentId, +}; + +const paginationPayload = (nextPageUrl: string) => ({ + pagination: { skip: 0, limit: 10, count: 100, next_page: nextPageUrl }, +}); + +describe("createDeliveryPagedByUrlQuery", () => { + it("returns a query with PagedFetchQuery shape", () => { + const query = createDeliveryPagedByUrlQuery({ + config: clientConfig, + request: undefined, + schema: async () => paginationSchema, + endpoint: "items", + }); + expect(isPagedFetchQueryWithExpectedFunctions(query)).toBeTruthy(); + }); + + it("resolves to the delivery URL for the configured endpoint", () => { + const endpoint = "items" as const; + const { inspect } = createDeliveryPagedByUrlQuery({ + config: clientConfig, + request: undefined, + schema: async () => paginationSchema, + endpoint, + }); + expect(inspect().data?.url?.toString()).toEqual(new URL(getDeliveryUrl({ ...clientConfig, path: endpoint })).toString()); + }); + + it("has no query string when request is undefined", () => { + const { inspect } = createDeliveryPagedByUrlQuery({ + config: clientConfig, + request: undefined, + schema: async () => paginationSchema, + endpoint: "items", + }); + expect(inspect().data?.url?.toString()).not.toContain("?"); + }); + + it("has no query string when request has neither query nor filters", () => { + const request: DeliveryRequest = {}; + const { inspect } = createDeliveryPagedByUrlQuery({ + config: clientConfig, + request, + schema: async () => paginationSchema, + endpoint: "items", + }); + expect(inspect().data?.url?.toString()).not.toContain("?"); + }); + + it("includes query parameters when request.query is provided", () => { + const request: DeliveryRequest<{ readonly skip: number; readonly limit: number }, never> = { + query: { skip: 10, limit: 5 }, + }; + const { inspect } = createDeliveryPagedByUrlQuery({ + config: clientConfig, + request, + schema: async () => paginationSchema, + endpoint: "items", + }); + + const url = inspect().data?.url; + expect(url?.searchParams.get("skip")).toBe("10"); + expect(url?.searchParams.get("limit")).toBe("5"); + }); + + it("includes filters when request.filters is provided", () => { + const request: DeliveryRequest[]> = { + filters: [{ property: "system.type", operator: "eq", value: "movie" }], + }; + const { inspect } = createDeliveryPagedByUrlQuery({ + config: clientConfig, + request, + schema: async () => paginationSchema, + endpoint: "items", + }); + expect(inspect().data?.url?.toString()).toContain(new URLSearchParams("system.type[eq]=movie").toString()); + }); +}); + +describe("createDeliveryPagedByUrlQuery — nextPageUrl in fetchAllPagesSafe result", () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + it("nextPageUrl equals the next_page value of the last fetched page", async () => { + const expectedUrl = "https://deliver.kontent.ai/next-page"; + mockGlobalFetchJsonResponse({ jsonResponse: paginationPayload(expectedUrl), statusCode: 200 }); + + const { success, nextPageUrl } = await createDeliveryPagedByUrlQuery({ + config: clientConfig, + request: undefined, + schema: async () => paginationSchema, + endpoint: "items", + }).fetchAllPagesSafe({ maxPagesCount: 1 }); + + expect(success).toBeTruthy(); + expect(nextPageUrl).toBe(expectedUrl); + }); + + it("nextPageUrl is an empty string when the last page has no next page", async () => { + mockGlobalFetchJsonResponse({ jsonResponse: paginationPayload(""), statusCode: 200 }); + + const { success, nextPageUrl } = await createDeliveryPagedByUrlQuery({ + config: clientConfig, + request: undefined, + schema: async () => paginationSchema, + endpoint: "items", + }).fetchAllPagesSafe(); + + expect(success).toBeTruthy(); + expect(nextPageUrl).toBe(""); + }); +}); + +describe("createDeliveryPagedByUrlQuery — nextPageUrl in fetchAllPages result", () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + it("nextPageUrl equals the next_page value of the last fetched page", async () => { + const expectedUrl = "https://deliver.kontent.ai/next-page"; + mockGlobalFetchJsonResponse({ jsonResponse: paginationPayload(expectedUrl), statusCode: 200 }); + + const { nextPageUrl } = await createDeliveryPagedByUrlQuery({ + config: clientConfig, + request: undefined, + schema: async () => paginationSchema, + endpoint: "items", + }).fetchAllPages({ maxPagesCount: 1 }); + + expect(nextPageUrl).toBe(expectedUrl); + }); +}); diff --git a/tests/unit/errors/custom-errors.spec.ts b/tests/unit/errors/custom-errors.spec.ts new file mode 100644 index 00000000..fbf1ca44 --- /dev/null +++ b/tests/unit/errors/custom-errors.spec.ts @@ -0,0 +1,38 @@ +import { type ErrorReason, getDefaultHttpService } from "@kontent-ai/core-sdk"; +import { describe, expect, it } from "vitest"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +class CustomError extends Error {} + +describe("Custom Error Handling", async () => { + const { success, error } = await createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: () => { + throw new CustomError(); + }, + }, + }), + }) + .listLanguages() + .fetchPageSafe(); + + it("returns a failed response", () => { + expect(success).toBe(false); + }); + + it("sets the error reason to adapterError", () => { + expect(error?.details.reason).toBe("adapterError"); + }); + + it("propagates the original error as a CustomError instance", () => { + if (error?.details.reason === "adapterError") { + expect(error.details.originalError).toBeInstanceOf(CustomError); + } else { + throw new Error("Error should be unknown"); + } + }); +}); diff --git a/tests/unit/errors/delivery-sdk-error.spec.ts b/tests/unit/errors/delivery-sdk-error.spec.ts new file mode 100644 index 00000000..e3a8c2d1 --- /dev/null +++ b/tests/unit/errors/delivery-sdk-error.spec.ts @@ -0,0 +1,25 @@ +import { getDefaultHttpService } from "@kontent-ai/core-sdk"; +import { describe, expect, it } from "vitest"; +import { DeliverySdkError } from "../../../lib/models/error.models.js"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("DeliverySdkError", async () => { + const { error } = await createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: () => { + throw new Error("Simulated failure"); + }, + }, + }), + }) + .listLanguages() + .fetchPageSafe(); + + it("returns a DeliverySdkError on failure", () => { + expect(error).toBeInstanceOf(DeliverySdkError); + }); +}); diff --git a/tests/unit/filters/filters.spec.ts b/tests/unit/filters/filters.spec.ts new file mode 100644 index 00000000..6a4aefa7 --- /dev/null +++ b/tests/unit/filters/filters.spec.ts @@ -0,0 +1,126 @@ +import { describe, expect, it } from "vitest"; +import { createDeliveryClient } from "../../../lib/client/delivery-client.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Filters", () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + }); + + it("adds an object filter to the URL", () => { + const { data } = client + .listContentItems({ + filters: [ + { + property: "system.language", + operator: "eq", + value: "default", + }, + ], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("system.language[eq]=default").toString()); + }); + + it("adds a string filter to the URL", () => { + const { data } = client + .listContentItems({ + filters: ["system.language[eq]=default"], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("system.language[eq]=default").toString()); + }); + + it("handles multiple equal signs in the filter value", () => { + const { data } = client + .listContentItems({ + filters: ["system.codename[eq]=abc=def"], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("system.codename[eq]=abc=def").toString()); + }); + + it("handles the '=' operator", () => { + const { data } = client + .listContentItems({ + filters: [ + { + property: "system.language", + operator: "=", + value: "default", + }, + ], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("system.language=default").toString()); + }); + + it("handles the '!=' operator", () => { + const { data } = client + .listContentItems({ + filters: [ + { + property: "system.language", + operator: "!=", + value: "default", + }, + ], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("system.language[neq]=default").toString()); + }); + + it("adds [eq]=


for isEmptyRichText operator", () => { + const { data } = client + .listContentItems({ + filters: [ + { + property: "elements.description", + operator: "isEmptyRichText", + }, + ], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("elements.description[eq]=


").toString()); + }); + + it("adds [neq]=


for isNotEmptyRichText operator", () => { + const { data } = client + .listContentItems({ + filters: [ + { + property: "elements.description", + operator: "isNotEmptyRichText", + }, + ], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("elements.description[neq]=


").toString()); + }); + + it("adds both object and string filters to the URL", () => { + const { data } = client + .listContentItems({ + filters: [ + { + property: "system.language", + operator: "eq", + value: "default", + }, + "system.type[eq]=movie", + ], + }) + .inspect(); + + expect(data?.url.toString()).toContain(new URLSearchParams("system.language[eq]=default").toString()); + expect(data?.url.toString()).toContain(new URLSearchParams("system.type[eq]=movie").toString()); + }); +}); diff --git a/tests/unit/headers/headers.spec.ts b/tests/unit/headers/headers.spec.ts new file mode 100644 index 00000000..ce356c53 --- /dev/null +++ b/tests/unit/headers/headers.spec.ts @@ -0,0 +1,120 @@ +import { + type ContinuationTokenHeaderName, + createSdkIdHeader, + getDefaultHttpAdapter, + getDefaultHttpService, + type Header, +} from "@kontent-ai/core-sdk"; +import { mockGlobalFetchJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { createDeliveryClient } from "../../../lib/client/delivery-client.js"; +import type { DeliveryClientSchema, WaitForLoadingNewContentHeaderName } from "../../../lib/models/core.models.js"; +import type { ItemsFeedQueryRequest } from "../../../lib/queries/content-items/items-feed-query.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +async function captureRequestHeaders(listConfig?: ItemsFeedQueryRequest): Promise { + let captured: readonly Header[] = []; + + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: async (options) => { + captured = options.requestHeaders ?? []; + return await getDefaultHttpAdapter().executeRequest(options); + }, + }, + }), + }); + + await client.itemsFeed(listConfig).fetchPageSafe(); + + return captured; +} + +describe("Delivery tracking header", async () => { + const expectedHeader = createSdkIdHeader({ + name: "@kontent-ai/delivery-sdk", + version: "{{version}}", + host: "npmjs.com", + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + mockGlobalFetchJsonResponse({ + jsonResponse: {}, + statusCode: 200, + continuationToken: "x", + }); + + const requestHeaders = await captureRequestHeaders(); + + it("includes the delivery tracking header with current package info", () => { + const syncTrackingHeader = requestHeaders.find((header) => header.name === expectedHeader.name); + expect(syncTrackingHeader?.value).toEqual(expectedHeader.value); + }); +}); + +describe("Bypass CDN Cache Header", async () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + mockGlobalFetchJsonResponse({ + jsonResponse: {}, + statusCode: 200, + continuationToken: "x", + }); + + const requestHeaders = await captureRequestHeaders(); + + it("is absent by default", () => { + const bypassCdnCacheHeader = requestHeaders.find( + (header) => header.name === ("X-KC-Wait-For-Loading-New-Content" satisfies WaitForLoadingNewContentHeaderName), + ); + expect(bypassCdnCacheHeader).toBeUndefined(); + }); +}); + +describe("Extra Request Headers", async () => { + const extraHeader: Header = { name: "X-Extra-Header", value: "extra" }; + + afterEach(() => { + vi.resetAllMocks(); + }); + + mockGlobalFetchJsonResponse({ + jsonResponse: {}, + statusCode: 200, + continuationToken: "x", + }); + + const requestHeaders = await captureRequestHeaders({ config: { customHeaders: [extraHeader] } }); + + it("are forwarded from the request config", () => { + const foundHeader = requestHeaders.find((header) => header.name === extraHeader.name); + expect(foundHeader?.value).toEqual(extraHeader.value); + }); +}); + +describe("Continuation Token Header — when provided in the request", async () => { + const continuationTokenValue = "x"; + const requestHeaders = await captureRequestHeaders({ headers: { "X-Continuation": continuationTokenValue } }); + + it("is sent to the API", () => { + const foundHeader = requestHeaders.find((header) => header.name === ("X-Continuation" satisfies ContinuationTokenHeaderName)); + expect(foundHeader?.value).toEqual(continuationTokenValue); + }); +}); + +describe("Continuation Token Header — when not provided", async () => { + const requestHeaders = await captureRequestHeaders(); + + it("is not sent to the API", () => { + const foundHeader = requestHeaders.find((header) => header.name === ("X-Continuation" satisfies ContinuationTokenHeaderName)); + expect(foundHeader).toBeUndefined(); + }); +}); diff --git a/tests/unit/paging/paging.utils.spec.ts b/tests/unit/paging/paging.utils.spec.ts new file mode 100644 index 00000000..2808941a --- /dev/null +++ b/tests/unit/paging/paging.utils.spec.ts @@ -0,0 +1,31 @@ +import type { QueryResponse } from "@kontent-ai/core-sdk"; +import { describe, expect, it } from "vitest"; +import type { PaginationPayload } from "../../../lib/models/pagination.models.js"; +import { getNextPageByUrl } from "../../../lib/utils/paging.utils.js"; + +describe("Paging Utils", () => { + it("returns the next page URL", () => { + const response: QueryResponse = { + meta: { + status: 200, + responseHeaders: [], + url: new URL("https://domain.com"), + }, + payload: { + pagination: { + skip: 0, + limit: 10, + count: 100, + next_page: "https://domain.com/next", + }, + }, + }; + + const result = getNextPageByUrl()(response); + + expect(result).toEqual({ + continuationToken: undefined, + nextPageUrl: "https://domain.com/next", + }); + }); +}); diff --git a/tests/unit/queries/abort-signal.spec.ts b/tests/unit/queries/abort-signal.spec.ts new file mode 100644 index 00000000..4c04931b --- /dev/null +++ b/tests/unit/queries/abort-signal.spec.ts @@ -0,0 +1,28 @@ +import { AdapterAbortError, type KontentSdkError } from "@kontent-ai/core-sdk"; +import { describe, expect, it } from "vitest"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Query cancellation via abortSignal", () => { + it("rejects the in-flight query when the supplied abortSignal is aborted", async () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: false, + }, + }); + + const controller = new AbortController(); + const pendingQuery = client.listLanguages({ config: { abortSignal: controller.signal } }).fetchPageSafe(); + + controller.abort(); + + const { error } = await pendingQuery; + expect(error?.details.reason).toEqual("aborted"); + + if (error?.details.reason === "aborted") { + expect(error.details.originalError).toBeInstanceOf(AdapterAbortError); + } + }); +}); diff --git a/tests/unit/queries/path-encoding.spec.ts b/tests/unit/queries/path-encoding.spec.ts new file mode 100644 index 00000000..80f9ed00 --- /dev/null +++ b/tests/unit/queries/path-encoding.spec.ts @@ -0,0 +1,81 @@ +import { describe, expect, it } from "vitest"; +import type { DeliveryClientConfig } from "../../../lib/models/core.models.js"; +import { fetchContentItemQuery } from "../../../lib/queries/content-items/fetch-content-item-query.js"; +import { itemsReferencingAssetQuery } from "../../../lib/queries/content-items/items-referencing-asset-query.js"; +import { itemsReferencingItemQuery } from "../../../lib/queries/content-items/items-referencing-item-query.js"; +import { fetchContentTypeElementQuery } from "../../../lib/queries/content-types/fetch-content-type-element-query.js"; +import { fetchContentTypeQuery } from "../../../lib/queries/content-types/fetch-content-type-query.js"; +import { fetchTaxonomyQuery } from "../../../lib/queries/taxonomies/fetch-taxonomy-query.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +const clientConfig: DeliveryClientConfig = { + apiMode: "public", + environmentId: unitEnvironmentId, +}; + +// A codename crafted to break out of its path segment and inject a new query if left unencoded. +const maliciousCodename = "my item/../x?a=1#f"; +const encodedCodename = encodeURIComponent(maliciousCodename); + +describe("URL path segment encoding", () => { + it("encodes the encoded segment so reserved characters are escaped", () => { + // Sanity check on the expectation itself. + expect(encodedCodename).toBe("my%20item%2F..%2Fx%3Fa%3D1%23f"); + expect(encodedCodename).not.toContain("/"); + expect(encodedCodename).not.toContain("?"); + expect(encodedCodename).not.toContain("#"); + }); + + it("encodes the codename in fetchContentItemQuery (items/{codename})", () => { + const url = fetchContentItemQuery(clientConfig, { codename: maliciousCodename }).inspect().data?.url?.toString() ?? ""; + + expect(url).toContain(`/items/${encodedCodename}`); + // The raw codename must not appear as a real path/query break. + expect(url).not.toContain(maliciousCodename); + // No extra segment or query smuggled in. + const { pathname, search } = new URL(url); + expect(pathname.endsWith(`/items/${encodedCodename}`)).toBe(true); + expect(search).toBe(""); + }); + + it("encodes the codename in fetchContentTypeQuery (types/{codename})", () => { + const url = fetchContentTypeQuery(clientConfig, { codename: maliciousCodename }).inspect().data?.url?.toString() ?? ""; + + expect(url).toContain(`/types/${encodedCodename}`); + expect(new URL(url).search).toBe(""); + }); + + it("encodes the codename in fetchTaxonomyQuery (taxonomies/{codename})", () => { + const url = fetchTaxonomyQuery(clientConfig, { codename: maliciousCodename }).inspect().data?.url?.toString() ?? ""; + + expect(url).toContain(`/taxonomies/${encodedCodename}`); + expect(new URL(url).search).toBe(""); + }); + + it("encodes the codename in itemsReferencingItemQuery (items/{codename}/used-in)", () => { + const url = itemsReferencingItemQuery(clientConfig, { codename: maliciousCodename }).inspect().data?.url?.toString() ?? ""; + + expect(url).toContain(`/items/${encodedCodename}/used-in`); + expect(new URL(url).search).toBe(""); + }); + + it("encodes the codename in itemsReferencingAssetQuery (assets/{codename}/used-in)", () => { + const url = itemsReferencingAssetQuery(clientConfig, { codename: maliciousCodename }).inspect().data?.url?.toString() ?? ""; + + expect(url).toContain(`/assets/${encodedCodename}/used-in`); + expect(new URL(url).search).toBe(""); + }); + + it("encodes both segments in fetchContentTypeElementQuery (types/{type}/elements/{element})", () => { + const url = + fetchContentTypeElementQuery(clientConfig, { + typeCodename: maliciousCodename, + elementCodename: maliciousCodename, + }) + .inspect() + .data?.url?.toString() ?? ""; + + expect(url).toContain(`/types/${encodedCodename}/elements/${encodedCodename}`); + expect(new URL(url).search).toBe(""); + }); +}); diff --git a/tests/unit/queries/query-parameters.spec.ts b/tests/unit/queries/query-parameters.spec.ts new file mode 100644 index 00000000..5d584212 --- /dev/null +++ b/tests/unit/queries/query-parameters.spec.ts @@ -0,0 +1,75 @@ +import type { JsonValue } from "@kontent-ai/core-sdk"; +import { describe, expect, it } from "vitest"; +import type { DeliveryMetadata, DeliveryPagedFetchQuery } from "../../../lib/models/core.models.js"; +import { createDeliveryClient } from "../../../lib/public_api.js"; +import { unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Query Parameters", () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + }); + + it("adds paging parameters to the URL", () => { + const listingQueries: readonly DeliveryPagedFetchQuery[] = [ + client.listLanguages({ + query: { + order: "system.name[asc]", + skip: 5, + limit: 10, + }, + }), + client.listTaxonomies({ + query: { + order: "system.name[asc]", + skip: 5, + limit: 10, + }, + }), + client.listContentTypes({ + query: { + order: "system.name[asc]", + skip: 5, + limit: 10, + }, + }), + client.listContentItems({ + query: { + order: "system.name[asc]", + skip: 5, + limit: 10, + depth: 4, + }, + }), + ]; + + for (const { inspect } of listingQueries) { + const { success, data, error } = inspect(); + + if (!success) { + throw new Error(`Failed to inspect query: ${error}`); + } + + const { url } = data; + expect(url.searchParams.get("skip")).toStrictEqual("5"); + expect(url.searchParams.get("limit")).toStrictEqual("10"); + expect(url.searchParams.get("order")).toStrictEqual("system.name[asc]"); + } + }); + + it("adds the elements parameter as a comma-separated list", () => { + const { inspect } = client.listContentTypes({ + query: { + elements: ["x", "y", "z"], + }, + }); + + const { success, data, error } = inspect(); + + if (!success) { + throw new Error(`Failed to inspect query: ${error}`); + } + + expect(data.url.searchParams.get("elements")).toStrictEqual("x,y,z"); + }); +}); diff --git a/tests/unit/schemas/content-item-schemas.spec.ts b/tests/unit/schemas/content-item-schemas.spec.ts new file mode 100644 index 00000000..d677882b --- /dev/null +++ b/tests/unit/schemas/content-item-schemas.spec.ts @@ -0,0 +1,49 @@ +import { describe, expect, it } from "vitest"; +import type { DeliveryClientSchema } from "../../../lib/models/core.models.js"; +import { contentItemSystemWithCodename } from "../../../lib/queries/content-items/schemas/content-item.schemas.js"; +import { elementDef } from "../../../lib/queries/content-items/schemas/element.schemas.js"; +import { getFakeUuid } from "../../utils/test.utils.js"; + +type TestSchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["default"]; + readonly taxonomies: Record; + readonly contentTypes: { + readonly movie: readonly []; + }; + readonly collectionCodenames: readonly ["default"]; + readonly workflowCodenames: readonly ["default"]; + readonly workflowStepCodenames: readonly ["published"]; +}>; + +describe("contentItemSystemWithCodename", () => { + it("parses a system payload whose type matches the literal codename", () => { + const result = contentItemSystemWithCodename("movie").safeParse({ + id: getFakeUuid(), + name: "The Dark Knight", + codename: "the_dark_knight", + language: "default", + type: "movie", + collection: "default", + last_modified: "2026-05-04T10:30:48.5100633Z", + workflow: "default", + workflow_step: "published", + sitemap_locations: [], + }); + expect(result.success).toBe(true); + }); +}); + +describe("elementDef.richText extended items validator", () => { + it("invokes the custom check and rejects an invalid resolved item", () => { + const result = elementDef.richText().safeParse({ + type: "rich_text", + name: "Description", + value: "

x

", + images: {}, + links: {}, + modular_content: ["some_codename"], + items: [{ not: "a valid extended content item" }], + }); + expect(result.success).toBe(false); + }); +}); diff --git a/tests/unit/transforms/content-item-transform.spec.ts b/tests/unit/transforms/content-item-transform.spec.ts new file mode 100644 index 00000000..4462b2c8 --- /dev/null +++ b/tests/unit/transforms/content-item-transform.spec.ts @@ -0,0 +1,249 @@ +import { describe, expect, it } from "vitest"; +import type { DeliveryClientSchema } from "../../../lib/models/core.models.js"; +import type { ContentItemPayload } from "../../../lib/queries/content-items/models/content-item.models.js"; +import { joinItems, mapToExtendedItem, mapToExtendedModularContent } from "../../../lib/transforms/content-item-transforms.js"; +import { getFakeUuid } from "../../utils/test.utils.js"; + +type TestSchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["default"]; + readonly taxonomies: Record; + readonly contentTypes: { + readonly movie: readonly []; + readonly star: readonly []; + }; + readonly collectionCodenames: readonly ["default"]; + readonly workflowCodenames: readonly ["default"]; + readonly workflowStepCodenames: readonly ["published"]; +}>; + +const createItem = (codename: string, type: "movie" | "star" = "star"): ContentItemPayload => ({ + system: { + id: getFakeUuid(), + name: codename, + codename, + language: "default", + type, + collection: "default", + last_modified: "2026-05-04T10:30:48.5100633Z", + workflow: "default", + workflow_step: "published", + sitemap_locations: [], + }, + elements: { + firstname: { + type: "text", + name: "Firstname", + value: codename, + }, + }, +}); + +const createItemWithReferences = ( + codename: string, + richTextRefs: readonly string[], + linkedItemRefs: readonly string[], +): ContentItemPayload => ({ + system: { + id: getFakeUuid(), + name: codename, + codename, + language: "default", + type: "movie", + collection: "default", + last_modified: "2026-05-04T10:30:48.5100633Z", + workflow: "default", + workflow_step: "published", + sitemap_locations: [], + }, + elements: { + description: { + type: "rich_text", + name: "Description", + value: "

Some rich text

", + images: {}, + links: {}, + modular_content: richTextRefs, + }, + cast: { + type: "modular_content", + name: "Cast", + value: linkedItemRefs, + }, + }, +}); + +describe("mapToExtendedItem", () => { + it("populates rich text and linked items elements with referenced items from allItems", () => { + const christianBale = createItem("christian_bale"); + const garyOldman = createItem("gary_oldman"); + const heathLedger = createItem("heath_ledger"); + + const allItems = { + christian_bale: christianBale, + gary_oldman: garyOldman, + heath_ledger: heathLedger, + }; + + const item = createItemWithReferences("the_dark_knight", ["heath_ledger"], ["christian_bale", "gary_oldman"]); + + const result = mapToExtendedItem({ allItems, item }); + + const richText = result.elements.description; + const linkedItems = result.elements.cast; + + if (richText?.type !== "rich_text") { + throw new Error("Expected rich_text element"); + } + if (linkedItems?.type !== "modular_content") { + throw new Error("Expected modular_content element"); + } + + expect(richText.items).toHaveLength(1); + expect(richText.items[0]).toBe(heathLedger); + + expect(linkedItems.items).toHaveLength(2); + expect(linkedItems.items[0]).toBe(christianBale); + expect(linkedItems.items[1]).toBe(garyOldman); + }); + + it("skips codenames that are not present in allItems", () => { + const christianBale = createItem("christian_bale"); + const allItems = { christian_bale: christianBale }; + + const item = createItemWithReferences("the_dark_knight", ["missing_codename"], ["christian_bale", "another_missing"]); + + const result = mapToExtendedItem({ allItems, item }); + + const richText = result.elements.description; + const linkedItems = result.elements.cast; + + if (richText?.type !== "rich_text" || linkedItems?.type !== "modular_content") { + throw new Error("Unexpected element types"); + } + + expect(richText.items).toHaveLength(0); + expect(linkedItems.items).toHaveLength(1); + expect(linkedItems.items[0]).toBe(christianBale); + }); + + it("leaves non-referencing elements unchanged", () => { + const item = createItem("plain_star"); + const result = mapToExtendedItem({ allItems: {}, item }); + + const firstname = result.elements.firstname; + if (firstname?.type !== "text") { + throw new Error("Expected text element"); + } + expect(firstname.value).toBe("plain_star"); + }); +}); + +describe("mapToExtendedModularContent", () => { + it("maps every record in modularContents and resolves their referenced items", () => { + const christianBale = createItem("christian_bale"); + const garyOldman = createItem("gary_oldman"); + const heathLedger = createItem("heath_ledger"); + + const movieA = createItemWithReferences("movie_a", ["heath_ledger"], ["christian_bale"]); + const movieB = createItemWithReferences("movie_b", ["christian_bale"], ["gary_oldman", "heath_ledger"]); + + const modularContents = { movie_a: movieA, movie_b: movieB }; + const allItems = { + christian_bale: christianBale, + gary_oldman: garyOldman, + heath_ledger: heathLedger, + movie_a: movieA, + movie_b: movieB, + }; + + const result = mapToExtendedModularContent({ allItems, modularContents }); + + expect(Object.keys(result)).toHaveLength(Object.keys(modularContents).length); + expect(Object.keys(result).sort()).toEqual(["movie_a", "movie_b"]); + + const movieARichText = result.movie_a?.elements.description; + const movieALinkedItems = result.movie_a?.elements.cast; + const movieBRichText = result.movie_b?.elements.description; + const movieBLinkedItems = result.movie_b?.elements.cast; + + if (movieARichText?.type !== "rich_text" || movieALinkedItems?.type !== "modular_content") { + throw new Error("movie_a has unexpected element types"); + } + if (movieBRichText?.type !== "rich_text" || movieBLinkedItems?.type !== "modular_content") { + throw new Error("movie_b has unexpected element types"); + } + + expect(movieARichText.items).toEqual([heathLedger]); + expect(movieALinkedItems.items).toEqual([christianBale]); + + expect(movieBRichText.items).toEqual([christianBale]); + expect(movieBLinkedItems.items).toEqual([garyOldman, heathLedger]); + }); + + it("returns an empty record when modularContents is empty", () => { + const result = mapToExtendedModularContent({ allItems: {}, modularContents: {} }); + expect(Object.keys(result)).toHaveLength(0); + }); +}); + +describe("joinItems", () => { + it("joins items and modularContent into a single record keyed by codename, preserving the source size when codenames are unique", () => { + const itemA = createItem("item_a"); + const itemB = createItem("item_b"); + const modularA = createItem("modular_a"); + const modularB = createItem("modular_b"); + + const result = joinItems({ + items: [itemA, itemB], + modularContent: [{ modular_a: modularA, modular_b: modularB }], + }); + + const sourceSize = 2 + Object.keys({ modular_a: modularA, modular_b: modularB }).length; + + expect(Object.keys(result)).toHaveLength(sourceSize); + expect(result.item_a).toBe(itemA); + expect(result.item_b).toBe(itemB); + expect(result.modular_a).toBe(modularA); + expect(result.modular_b).toBe(modularB); + }); + + it("merges multiple modularContent records and items together", () => { + const itemA = createItem("item_a"); + const modularA = createItem("modular_a"); + const modularB = createItem("modular_b"); + + const result = joinItems({ + items: [itemA], + modularContent: [{ modular_a: modularA }, { modular_b: modularB }], + }); + + expect(Object.keys(result)).toHaveLength(3); + expect(result.item_a).toBe(itemA); + expect(result.modular_a).toBe(modularA); + expect(result.modular_b).toBe(modularB); + }); + + it("deduplicates entries with the same codename, so the result is smaller than the source", () => { + const sharedFromItems = createItem("shared"); + const sharedFromModular = createItem("shared"); + const uniqueItem = createItem("unique_item"); + const uniqueModular = createItem("unique_modular"); + + const modularRecord = { shared: sharedFromModular, unique_modular: uniqueModular }; + const items = [sharedFromItems, uniqueItem]; + + const sourceSize = items.length + Object.keys(modularRecord).length; + + const result = joinItems({ + items, + modularContent: [modularRecord], + }); + + expect(Object.keys(result).length).toBeLessThan(sourceSize); + expect(Object.keys(result)).toHaveLength(3); + expect(Object.keys(result).sort()).toEqual(["shared", "unique_item", "unique_modular"]); + expect(result.shared).toBe(sharedFromItems); + expect(result.unique_item).toBe(uniqueItem); + expect(result.unique_modular).toBe(uniqueModular); + }); +}); diff --git a/tests/unit/utils/url-utils.spec.ts b/tests/unit/utils/url-utils.spec.ts new file mode 100644 index 00000000..4fa480d4 --- /dev/null +++ b/tests/unit/utils/url-utils.spec.ts @@ -0,0 +1,79 @@ +import { describe, expect, it } from "vitest"; +import { addQueryParametersToUrl, isEmptyRichTextFilter } from "../../../lib/utils/url.utils.js"; + +describe("addQueryParametersToUrl", () => { + const baseUrl = "https://deliver.kontent.ai/xyz/languages"; + + it("returns URL unchanged when query is undefined", () => { + expect(addQueryParametersToUrl(baseUrl, undefined, undefined)).toStrictEqual(baseUrl); + }); + + it("appends parameters with ? when URL has no existing query string", () => { + const result = addQueryParametersToUrl(baseUrl, { skip: "5" }, undefined); + + expect(result).toStrictEqual(`${baseUrl}?skip=5`); + }); + + it("appends parameters with & when URL already contains a query string", () => { + const urlWithQuery = `${baseUrl}?existing=1`; + const result = addQueryParametersToUrl(urlWithQuery, { skip: "2" }, undefined); + + expect(result).toStrictEqual(`${urlWithQuery}&skip=2`); + }); + + it("converts number values to strings", () => { + const result = addQueryParametersToUrl(baseUrl, { skip: 3, limit: 7 }, undefined); + const params = new URL(result).searchParams; + + expect(params.get("skip")).toStrictEqual("3"); + expect(params.get("limit")).toStrictEqual("7"); + }); + + it("omits undefined query parameter values", () => { + const result = addQueryParametersToUrl(baseUrl, { skip: 1, limit: undefined }, undefined); + const params = new URL(result).searchParams; + + expect(params.get("skip")).toStrictEqual("1"); + expect(params.has("limit")).toBe(false); + }); + + it("omits undefined filter values", () => { + const result = addQueryParametersToUrl(baseUrl, undefined, [{ property: "system.language", operator: "eq", value: undefined }]); + const params = new URL(result).searchParams; + + expect(params.has("system.language")).toBe(false); + }); + + it("omits filter with undefined value", () => { + const result = addQueryParametersToUrl(baseUrl, undefined, [{ property: "system.language", operator: "eq", value: undefined }]); + const params = new URL(result).searchParams; + + expect(params.has("system.language")).toBe(false); + }); +}); + +describe("isEmptyRichTextFilter", () => { + it("returns true for object with isEmptyRichText operator", () => { + expect(isEmptyRichTextFilter({ property: "elements.description", operator: "isEmptyRichText" })).toBe(true); + }); + + it("returns true for object with isNotEmptyRichText operator", () => { + expect(isEmptyRichTextFilter({ property: "elements.description", operator: "isNotEmptyRichText" })).toBe(true); + }); + + it("returns false for object with a different operator", () => { + expect(isEmptyRichTextFilter({ property: "elements.description", operator: "eq", value: "test" })).toBe(false); + }); + + it("returns false for object missing operator", () => { + expect(isEmptyRichTextFilter({ property: "elements.description" })).toBe(false); + }); + + it("returns false for null", () => { + expect(isEmptyRichTextFilter(null)).toBe(false); + }); + + it("returns false for a string", () => { + expect(isEmptyRichTextFilter("elements.description[eq]=test")).toBe(false); + }); +}); diff --git a/tests/unit/validation/response-validation.spec.ts b/tests/unit/validation/response-validation.spec.ts new file mode 100644 index 00000000..f38a7289 --- /dev/null +++ b/tests/unit/validation/response-validation.spec.ts @@ -0,0 +1,214 @@ +import type { ErrorReason } from "@kontent-ai/core-sdk"; +import { getTestHttpServiceWithJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { describe, expect, test } from "vitest"; +import * as z from "zod/mini"; +import { createDeliveryClient } from "../../../lib/client/delivery-client.js"; +import type { DeliveryClientSchema } from "../../../lib/models/core.models.js"; +import type { PaginationPayload } from "../../../lib/public_api.js"; +import type { ListLanguagesPayload } from "../../../lib/queries/languages/models/language.models.js"; +import { getFakeUuid, unitEnvironmentId } from "../../utils/test.utils.js"; + +describe("Response validation", () => { + describe("Codename narrowing", () => { + type TestSchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["en-US", "cs-CZ", "de-DE"]; + readonly taxonomies: Record; + readonly contentTypes: Record; + readonly collectionCodenames: readonly []; + readonly workflowCodenames: readonly []; + readonly workflowStepCodenames: readonly []; + }>; + + const mockPayload: ListLanguagesPayload = { + languages: [ + { + system: { + id: getFakeUuid(), + codename: "de-DE", + name: "German", + }, + }, + ], + pagination: { + skip: 0, + limit: 0, + count: 1, + next_page: "", + }, + }; + + type NarrowSchema = DeliveryClientSchema<{ + readonly languageCodenames: readonly ["en-US", "cs-CZ"]; + readonly taxonomies: Record; + readonly contentTypes: Record; + readonly collectionCodenames: readonly []; + readonly workflowCodenames: readonly []; + readonly workflowStepCodenames: readonly []; + }>; + + test("succeeds when the response contains a codename outside the defined schema (type-only narrowing)", async () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: mockPayload, + statusCode: 200, + }), + }); + + const { success, error } = await client.listLanguages().fetchPageSafe(); + + expect(error).toBeUndefined(); + expect(success).toBeTruthy(); + }); + + test("succeeds when the response contains only codenames within the defined schema", async () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: mockPayload, + statusCode: 200, + }), + }); + + const { success, error } = await client.listLanguages().fetchPageSafe(); + + expect(error).toBeUndefined(); + expect(success).toBeTruthy(); + }); + + test("succeeds when the schema has no codename constraints", async () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: mockPayload, + statusCode: 200, + }), + }); + + const { success, error } = await client.listLanguages().fetchPageSafe(); + + expect(error).toBeUndefined(); + expect(success).toBeTruthy(); + }); + }); + + describe("Extra properties", () => { + const mockPayload: ListLanguagesPayload & { readonly extraProperty: string } = { + languages: [ + { + system: { + id: getFakeUuid(), + codename: "de-DE", + name: "German", + extraSystemProperty: "extra", + } as ListLanguagesPayload["languages"][0]["system"] & { readonly extraSystemProperty: string }, + }, + ], + extraProperty: "extra", + pagination: { + skip: 0, + limit: 0, + count: 1, + next_page: "", + extraPaginationProperty: "extra", + } as PaginationPayload["pagination"] & { readonly extraPaginationProperty: string }, + }; + + test("succeeds when the response includes unrecognised properties", async () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: mockPayload, + statusCode: 200, + }), + }); + + const { success, error } = await client.listLanguages().fetchPageSafe(); + + expect(error).toBeUndefined(); + expect(success).toBeTruthy(); + }); + }); + + describe("Missing required properties", () => { + const mockPayload: Omit, "pagination"> = { + languages: [ + { + system: { + id: getFakeUuid(), + codename: "de-DE", + name: "German", + }, + }, + ], + }; + + test("fails when the response is missing a required property", async () => { + const client = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: mockPayload, + statusCode: 200, + }), + }); + + const { success, error } = await client.listLanguages().fetchPageSafe(); + + expect(error).toBeDefined(); + expect(success).toBeFalsy(); + expect(error?.details.reason).toBe("parsingFailed"); + }); + }); + + describe("Error details", () => { + test("populates url, zodError and response on a parsing failure", async ({ expect }) => { + const query = createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: { + result: "invalidValue", + }, + statusCode: 200, + }), + }).listLanguages(); + + const { success, error } = await query.fetchPageSafe(); + + expect(success).toBe(false); + expect(error).toBeDefined(); + expect(error?.details.reason).toStrictEqual("parsingFailed"); + + if (error?.details.reason === "parsingFailed") { + expect(error.details.url).toStrictEqual(query.inspect().data?.url); + expect(error.details.zodError).toBeInstanceOf(z.core.$ZodError); + expect(error.details.payload).toBeDefined(); + } else { + throw new Error(`Unexpected error reason '${error?.details.reason}'`); + } + }); + }); +}); diff --git a/tests/utils/integration-test.utils.ts b/tests/utils/integration-test.utils.ts new file mode 100644 index 00000000..1b69c948 --- /dev/null +++ b/tests/utils/integration-test.utils.ts @@ -0,0 +1,436 @@ +import { + type BaseUrl, + type FetchQuery, + getDefaultHttpService, + isPagingQuery, + type JsonValue, + type KontentSdkError, + type PagedFetchQuery, +} from "@kontent-ai/core-sdk"; +import { getTestHttpServiceWithJsonResponse } from "@kontent-ai/core-sdk/testkit"; +import { expect, it } from "vitest"; +import type { ZodMiniType } from "zod/mini"; +import type { DeliveryClient, DeliveryClientSchema, DeliveryEndpoint } from "../../lib/models/core.models.js"; +import { DeliverySdkError } from "../../lib/models/error.models.js"; +import { createDeliveryClient } from "../../lib/public_api.js"; +import { getDeliveryUrl } from "../../lib/utils/url.utils.js"; +import { getIntegrationTestConfig } from "../integration-tests.config.js"; +import { isFetchQueryWithExpectedFunctions, isPagedFetchQueryWithExpectedFunctions, unitEnvironmentId } from "./test.utils.js"; + +type TestType = "Integration" | "Unit"; + +type SelectQuery = ( + client: DeliveryClient, +) => FetchQuery | PagedFetchQuery; + +export async function runQueryTestsAsync({ + endpoint, + rawPayload, + selectQuery, + expectedSchema, + extraTests, +}: { + readonly expectedSchema: ZodMiniType; + readonly endpoint: DeliveryEndpoint; + readonly rawPayload: TResponsePayload | undefined; + readonly selectQuery: SelectQuery; + readonly extraTests?: ((response: TResponsePayload) => void) | undefined; +}): Promise { + const integrationTestConfig = getIntegrationTestConfig(); + + const clients = createTestClients({ + rawPayload, + environmentId: integrationTestConfig.env.id, + deliveryBaseUrl: integrationTestConfig.env.deliveryBaseUrl, + }); + + for (const client of clients) { + await runClientQueryTestsAsync({ + client, + integrationEnvironmentId: integrationTestConfig.env.id, + endpoint, + selectQuery, + expectedSchema, + rawPayload, + extraTests, + }); + } + + await runFailingClientQueryTestAsync({ endpoint, selectQuery }); +} + +async function runClientQueryTestsAsync({ + client, + integrationEnvironmentId, + endpoint, + selectQuery, + expectedSchema, + rawPayload, + extraTests, +}: { + readonly client: DeliveryClient; + readonly integrationEnvironmentId: string; + readonly endpoint: DeliveryEndpoint; + readonly selectQuery: SelectQuery; + readonly expectedSchema: ZodMiniType; + readonly rawPayload: TResponsePayload | undefined; + readonly extraTests?: ((response: TResponsePayload) => void) | undefined; +}): Promise { + const { testType, testName } = createTestMetadata({ + clientEnvironmentId: client.config.environmentId, + integrationEnvironmentId, + endpoint, + }); + + const { query, response, success, error } = await executeDefaultQueryAsync({ client, selectQuery }); + + registerBaseTests({ testName, endpoint, client, query, response, success, error, expectedSchema, rawPayload, testType }); + + if (isPagingQuery(query)) { + const pagingResult = await executePagingQueryAsync({ query }); + registerPagingTests({ + query, + testName, + testType, + rawPayload, + expectedSchema, + response, + ...pagingResult, + }); + + if (extraTests) { + for (const pagingResponse of pagingResult.pagingResponses ?? []) { + extraTests(pagingResponse.payload); + } + } + } else if (extraTests && response) { + extraTests(response.payload); + } +} + +function createFailingUnitTestClient(): DeliveryClient { + return createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + httpService: getDefaultHttpService({ + adapter: { + executeRequest: () => { + throw new Error("Simulated failure"); + }, + }, + }), + }); +} + +function createUnitTestClient( + rawPayload: TResponsePayload, +): DeliveryClient { + return createDeliveryClient({ + apiMode: "public", + environmentId: unitEnvironmentId, + runtimeValidation: { + validateResponses: true, + }, + httpService: getTestHttpServiceWithJsonResponse({ + jsonResponse: rawPayload, + statusCode: 200, + }), + }); +} + +function createIntegrationTestClient( + environmentId: string, + deliveryBaseUrl: BaseUrl | undefined, +): DeliveryClient { + return createDeliveryClient({ + apiMode: "public", + environmentId, + runtimeValidation: { + validateResponses: true, + }, + ...(deliveryBaseUrl ? { baseUrl: deliveryBaseUrl } : {}), + }); +} + +function createTestClients({ + rawPayload, + environmentId, + deliveryBaseUrl, +}: { + readonly rawPayload: TResponsePayload | undefined; + readonly environmentId: string; + readonly deliveryBaseUrl: BaseUrl | undefined; +}): readonly DeliveryClient[] { + const integrationClient = createIntegrationTestClient(environmentId, deliveryBaseUrl); + return rawPayload === undefined + ? [integrationClient] + : [createUnitTestClient(rawPayload), integrationClient]; +} + +function createTestMetadata({ + clientEnvironmentId, + integrationEnvironmentId, + endpoint, +}: { + readonly clientEnvironmentId: string; + readonly integrationEnvironmentId: string; + readonly endpoint: DeliveryEndpoint; +}): { + readonly isIntegrationTest: boolean; + readonly testType: TestType; + readonly testName: string; +} { + const isIntegrationTest = clientEnvironmentId === integrationEnvironmentId; + const testType = isIntegrationTest ? "Integration" : "Unit"; + const testName = `${testType}[${endpoint}]: `; + return { isIntegrationTest, testType, testName }; +} + +function registerBaseTests({ + testName, + endpoint, + client, + query, + response, + success, + error, + expectedSchema, + rawPayload, + testType, +}: { + readonly testName: string; + readonly endpoint: DeliveryEndpoint; + readonly client: DeliveryClient; + readonly query: ReturnType>; + readonly response: { readonly payload: TResponsePayload } | undefined; + readonly success: boolean; + readonly error: unknown; + readonly expectedSchema: ZodMiniType; + readonly rawPayload: TResponsePayload; + readonly testType: TestType; +}): void { + registerQueryStructureTests({ testName, query, endpoint, client }); + registerResponseValidationTests({ testName, success, error, expectedSchema, response, testType, rawPayload }); +} + +function registerQueryStructureTests({ + testName, + query, + endpoint, + client, +}: { + readonly testName: string; + readonly query: ReturnType>; + readonly endpoint: DeliveryEndpoint; + readonly client: DeliveryClient; +}): void { + it(`${testName} Expect url to be correct`, () => { + expect(query.inspect()?.data?.url).toEqual( + new URL(getDeliveryUrl({ apiMode: "public", environmentId: client.config.environmentId, path: endpoint })), + ); + }); + if (!isPagingQuery(query)) { + it(`${testName} Query should be a fetch query with expected functions`, () => { + expect(isFetchQueryWithExpectedFunctions(query)).toBeTruthy(); + }); + } +} + +function registerResponseValidationTests({ + testName, + success, + error, + expectedSchema, + response, + testType, + rawPayload, +}: { + readonly testName: string; + readonly success: boolean; + readonly error: unknown; + readonly expectedSchema: ZodMiniType; + readonly response: { readonly payload: TResponsePayload } | undefined; + readonly testType: TestType; + readonly rawPayload: TResponsePayload; +}): void { + it(`${testName} Response should be successful`, () => { + expect(error).toBeUndefined(); + expect(success).toBeTruthy(); + }); + it(`${testName} Response payload should match schema`, async () => { + const { error: parseError, success: parseSuccess } = await expectedSchema.safeParseAsync(response?.payload); + expect(parseError).toBeUndefined(); + expect(parseSuccess).toBeTruthy(); + }); + if (testType === "Unit" && rawPayload) { + it(`${testName} Payload should be equal to unit test payload`, () => { + expect(response?.payload).toEqual(rawPayload); + }); + } +} + +function registerPagingTests({ + query, + testName, + testType, + rawPayload, + expectedSchema, + response, + pagingResponses, + pagingSuccess, + pagingError, + iteratorPayloads, +}: { + readonly query: PagedFetchQuery; + readonly testName: string; + readonly testType: TestType; + readonly rawPayload: TResponsePayload; + readonly expectedSchema: ZodMiniType; + readonly response: { readonly payload: TResponsePayload } | undefined; + readonly pagingResponses: readonly { readonly payload: TResponsePayload }[] | undefined; + readonly pagingSuccess: boolean; + readonly pagingError: unknown; + readonly iteratorPayloads: readonly TResponsePayload[]; +}): void { + registerPagingResponseTests({ + testName, + pagingSuccess, + pagingError, + expectedSchema, + response, + testType, + pagingResponses, + rawPayload, + }); + registerPagingIteratorTests({ testName, query, iteratorPayloads, testType, rawPayload }); +} + +function registerPagingResponseTests({ + testName, + pagingSuccess, + pagingError, + expectedSchema, + response, + testType, + pagingResponses, + rawPayload, +}: { + readonly testName: string; + readonly pagingSuccess: boolean; + readonly pagingError: unknown; + readonly expectedSchema: ZodMiniType; + readonly response: { readonly payload: TResponsePayload } | undefined; + readonly testType: TestType; + readonly pagingResponses: readonly { readonly payload: TResponsePayload }[] | undefined; + readonly rawPayload: TResponsePayload; +}): void { + it(`${testName} Response should be successful`, () => { + expect(pagingError).toBeUndefined(); + expect(pagingSuccess).toBeTruthy(); + }); + it(`${testName} Response payload should match schema`, async () => { + const { error: parseError, success: parseSuccess } = await expectedSchema.safeParseAsync(response?.payload); + expect(parseError).toBeUndefined(); + expect(parseSuccess).toBeTruthy(); + }); + + for (const pagingResponse of pagingResponses ?? []) { + it(`${testName} Paging Response payload should match schema`, async () => { + const { error: parseError, success: parseSuccess } = await expectedSchema.safeParseAsync(pagingResponse?.payload); + expect(parseError).toBeUndefined(); + expect(parseSuccess).toBeTruthy(); + }); + } + + if (testType === "Unit" && rawPayload) { + const firstResponse = pagingResponses?.[0]; + it(`${testName} First paging response payload should match unit test payload`, () => { + expect(firstResponse?.payload).toEqual(rawPayload); + }); + } +} + +function registerPagingIteratorTests({ + testName, + query, + iteratorPayloads, + testType, + rawPayload, +}: { + readonly testName: string; + readonly query: PagedFetchQuery; + readonly iteratorPayloads: readonly TResponsePayload[]; + readonly testType: TestType; + readonly rawPayload: TResponsePayload; +}): void { + it(`${testName} Query should be a paged fetch query with expected functions`, () => { + expect(isPagedFetchQueryWithExpectedFunctions(query)).toBeTruthy(); + }); + if (testType === "Unit") { + const firstIteratorResponse = iteratorPayloads?.[0]; + it(`${testName} First iterator response payload should match schema`, () => { + expect(firstIteratorResponse).toEqual(rawPayload); + }); + } +} + +async function runFailingClientQueryTestAsync({ + endpoint, + selectQuery, +}: { + readonly endpoint: DeliveryEndpoint; + readonly selectQuery: SelectQuery; +}): Promise { + const client = createFailingUnitTestClient(); + const query = selectQuery(client); + const { error } = isPagingQuery(query) ? await query.fetchPageSafe() : await query.fetchSafe(); + const testName = `Unit[${endpoint}]: `; + + it(`${testName} Error should be an instance of DeliverySdkError`, () => { + expect(error).toBeInstanceOf(DeliverySdkError); + }); +} + +async function executeDefaultQueryAsync({ + client, + selectQuery, +}: { + readonly client: DeliveryClient; + readonly selectQuery: SelectQuery; +}): Promise<{ + readonly query: ReturnType>; + readonly response: { readonly payload: TResponsePayload } | undefined; + readonly success: boolean; + readonly error: unknown; +}> { + const query = selectQuery(client); + if (isPagingQuery(query)) { + const { response, success, error } = await query.fetchPageSafe(); + return { query, response, success, error }; + } + const { response, success, error } = await query.fetchSafe(); + return { query, response, success, error }; +} + +async function executePagingQueryAsync({ + query, +}: { + readonly query: PagedFetchQuery; +}): Promise<{ + readonly pagingResponses: readonly { readonly payload: TResponsePayload }[] | undefined; + readonly pagingSuccess: boolean; + readonly pagingError: unknown; + readonly iteratorPayloads: readonly TResponsePayload[]; +}> { + const { responses: pagingResponses, success: pagingSuccess, error: pagingError } = await query.fetchAllPagesSafe(); + const iteratorPayloads: TResponsePayload[] = []; + for await (const pageResponse of query.pages()) { + iteratorPayloads.push(pageResponse?.payload); + } + return { + pagingResponses, + pagingSuccess, + pagingError, + iteratorPayloads, + }; +} diff --git a/tests/utils/test.utils.ts b/tests/utils/test.utils.ts new file mode 100644 index 00000000..d48c57f1 --- /dev/null +++ b/tests/utils/test.utils.ts @@ -0,0 +1,56 @@ +import { + type ContinuationTokenHeaderName, + type FetchQuery, + type Header, + type JsonValue, + type KontentSdkError, + nilUuid, + type PagedFetchQuery, +} from "@kontent-ai/core-sdk"; + +export const fakeXContinuationTokenHeader: Header = { + name: "X-Continuation" satisfies ContinuationTokenHeaderName, + value: "x", +}; + +export const unitEnvironmentId = "xyz"; + +export function getFakeUuid(): string { + return nilUuid; +} + +export function isFetchQueryWithExpectedFunctions(query: unknown): query is FetchQuery { + type ExpectedFunctions = keyof FetchQuery; + if (!query || typeof query !== "object") { + return false; + } + + const expectedFunctions: readonly ExpectedFunctions[] = ["fetchSafe", "fetch", "inspect"]; + + if (expectedFunctions.every((func) => func in query)) { + return true; + } + return false; +} + +export function isPagedFetchQueryWithExpectedFunctions(query: unknown): query is PagedFetchQuery { + type ExpectedFunctions = keyof PagedFetchQuery; + if (!query || typeof query !== "object") { + return false; + } + + const expectedFunctions: readonly ExpectedFunctions[] = [ + "fetchAllPagesSafe", + "fetchPageSafe", + "pages", + "inspect", + "fetchAllPages", + "fetchPage", + "pagesSafe", + ]; + + if (expectedFunctions.every((func) => func in query)) { + return true; + } + return false; +} diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..d90cc3df --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": false, + "outDir": "dist", + "rootDir": "./lib" + }, + "include": ["lib/**/*"], + "exclude": ["tests/**/*", "scripts/**/*", "sample/**/*"] +} diff --git a/tsconfig.json b/tsconfig.json index f75651c6..90157bc5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,30 +1,38 @@ { - "compileOnSave": true, - "compilerOptions": { - "baseUrl": ".", - "outDir": "dist", - "sourceMap": true, - "declaration": true, - "moduleResolution": "node", - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "module": "commonjs", - "target": "es6", - "strict": true, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "resolveJsonModule": true, - "noImplicitReturns": true, - "allowUnreachableCode": false, - "alwaysStrict": true, - "forceConsistentCasingInFileNames": true, - "noUnusedParameters": false, - "noUnusedLocals": true, - "strictFunctionTypes": true, - "noImplicitAny": true, - "typeRoots": ["./node_modules/@types"], - "lib": ["ESNext", "dom"] - }, - "include": ["lib/**/*", "test/**/*", "misc/**/*", "clean.ts", "eslint.config.mjs"], - "exclude": ["node_modules"] + "compileOnSave": true, + "compilerOptions": { + // Language + runtime environment + "rootDir": ".", + "target": "esnext", + "lib": ["esnext"], + + // Modules + resolution + "module": "NodeNext", + "moduleResolution": "nodenext", + "resolveJsonModule": true, + + // Emit behavior (even if `noEmit` is true, these are useful for tooling expectations) + "noEmit": true, + "declaration": true, + "sourceMap": true, + + // Strictness + type safety + "strict": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "allowUnreachableCode": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "exactOptionalPropertyTypes": true, + "noUncheckedIndexedAccess": true, + "noFallthroughCasesInSwitch": true, + "useUnknownInCatchVariables": true, + "skipLibCheck": true, + + // Types + "types": ["node"] + }, + "include": ["lib/**/*", "tests/**/*", "eslint.config.js", "vitest.config.ts", "sample/**/*", "scripts/**/*"], + "exclude": ["node_modules", "_legacy"] } diff --git a/tsconfig.prod.json b/tsconfig.prod.json deleted file mode 100644 index 088e5857..00000000 --- a/tsconfig.prod.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": [ - "lib/**/*" - ] -} \ No newline at end of file diff --git a/tsconfig.webpack.json b/tsconfig.webpack.json deleted file mode 100644 index 2f0dbac1..00000000 --- a/tsconfig.webpack.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.prod.json", - "compilerOptions": { - "declaration": false - } -} \ No newline at end of file diff --git a/vitest-integration.config.ts b/vitest-integration.config.ts new file mode 100644 index 00000000..71f06313 --- /dev/null +++ b/vitest-integration.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + root: ".", + test: { + dir: "tests/integration", + globals: true, + environment: "node", + }, + build: { + target: "esnext", + }, +}); diff --git a/vitest-unit.config.ts b/vitest-unit.config.ts new file mode 100644 index 00000000..b3db08a1 --- /dev/null +++ b/vitest-unit.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + root: ".", + test: { + dir: "tests/unit", + globals: true, + environment: "node", + coverage: { + provider: "v8", + include: ["lib/**/*.ts"], + }, + }, + build: { + target: "esnext", + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 00000000..9977aca2 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + root: ".", + test: { + dir: "tests", + globals: true, + environment: "node", + coverage: { + provider: "v8", + reporter: ["text"], + thresholds: { lines: 100, functions: 100, branches: 100 }, + exclude: ["**/tests/**", "**/types/**"], + include: ["lib/**"], + }, + }, + build: { + target: "esnext", + }, +}); diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 702fae82..00000000 --- a/webpack.config.js +++ /dev/null @@ -1,58 +0,0 @@ -const path = require('path'); -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; - -const isProd = (args) => { - return args.mode === 'production' -} - -const outputFolder = (args) => path.resolve(__dirname, 'dist/bundles'); -const bundleFilename = (args) => { - return 'kontent-delivery.umd' + (isProd(args) ? '.min.js' : '.js'); -} - -module.exports = (env, args) => ({ - mode: args.mode, - entry: { - 'index': './lib/index.ts', - }, - resolve: { - extensions: ['.ts', '.js'] - }, - output: { - path: outputFolder(args), - filename: bundleFilename(args), - libraryTarget: 'umd', - umdNamedDefine: true, - library: 'kontentDelivery' - }, - devtool: 'source-map', - module: { - rules: [ - { - test: /\.ts$/, - loader: 'ts-loader', - include: [ - path.resolve(__dirname, 'lib'), - ], - options: { - configFile: require.resolve('./tsconfig.webpack.json') - } - } - ], - }, - performance: { - hints: 'warning', - maxEntrypointSize: 1000000, - maxAssetSize: 1000000 - }, - plugins: [ - new BundleAnalyzerPlugin({ - generateStatsFile: true, - analyzerMode: 'json', - reportFilename: (isProd(args) ? 'report.min' : 'report') + '.json', - statsFilename: (isProd(args) ? 'stats.min' : 'stats') + '.json' - }) - ] -}); - -