From b7b690a4d30090910f257707e638add9aa3ad30c Mon Sep 17 00:00:00 2001 From: Daniel Pokorny Date: Thu, 7 Dec 2023 15:06:51 +0100 Subject: [PATCH 1/6] add alt image attribute --- .../portable-text-transformer/portable-text-transformer.ts | 3 ++- src/transformers/transformer-models.ts | 4 ++++ src/utils/transformer-utils.ts | 1 + .../__snapshots__/portable-text-transformer.spec.ts.snap | 5 +++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/transformers/portable-text-transformer/portable-text-transformer.ts b/src/transformers/portable-text-transformer/portable-text-transformer.ts index 603a41b..9b12173 100644 --- a/src/transformers/portable-text-transformer/portable-text-transformer.ts +++ b/src/transformers/portable-text-transformer/portable-text-transformer.ts @@ -258,11 +258,12 @@ const transformElement = (node: IDomHtmlNode, depth: number, listType?: Portable } const transformImage: TransformElementFunction = (node) => { - const block = createImageBlock(uid().toString()); const imageTag = node.children[0] as IDomHtmlNode; + const block = createImageBlock(uid().toString()); block.asset._ref = node.attributes['data-image-id']; block.asset.url = imageTag.attributes['src']; + block.asset.alt = imageTag.attributes['alt']; return [block]; } diff --git a/src/transformers/transformer-models.ts b/src/transformers/transformer-models.ts index 8150afb..3898100 100644 --- a/src/transformers/transformer-models.ts +++ b/src/transformers/transformer-models.ts @@ -25,6 +25,10 @@ export interface AssetReference extends Reference { * URL of an asset. */ url: string; + /** + * Alternate image text. + */ + alt: string; } /** diff --git a/src/utils/transformer-utils.ts b/src/utils/transformer-utils.ts index d14868f..61bba5e 100644 --- a/src/utils/transformer-utils.ts +++ b/src/utils/transformer-utils.ts @@ -144,6 +144,7 @@ export const createImageBlock = (guid: string): PortableTextImage => { _type: "reference", _ref: "", url: "", + alt: "", }, }; }; diff --git a/tests/transfomers/portable-text-transformer/__snapshots__/portable-text-transformer.spec.ts.snap b/tests/transfomers/portable-text-transformer/__snapshots__/portable-text-transformer.spec.ts.snap index 2af0df4..2b1c647 100644 --- a/tests/transfomers/portable-text-transformer/__snapshots__/portable-text-transformer.spec.ts.snap +++ b/tests/transfomers/portable-text-transformer/__snapshots__/portable-text-transformer.spec.ts.snap @@ -747,6 +747,7 @@ exports[`portable text transformer transforms images 1`] = ` "asset": { "_ref": "7d866175-d3db-4a02-b0eb-891fb06b6ab0", "_type": "reference", + "alt": "", "url": "https://assets-eu-01.kc-usercontent.com:443/6d864951-9d19-0138-e14d-98ba886a4410/236ecb7f-41e3-40c7-b0db-ea9c2c44003b/sharad-bhat-62p19OGT2qg-unsplash.jpg", }, }, @@ -1307,6 +1308,7 @@ exports[`portable text transformer transforms table with input

Text

"asset": { "_ref": "8c35b61a-8fcb-4089-a576-5a5e7a158bf2", "_type": "reference", + "alt": "", "url": "https://example.com/image.png", }, }, @@ -1544,6 +1546,7 @@ exports[`portable text transformer transforms table with input

Text

"asset": { "_ref": "8c35b61a-8fcb-4089-a576-5a5e7a158bf2", "_type": "reference", + "alt": "", "url": "https://example.com/image.png", }, }, @@ -2625,6 +2628,7 @@ exports[`portable text transformer transforms table with input "asset": { "_ref": "bb79f32d-4fed-4d46-bec3-71b1c285ca30", "_type": "reference", + "alt": "", "url": "https://qa-preview-assets-eu-01.devkontentmasters.com:443/0a12060e-20af-0124-a95d-871d26379561/2af0a87f-d750-4f6c-b6ff-8f895fa7d235/scalpel_blade_12.jpg", }, }, @@ -2667,6 +2671,7 @@ exports[`portable text transformer transforms table with input
"asset": { "_ref": "f6827ddf-7b07-49c3-819d-5270f1ac0164", "_type": "reference", + "alt": "", "url": "https://qa-preview-assets-eu-01.devkontentmasters.com:443/0a12060e-20af-0124-a95d-871d26379561/653b1fc7-466a-4d91-945a-964ae4f9570a/scalpel_blade_11.jpg", }, }, From 70509575a06697b00e634b9b9cf4211883d5210a Mon Sep 17 00:00:00 2001 From: Daniel Pokorny Date: Mon, 11 Dec 2023 00:19:56 +0100 Subject: [PATCH 2/6] add default image resolution and tests add resolverMethod type split resolution methods to standalone files extend default resolution for vue --- index.ts | 2 +- jest.config.cjs | 3 + package-lock.json | 1256 ++++++++++++++++- package.json | 13 +- showcase/showcase.ts | 3 +- src/utils/resolution/html.ts | 58 + src/utils/resolution/vue.ts | 67 + src/utils/transformer-utils.ts | 31 +- tests/components/portable-text.spec.tsx | 2 +- .../html-transformer.spec.ts.snap | 4 +- .../html-transformer.spec.ts | 55 +- .../vue-transformer.spec.ts | 109 ++ 12 files changed, 1538 insertions(+), 65 deletions(-) create mode 100644 src/utils/resolution/html.ts create mode 100644 src/utils/resolution/vue.ts create mode 100644 tests/transfomers/portable-text-transformer/vue-transformer.spec.ts diff --git a/index.ts b/index.ts index 08b37e9..ef8e245 100644 --- a/index.ts +++ b/index.ts @@ -1,5 +1,5 @@ export { transformToJson } from "./src/transformers/json-transformer/json-transformer.js"; export { transformToPortableText } from "./src/transformers/portable-text-transformer/portable-text-transformer.js"; -export { resolveTable, traversePortableText } from "./src/utils/transformer-utils.js"; +export { extendPortableText } from "./src/utils/transformer-utils.js"; export { parse as browserParse } from "./src/parser/browser/rich-text-browser-parser.js"; export { parse as nodeParse } from "./src/parser/node/rich-text-node-parser.js"; \ No newline at end of file diff --git a/jest.config.cjs b/jest.config.cjs index e18c97b..42369f1 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -2,6 +2,9 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', + testEnvironmentOptions: { + customExportConditions: ["node", "node-addons"], + }, extensionsToTreatAsEsm: ['.ts'], moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', diff --git a/package-lock.json b/package-lock.json index e8453db..416e1f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,12 +17,12 @@ "@kontent-ai/delivery-sdk": "^14.6.0", "@portabletext/react": "^3.0.11", "@portabletext/to-html": "^2.0.5", - "@testing-library/jest-dom": "^6.2.0", + "@testing-library/jest-dom": "^6.1.5", "@types/jest": "^29.5.11", "@types/react": "^18.2.47", "@types/react-test-renderer": "^18.0.7", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", + "@typescript-eslint/eslint-plugin": "^5.58.0", + "@typescript-eslint/parser": "^5.58.0", "babel-jest": "^29.7.0", "eslint": "^8.56.0", "eslint-config-kontent-ai": "^0.1.8", @@ -31,7 +31,8 @@ "react": "^18.2.0", "react-test-renderer": "^18.2.0", "ts-jest": "^29.1.1", - "typescript": "5.0.3" + "typescript": "5.0.3", + "vue": "^3.3.11" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -331,9 +332,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -720,6 +721,102 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "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, + "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.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "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 + }, + "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, + "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.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "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, + "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/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1442,9 +1539,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -1518,6 +1615,22 @@ "node": ">= 8" } }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "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, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@portabletext/react": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/@portabletext/react/-/react-3.0.11.tgz", @@ -1567,6 +1680,19 @@ "node": "^14.13.1 || >=16.0.0 || >=18.0.0" } }, + "node_modules/@portabletext/vue": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@portabletext/vue/-/vue-1.0.6.tgz", + "integrity": "sha512-YQsrZUpJG8D+SLBBUicFa0Nvhe5S6zI6XbomO316YDKe3EAqvkM0NNDlgRP6WcQIM+ZRZhfAon15PBI5DUDB8g==", + "dev": true, + "dependencies": { + "@portabletext/toolkit": "^2.0.10", + "@portabletext/types": "^2.0.8" + }, + "peerDependencies": { + "vue": "^3.3.4" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -2457,12 +2583,152 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vue/compiler-core": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.11.tgz", + "integrity": "sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.5", + "@vue/shared": "3.3.11", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.11.tgz", + "integrity": "sha512-zoAiUIqSKqAJ81WhfPXYmFGwDRuO+loqLxvXmfUdR5fOitPoUiIeFI9cTTyv9MU5O1+ZZglJVTusWzy+wfk5hw==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.11.tgz", + "integrity": "sha512-U4iqPlHO0KQeK1mrsxCN0vZzw43/lL8POxgpzcJweopmqtoYy9nljJzWDIQS3EfjiYhfdtdk9Gtgz7MRXnz3GA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.5", + "@vue/compiler-core": "3.3.11", + "@vue/compiler-dom": "3.3.11", + "@vue/compiler-ssr": "3.3.11", + "@vue/reactivity-transform": "3.3.11", + "@vue/shared": "3.3.11", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.5", + "postcss": "^8.4.32", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.11.tgz", + "integrity": "sha512-Zd66ZwMvndxRTgVPdo+muV4Rv9n9DwQ4SSgWWKWkPFebHQfVYRrVjeygmmDmPewsHyznCNvJ2P2d6iOOhdv8Qg==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.11.tgz", + "integrity": "sha512-D5tcw091f0nuu+hXq5XANofD0OXnBmaRqMYl5B3fCR+mX+cXJIGNw/VNawBqkjLNWETrFW0i+xH9NvDbTPVh7g==", + "dev": true, + "dependencies": { + "@vue/shared": "3.3.11" + } + }, + "node_modules/@vue/reactivity-transform": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.11.tgz", + "integrity": "sha512-fPGjH0wqJo68A0wQ1k158utDq/cRyZNlFoxGwNScE28aUFOKFEnCBsvyD8jHn+0kd0UKVpuGuaZEQ6r9FJRqCg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.5", + "@vue/compiler-core": "3.3.11", + "@vue/shared": "3.3.11", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.5" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.11.tgz", + "integrity": "sha512-g9ztHGwEbS5RyWaOpXuyIVFTschclnwhqEbdy5AwGhYOgc7m/q3NFwr50MirZwTTzX55JY8pSkeib9BX04NIpw==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.11.tgz", + "integrity": "sha512-OlhtV1PVpbgk+I2zl+Y5rQtDNcCDs12rsRg71XwaA2/Rbllw6mBLMi57VOn8G0AjOJ4Mdb4k56V37+g8ukShpQ==", + "dev": true, + "dependencies": { + "@vue/runtime-core": "3.3.11", + "@vue/shared": "3.3.11", + "csstype": "^3.1.2" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.11.tgz", + "integrity": "sha512-AIWk0VwwxCAm4wqtJyxBylRTXSy1wCLOKbWxHaHiu14wjsNYtiRCSgVuqEPVuDpErOlRdNnuRgipQfXRLjLN5A==", + "dev": true, + "dependencies": { + "@vue/compiler-ssr": "3.3.11", + "@vue/shared": "3.3.11" + }, + "peerDependencies": { + "vue": "3.3.11" + } + }, + "node_modules/@vue/shared": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.11.tgz", + "integrity": "sha512-u2G8ZQ9IhMWTMXaWqZycnK4UthG1fA238CD+DP4Dm4WJi5hdUKKLg0RMRaRpDPNMdkTwIDkp7WtD0Rd9BH9fLw==", + "dev": true + }, + "node_modules/@vue/test-utils": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.3.tgz", + "integrity": "sha512-F4K7mF+ad++VlTrxMJVRnenKSJmO6fkQt2wpRDiKDesQMkfpniGWsqEi/JevxGBo2qEkwwjvTUAoiGJLNx++CA==", + "dev": true, + "dependencies": { + "js-beautify": "^1.14.9", + "vue-component-type-helpers": "^1.8.21" + }, + "peerDependencies": { + "@vue/server-renderer": "^3.0.1", + "vue": "^3.0.1" + }, + "peerDependenciesMeta": { + "@vue/server-renderer": { + "optional": true + } + } + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/acorn": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", @@ -3119,12 +3385,31 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "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 }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "node_modules/convert-source-map": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", @@ -3296,9 +3581,9 @@ "dev": true }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, "node_modules/data-urls": { @@ -3531,6 +3816,69 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "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 + }, + "node_modules/editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/editorconfig/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.334", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.334.tgz", @@ -4349,6 +4697,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4555,6 +4909,34 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/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, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -5037,6 +5419,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "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 + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -5486,6 +5874,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -7072,6 +7478,72 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-beautify": { + "version": "1.14.11", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.11.tgz", + "integrity": "sha512-rPogWqAfoYh1Ryqqh2agUpVfbxAhbjuN1SmU86dskQUKouRiggUTCO4+2ym9UPXllc2WAp0J+T5qxn7Um3lCdw==", + "dev": true, + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.3", + "glob": "^10.3.3", + "nopt": "^7.2.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/js-beautify/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/js-beautify/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-beautify/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7283,8 +7755,20 @@ "node": ">=10" } }, - "node_modules/make-dir": { - "version": "4.0.0", + "node_modules/magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "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, @@ -7417,12 +7901,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7456,6 +7967,21 @@ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, + "node_modules/nopt": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", + "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7787,6 +8313,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -7835,6 +8386,34 @@ "node": ">=8" } }, + "node_modules/postcss": { + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -7902,6 +8481,12 @@ "dev": true, "peer": true }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -8287,6 +8872,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -8363,6 +8957,21 @@ "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, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -8443,6 +9052,19 @@ "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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -8868,6 +9490,33 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/vue": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.11.tgz", + "integrity": "sha512-d4oBctG92CRO1cQfVBZp6WJAs0n8AK4Xf5fNjQCBeKCvMI1efGQ5E3Alt1slFJS9fZuPcFoiAiqFvQlv1X7t/w==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.3.11", + "@vue/compiler-sfc": "3.3.11", + "@vue/runtime-dom": "3.3.11", + "@vue/server-renderer": "3.3.11", + "@vue/shared": "3.3.11" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-component-type-helpers": { + "version": "1.8.25", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-1.8.25.tgz", + "integrity": "sha512-NCA6sekiJIMnMs4DdORxATXD+/NRkQpS32UC+I1KQJUasx+Z7MZUb3Y+MsKsFmX+PgyTYSteb73JW77AibaCCw==", + "dev": true + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -9024,6 +9673,57 @@ "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, + "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/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/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 + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -9399,9 +10099,9 @@ } }, "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -9678,6 +10378,71 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "@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, + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "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, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -10223,9 +10988,9 @@ "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { @@ -10284,6 +11049,19 @@ "fastq": "^1.6.0" } }, + "@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "@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, + "optional": true + }, "@portabletext/react": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/@portabletext/react/-/react-3.0.11.tgz", @@ -10318,6 +11096,16 @@ "resolved": "https://registry.npmjs.org/@portabletext/types/-/types-2.0.8.tgz", "integrity": "sha512-eiq9/kMX2bYezS4/kLFk3xNnruCFjCDdw6aYEv5ECHVKkYROiuLd3/AsP5d7tWF3+kPPy6tB0Wq8aqDG/URHGA==" }, + "@portabletext/vue": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@portabletext/vue/-/vue-1.0.6.tgz", + "integrity": "sha512-YQsrZUpJG8D+SLBBUicFa0Nvhe5S6zI6XbomO316YDKe3EAqvkM0NNDlgRP6WcQIM+ZRZhfAon15PBI5DUDB8g==", + "dev": true, + "requires": { + "@portabletext/toolkit": "^2.0.10", + "@portabletext/types": "^2.0.8" + } + }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -10926,12 +11714,137 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "@vue/compiler-core": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.11.tgz", + "integrity": "sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==", + "dev": true, + "requires": { + "@babel/parser": "^7.23.5", + "@vue/shared": "3.3.11", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "@vue/compiler-dom": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.11.tgz", + "integrity": "sha512-zoAiUIqSKqAJ81WhfPXYmFGwDRuO+loqLxvXmfUdR5fOitPoUiIeFI9cTTyv9MU5O1+ZZglJVTusWzy+wfk5hw==", + "dev": true, + "requires": { + "@vue/compiler-core": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "@vue/compiler-sfc": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.11.tgz", + "integrity": "sha512-U4iqPlHO0KQeK1mrsxCN0vZzw43/lL8POxgpzcJweopmqtoYy9nljJzWDIQS3EfjiYhfdtdk9Gtgz7MRXnz3GA==", + "dev": true, + "requires": { + "@babel/parser": "^7.23.5", + "@vue/compiler-core": "3.3.11", + "@vue/compiler-dom": "3.3.11", + "@vue/compiler-ssr": "3.3.11", + "@vue/reactivity-transform": "3.3.11", + "@vue/shared": "3.3.11", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.5", + "postcss": "^8.4.32", + "source-map-js": "^1.0.2" + } + }, + "@vue/compiler-ssr": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.11.tgz", + "integrity": "sha512-Zd66ZwMvndxRTgVPdo+muV4Rv9n9DwQ4SSgWWKWkPFebHQfVYRrVjeygmmDmPewsHyznCNvJ2P2d6iOOhdv8Qg==", + "dev": true, + "requires": { + "@vue/compiler-dom": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "@vue/reactivity": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.11.tgz", + "integrity": "sha512-D5tcw091f0nuu+hXq5XANofD0OXnBmaRqMYl5B3fCR+mX+cXJIGNw/VNawBqkjLNWETrFW0i+xH9NvDbTPVh7g==", + "dev": true, + "requires": { + "@vue/shared": "3.3.11" + } + }, + "@vue/reactivity-transform": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.11.tgz", + "integrity": "sha512-fPGjH0wqJo68A0wQ1k158utDq/cRyZNlFoxGwNScE28aUFOKFEnCBsvyD8jHn+0kd0UKVpuGuaZEQ6r9FJRqCg==", + "dev": true, + "requires": { + "@babel/parser": "^7.23.5", + "@vue/compiler-core": "3.3.11", + "@vue/shared": "3.3.11", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.5" + } + }, + "@vue/runtime-core": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.11.tgz", + "integrity": "sha512-g9ztHGwEbS5RyWaOpXuyIVFTschclnwhqEbdy5AwGhYOgc7m/q3NFwr50MirZwTTzX55JY8pSkeib9BX04NIpw==", + "dev": true, + "requires": { + "@vue/reactivity": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "@vue/runtime-dom": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.11.tgz", + "integrity": "sha512-OlhtV1PVpbgk+I2zl+Y5rQtDNcCDs12rsRg71XwaA2/Rbllw6mBLMi57VOn8G0AjOJ4Mdb4k56V37+g8ukShpQ==", + "dev": true, + "requires": { + "@vue/runtime-core": "3.3.11", + "@vue/shared": "3.3.11", + "csstype": "^3.1.2" + } + }, + "@vue/server-renderer": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.11.tgz", + "integrity": "sha512-AIWk0VwwxCAm4wqtJyxBylRTXSy1wCLOKbWxHaHiu14wjsNYtiRCSgVuqEPVuDpErOlRdNnuRgipQfXRLjLN5A==", + "dev": true, + "requires": { + "@vue/compiler-ssr": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "@vue/shared": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.11.tgz", + "integrity": "sha512-u2G8ZQ9IhMWTMXaWqZycnK4UthG1fA238CD+DP4Dm4WJi5hdUKKLg0RMRaRpDPNMdkTwIDkp7WtD0Rd9BH9fLw==", + "dev": true + }, + "@vue/test-utils": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.3.tgz", + "integrity": "sha512-F4K7mF+ad++VlTrxMJVRnenKSJmO6fkQt2wpRDiKDesQMkfpniGWsqEi/JevxGBo2qEkwwjvTUAoiGJLNx++CA==", + "dev": true, + "requires": { + "js-beautify": "^1.14.9", + "vue-component-type-helpers": "^1.8.21" + } + }, "abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, + "abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true + }, "acorn": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", @@ -11419,12 +12332,28 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "convert-source-map": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", @@ -11558,9 +12487,9 @@ } }, "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, "data-urls": { @@ -11727,6 +12656,53 @@ "domhandler": "^5.0.3" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, + "requires": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "electron-to-chromium": { "version": "1.4.334", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.334.tgz", @@ -12328,6 +13304,12 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12489,6 +13471,24 @@ "is-callable": "^1.1.3" } }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "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 + } + } + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -12828,6 +13828,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -13144,6 +14150,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -14313,6 +15329,51 @@ } } }, + "js-beautify": { + "version": "1.14.11", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.11.tgz", + "integrity": "sha512-rPogWqAfoYh1Ryqqh2agUpVfbxAhbjuN1SmU86dskQUKouRiggUTCO4+2ym9UPXllc2WAp0J+T5qxn7Um3lCdw==", + "dev": true, + "requires": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.3", + "glob": "^10.3.3", + "nopt": "^7.2.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14477,6 +15538,15 @@ "yallist": "^4.0.0" } }, + "magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -14577,12 +15647,24 @@ "dev": true, "peer": true }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -14616,6 +15698,15 @@ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, + "nopt": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", + "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "dev": true, + "requires": { + "abbrev": "^2.0.0" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -14853,6 +15944,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true + } + } + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -14886,6 +15995,17 @@ "find-up": "^4.0.0" } }, + "postcss": { + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "dev": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -14942,6 +16062,12 @@ } } }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -15212,6 +16338,12 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, "source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -15275,6 +16407,17 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@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, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -15337,6 +16480,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -15630,6 +16782,25 @@ } } }, + "vue": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.11.tgz", + "integrity": "sha512-d4oBctG92CRO1cQfVBZp6WJAs0n8AK4Xf5fNjQCBeKCvMI1efGQ5E3Alt1slFJS9fZuPcFoiAiqFvQlv1X7t/w==", + "dev": true, + "requires": { + "@vue/compiler-dom": "3.3.11", + "@vue/compiler-sfc": "3.3.11", + "@vue/runtime-dom": "3.3.11", + "@vue/server-renderer": "3.3.11", + "@vue/shared": "3.3.11" + } + }, + "vue-component-type-helpers": { + "version": "1.8.25", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-1.8.25.tgz", + "integrity": "sha512-NCA6sekiJIMnMs4DdORxATXD+/NRkQpS32UC+I1KQJUasx+Z7MZUb3Y+MsKsFmX+PgyTYSteb73JW77AibaCCw==", + "dev": true + }, "w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -15770,6 +16941,43 @@ } } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 2b70b94..c880893 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,14 @@ "import": "./dist/esnext/src/utils/common-utils.js", "require": "./dist/cjs/src/utils/common-utils.js" }, + "./utils/vue": { + "import": "./dist/esnext/src/utils/resolution/vue.js", + "require": "./dist/cjs/src/utils/resolution/vue.js" + }, + "./utils/html": { + "import": "./dist/esnext/src/utils/resolution/html.js", + "require": "./dist/cjs/src/utils/resolution/html.js" + }, "./types/transformer": { "import": "./dist/esnext/src/transformers/transformer-models.js", "require": "./dist/cjs/src/transformers/transformer-models.js" @@ -61,11 +69,13 @@ "@portabletext/react": "^3.0.11", "@portabletext/to-html": "^2.0.5", "@testing-library/jest-dom": "^6.2.0", + "@portabletext/vue": "^1.0.6", "@types/jest": "^29.5.11", "@types/react": "^18.2.47", "@types/react-test-renderer": "^18.0.7", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "@vue/test-utils": "^2.4.3", "babel-jest": "^29.7.0", "eslint": "^8.56.0", "eslint-config-kontent-ai": "^0.1.8", @@ -74,7 +84,8 @@ "react": "^18.2.0", "react-test-renderer": "^18.2.0", "ts-jest": "^29.1.1", - "typescript": "5.0.3" + "typescript": "^5.0.3", + "vue": "^3.3.11" }, "dependencies": { "@portabletext/types": "^2.0.8", diff --git a/showcase/showcase.ts b/showcase/showcase.ts index d79dc3f..239b420 100644 --- a/showcase/showcase.ts +++ b/showcase/showcase.ts @@ -15,7 +15,8 @@ import { PortableTextComponent, PortableTextImage, PortableTextInternalLink, Por asset: { _type: "reference", _ref: "bc6f3ce5-935d-4446-82d4-ce77436dd412", - url: "https://assets-us-01.kc-usercontent.com:443/.../image.jpg" + url: "https://assets-us-01.kc-usercontent.com:443/.../image.jpg", + alt: "" } }; diff --git a/src/utils/resolution/html.ts b/src/utils/resolution/html.ts new file mode 100644 index 0000000..2336b6a --- /dev/null +++ b/src/utils/resolution/html.ts @@ -0,0 +1,58 @@ +import { PortableTextBlock } from "@portabletext/types"; + +import { + PortableTextImage, + PortableTextTable, + PortableTextTableCell, + PortableTextTableRow, +} from "../../index.js"; + +/** + * Renders a portable text table to HTML. + * + * @param {PortableTextTable} table - The portable text table object to render. + * @param {(value: PortableTextBlock[]) => string} resolver - A function that resolves + * the content of each cell in the table. + * @returns {string} The rendered table as an HTML string. + */ +export const resolveTable = ( + table: PortableTextTable, + resolver: (value: PortableTextBlock[]) => string +) => { + const renderCell = (cell: PortableTextTableCell) => { + const cellContent = resolver(cell.content); + return ``; + }; + + const renderRow = (row: PortableTextTableRow) => { + const cells = row.cells.map(renderCell); + return `${cells.join("")}`; + }; + + const renderRows = () => table.rows.map(renderRow).join(""); + + return `
${cellContent}
${renderRows()}
`; +}; + +/** + * Resolves an image object to HTML. + * + * @param {PortableTextImage} image - The portable text image object to be rendered. + * @param {(image: PortableTextImage) => string} resolver - A resolver function that returns the image as an HTML string. + * @returns {string} The resolved image as an HTML string. + */ +export const resolveImage = ( + image: PortableTextImage, + resolver: (image: PortableTextImage) => string +): string => resolver(image); + +/** + * Provides a default resolver function for an image object to HTML. This function can be used as + * a default argument for the `resolveImage` function. + * + * @param {PortableTextImage} image - The portable text image object to be rendered. + * @returns {VueImage} An object representing the image, containing `src` and `alt` properties, + * and potentially other HTML attributes. + */ +export const toHTMLImageDefault = (image: PortableTextImage): string => + `${image.asset.alt}`; diff --git a/src/utils/resolution/vue.ts b/src/utils/resolution/vue.ts new file mode 100644 index 0000000..29e6d0b --- /dev/null +++ b/src/utils/resolution/vue.ts @@ -0,0 +1,67 @@ +import { PortableTextBlock } from "@portabletext/types"; + +import { + PortableTextImage, + PortableTextTable, + PortableTextTableCell, + PortableTextTableRow, +} from "../../index.js"; + +/** + * Renders a portable text table to a Vue virtual DOM node. + * + * @param {PortableTextTable} table - The portable text table object to render. + * @param {(value: PortableTextBlock[]) => string} resolver - A function that resolves + * the content of each cell in the table. + * @param {Function} vueRenderFunction - A Vue render function, typically the `h` function from Vue. + * @returns {VueNode} The rendered table as a Vue virtual DOM node. + */ +export const resolveTable = ( + table: PortableTextTable, + vueRenderFunction: Function, + resolver: (value: PortableTextBlock[]) => string +) => { + const renderCell = (cell: PortableTextTableCell) => { + const cellContent = resolver(cell.content); + return vueRenderFunction("td", {}, cellContent); + }; + + const renderRow = (row: PortableTextTableRow) => { + const cells = row.cells.map(renderCell); + return vueRenderFunction("tr", {}, cells); + }; + + const renderRows = () => table.rows.map(renderRow); + + return vueRenderFunction("table", {}, renderRows()); +}; + +/** + * Resolves an image object to a Vue virtual DOM node using a provided Vue render function. + * + * @param {PortableTextImage} image - The portable text image object to be rendered. + * @param {Function} vueRenderFunction - A Vue render function, typically the `h` function from Vue. + * @param {(image: PortableTextImage) => VueImage} resolver - A function that takes an image object + * and returns an object with `src` and `alt` properties, and possibly other HTML attributes. + * @returns {VueNode} The resolved image as a Vue virtual DOM node. + */ +export const resolveImage = ( + image: PortableTextImage, + vueRenderFunction: Function, + resolver: (image: PortableTextImage) => VueImage +) => vueRenderFunction("img", resolver(image)); + +/** + * Provides a default resolver function for an image object to Vue. This function can be used as + * a default argument for the `resolveImage` function. + * + * @param {PortableTextImage} image - The portable text image object to be rendered. + * @returns {VueImage} An object representing the image, containing `src` and `alt` properties, + * and potentially other HTML attributes. + */ +export const toVueImageDefault = (image: PortableTextImage): VueImage => ({ + src: image.asset.url, + alt: image.asset.alt || "", +}); + +type VueImage = { src: string; alt: string; [key: string]: any }; diff --git a/src/utils/transformer-utils.ts b/src/utils/transformer-utils.ts index 61bba5e..5c032ad 100644 --- a/src/utils/transformer-utils.ts +++ b/src/utils/transformer-utils.ts @@ -1,4 +1,10 @@ -import { ArbitraryTypedObject, PortableTextBlockStyle, PortableTextListItemType, PortableTextMarkDefinition, PortableTextSpan } from "@portabletext/types" +import { +ArbitraryTypedObject, +PortableTextBlockStyle, +PortableTextListItemType, +PortableTextMarkDefinition, +PortableTextSpan +} from "@portabletext/types" import ShortUniqueId from "short-unique-id"; import { IDomHtmlNode, IDomTextNode } from "../parser/index.js"; @@ -56,6 +62,7 @@ export type TransformTableCellFunction = (node: IDomHtmlNode) => PortableTextIte export type TransformFunction = TransformElementFunction | TransformListItemFunction; export type MergePortableTextItemsFunction = (itemsToMerge: ReadonlyArray) => PortableTextItem[]; +export type ResolverFunction = (value: T) => string; /** * Recursively traverses and optionally transforms a Portable Text structure using a provided @@ -263,28 +270,6 @@ export const compose = ( firstFunction ); -export const resolveTable = ( - table: PortableTextTable, - resolver: (value: any) => string -): string => { - let tableHtml = ""; - const resolveCell = (cell: PortableTextTableCell) => { - tableHtml += ""; - }; - for (let i = 0; i < table.numColumns; i++) { - const currentRow = table.rows[i]; - tableHtml += ""; - currentRow.cells.forEach(resolveCell); - tableHtml += ""; - } - tableHtml += "
"; - for (let j = 0; j < cell.childBlocksCount; j++) { - tableHtml += resolver(cell.content); - } - tableHtml += "
"; - return tableHtml; -}; - export const getAllNewLineAndWhiteSpace = /\n\s*/g; export const uid = new ShortUniqueId.default({length: 16}); diff --git a/tests/components/portable-text.spec.tsx b/tests/components/portable-text.spec.tsx index eb61bc1..6a97eec 100644 --- a/tests/components/portable-text.spec.tsx +++ b/tests/components/portable-text.spec.tsx @@ -16,9 +16,9 @@ PortableTextExternalLink, PortableTextImage, PortableTextInternalLink, PortableTextTable, -resolveTable, transformToPortableText } from '../../src' +import { resolveTable } from '../../src/utils/resolution/html'; const dummyRichText: Elements.RichTextElement = { value: "

some text in a paragraph

", diff --git a/tests/transfomers/portable-text-transformer/__snapshots__/html-transformer.spec.ts.snap b/tests/transfomers/portable-text-transformer/__snapshots__/html-transformer.spec.ts.snap index 24f1b9a..5a4a8ae 100644 --- a/tests/transfomers/portable-text-transformer/__snapshots__/html-transformer.spec.ts.snap +++ b/tests/transfomers/portable-text-transformer/__snapshots__/html-transformer.spec.ts.snap @@ -6,6 +6,8 @@ exports[`HTML converter resolves a linked item 1`] = `"

resolved value of text exports[`HTML converter resolves a table 1`] = `"

Ivan

Jiri

Ondra

Dan

"`; -exports[`HTML converter resolves an asset 1`] = `""`; +exports[`HTML converter resolves an asset 1`] = `""`; + +exports[`HTML converter resolves an asset with custom resolver 1`] = `""`; exports[`HTML converter resolves internal link 1`] = `"

item

"`; diff --git a/tests/transfomers/portable-text-transformer/html-transformer.spec.ts b/tests/transfomers/portable-text-transformer/html-transformer.spec.ts index 319f3f2..2119d81 100644 --- a/tests/transfomers/portable-text-transformer/html-transformer.spec.ts +++ b/tests/transfomers/portable-text-transformer/html-transformer.spec.ts @@ -8,16 +8,18 @@ import { } from "@portabletext/to-html"; import { - browserParse, - nodeParse, - PortableTextComponent, - PortableTextExternalLink, - PortableTextImage, - PortableTextInternalLink, - PortableTextTable, - resolveTable, - transformToPortableText, -} from "../../../src"; +browserParse, +nodeParse, +PortableTextComponent, +PortableTextExternalLink, +PortableTextImage, +PortableTextInternalLink, +PortableTextTable, +ResolverFunction, +transformToPortableText +} from "../../../src" + +import { resolveImage, resolveTable, toHTMLImageDefault } from "../../../src/utils/resolution/html"; jest.mock('short-unique-id', () => { return { @@ -27,6 +29,19 @@ jest.mock('short-unique-id', () => { } }); + type CustomResolvers = { + image?: ResolverFunction; + block?: ResolverFunction; + table?: ResolverFunction; + component?: ResolverFunction; + internalLink?: ResolverFunction; + link?: ResolverFunction; +}; + +const customResolvers: Partial = { + image: (image) => `` +} + describe("HTML converter", () => { const richTextTemplate: Elements.RichTextElement = { @@ -61,11 +76,11 @@ describe("HTML converter", () => { name: "dummy" }; - const getPortableTextComponents = (element: Elements.RichTextElement): PortableTextOptions => ({ + const getPortableTextComponents = (element: Elements.RichTextElement, customResolvers: CustomResolvers = {}): PortableTextOptions => ({ components: { types: { - image: ({ value }: PortableTextTypeComponentOptions) => { - return ``; + image: ({ value }) => { + return customResolvers.image ? customResolvers.image(value) : resolveImage(value, toHTMLImageDefault); }, component: ({ value }: PortableTextTypeComponentOptions) => { const linkedItem = element.linkedItems.find(item => item.system.codename === value.component._ref); @@ -165,4 +180,18 @@ describe("HTML converter", () => { expect(nodeResult).toMatchSnapshot(); expect(nodeResult).toEqual(browserResult); }) + + it("resolves an asset with custom resolver", () => { + const richTextInput = { ...richTextTemplate } + richTextInput.value = `
`; + const browserTree = browserParse(richTextInput.value); + const nodeTree = nodeParse(richTextInput.value); + const nodePortableText = transformToPortableText(nodeTree); + const browserPortableText = transformToPortableText(browserTree); + const nodeResult = toHTML(nodePortableText, getPortableTextComponents(richTextInput, customResolvers)); + const browserResult = toHTML(browserPortableText, getPortableTextComponents(richTextInput, customResolvers)); + + expect(nodeResult).toMatchSnapshot(); + expect(nodeResult).toEqual(browserResult); + }) }) \ No newline at end of file diff --git a/tests/transfomers/portable-text-transformer/vue-transformer.spec.ts b/tests/transfomers/portable-text-transformer/vue-transformer.spec.ts new file mode 100644 index 0000000..d350b8a --- /dev/null +++ b/tests/transfomers/portable-text-transformer/vue-transformer.spec.ts @@ -0,0 +1,109 @@ +import { Elements,ElementType } from "@kontent-ai/delivery-sdk"; +import { PortableText, PortableTextComponentProps, PortableTextComponents, toPlainText } from "@portabletext/vue" +import { mount } from "@vue/test-utils"; +import { h } from "vue"; + +import { nodeParse, PortableTextImage, PortableTextTable, transformToPortableText } from "../../../src" +import { resolveImage, resolveTable,toVueImageDefault } from '../../../src/utils/resolution/vue'; + +const dummyRichText: Elements.RichTextElement = { + value: "

some text in a paragraph

", + type: ElementType.RichText, + images: [], + linkedItemCodenames: [], + linkedItems: [ + { + system: { + id: "99e17fe7-a215-400d-813a-dc3608ee0294", + name: "test item", + codename: "test_item", + language: "default", + type: "test", + collection: "default", + sitemapLocations: [], + lastModified: "2022-10-11T11:27:25.4033512Z", + workflowStep: "published", + workflow: "default" + }, + elements: { + text_element: { + type: ElementType.Text, + name: "text element", + value: "random text value", + }, + }, + }, + ], + links: [], + name: "dummy", +}; + +const components: PortableTextComponents = { + types: { + image: ({ value }: PortableTextComponentProps) => + resolveImage(value, h, toVueImageDefault), + table: ({ value }: PortableTextComponentProps) => + resolveTable(value, h, toPlainText), + }, +}; + +describe("PortableText Vue Renderer", () => { + it("renders simple HTML from portable text", () => { + const jsonTree = nodeParse(dummyRichText.value); + const portableText = transformToPortableText(jsonTree); + + const wrapper = mount(PortableText, { + props: { + value: portableText, + }, + }); + + expect(wrapper.html()).toMatchInlineSnapshot( + `"

some text in a paragraph

"` + ); + }); + + it("renders an image", () => { + dummyRichText.value = `

some text before an asset

alternative_text
`; + const jsonTree = nodeParse(dummyRichText.value); + const portableText = transformToPortableText(jsonTree); + + const wrapper = mount(PortableText, { + props: { + value: portableText, + components: components, + }, + }); + + expect(wrapper.html()).toMatchInlineSnapshot(` +"

some text before an asset

+alternative_text" +`); + }); + + it("renders a table", () => { + dummyRichText.value = "\n \n \n
IvanJiri
OndraDan
"; + const jsonTree = nodeParse(dummyRichText.value); + const portableText = transformToPortableText(jsonTree); + + const wrapper = mount(PortableText, { + props: { + value: portableText, + components: components, + }, + }); + + expect(wrapper.html()).toMatchInlineSnapshot(` +" + + + + + + + + +
IvanJiri
OndraDan
" +`); + }); +}); From 777792140f1f98601400d4b2c735f7fcf98a618d Mon Sep 17 00:00:00 2001 From: Daniel Pokorny Date: Fri, 12 Jan 2024 11:51:59 +0100 Subject: [PATCH 3/6] update tests --- tests/components/portable-text.spec.tsx | 5 +++-- .../portable-text-transformer/html-transformer.spec.ts | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/components/portable-text.spec.tsx b/tests/components/portable-text.spec.tsx index 6a97eec..70625a6 100644 --- a/tests/components/portable-text.spec.tsx +++ b/tests/components/portable-text.spec.tsx @@ -18,7 +18,7 @@ PortableTextInternalLink, PortableTextTable, transformToPortableText } from '../../src' -import { resolveTable } from '../../src/utils/resolution/html'; +import { resolveImage, resolveTable, toHTMLImageDefault } from '../../src/utils/resolution/html'; const dummyRichText: Elements.RichTextElement = { value: "

some text in a paragraph

", @@ -63,7 +63,8 @@ const portableTextComponents: Partial = { return <>{tableString}; }, image: ({ value }: PortableTextTypeComponentProps) => { - return ; + const imageString = resolveImage(value, toHTMLImageDefault); + return <>{imageString}; } }, marks: { diff --git a/tests/transfomers/portable-text-transformer/html-transformer.spec.ts b/tests/transfomers/portable-text-transformer/html-transformer.spec.ts index 2119d81..3919b56 100644 --- a/tests/transfomers/portable-text-transformer/html-transformer.spec.ts +++ b/tests/transfomers/portable-text-transformer/html-transformer.spec.ts @@ -10,6 +10,7 @@ import { import { browserParse, nodeParse, +PortableTextBlock, PortableTextComponent, PortableTextExternalLink, PortableTextImage, @@ -18,7 +19,6 @@ PortableTextTable, ResolverFunction, transformToPortableText } from "../../../src" - import { resolveImage, resolveTable, toHTMLImageDefault } from "../../../src/utils/resolution/html"; jest.mock('short-unique-id', () => { @@ -79,7 +79,7 @@ describe("HTML converter", () => { const getPortableTextComponents = (element: Elements.RichTextElement, customResolvers: CustomResolvers = {}): PortableTextOptions => ({ components: { types: { - image: ({ value }) => { + image: ({ value }: PortableTextTypeComponentOptions) => { return customResolvers.image ? customResolvers.image(value) : resolveImage(value, toHTMLImageDefault); }, component: ({ value }: PortableTextTypeComponentOptions) => { From 13118418e480bbab1ca8826eda422e3077bfae20 Mon Sep 17 00:00:00 2001 From: Daniel Pokorny Date: Fri, 12 Jan 2024 11:51:00 +0100 Subject: [PATCH 4/6] update packages --- package-lock.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 416e1f8..5ace6c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,12 +17,14 @@ "@kontent-ai/delivery-sdk": "^14.6.0", "@portabletext/react": "^3.0.11", "@portabletext/to-html": "^2.0.5", - "@testing-library/jest-dom": "^6.1.5", + "@portabletext/vue": "^1.0.6", + "@testing-library/jest-dom": "^6.2.0", "@types/jest": "^29.5.11", "@types/react": "^18.2.47", "@types/react-test-renderer": "^18.0.7", - "@typescript-eslint/eslint-plugin": "^5.58.0", - "@typescript-eslint/parser": "^5.58.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "@vue/test-utils": "^2.4.3", "babel-jest": "^29.7.0", "eslint": "^8.56.0", "eslint-config-kontent-ai": "^0.1.8", @@ -31,7 +33,7 @@ "react": "^18.2.0", "react-test-renderer": "^18.2.0", "ts-jest": "^29.1.1", - "typescript": "5.0.3", + "typescript": "^5.0.3", "vue": "^3.3.11" } }, From 7e6c0e33aac7c9f60d33de3c1d97c60f32ada8b5 Mon Sep 17 00:00:00 2001 From: Daniel Pokorny Date: Fri, 12 Jan 2024 11:51:34 +0100 Subject: [PATCH 5/6] export traverse method --- index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.ts b/index.ts index ef8e245..c7e7411 100644 --- a/index.ts +++ b/index.ts @@ -1,5 +1,5 @@ +export { traversePortableText } from './src/utils/transformer-utils.js'; export { transformToJson } from "./src/transformers/json-transformer/json-transformer.js"; export { transformToPortableText } from "./src/transformers/portable-text-transformer/portable-text-transformer.js"; -export { extendPortableText } from "./src/utils/transformer-utils.js"; export { parse as browserParse } from "./src/parser/browser/rich-text-browser-parser.js"; export { parse as nodeParse } from "./src/parser/node/rich-text-node-parser.js"; \ No newline at end of file From 183b2163fd8e99a5b6e67844402f0628727ddbb9 Mon Sep 17 00:00:00 2001 From: Daniel Pokorny Date: Fri, 12 Jan 2024 11:51:48 +0100 Subject: [PATCH 6/6] adjust readme, regenerate tests --- README.md | 13 +++++++++---- tests/components/portable-text.spec.tsx | 4 +--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c3b840d..6e6a8e5 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ https://github.com/kontent-ai/rich-text-resolver-js/blob/14dcf88e5cb5233b1ff529b https://github.com/kontent-ai/rich-text-resolver-js/blob/14dcf88e5cb5233b1ff529b350341dfac79a888b/showcase/showcase.ts#L12-L20 +> 💡 For image resolution, you may use `resolveImage` helper function. You can provide it either with a custom resolution method or use provided default implementations for HTML and Vue, `toHTMLImageDefault` and `toVueImageDefault` respectively. + #### Item link https://github.com/kontent-ai/rich-text-resolver-js/blob/14dcf88e5cb5233b1ff529b350341dfac79a888b/showcase/showcase.ts#L22-L29 @@ -59,7 +61,7 @@ https://github.com/kontent-ai/rich-text-resolver-js/blob/14dcf88e5cb5233b1ff529b https://github.com/kontent-ai/rich-text-resolver-js/blob/14dcf88e5cb5233b1ff529b350341dfac79a888b/showcase/showcase.ts#L31-L58 -> 💡 For table resolution, you may use `resolveTable` helper function. It accepts two arguments -- custom block of type `table` and a method to transform content of its cells into valid HTML. See below for usage examples. Alternatively, you can iterate over the table structure and resolve it as per your requirements (e.g. if you want to add CSS classes to its elements) +> 💡 For table resolution, you may use `resolveTable` helper function. You can provide it either with a custom resolution method or use default implementation from a resolution package of your choice (such as `toHTML` or `toPlainText`)
@@ -102,7 +104,8 @@ HTML resolution using `@portabletext/to-html` package. ```ts import { escapeHTML, PortableTextOptions, toHTML } from "@portabletext/to-html"; -import { resolveTable } from "@kontent-ai/rich-text-resolver"; +import { resolveTable, resolveImage, toHTMLImageDefault } from "@kontent-ai/rich-text-resolver/utils/html"; + const richTextValue = ""; const linkedItems = [""]; // e.g. from SDK @@ -113,7 +116,8 @@ const portableTextComponents: PortableTextOptions = { components: { types: { image: ({ value }: PortableTextTypeComponentOptions) => { - return ``; + // helper method for resolving images + return resolveImage(value, toHTMLImageDefault); }, component: ({ value }: PortableTextTypeComponentOptions) => { const linkedItem = linkedItems.find( @@ -129,7 +133,8 @@ const portableTextComponents: PortableTextOptions = { } }, table: ({ value }: PortableTextTypeComponentOptions => { - const tableHtml = resolveTable(value, toHTML); // helper method for resolving tables + // helper method for resolving tables + const tableHtml = resolveTable(value, toHTML); return tableHtml; }, }, diff --git a/tests/components/portable-text.spec.tsx b/tests/components/portable-text.spec.tsx index 70625a6..8216673 100644 --- a/tests/components/portable-text.spec.tsx +++ b/tests/components/portable-text.spec.tsx @@ -164,9 +164,7 @@ describe("portable text React resolver", () => {

some text before an asset

, - , + "", ] `); })