diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..d76d47d --- /dev/null +++ b/.eslintignore @@ -0,0 +1,11 @@ +# Ignore built distributions and generated bundles +node/*/dist/** +node/**/dist/** +**/web-bundle*.js +**/web-bundle*.min.js +**/bundle*.js +**/*.min.js +# Keep node_modules excluded +node_modules/** +# Ignore other generated directories +**/dist/** diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..e12c35a --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,33 @@ +// Flat ESLint config compatible with ESLint v9 +module.exports = [ + { + ignores: ["dist", "node_modules", "bin"], + languageOptions: { + parserOptions: { + ecmaVersion: 8, + }, + globals: { + // browser globals + window: "readonly", + document: "readonly", + navigator: "readonly", + // node globals + global: "readonly", + process: "readonly", + module: "readonly", + require: "readonly", + __dirname: "readonly", + __filename: "readonly", + // jest globals + describe: "readonly", + it: "readonly", + test: "readonly", + expect: "readonly", + beforeEach: "readonly", + afterEach: "readonly", + jest: "readonly", + }, + }, + extends: ["eslint:recommended", "prettier"], + }, +]; diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..493f284 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,13 @@ +module.exports = { + env: { + browser: true, + es6: true, + node: true, + jest: true, + }, + parserOptions: { + ecmaVersion: 8, + }, + extends: ["eslint:recommended", "prettier"], + ignorePatterns: ["dist", "node_modules", "bin"], +}; diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 9322a9d..c64a3ec 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -28,11 +28,8 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Install ESLint - run: | - npm install eslint@8.10.0 - npm install @microsoft/eslint-formatter-sarif@2.1.7 - npm install eslint-config-prettier@8.8.0 + - name: Install Dependencies + run: npm install - name: Run ESLint run: "npm run lint:sarif" diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml index 001cf30..4dfb856 100644 --- a/.github/workflows/prettier.yml +++ b/.github/workflows/prettier.yml @@ -17,8 +17,8 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Install prettier - run: npm install prettier@2.3.2 + - name: Install Dependencies + run: npm install - name: Run prettier run: npm run format:check diff --git a/.prettierrc.json b/.prettierrc.json index 57717ef..0457bf8 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -11,5 +11,6 @@ "tabWidth": 2 } } - ] + ], + "quoteProps": "preserve" } diff --git a/eslint.config.cjs b/eslint.config.cjs new file mode 100644 index 0000000..b1534d2 --- /dev/null +++ b/eslint.config.cjs @@ -0,0 +1,52 @@ +// Minimal flat ESLint config (eslint v9+) +module.exports = [ + { + // Apply to JS/TS source files + files: ["**/*.{js,ts,jsx,tsx}"], + // Ignore top-level/build artifacts and package bundles. Keep linting focused on source files. + ignores: [ + "dist", + "dist/**", + "node_modules", + "node_modules/**", + "bin", + "bin/**", + // ignore built distributions inside node/* packages + "node/*/dist", + "node/*/dist/**", + "node/**/dist", + "node/**/dist/**", + // ignore generated web bundles and minified bundles + "node/**/web-bundle*.js", + "node/**/web-bundle*.min.js", + "node/**/bundle*.js", + "**/*.min.js", + ], + languageOptions: { + parserOptions: { + ecmaVersion: 8, + }, + globals: { + // browser globals + window: "readonly", + document: "readonly", + navigator: "readonly", + // node globals + global: "readonly", + process: "readonly", + module: "readonly", + require: "readonly", + __dirname: "readonly", + __filename: "readonly", + // jest globals + describe: "readonly", + it: "readonly", + test: "readonly", + expect: "readonly", + beforeEach: "readonly", + afterEach: "readonly", + jest: "readonly", + }, + }, + }, +]; diff --git a/node/td-utils/index.ts b/node/td-utils/index.ts index 4e31132..548c16a 100644 --- a/node/td-utils/index.ts +++ b/node/td-utils/index.ts @@ -1 +1,2 @@ export { detectProtocolSchemes } from "./src/detectProtocolSchemes"; +export { expandTD } from "./src/expand"; diff --git a/node/td-utils/package-lock.json b/node/td-utils/package-lock.json index 60f9575..8e0a76c 100644 --- a/node/td-utils/package-lock.json +++ b/node/td-utils/package-lock.json @@ -13,10 +13,12 @@ "@babel/preset-env": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@types/jest": "^29.5.12", + "@types/node": "^24.10.0", "babel-jest": "^29.7.0", "browserify": "^17.0.0", "jest": "^28.1.3", "terser": "^5.14.2", + "tslib": "^2.8.1", "wot-thing-description-types": "^1.1.0-09-November-2023" } }, @@ -60,6 +62,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -2525,12 +2528,13 @@ } }, "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "version": "24.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", + "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.16.0" } }, "node_modules/@types/prettier": { @@ -3232,6 +3236,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001629", "electron-to-chromium": "^1.4.796", @@ -6721,6 +6726,13 @@ "node": ">=8.0" } }, + "node_modules/tslib": { + "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/tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", @@ -6780,10 +6792,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", diff --git a/node/td-utils/package.json b/node/td-utils/package.json index 2e53cf2..733868f 100644 --- a/node/td-utils/package.json +++ b/node/td-utils/package.json @@ -21,10 +21,12 @@ "@babel/preset-env": "^7.24.7", "@babel/preset-typescript": "^7.24.7", "@types/jest": "^29.5.12", + "@types/node": "^24.10.0", "babel-jest": "^29.7.0", "browserify": "^17.0.0", "jest": "^28.1.3", "terser": "^5.14.2", + "tslib": "^2.8.1", "wot-thing-description-types": "^1.1.0-09-November-2023" }, "author": "Eclipse Thingweb (https://thingweb.io/)", diff --git a/node/td-utils/src/expand.ts b/node/td-utils/src/expand.ts new file mode 100644 index 0000000..ec60072 --- /dev/null +++ b/node/td-utils/src/expand.ts @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and + * Document License (2015-05-13) which is available at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. + * + * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 + */ + +import { + AnyUri, + Form, + ThingDescription, + PropertyElement, + ActionElement, + EventElement, +} from "wot-thing-description-types"; + +const topLevelFormKey = "form"; +const topLevelFormDefinitions = "formDefinitions"; +const topLevelConnectionKey = "connection"; +const topLevelConnectionDefinitions = "connectionDefinitions"; +const topLevelSecurityKey = "security"; +const topLevelSecurityDefinitions = "securityDefinitions"; + +// Expand a TD with form/connection/security definitions at the top level into each interaction affordance +export function expandTD(inputTD: any): ThingDescription | undefined { + // in case of single form or connection + let defaultForm: any = {}; + let defaultConnection: any = {}; + let defaultSecurity: any = {}; + + // in case of multiple form or connections + let defaultFormArray: any = []; + let defaultConnectionArray: any = []; + let defaultSecurityArray: any = []; + + // finding default security(s) based on the top level "security" and "securityDefinitions" keys + if (topLevelSecurityKey in inputTD) { + const topLevelSecurity = (inputTD as any)[topLevelSecurityKey]; + + if (Array.isArray(topLevelSecurity)) { + if (topLevelSecurity.length > 1) { + defaultSecurityArray = topLevelSecurity.map((secKey: string) => { + return (inputTD as any)[topLevelSecurityDefinitions]?.[secKey]; + }); + + delete inputTD[topLevelSecurityKey]; + } else if (topLevelSecurity.length === 1) { + defaultSecurity = {security:(inputTD as any)[topLevelSecurityDefinitions]?.[topLevelSecurity[0]]}; + delete inputTD[topLevelSecurityKey]; + } else if (topLevelSecurity.length === 0) { + throw new Error("Empty security array is not allowed"); + } else { + // should not be possible. throw error + throw new Error("Badly formatted security array"); + } + } else if (typeof topLevelSecurity === "object" && topLevelSecurity !== null) { + // Check if object is empty + if (Object.keys(topLevelSecurity).length === 0) { + throw new Error("Empty security object is not allowed"); + } + defaultSecurity = {security:topLevelSecurity}; + delete inputTD[topLevelSecurityKey]; + } else { + // only object or array is allowed. return error + throw new Error("Only object or array is allowed for the security key in the top level"); + } + } else { + // no top level security to expand. There can be in a form or connection in the top level. + } + + // finding default connection(s) based on the top level "connection" and "connectionDefinitions" keys + if (topLevelConnectionKey in inputTD) { + const topLevelConnection = (inputTD as any)[topLevelConnectionKey]; + + if (Array.isArray(topLevelConnection)) { + if (topLevelConnection.length > 1) { + defaultConnectionArray = topLevelConnection.map((connKey: string) => { + return (inputTD as any)[topLevelConnectionDefinitions]?.[connKey]; + }); + + delete inputTD[topLevelConnectionKey]; + } else if (topLevelConnection.length === 1) { + defaultConnection = (inputTD as any)[topLevelConnectionDefinitions]?.[topLevelConnection[0]]; + delete inputTD[topLevelConnectionKey]; + } else if (topLevelConnection.length === 0) { + throw new Error("Empty connection array is not allowed"); + } else { + // should not be possible. throw error + throw new Error("Badly formatted connection array"); + } + } else if (typeof topLevelConnection === "object" && topLevelConnection !== null) { + // Check if object is empty + if (Object.keys(topLevelConnection).length === 0) { + throw new Error("Empty connection object is not allowed"); + } + defaultConnection = topLevelConnection; + delete inputTD[topLevelConnectionKey]; + } else { + // only object or array is allowed. return error + throw new Error("Only object or array is allowed for the connection key in the top level"); + } + } else { + // no top level connection to expand. There can be form etc. in the top level. + } + + // finding default form(s) based on the top level "form" and "formDefinitions" keys + if (topLevelFormKey in inputTD) { + const topLevelForm = (inputTD as any)[topLevelFormKey]; + if (Array.isArray(topLevelForm)) { + if (topLevelForm.length > 1) { + defaultFormArray = topLevelForm.map((formKey: string) => { + return (inputTD as any)[topLevelFormDefinitions]?.[formKey]; + }); + + delete inputTD[topLevelFormKey]; + } else if (topLevelForm.length === 1) { + defaultForm = (inputTD as any)[topLevelFormDefinitions]?.[topLevelForm[0]]; + delete inputTD[topLevelFormKey]; + } else if (topLevelForm.length === 0) { + throw new Error("Empty form array is not allowed"); + } else { + // should not be possible. throw error + throw new Error("Badly formatted form array"); + } + } else if (typeof topLevelForm === "object" && topLevelForm !== null) { + // Check if object is empty + if (Object.keys(topLevelForm).length === 0) { + throw new Error("Empty form object is not allowed"); + } + defaultForm = topLevelForm; + delete inputTD[topLevelFormKey]; + } else { + // only object or array is allowed. return error + throw new Error("Only non-empty object or array is allowed for the form key in the top level"); + } + } else { + // no top level form to expand. There can be connection etc. in the top level. + } + + console.log("Default form before merging:", defaultForm); + console.log("Default connection before merging:", defaultConnection); + console.log("Default security before merging:", defaultSecurity); + + // if defaultForm, defaultConnection and defaultSecurity are filled with items, merge them. defaultForm > defaultConnection > defaultSecurity + // The merging happens in groups of two but only if both are objects and not empty due to initialization as {} + if (typeof defaultConnection === "object" && Object.keys(defaultConnection).length > 0 && typeof defaultSecurity === "object" && Object.keys(defaultSecurity).length > 0) { + if (Object.keys(defaultConnection).length > 0 && Object.keys(defaultSecurity).length > 0) { + defaultConnection = { defaultSecurity, ...defaultConnection }; + } else if (Object.keys(defaultSecurity).length > 0) { + defaultConnection = defaultSecurity; + } + } + + console.log("Default connection after merging security:", defaultConnection); + if (typeof defaultConnection === "object" && Object.keys(defaultConnection).length > 0 && typeof defaultForm === "object" && Object.keys(defaultForm).length > 0) { + if (Object.keys(defaultForm).length > 0 && Object.keys(defaultConnection).length > 0) { + defaultForm = { ...defaultConnection, ...defaultForm }; + } else if (Object.keys(defaultConnection).length > 0) { + defaultForm = defaultConnection; + } + + } + defaultFormArray[0] = defaultForm; + + console.log("Default form after merging:", defaultForm); + console.log("Default form after merging:", defaultFormArray); + + // TODO: if one is object and the other is array, doesn't work. Way out?: convert the object to array of one and proceed + // TODO: no references in the root + + // // like above but for the array case. However, each array needs to be merged like a matrix multiplication. form array of length 2 and connection array of length 3 results in 6 forms + if (defaultFormArray.length > 0 && defaultConnectionArray.length > 0) { + const mergedFormArray: any[] = []; + for (const formItem of defaultFormArray) { + for (const connItem of defaultConnectionArray) { + mergedFormArray.push({ ...connItem, ...formItem }); + } + } + defaultFormArray = mergedFormArray; + console.log("Merged default form array:", defaultFormArray); + delete inputTD[topLevelConnectionDefinitions]; + delete inputTD[topLevelFormDefinitions]; + } + + // Helper function to expand forms for an interaction affordance + function expandForms(element: PropertyElement | ActionElement | EventElement, defaultFormArray: any) { + // if single default form and multiple affordance forms, it is fine + // if multiple default forms and single affordance form, it is fine. Need to expand that form array with each default form as potentials + // if multiple default forms and multiple affordance forms, throw error + + // helper to merge a form with a default object (handles base/href expansion and missing keys) + const mergeFormWithDefaults = (original: Form, def: any): Form => { + const newForm: Form = { ...original }; + if ("base" in def && newForm.href) { + try { + newForm.href = new URL(newForm.href as string, def.base as string).toString(); + } catch { + // ignore URL errors and leave href as-is + } + } + for (const key in def) { + if (key === "base") continue; + if (!(key in newForm)) { + (newForm as any)[key] = def[key]; + } + } + return newForm; + }; + + if (defaultFormArray.length > 1 && element.forms.length > 1) { + throw new Error("Multiple default forms and multiple affordance forms are not allowed together"); + } else if (defaultFormArray.length > 1 && element.forms.length === 1) { + // expand the single form with each default form + const originalForm = element.forms[0]; + element.forms = defaultFormArray.map((defForm: any) => mergeFormWithDefaults(originalForm, defForm)); + return; + } else if (defaultFormArray.length === 1 && element.forms.length >= 1) { + // case for single default form + const def = defaultFormArray[0]; + element.forms = element.forms.map((formElement: Form) => mergeFormWithDefaults(formElement, def)) as [ + Form, + ...Form[], + ]; + return; + } + } + + if (defaultFormArray.length > 0) { + // case for single default form + if ("properties" in inputTD) { + const properties = inputTD.properties; + for (const propertyKey in properties) { + expandForms(properties[propertyKey] as PropertyElement, defaultFormArray); + } + } + + if ("actions" in inputTD) { + const actions = inputTD.actions; + for (const actionKey in actions) { + expandForms(actions[actionKey] as ActionElement, defaultFormArray); + } + } + + if ("events" in inputTD) { + const events = inputTD.events; + for (const eventKey in events) { + expandForms(events[eventKey] as EventElement, defaultFormArray); + } + } + return inputTD; + // case for multiple default forms, i.e. multi ip address, multi protocol, multi content type + // [ + // { base: 'http://192.168.1.10:8080/mything' }, + // { base: 'coap://[2001:DB8::1]/mything' } + // ] + } else { + // no defaults at the top level. Investigate individual forms + } +} diff --git a/node/td-utils/test/expansion.test.suite.ts b/node/td-utils/test/expansion.test.suite.ts new file mode 100644 index 0000000..3355251 --- /dev/null +++ b/node/td-utils/test/expansion.test.suite.ts @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and + * Document License (2015-05-13) which is available at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. + * + * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 + */ + +export const positiveTestSuite = [ + { + name: "cborcoap", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-cbor-default", + "form": { + "contentType": "application/cbor", + "base": "coap://[2001:DB8::1]/mything/", + "security": { + "scheme": "nosec", + }, + }, + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "props/prop1", + }, + ], + }, + "prop2": { + "type": "string", + "forms": [ + { + "href": "props/prop2", + "contentType": "application/json", + }, + ], + }, + }, + "actions": { + "act1": { + "input": { "type": "string" }, + "forms": [ + { + "href": "actions/act1", + }, + ], + }, + }, + "events": { + "evt1": { + "data": { "type": "string" }, + "forms": [ + { + "href": "events/evt1", + }, + ], + }, + }, + }, + expected: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-cbor-default", + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "coap://[2001:db8::1]/mything/props/prop1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + "prop2": { + "type": "string", + "forms": [ + { + "href": "coap://[2001:db8::1]/mything/props/prop2", + "contentType": "application/json", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + }, + "actions": { + "act1": { + "input": { "type": "string" }, + "forms": [ + { + "href": "coap://[2001:db8::1]/mything/actions/act1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + }, + "events": { + "evt1": { + "data": { "type": "string" }, + "forms": [ + { + "href": "coap://[2001:db8::1]/mything/events/evt1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + }, + }, + }, + { + name: "cborcoap-alternate-input-1", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-cbor-default", + "formDefinitions": { + "f1": { + "contentType": "application/cbor", + "base": "coap://[2001:DB8::1]/mything/", + "security": { + "scheme": "nosec", + }, + }, + }, + "form": ["f1"], + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "props/prop1", + }, + ], + }, + }, + }, + expected: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-cbor-default", + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "coap://[2001:db8::1]/mything/props/prop1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + }, + }, + }, + { + name: "cborcoap-alternate-input-2", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-cbor-default", + "form": { + "contentType": "application/cbor", + }, + "connection":{ + "base": "coap://[2001:DB8::1]/mything/", + }, + "security": { + "scheme": "nosec" + }, + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "props/prop1", + }, + ], + }, + }, + }, + expected: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-cbor-default", + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "coap://[2001:db8::1]/mything/props/prop1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + }, + }, + }, + { + name: "modbus-separate-form-connection", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-modbus-params", + "connection": { + "base": "modbus+tcp://192.168.178.32:502/1/", + "modv:timeout": 1000, + "security": { + "scheme": "nosec", + }, + }, + "form": { + "modv:pollingInterval": 5000, + "modv:zeroBasedAddressing": true, + "modv:mostSignificantByte": true, + "modv:mostSignificantWord": true, + "contentType": "application/octet-stream", + }, + "properties": { + "prop1": { + "type": "boolean", + "forms": [ + { + "href": "1", + "modv:entity": "Coil", + }, + ], + }, + "prop2": { + "type": "string", + "forms": [ + { + "href": "2?quantity=8", + "modv:entity": "HoldingRegister", + }, + ], + }, + }, + }, + expected: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-modbus-params", + "properties": { + "prop1": { + "type": "boolean", + "forms": [ + { + "href": "modbus+tcp://192.168.178.32:502/1/1", + "modv:entity": "Coil", + "modv:timeout": 1000, + "security": { + "scheme": "nosec", + }, + "modv:pollingInterval": 5000, + "modv:zeroBasedAddressing": true, + "modv:mostSignificantByte": true, + "modv:mostSignificantWord": true, + "contentType": "application/octet-stream", + }, + ], + }, + "prop2": { + "type": "string", + "forms": [ + { + "href": "modbus+tcp://192.168.178.32:502/1/2?quantity=8", + "modv:entity": "HoldingRegister", + "modv:timeout": 1000, + "security": { + "scheme": "nosec", + }, + "modv:pollingInterval": 5000, + "modv:zeroBasedAddressing": true, + "modv:mostSignificantByte": true, + "modv:mostSignificantWord": true, + "contentType": "application/octet-stream", + }, + ], + }, + }, + }, + }, + { + name: "multi-protocol-multi-contenttype", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-multi-protocol", + "connectionDefinitions": { + "http": { + "base": "http://192.168.1.10:8080/mything", + }, + "coap": { + "base": "coap://[2001:DB8::1]/mything", + }, + }, + "formDefinitions": { + "json": { + "contentType": "application/json", + }, + "cbor": { + "contentType": "application/cbor", + }, + }, + "form": ["json", "cbor"], + "connection": ["http", "coap"], + "security": { + "scheme": "nosec", + }, + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "props/prop1", + }, + ], + }, + "prop2": { + "type": "string", + "forms": [ + { + "href": "props/prop2", + }, + ], + }, + }, + }, + expected: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-multi-protocol", + + "properties": { + "prop1": { + "type": "string", + "forms": [ + { + "href": "http://192.168.1.10:8080/props/prop1", + "contentType": "application/json", + "security": { + "scheme": "nosec", + }, + }, + { + "href": "coap://[2001:db8::1]/props/prop1", + "contentType": "application/json", + "security": { + "scheme": "nosec", + }, + }, + { + "href": "http://192.168.1.10:8080/props/prop1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + { + "href": "coap://[2001:db8::1]/props/prop1", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + "prop2": { + "type": "string", + "forms": [ + { + "href": "http://192.168.1.10:8080/props/prop2", + "contentType": "application/json", + "security": { + "scheme": "nosec", + }, + }, + { + "href": "coap://[2001:db8::1]/props/prop2", + "contentType": "application/json", + "security": { + "scheme": "nosec", + }, + }, + { + "href": "http://192.168.1.10:8080/props/prop2", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + { + "href": "coap://[2001:db8::1]/props/prop2", + "contentType": "application/cbor", + "security": { + "scheme": "nosec", + }, + }, + ], + }, + }, + }, + }, +]; + +export const negativeTestSuite = [ + { + name: "empty-connection-object", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-modbus-params", + "connection": {}, + "properties": { + "prop1": { + "type": "boolean", + "forms": [ + { + "href": "1", + "modv:entity": "Coil", + }, + ], + }, + }, + }, + expected: "Empty connection object is not allowed", + }, + { + name: "empty-form-object", + input: { + "@context": "https://www.w3.org/ns/wot-next/td", + "title": "recommended-test-modbus-params", + "form": {}, + "properties": { + "prop1": { + "type": "boolean", + "forms": [ + { + "href": "1", + "modv:entity": "Coil", + }, + ], + }, + }, + }, + expected: "Empty form object is not allowed", + }, +]; diff --git a/node/td-utils/test/expansion.test.ts b/node/td-utils/test/expansion.test.ts new file mode 100644 index 0000000..8003ad7 --- /dev/null +++ b/node/td-utils/test/expansion.test.ts @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and + * Document License (2015-05-13) which is available at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. + * + * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 + */ +import { expandTD } from "../src/expand"; +import { ThingDescription } from "wot-thing-description-types"; +import { positiveTestSuite } from "./expansion.test.suite"; +import { negativeTestSuite } from "./expansion.test.suite"; + +describe("test examples", () => { + positiveTestSuite.forEach((t: (typeof positiveTestSuite)[number]) => { + it(`should test ${t.name}`, () => { + testTD(t.input, t.expected); + }); + }); +}); + +describe("test negative examples", () => { + negativeTestSuite.forEach((t: (typeof negativeTestSuite)[number]) => { + it(`should test ${t.name}`, () => { + try { + const generatedTD = expandTD(t.input as any); + } catch (error) { + // console.error(`❌ ${t.name} Caught error:`, (error as Error).message); + expect((error as Error).message).toBe(t.expected); + } + }); + }); +}); + +const testTD = (tdCompact: any, tdExpanded: any) => { + const generatedTD = expandTD(tdCompact); + + expect(generatedTD).toMatchObject(tdExpanded); +}; diff --git a/node/td-utils/test/protocol-detection.test.suite.ts b/node/td-utils/test/protocol-detection.test.suite.ts index 75a0252..0a841ee 100644 --- a/node/td-utils/test/protocol-detection.test.suite.ts +++ b/node/td-utils/test/protocol-detection.test.suite.ts @@ -1,8 +1,8 @@ -import httpAndMqtt from "./examples/httpAndMqtt.json"; -import noProtocol from "./examples/noProtocol.json"; -import onlyHttp from "./examples/onlyHttp.json"; -import onlyMqtt from "./examples/onlyMqtt.json"; -import secureProtocols from "./examples/secureProtocols.json"; +import httpAndMqtt from "./protocolDetectionExamples/httpAndMqtt.json"; +import noProtocol from "./protocolDetectionExamples/noProtocol.json"; +import onlyHttp from "./protocolDetectionExamples/onlyHttp.json"; +import onlyMqtt from "./protocolDetectionExamples/onlyMqtt.json"; +import secureProtocols from "./protocolDetectionExamples/secureProtocols.json"; export const testSuite = [ { diff --git a/node/td-utils/test/examples/httpAndMqtt.json b/node/td-utils/test/protocolDetectionExamples/httpAndMqtt.json similarity index 100% rename from node/td-utils/test/examples/httpAndMqtt.json rename to node/td-utils/test/protocolDetectionExamples/httpAndMqtt.json diff --git a/node/td-utils/test/examples/noProtocol.json b/node/td-utils/test/protocolDetectionExamples/noProtocol.json similarity index 100% rename from node/td-utils/test/examples/noProtocol.json rename to node/td-utils/test/protocolDetectionExamples/noProtocol.json diff --git a/node/td-utils/test/examples/onlyHttp.json b/node/td-utils/test/protocolDetectionExamples/onlyHttp.json similarity index 100% rename from node/td-utils/test/examples/onlyHttp.json rename to node/td-utils/test/protocolDetectionExamples/onlyHttp.json diff --git a/node/td-utils/test/examples/onlyMqtt.json b/node/td-utils/test/protocolDetectionExamples/onlyMqtt.json similarity index 100% rename from node/td-utils/test/examples/onlyMqtt.json rename to node/td-utils/test/protocolDetectionExamples/onlyMqtt.json diff --git a/node/td-utils/test/examples/secureProtocols.json b/node/td-utils/test/protocolDetectionExamples/secureProtocols.json similarity index 100% rename from node/td-utils/test/examples/secureProtocols.json rename to node/td-utils/test/protocolDetectionExamples/secureProtocols.json diff --git a/package-lock.json b/package-lock.json index 6c9166a..1171a5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,22 +7,12 @@ "name": "Thingweb TD Tools", "license": "EPL-2.0 OR W3C-20150513", "devDependencies": { - "@microsoft/eslint-formatter-sarif": "^2.1.7", - "eslint": "^8.22.0", - "eslint-config-prettier": "^8.8.0", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", "husky": "^7.0.4", "lerna": "^5.4.3", - "prettier": "^2.3.2", - "pretty-quick": "^3.1.1" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "prettier": "3.0.0", + "pretty-quick": "^4.2.2" } }, "node_modules/@babel/code-frame": { @@ -204,39 +194,99 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -244,19 +294,47 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@gar/promisify": { @@ -265,18 +343,28 @@ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -284,6 +372,7 @@ "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" }, @@ -292,11 +381,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", @@ -1371,18 +1468,6 @@ "node": "^14.15.0 || >=16.0.0" } }, - "node_modules/@microsoft/eslint-formatter-sarif": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@microsoft/eslint-formatter-sarif/-/eslint-formatter-sarif-2.1.7.tgz", - "integrity": "sha512-gDNc2elHjX0eqk34HxxRxEwEL49SrvXImOoK1bZHq7IDYfuY1xY/CUx8/gOWgvwf6Qv2Yy3HirzjIvKXKH82vQ==", - "dev": true, - "dependencies": { - "eslint": "^8.9.0", - "jschardet": "latest", - "lodash": "^4.17.14", - "utf8": "^3.0.0" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1857,6 +1942,7 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dev": true, + "peer": true, "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -2038,6 +2124,19 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -2047,6 +2146,20 @@ "node": ">= 10" } }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -2071,12 +2184,6 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "dev": true }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -2137,10 +2244,12 @@ "dev": true }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2153,6 +2262,7 @@ "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" } @@ -2205,6 +2315,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3003,10 +3114,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3105,7 +3217,8 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/defaults": { "version": "1.0.4", @@ -3180,18 +3293,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dot-prop": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", @@ -3243,29 +3344,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -3337,6 +3415,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3345,112 +3424,125 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.1", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -3470,10 +3562,11 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "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" }, @@ -3486,6 +3579,7 @@ "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" }, @@ -3498,6 +3592,7 @@ "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" } @@ -3507,6 +3602,7 @@ "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" } @@ -3576,7 +3672,8 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -3610,13 +3707,15 @@ "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 + "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 + "dev": true, + "license": "MIT" }, "node_modules/fastq": { "version": "1.17.0", @@ -3652,15 +3751,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/filelist": { @@ -3710,6 +3810,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -3731,24 +3832,25 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.5", @@ -4060,6 +4162,7 @@ "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" }, @@ -4089,15 +4192,13 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4129,12 +4230,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", @@ -4622,15 +4717,6 @@ "node": ">=8" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -4769,20 +4855,12 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jschardet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-3.0.0.tgz", - "integrity": "sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-better-errors": { "version": "1.0.2", @@ -4800,13 +4878,15 @@ "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 + "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 + "dev": true, + "license": "MIT" }, "node_modules/json-stringify-nice": { "version": "1.1.4", @@ -4895,6 +4975,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -4950,6 +5031,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -5096,6 +5178,7 @@ "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" }, @@ -5122,7 +5205,8 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -5620,6 +5704,7 @@ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5668,7 +5753,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", @@ -6060,6 +6146,7 @@ "integrity": "sha512-1qlEeDjX9OKZEryC8i4bA+twNg+lB5RKrozlNwWx/lLJHqWPUfvUTvxh+uxlPYL9KzVReQjUuxMLFMsHNqWUrA==", "dev": true, "hasInstallScript": true, + "peer": true, "dependencies": { "@nrwl/cli": "15.9.7", "@nrwl/tao": "15.9.7", @@ -6295,17 +6382,18 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -6357,6 +6445,7 @@ "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" }, @@ -6372,6 +6461,7 @@ "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" }, @@ -6652,10 +6742,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -6750,155 +6841,74 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", "dev": true, + "license": "MIT", + "peer": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/pretty-quick": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.3.1.tgz", - "integrity": "sha512-3b36UXfYQ+IXXqex6mCca89jC8u0mYLqFAN5eTQKoXO6oCQYcIVYZEB/5AlBHI7JPYygReM2Vv6Vom/Gln7fBg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-4.2.2.tgz", + "integrity": "sha512-uAh96tBW1SsD34VhhDmWuEmqbpfYc/B3j++5MC/6b3Cb8Ow7NJsvKFhg0eoGu2xXX+o9RkahkTK6sUdd8E7g5w==", "dev": true, + "license": "MIT", "dependencies": { - "execa": "^4.1.0", - "find-up": "^4.1.0", - "ignore": "^5.3.0", + "@pkgr/core": "^0.2.7", + "ignore": "^7.0.5", "mri": "^1.2.0", - "picocolors": "^1.0.0", - "picomatch": "^3.0.1", - "tslib": "^2.6.2" + "picocolors": "^1.1.1", + "picomatch": "^4.0.2", + "tinyexec": "^0.3.2", + "tslib": "^2.8.1" }, "bin": { - "pretty-quick": "dist/cli.js" + "pretty-quick": "lib/cli.mjs" }, "engines": { - "node": ">=10.13" - }, - "peerDependencies": { - "prettier": "^2.0.0" - } - }, - "node_modules/pretty-quick/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/pretty-quick/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" + "url": "https://opencollective.com/pretty-quick" }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "prettier": "^3.0.0" } }, - "node_modules/pretty-quick/node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "node_modules/pretty-quick/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/pretty-quick/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-quick/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" + "node": ">= 4" } }, "node_modules/pretty-quick/node_modules/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -6983,21 +6993,12 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7828,6 +7829,7 @@ "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" }, @@ -7936,12 +7938,6 @@ "node": ">=0.10" } }, - "node_modules/text-table": { - "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 - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -7957,6 +7953,13 @@ "readable-stream": "3" } }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -8029,16 +8032,18 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "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/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -8046,18 +8051,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -8153,16 +8146,11 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -8261,6 +8249,16 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -8509,6 +8507,7 @@ "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 242aa1e..b72d622 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,17 @@ "url": "https://github.com/eclipse-thingweb/td-tools.git" }, "devDependencies": { - "@microsoft/eslint-formatter-sarif": "^2.1.7", - "eslint": "^8.22.0", - "eslint-config-prettier": "^8.8.0", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", "husky": "^7.0.4", "lerna": "^5.4.3", - "prettier": "^2.3.2", - "pretty-quick": "^3.1.1" + "prettier": "3.0.0", + "pretty-quick": "^4.2.2" }, "scripts": { - "lint": "npx eslint . --config .eslintrc.json", - "lint:sarif": "npx eslint . --config .eslintrc.json --format @microsoft/eslint-formatter-sarif --output-file eslint-results.sarif", - "lint:fix": "npx eslint . --config .eslintrc.json --fix", + "lint": "npx eslint node/*/src node/*/test *.js", + "lint:sarif": "npx eslint node/*/src node/*/test *.js --format @microsoft/eslint-formatter-sarif --output-file eslint-results.sarif", + "lint:fix": "npx eslint node/*/src node/*/test *.js --fix", "format": "prettier --write . && npm run format --silent --workspaces --if-present", "format:check": "prettier --check .", "format:quick": "pretty-quick"