From 2db70df4715bbb466e645e1ff6a101b9aaa30c68 Mon Sep 17 00:00:00 2001 From: Laurin Weger Date: Thu, 11 Sep 2025 19:57:06 +0300 Subject: [PATCH] add readableName to shexJ --- package-lock.json | 366 +++++++++----- package.json | 5 +- packages/cli/src/build.ts | 10 +- packages/schema-converter-shex/src/index.ts | 1 + .../typing/ShexJTypingTransformerCompact.ts | 469 ++++++++---------- .../src/typing/shexjToTypingCompact.ts | 13 +- .../src/util/annotateReadablePredicates.ts | 133 +++++ .../test/testData/propertyCollision.ts | 10 +- 8 files changed, 630 insertions(+), 377 deletions(-) create mode 100644 packages/schema-converter-shex/src/util/annotateReadablePredicates.ts diff --git a/package-lock.json b/package-lock.json index 32fd313..f4a56d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "workspaces": [ "packages/*" ], + "dependencies": { + "prettier-eslint": "^16.4.2" + }, "devDependencies": { "@babel/preset-env": "^7.26.9", "@testing-library/react": "^16.3.0", @@ -16906,7 +16909,6 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -16925,7 +16927,6 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -16935,7 +16936,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -16959,14 +16959,12 @@ "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/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -16977,7 +16975,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -16993,7 +16990,6 @@ "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" @@ -17006,7 +17002,6 @@ "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" @@ -17019,7 +17014,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -17032,7 +17026,6 @@ "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -17067,7 +17060,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", - "dev": true, "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", @@ -17082,7 +17074,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -17093,7 +17084,6 @@ "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" @@ -17106,7 +17096,6 @@ "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" @@ -17121,7 +17110,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/@hutson/parse-repository-url": { @@ -17649,7 +17637,6 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -18698,7 +18685,6 @@ "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", @@ -18712,7 +18698,6 @@ "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" @@ -18722,7 +18707,6 @@ "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", @@ -20718,7 +20702,6 @@ "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, "license": "MIT" }, "node_modules/@sindresorhus/is": { @@ -23140,7 +23123,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", @@ -23169,7 +23151,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", @@ -23215,7 +23196,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, "license": "MIT", "engines": { "node": "^16.0.0 || >=18.0.0" @@ -23229,7 +23209,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.21.0", @@ -23258,7 +23237,6 @@ "version": "7.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -23310,7 +23288,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.21.0", @@ -23328,7 +23305,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, "license": "ISC" }, "node_modules/@vitejs/plugin-react": { @@ -23842,7 +23818,6 @@ "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" @@ -23935,7 +23910,6 @@ "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", @@ -24142,7 +24116,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -24639,7 +24612,6 @@ "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" @@ -25025,7 +24997,6 @@ "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" @@ -25125,6 +25096,70 @@ "node": ">=12" } }, + "node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk/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==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chalk/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -25512,6 +25547,15 @@ "node": "^12.20.0 || >=14" } }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -26546,7 +26590,6 @@ "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/deepmerge": { @@ -26731,7 +26774,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "license": "MIT", "dependencies": { "path-type": "^4.0.0" @@ -26740,11 +26782,16 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -27355,7 +27402,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -27554,7 +27600,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -27571,7 +27616,6 @@ "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" @@ -27584,14 +27628,12 @@ "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/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -27602,7 +27644,6 @@ "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", @@ -27619,7 +27660,6 @@ "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", @@ -27634,7 +27674,6 @@ "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", @@ -27651,7 +27690,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -27667,7 +27705,6 @@ "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" @@ -27680,7 +27717,6 @@ "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" @@ -27696,7 +27732,6 @@ "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" @@ -27709,7 +27744,6 @@ "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" @@ -27725,7 +27759,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -27738,7 +27771,6 @@ "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" @@ -27764,7 +27796,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", @@ -27782,7 +27813,6 @@ "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -27809,7 +27839,6 @@ "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" @@ -27822,7 +27851,6 @@ "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" @@ -27835,7 +27863,6 @@ "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" @@ -27852,7 +27879,6 @@ "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" @@ -28177,7 +28203,6 @@ "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", @@ -28194,7 +28219,6 @@ "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" @@ -28207,21 +28231,18 @@ "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/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" @@ -28350,7 +28371,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" @@ -28384,7 +28404,6 @@ "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" @@ -28421,7 +28440,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -28437,7 +28455,6 @@ "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" @@ -28453,7 +28470,6 @@ "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/fn.name": { @@ -28648,7 +28664,6 @@ "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": { @@ -29023,7 +29038,6 @@ "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", @@ -29044,7 +29058,6 @@ "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" @@ -29057,7 +29070,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -29068,7 +29080,6 @@ "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" @@ -29118,7 +29129,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, "license": "MIT", "dependencies": { "array-union": "^2.1.0", @@ -29182,7 +29192,6 @@ "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/graphql": { @@ -29283,6 +29292,27 @@ "dev": true, "license": "(Apache-2.0 OR MPL-1.1)" }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -29755,7 +29785,6 @@ "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" @@ -29797,7 +29826,6 @@ "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", @@ -29814,7 +29842,6 @@ "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" @@ -29863,7 +29890,6 @@ "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" @@ -29881,7 +29907,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", @@ -30268,7 +30293,6 @@ "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" @@ -30331,7 +30355,6 @@ "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" @@ -30374,7 +30397,6 @@ "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" @@ -30411,7 +30433,6 @@ "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" @@ -32460,14 +32481,12 @@ "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": { @@ -33512,7 +33531,6 @@ "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", @@ -33764,7 +33782,6 @@ "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": { @@ -33820,7 +33837,6 @@ "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/lodash.orderby": { @@ -33880,6 +33896,29 @@ "node": ">= 12.0.0" } }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-colored-level-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", + "integrity": "sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==", + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "loglevel": "^1.4.1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -34228,7 +34267,6 @@ "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" @@ -34270,7 +34308,6 @@ "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", @@ -34343,7 +34380,6 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -34633,7 +34669,6 @@ "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/negotiate": { @@ -36149,7 +36184,6 @@ "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", @@ -36255,7 +36289,6 @@ "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" @@ -36699,7 +36732,6 @@ "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" @@ -36804,7 +36836,6 @@ "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" @@ -36814,7 +36845,6 @@ "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" @@ -36880,7 +36910,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -36927,7 +36956,6 @@ "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" @@ -37034,7 +37062,6 @@ "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" @@ -37055,6 +37082,91 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-eslint": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-16.4.2.tgz", + "integrity": "sha512-vtJAQEkaN8fW5QKl08t7A5KCjlZuDUNeIlr9hgolMS5s3+uzbfRHDwaRnzrdqnY2YpHDmeDS/8zY0MKQHXJtaA==", + "license": "MIT", + "dependencies": { + "@typescript-eslint/parser": "^6.21.0", + "common-tags": "^1.8.2", + "dlv": "^1.1.3", + "eslint": "^8.57.1", + "indent-string": "^4.0.0", + "lodash.merge": "^4.6.2", + "loglevel-colored-level-prefix": "^1.0.0", + "prettier": "^3.5.3", + "pretty-format": "^29.7.0", + "require-relative": "^0.8.7", + "tslib": "^2.8.1", + "vue-eslint-parser": "^9.4.3" + }, + "engines": { + "node": ">=16.10.0" + }, + "funding": { + "url": "https://opencollective.com/prettier-eslint" + }, + "peerDependencies": { + "prettier-plugin-svelte": "^3.0.0", + "svelte-eslint-parser": "*" + }, + "peerDependenciesMeta": { + "prettier-plugin-svelte": { + "optional": true + }, + "svelte-eslint-parser": { + "optional": true + } + } + }, + "node_modules/prettier-eslint/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prettier-eslint/node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-eslint/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/prettier-eslint/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", @@ -37362,7 +37474,6 @@ "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", @@ -39904,6 +40015,12 @@ "node": ">=0.10.0" } }, + "node_modules/require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==", + "license": "MIT" + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -40022,7 +40139,6 @@ "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", @@ -40130,7 +40246,6 @@ "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", @@ -40882,7 +40997,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -41617,7 +41731,6 @@ "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" @@ -41972,7 +42085,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, "license": "MIT" }, "node_modules/then-request": { @@ -42268,7 +42380,6 @@ "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" @@ -42351,7 +42462,6 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", - "dev": true, "license": "MIT", "engines": { "node": ">=16" @@ -42608,7 +42718,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/tsscmp": { @@ -43304,7 +43413,6 @@ "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" @@ -43447,7 +43555,6 @@ "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -43646,7 +43753,6 @@ "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" @@ -45284,6 +45390,42 @@ "dev": true, "license": "MIT" }, + "node_modules/vue-eslint-parser": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/vue-template-compiler": { "version": "2.7.16", "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", @@ -45648,7 +45790,6 @@ "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" @@ -45959,7 +46100,6 @@ "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" diff --git a/package.json b/package.json index 3c49c16..c86f7d9 100644 --- a/package.json +++ b/package.json @@ -32,5 +32,8 @@ "ts-jest": "^29.3.0", "typescript": "^5.2.2", "vitest": "^3.1.3" + }, + "dependencies": { + "prettier-eslint": "^16.4.2" } -} \ No newline at end of file +} diff --git a/packages/cli/src/build.ts b/packages/cli/src/build.ts index 984fcf6..9986bae 100644 --- a/packages/cli/src/build.ts +++ b/packages/cli/src/build.ts @@ -9,6 +9,7 @@ import loading from "loading-cli"; import { dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { forAllShapes } from "./util/forAllShapes.js"; +import { annotateReadablePredicates } from "@ldo/schema-converter-shex"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -45,6 +46,9 @@ export async function build(options: BuildOptions) { console.error(`Error processing ${fileName}: ${errMessage}`); return; } + // Pre-annotate schema with readablePredicate to unify naming across outputs + annotateReadablePredicates(schema); + // Convert the content to types const format = options.format || "ldo"; const [typings, context] = await schemaConverterShex(schema, { format }); @@ -66,13 +70,13 @@ export async function build(options: BuildOptions) { schema: JSON.stringify(schema, null, 2), context: JSON.stringify(context, null, 2), format, - } + }, ); await fs.promises.writeFile( path.join(options.output, `${fileName}.${templateName}.ts`), - await prettier.format(finalContent, { parser: "typescript" }) + await prettier.format(finalContent, { parser: "typescript" }), ); - }) + }), ); }); diff --git a/packages/schema-converter-shex/src/index.ts b/packages/schema-converter-shex/src/index.ts index 830874c..802b007 100644 --- a/packages/schema-converter-shex/src/index.ts +++ b/packages/schema-converter-shex/src/index.ts @@ -1,3 +1,4 @@ import { shexjToTyping } from "./typing/shexjToTyping.js"; +export { annotateReadablePredicates } from "./util/annotateReadablePredicates.js"; export default shexjToTyping; diff --git a/packages/schema-converter-shex/src/typing/ShexJTypingTransformerCompact.ts b/packages/schema-converter-shex/src/typing/ShexJTypingTransformerCompact.ts index 7ba0c18..d84e081 100644 --- a/packages/schema-converter-shex/src/typing/ShexJTypingTransformerCompact.ts +++ b/packages/schema-converter-shex/src/typing/ShexJTypingTransformerCompact.ts @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import ShexJTraverser from "@ldo/traverser-shexj"; import type { Annotation } from "shexj"; import { nameFromObject } from "../context/JsonLdContextBuilder.js"; import type { ShapeInterfaceDeclaration } from "./ShapeInterfaceDeclaration.js"; -import { getRdfTypesForTripleConstraint } from "../util/getRdfTypesForTripleConstraint.js"; import * as dom from "dts-dom"; // Collected enum alias names (e.g., AuthenticatedAgentId) to emit at end @@ -44,65 +45,58 @@ function isPrimitiveLike(t: dom.Type): boolean { return intrinsicKinds.has(kind || ""); } -// Property name collision resolution using predicate IRI mapping -const predicateIriByProp = new WeakMap(); -/** - * resolveCollisions - * ----------------- - * Purpose: ensure that properties derived from different predicate IRIs but - * sharing the same local ending (final segment after '/', '#' or ':') become - * uniquely named TypeScript properties. - * - * Strategy (simplified): - * 1. Group properties by their current (local) name. - * 2. For any group with more than one property, rename each to - * `${secondLast}_${local}` where `secondLast` is the segment immediately - * before the local segment in the predicate IRI. - * 3. If collisions still remain (i.e. two IRIs share both secondLast and local - * segments), fall back to using a sanitized form of the full IRI (without the - * protocol) as the property name. - */ -function resolveCollisions(props: dom.PropertyDeclaration[]): void { - const groups = new Map(); - props.forEach((p) => { - const name = p.name; - if (!groups.has(name)) groups.set(name, []); - groups.get(name)!.push(p); - }); - groups.forEach((list) => { - if (list.length < 2) return; +// Small helpers for unions and alias naming +function isUnionType(t: dom.Type): t is dom.UnionType { + return (t as any)?.kind === "union"; +} - const predicateIris = new Set( - list.map((p) => predicateIriByProp.get(p)).filter(Boolean), - ); - if (predicateIris.size < 2) { - return; +function unionOf(types: dom.Type[]): dom.Type { + const flat: dom.Type[] = []; + const collect = (tt: dom.Type) => { + if (isUnionType(tt)) tt.members.forEach(collect); + else flat.push(tt); + }; + types.forEach(collect); + const seen = new Set(); + const unique: dom.Type[] = []; + flat.forEach((m) => { + const key = + (m as any).name || + (m as any).value || + (m as any).kind + JSON.stringify(m); + if (!seen.has(key)) { + seen.add(key); + unique.push(m); } - - // First pass rename using second last segment - list.forEach((prop) => { - const iri = predicateIriByProp.get(prop); - if (!iri) return; - const segs = iri.split(/[#:\/]/).filter(Boolean); - if (segs.length < 2) return; - const local = segs.at(-1)!; - const secondLast = segs.at(-2)!; - prop.name = `${secondLast}_${local}`; - }); - // Detect any remaining duplicates after first pass - const nameCounts = new Map(); - list.forEach((p) => - nameCounts.set(p.name, (nameCounts.get(p.name) || 0) + 1), - ); - list.forEach((p) => { - if (nameCounts.get(p.name)! > 1) { - const iri = predicateIriByProp.get(p); - if (iri) p.name = iri; - } - }); }); + if (unique.length === 0) return dom.type.any as unknown as dom.Type; + if (unique.length === 1) return unique[0]; + return dom.create.union(unique); } +function setOf(inner: dom.Type): dom.NamedTypeReference { + return { + kind: "name", + name: "Set", + typeArguments: [inner], + } as any; +} + +function recordOf(key: dom.Type, value: dom.Type): dom.NamedTypeReference { + return { + kind: "name", + name: "Record", + typeArguments: [key, value], + } as any; +} + +// Note: aliasing helpers previously used in earlier versions were removed. + +// Property name collision resolution using predicate IRI mapping +const predicateIriByProp = new WeakMap(); + +// Note: collisions are handled by annotateReadablePredicates pre-pass. + // Merge duplicate properties without introducing LdSet. If a property appears multiple // times (e.g., via EXTENDS or grouped expressions) we: // - union the types (flattening existing unions) @@ -112,88 +106,110 @@ function resolveCollisions(props: dom.PropertyDeclaration[]): void { function dedupeCompactProperties( props: dom.PropertyDeclaration[], ): dom.PropertyDeclaration[] { - const byName: Record = {}; const isSetRef = (t: dom.Type): t is dom.NamedTypeReference => (t as any).kind === "name" && (t as any).name === "Set"; const getSetInner = (t: dom.Type): dom.Type => isSetRef(t) ? (t as any).typeArguments[0] : t; - const toSet = (inner: dom.Type): dom.Type => - ({ kind: "name", name: "Set", typeArguments: [inner] }) as any; - const makeUnion = (a: dom.Type, b: dom.Type): dom.Type => { - const collect = (t: dom.Type, acc: dom.Type[]) => { - if ((t as any).kind === "union") { - (t as any).members.forEach((m: dom.Type) => collect(m, acc)); - } else acc.push(t); - }; - const members: dom.Type[] = []; - collect(a, members); - collect(b, members); - // de-dup via string emission heuristic - const seen = new Set(); - const filtered: dom.Type[] = []; - members.forEach((m) => { - const key = - (m as any).name || - (m as any).value || - (m as any).kind + JSON.stringify(m); - if (!seen.has(key)) { - seen.add(key); - filtered.push(m); - } - }); - if (filtered.length === 1) return filtered[0]; - return dom.create.union(filtered); - }; - props.forEach((p) => { - const existing = byName[p.name]; - if (!existing) { - byName[p.name] = p; - return; - } - // If predicates differ, keep both (assign numeric suffix to new one) - const predExisting = predicateIriByProp.get(existing); - const predNew = predicateIriByProp.get(p); - if (predExisting && predNew && predExisting !== predNew) { - const base = p.name; - let counter = 2; - while (byName[`${base}${counter}`]) counter++; - const newName = `${base}${counter}`; - const clone = dom.create.property(newName, p.type, p.flags); - clone.jsDocComment = p.jsDocComment; - if (predNew) predicateIriByProp.set(clone, predNew); - byName[newName] = clone; - return; + + // Group by composite key (name + predicate IRI) + const groups = new Map(); + for (const p of props) { + const pred = predicateIriByProp.get(p) || ""; + const key = `${p.name}\u0000${pred}`; + if (!groups.has(key)) groups.set(key, []); + groups.get(key)!.push(p); + } + + const merged: dom.PropertyDeclaration[] = []; + for (const [, group] of groups) { + if (group.length === 1) { + merged.push(group[0]); + continue; } - const existingSet = isSetRef(existing.type); - const newSet = isSetRef(p.type); - let mergedType: dom.Type; - if (existingSet && newSet) { - mergedType = toSet( - makeUnion(getSetInner(existing.type), getSetInner(p.type)), - ); - } else if (existingSet && !newSet) { - mergedType = toSet(makeUnion(getSetInner(existing.type), p.type)); - } else if (!existingSet && newSet) { - mergedType = toSet(makeUnion(existing.type, getSetInner(p.type))); - } else { - mergedType = makeUnion(existing.type, p.type); + let acc = group[0]; + for (let i = 1; i < group.length; i++) { + const next = group[i]; + const accSet = isSetRef(acc.type); + const nextSet = isSetRef(next.type); + let mergedType: dom.Type; + if (accSet && nextSet) { + mergedType = setOf( + unionOf([getSetInner(acc.type), getSetInner(next.type)]), + ); + } else if (accSet && !nextSet) { + mergedType = setOf(unionOf([getSetInner(acc.type), next.type])); + } else if (!accSet && nextSet) { + mergedType = setOf(unionOf([acc.type, getSetInner(next.type)])); + } else { + mergedType = unionOf([acc.type, next.type]); + } + const optional = + acc.flags === dom.DeclarationFlags.Optional || + next.flags === dom.DeclarationFlags.Optional + ? dom.DeclarationFlags.Optional + : dom.DeclarationFlags.None; + const mergedProp = dom.create.property(acc.name, mergedType, optional); + mergedProp.jsDocComment = + acc.jsDocComment && next.jsDocComment + ? `${acc.jsDocComment} | ${next.jsDocComment}` + : acc.jsDocComment || next.jsDocComment; + const pred = predicateIriByProp.get(acc) || predicateIriByProp.get(next); + if (pred) predicateIriByProp.set(mergedProp, pred); + acc = mergedProp; } - const optional = - existing.flags === dom.DeclarationFlags.Optional || - p.flags === dom.DeclarationFlags.Optional - ? dom.DeclarationFlags.Optional - : dom.DeclarationFlags.None; - const merged = dom.create.property(p.name, mergedType, optional); - merged.jsDocComment = - existing.jsDocComment && p.jsDocComment - ? `${existing.jsDocComment} | ${p.jsDocComment}` - : existing.jsDocComment || p.jsDocComment; - // Preserve predicate mapping - const pred = predicateIriByProp.get(existing) || predicateIriByProp.get(p); - if (pred) predicateIriByProp.set(merged, pred); - byName[p.name] = merged; - }); - return Object.values(byName); + merged.push(acc); + } + return merged; +} + +// Helpers to add id: IRI to anonymous object(-union) types +function ensureIdOnMembers(members?: any[]): void { + if (!members) return; + const props = (members.filter?.((m: any) => m?.kind === "property") || + []) as dom.PropertyDeclaration[]; + if (!props.some((m) => m.name === "id")) { + members.unshift( + dom.create.property( + "id", + dom.create.namedTypeReference("IRI"), + dom.DeclarationFlags.None, + ), + ); + } +} + +function withIdOnAnonymousObject(t: dom.Type): dom.Type { + if ((t as any)?.kind === "object") { + const mems = (t as any).members as dom.PropertyDeclaration[] | undefined; + ensureIdOnMembers(mems as any); + return t; + } + return t; +} + +function withIdInUnionObjectMembers(t: dom.Type): dom.Type { + if (!isUnionType(t)) return t; + const members = (t as dom.UnionType).members.map((m) => + (m as any)?.kind === "object" ? withIdOnAnonymousObject(m) : m, + ); + return dom.create.union(members); +} + +// Create property and attach predicate IRI and annotations consistently +function createProperty( + name: string, + type: dom.Type, + flags: dom.DeclarationFlags, + predicateIri?: string, + annotations?: Annotation[], +): dom.PropertyDeclaration { + const prop = dom.create.property(name, type, flags); + if (predicateIri) predicateIriByProp.set(prop, predicateIri); + const cmt = commentFromAnnotations(annotations) || ""; + prop.jsDocComment = cmt + ? `${cmt}\n\nOriginal IRI: ${predicateIri ?? ""}`.trim() + : `Original IRI: ${predicateIri ?? ""}`; + return prop; } export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< @@ -334,17 +350,16 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< if (kind === "property") { inputProps.push(expr as dom.PropertyDeclaration); } else if (kind === "object" || kind === "interface") { - (expr as dom.ObjectType | dom.InterfaceDeclaration).members.forEach( - (m) => { - if ((m as any).kind === "property") { - inputProps.push(m as dom.PropertyDeclaration); - } - }, - ); + const mlist = (expr as dom.ObjectType | dom.InterfaceDeclaration) + .members; + mlist.forEach((m) => { + if ((m as any).kind === "property") { + inputProps.push(m as dom.PropertyDeclaration); + } + }); } }); const deduped = dedupeCompactProperties(inputProps); - resolveCollisions(deduped); objectType.members.push(...deduped); return objectType; }, @@ -360,11 +375,10 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< context, ) => { const transformedChildren = await getTransformedChildren(); - const rdfTypes = getRdfTypesForTripleConstraint(node); - const baseName = context.getNameFromIri( - tripleConstraint.predicate, - rdfTypes[0], - ); + const baseName = + ((tripleConstraint as any).readablePredicate as string | undefined) ?? + context.getNameFromIri(tripleConstraint.predicate); + const max = tripleConstraint.max; const isPlural = max === -1 || (max !== undefined && max !== 1); const isOptional = tripleConstraint.min === 0; @@ -373,6 +387,48 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< if (transformedChildren.valueExpr) valueType = transformedChildren.valueExpr as dom.Type; + // Generic: If valueExpr is a NodeConstraint with concrete `values`, + // build a union of named alias references derived from those values. + // Works for any predicate (not only rdf:type). + const originalValueExpr: any = (tripleConstraint as any)?.valueExpr; + if ( + originalValueExpr && + typeof originalValueExpr === "object" && + originalValueExpr.type === "NodeConstraint" && + Array.isArray(originalValueExpr.values) && + originalValueExpr.values.length > 0 + ) { + const aliasRefs: dom.Type[] = []; + for (const v of originalValueExpr.values) { + // valueSetValue can be string IRIREF or ObjectLiteral or other stems; handle IRIREF and ObjectLiteral + if (typeof v === "string") { + // For concrete IRIREF values, use a string literal of the IRI + aliasRefs.push(dom.type.stringLiteral(v)); + } else if (v && typeof v === "object") { + // ObjectLiteral has `value`; use that literal as alias base + const literalVal = (v as any).value as string | undefined; + if (literalVal) { + // For explicit literal values, use a string literal type + aliasRefs.push(dom.type.stringLiteral(literalVal)); + } + // For other union members (IriStem, ranges, Language, etc.), skip here; fall back covered below if none collected + } + } + if (aliasRefs.length > 0) { + const union = unionOf(aliasRefs); + const final = isPlural ? setOf(union) : union; + return createProperty( + baseName, + final, + isOptional + ? dom.DeclarationFlags.Optional + : dom.DeclarationFlags.None, + tripleConstraint.predicate, + tripleConstraint.annotations, + ); + } + } + if ( (valueType as dom.InterfaceDeclaration).kind === "interface" && !(valueType as dom.InterfaceDeclaration).name @@ -421,119 +477,36 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< ) { const ifaceName = (valueType as dom.InterfaceDeclaration).name; // Dictionary of full object instances keyed by IRI - finalType = { - kind: "name", - name: "Record", - typeArguments: [ - dom.create.namedTypeReference("IRI"), - dom.create.namedTypeReference(ifaceName), - ], - } as dom.Type; + finalType = recordOf( + dom.create.namedTypeReference("IRI"), + dom.create.namedTypeReference(ifaceName), + ); } else { // Anonymous object or union of anonymous/interface objects let valueForRecord: dom.Type = valueType; if (unionAllObjLike) { // Ensure each union member has id?: IRI if anonymous object - (valueType as dom.UnionType).members = ( - valueType as dom.UnionType - ).members.map((m) => { - if ((m as dom.InterfaceDeclaration).kind === "interface") - return m; - if ((m as dom.ObjectType).kind === "object") { - const anonMembers = ( - m as unknown as { members?: dom.PropertyDeclaration[] } - ).members; - const hasId = (anonMembers || []).some( - (mm) => mm.name === "id", - ); - if (!hasId && anonMembers) { - anonMembers.unshift( - dom.create.property( - "id", - dom.create.namedTypeReference("IRI"), - dom.DeclarationFlags.None, - ), - ); - } - } - return m; - }); - valueForRecord = valueType; // union retained + valueForRecord = withIdInUnionObjectMembers(valueType); } else { - const anon = valueType as dom.ObjectType; - const anonMembers = ( - anon as unknown as { members?: dom.PropertyDeclaration[] } - ).members; - const hasId = (anonMembers || []).some((m) => m.name === "id"); - if (!hasId && anonMembers) { - anonMembers.unshift( - dom.create.property( - "id", - dom.create.namedTypeReference("IRI"), - dom.DeclarationFlags.None, - ), - ); - } - valueForRecord = anon as dom.Type; + valueForRecord = withIdOnAnonymousObject(valueType); } - finalType = { - kind: "name", - name: "Record", - typeArguments: [ - dom.create.namedTypeReference("IRI"), - valueForRecord, - ], - } as dom.Type; + finalType = recordOf( + dom.create.namedTypeReference("IRI"), + valueForRecord, + ); } } else { - finalType = { - kind: "name", - name: "Set", - typeArguments: [valueType], - } as dom.Type; + finalType = setOf(valueType); } } else { // Singular // If anonymous object or union of object-like types, ensure id: IRI is present (mandatory) if (objLike) { if ((valueType as dom.ObjectType).kind === "object") { - const members = ( - valueType as unknown as { - members?: dom.PropertyDeclaration[]; - } - ).members; - const hasId = (members || []).some((m) => m.name === "id"); - if (!hasId && members) { - members.unshift( - dom.create.property( - "id", - dom.create.namedTypeReference("IRI"), - dom.DeclarationFlags.None, - ), - ); - } + valueType = withIdOnAnonymousObject(valueType); } } else if (isUnion && unionAllObjLike) { - (valueType as dom.UnionType).members = ( - valueType as dom.UnionType - ).members.map((m) => { - if ((m as dom.ObjectType).kind === "object") { - const mems = ( - m as unknown as { members?: dom.PropertyDeclaration[] } - ).members; - const hasId = (mems || []).some((mm) => mm.name === "id"); - if (!hasId && mems) { - mems.unshift( - dom.create.property( - "id", - dom.create.namedTypeReference("IRI"), - dom.DeclarationFlags.None, - ), - ); - } - } - return m; - }); + valueType = withIdInUnionObjectMembers(valueType); } // Singular: always the interface/object type itself (never Id union) if ( @@ -547,23 +520,13 @@ export const ShexJTypingTransformerCompact = ShexJTraverser.createTransformer< finalType = valueType; } } - - const prop = dom.create.property( + return createProperty( baseName, finalType, isOptional ? dom.DeclarationFlags.Optional : dom.DeclarationFlags.None, + tripleConstraint.predicate, + tripleConstraint.annotations, ); - predicateIriByProp.set(prop, tripleConstraint.predicate); - prop.jsDocComment = - commentFromAnnotations(tripleConstraint.annotations) || ""; - // Always append original predicate IRI reference (compact format only) - // If an existing comment is present, add a blank line before the Original IRI line. - if (prop.jsDocComment) { - prop.jsDocComment = `${prop.jsDocComment}\n\nOriginal IRI: ${tripleConstraint.predicate}`; - } else { - prop.jsDocComment = `Original IRI: ${tripleConstraint.predicate}`; - } - return prop; }, }, diff --git a/packages/schema-converter-shex/src/typing/shexjToTypingCompact.ts b/packages/schema-converter-shex/src/typing/shexjToTypingCompact.ts index bd0d39b..4278381 100644 --- a/packages/schema-converter-shex/src/typing/shexjToTypingCompact.ts +++ b/packages/schema-converter-shex/src/typing/shexjToTypingCompact.ts @@ -8,6 +8,7 @@ import { } from "./ShexJTypingTransformerCompact.js"; import * as dom from "dts-dom"; import type { TypeingReturn } from "./shexjToTypingLdo.js"; +import { annotateReadablePredicates } from "../util/annotateReadablePredicates.js"; export async function shexjToTypingCompact( shexj: Schema, @@ -24,6 +25,9 @@ export async function shexjToTypingCompact( const nameBuilder = new JsonLdContextBuilder(); await ShexJNameVisitor.visit(processedShexj, "Schema", nameBuilder); + // Ensure collisions are pre-resolved and stored in readablePredicate on EachOf TCs + annotateReadablePredicates(processedShexj); + additionalCompactEnumAliases.clear(); const declarations = await ShexJTypingTransformerCompact.transform( processedShexj, @@ -34,9 +38,14 @@ export async function shexjToTypingCompact( ); // Append only enum aliases (no interface Id aliases in compact format now) + const hasName = (d: unknown): d is { name: string } => + typeof (d as { name?: unknown }).name === "string"; additionalCompactEnumAliases.forEach((alias) => { - const exists = declarations.some((d) => (d as any).name === alias); - if (!exists) declarations.push(dom.create.alias(alias, dom.type.string)); + const exists = declarations.some((d) => hasName(d) && d.name === alias); + if (!exists) + declarations.push( + dom.create.alias(alias, dom.create.namedTypeReference("IRI")), + ); }); const typings = declarations.map((declaration) => ({ diff --git a/packages/schema-converter-shex/src/util/annotateReadablePredicates.ts b/packages/schema-converter-shex/src/util/annotateReadablePredicates.ts new file mode 100644 index 0000000..4ed9d67 --- /dev/null +++ b/packages/schema-converter-shex/src/util/annotateReadablePredicates.ts @@ -0,0 +1,133 @@ +import type { Schema, ShapeDecl, Shape, EachOf, TripleConstraint } from "shexj"; + +// Split IRI by colon, slash and hash; drop empties +const splitIriTokens = (iri: string): string[] => + iri.split(/[:/#]+/).filter(Boolean); +// Keep dots and dashes (so 0.1 stays as 0.1) but sanitize everything else +const sanitize = (s: string) => s.replace(/[^\w.\-]/g, "_"); + +type TCwReadable = TripleConstraint & { readablePredicate?: string }; + +/** + * Annotate EachOf-level TripleConstraints with a collision-free readablePredicate. + * Rule: for any group that shares the same local token, rename all members using + * prefix-first `${prefix}_${local}` from left to right; fallback to composite. + */ +export function annotateReadablePredicates(schema: Schema): void { + const shapes = schema.shapes ?? []; + + const annotateEachOf = (eachOf: EachOf): void => { + if ( + !eachOf || + eachOf.type !== "EachOf" || + !Array.isArray(eachOf.expressions) + ) + return; + + const tcs = (eachOf.expressions as unknown[]).filter( + (e): e is TCwReadable => + typeof e === "object" && + e !== null && + (e as any).type === "TripleConstraint", + ); + + if (tcs.length > 0) { + // Group by local token (last segment of IRI) and set a base readablePredicate for all + const groups = new Map(); + for (const tc of tcs) { + const tokens = splitIriTokens(tc.predicate); + const local = tokens.length ? tokens[tokens.length - 1] : tc.predicate; + // default base name for non-colliders + tc.readablePredicate = local; + const arr = groups.get(local) ?? []; + arr.push(tc); + groups.set(local, arr); + } + // Resolve each group (rename all in collisions) + for (const [, arr] of groups) { + if (arr.length <= 1) continue; + const used = new Set(); + const local = splitIriTokens(arr[0].predicate).slice(-1)[0] ?? ""; + for (const tc of arr) { + const tokens = splitIriTokens(tc.predicate); + let localIdx = tokens.lastIndexOf(local); + if (localIdx === -1) localIdx = Math.max(tokens.length - 1, 0); + let prefixIdx = localIdx - 1; + let assigned = false; + while (prefixIdx >= 0) { + const cand = `${sanitize(tokens[prefixIdx])}_${sanitize( + tokens[localIdx], + )}`; + if (!used.has(cand)) { + tc.readablePredicate = cand; + used.add(cand); + assigned = true; + break; + } + prefixIdx -= 1; + } + if (!assigned) { + const iriNoProto = tc.predicate.replace(/^[a-z]+:\/\//i, ""); + const composite = sanitize( + iriNoProto + .split(/[:/#]+/) + .slice(0, -1) + .join("_") || "iri", + ); + let cand = `${composite}_${sanitize(tokens[localIdx] || local)}`; + let n = 1; + while (used.has(cand)) cand = `${cand}_${n++}`; + tc.readablePredicate = cand; + used.add(cand); + } + } + } + + // Recurse into nested valueExpr shapes of each TC + for (const tc of tcs) { + const ve: any = (tc as any).valueExpr; + if (ve && typeof ve === "object") { + const t = (ve as any).type; + if (t === "Shape" && (ve as any).expression) + annotateEachOf((ve as any).expression as EachOf); + else if (t === "EachOf") annotateEachOf(ve as EachOf); + else if (t === "ShapeOr" && Array.isArray((ve as any).shapeExprs)) { + for (const sub of (ve as any).shapeExprs) annotateFromExpr(sub); + } else if ( + t === "ShapeAnd" && + Array.isArray((ve as any).shapeExprs) + ) { + for (const sub of (ve as any).shapeExprs) annotateFromExpr(sub); + } + } + } + } + + // Also recurse into any inline sub-EachOf/Shape expressions found directly in expressions + for (const ex of eachOf.expressions as any[]) { + if (ex && typeof ex === "object") annotateFromExpr(ex); + } + }; + + const annotateFromExpr = (expr: any): void => { + if (!expr || typeof expr !== "object") return; + const t = (expr as any).type; + if (t === "Shape" && (expr as any).expression) + annotateEachOf((expr as any).expression as EachOf); + else if (t === "EachOf") annotateEachOf(expr as EachOf); + else if (t === "ShapeOr" && Array.isArray((expr as any).shapeExprs)) { + for (const sub of (expr as any).shapeExprs) annotateFromExpr(sub); + } else if (t === "ShapeAnd" && Array.isArray((expr as any).shapeExprs)) { + for (const sub of (expr as any).shapeExprs) annotateFromExpr(sub); + } else if (t === "TripleConstraint") { + const ve = (expr as any).valueExpr; + if (ve && typeof ve === "object") annotateFromExpr(ve); + } + }; + + for (const s of shapes) { + const sd = s as ShapeDecl; + const shape = (sd.shapeExpr || (sd as any)) as Shape | undefined; + if (shape?.expression) annotateFromExpr(shape as any); + } +} diff --git a/packages/schema-converter-shex/test/testData/propertyCollision.ts b/packages/schema-converter-shex/test/testData/propertyCollision.ts index abe875b..23c5a80 100644 --- a/packages/schema-converter-shex/test/testData/propertyCollision.ts +++ b/packages/schema-converter-shex/test/testData/propertyCollision.ts @@ -21,23 +21,23 @@ export interface C { /** * Original IRI: http://ex/label */ - label: any; + ex_label: any; /** * Original IRI: http://ex2/label */ - label2: any; + ex2_label: any; /** * Original IRI: http://xmlns.com/foaf/0.1/label */ - label3: any; + "0.1_label": any; /** * Original IRI: http://example.com/v1#label */ - label4: any; + v1_label: any; /** * Original IRI: http://api.example.com/v2.1:label */ - "v2.1:label": any; + "v2.1_label": any; } `, };