diff --git a/.changeset/five-ties-wave.md b/.changeset/five-ties-wave.md new file mode 100644 index 0000000000..1bdde15f2f --- /dev/null +++ b/.changeset/five-ties-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Adding a new command `schema openapi lint` to lint your OpenAPI specs and ensure consistent style across Backstage plugins. diff --git a/.changeset/light-spoons-refuse.md b/.changeset/light-spoons-refuse.md new file mode 100644 index 0000000000..4978b48c3f --- /dev/null +++ b/.changeset/light-spoons-refuse.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-search-backend': patch +--- + +Update OpenAPI specs to be in line with linting standards. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e9b079e9f..e395370f62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,6 +95,9 @@ jobs: - name: verify api reference run: node scripts/verify-api-reference.js + - name: lint openapi yaml files + run: yarn backstage-repo-tools schema openapi lint + - name: verify openapi yaml file matches generated ts file run: yarn backstage-repo-tools schema openapi verify diff --git a/packages/repo-tools/cli-report.md b/packages/repo-tools/cli-report.md index 789b4bc407..a0df5e721c 100644 --- a/packages/repo-tools/cli-report.md +++ b/packages/repo-tools/cli-report.md @@ -60,6 +60,7 @@ Options: Commands: verify [paths...] generate [paths...] + lint [options] [paths...] help [command] ``` @@ -72,6 +73,16 @@ Options: -h, --help ``` +### `backstage-repo-tools schema openapi lint` + +``` +Usage: backstage-repo-tools schema openapi lint [options] [paths...] + +Options: + --strict + -h, --help +``` + ### `backstage-repo-tools schema openapi verify` ``` diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 934d0d5d8f..49b450c7f2 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -31,12 +31,20 @@ }, "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", + "@apisyouwonthate/style-guide": "^1.4.0", "@backstage/cli-common": "workspace:^", "@backstage/cli-node": "workspace:^", "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", "@microsoft/api-documenter": "^7.19.27", "@microsoft/api-extractor": "^7.33.7", + "@stoplight/spectral-core": "^1.18.0", + "@stoplight/spectral-formatters": "^1.1.0", + "@stoplight/spectral-functions": "^1.7.2", + "@stoplight/spectral-parsers": "^1.0.2", + "@stoplight/spectral-rulesets": "^1.16.0", + "@stoplight/spectral-runtime": "^1.1.2", + "@stoplight/types": "^13.14.0", "chalk": "^4.0.0", "commander": "^9.1.0", "fs-extra": "10.1.0", diff --git a/packages/repo-tools/src/commands/index.ts b/packages/repo-tools/src/commands/index.ts index a8324c7d33..e19ffde4b8 100644 --- a/packages/repo-tools/src/commands/index.ts +++ b/packages/repo-tools/src/commands/index.ts @@ -40,6 +40,15 @@ function registerSchemaCommand(program: Command) { 'Generates a Typescript file from an OpenAPI yaml spec. For use with the `@backstage/backend-openapi-utils` ApiRouter type.', ) .action(lazy(() => import('./openapi/generate').then(m => m.bulkCommand))); + + openApiCommand + .command('lint [paths...]') + .description('Lint OpenAPI schemas.') + .option( + '--strict', + 'Fail on any linting severity messages, not just errors.', + ) + .action(lazy(() => import('./openapi/lint').then(m => m.bulkCommand))); } export function registerCommands(program: Command) { diff --git a/packages/repo-tools/src/commands/openapi/lint.ts b/packages/repo-tools/src/commands/openapi/lint.ts new file mode 100644 index 0000000000..8aac0189b1 --- /dev/null +++ b/packages/repo-tools/src/commands/openapi/lint.ts @@ -0,0 +1,114 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Spectral, + Document, + Ruleset, + RulesetDefinition, +} from '@stoplight/spectral-core'; +import { Yaml } from '@stoplight/spectral-parsers'; +import ruleset from '@apisyouwonthate/style-guide'; +import fs from 'fs-extra'; +import chalk from 'chalk'; +import { resolve } from 'path'; +import { runner } from './runner'; +import { YAML_SCHEMA_PATH } from './constants'; +import { oas } from '@stoplight/spectral-rulesets'; +import { DiagnosticSeverity } from '@stoplight/types'; +import { pretty } from '@stoplight/spectral-formatters'; + +async function lint( + directoryPath: string, + config?: { skipMissingYamlFile: boolean; strict: boolean }, +) { + const { skipMissingYamlFile, strict } = config ?? {}; + const openapiPath = resolve(directoryPath, YAML_SCHEMA_PATH); + if (!(await fs.pathExists(openapiPath))) { + if (skipMissingYamlFile) { + return; + } + throw new Error(`Could not find a file at ${openapiPath}.`); + } + const openapiFileContent = await fs.readFile(openapiPath, 'utf8'); + + const document = new Document(openapiFileContent, Yaml, openapiPath); + + const spectral = new Spectral(); + + const backstageRuleset = new Ruleset( + { + extends: [oas, ruleset], + overrides: [ + { + files: ['*'], + rules: { + 'api-health': 'off', + 'api-home': 'off', + 'api-home-get': 'off', + 'operation-tags': 'off', + 'hosts-https-only-oas3': 'off', + 'no-unknown-error-format': 'off', + }, + }, + ], + } as RulesetDefinition, + { source: openapiPath }, + ); + + spectral.setRuleset(backstageRuleset); + // we lint our document using the ruleset we passed to the Spectral object + const result = await spectral.run(document); + const errors = result.filter(e => e.severity === DiagnosticSeverity.Error); + const numberOfErrors = (strict && result.length) || errors.length; + if (numberOfErrors > 0) { + console.error( + pretty(result, { + // Used to fulfill the types, but not used for prettier output. + failSeverity: DiagnosticSeverity.Error, + }), + ); + throw new Error(`${numberOfErrors} error(s) found when linting your spec.`); + } +} + +export async function bulkCommand( + paths: string[] = [], + options: { strict?: boolean }, +): Promise { + const resultsList = await runner(paths, (dir: string) => + lint(dir, { skipMissingYamlFile: true, strict: !!options.strict }), + ); + + let failed = false; + for (const { relativeDir, resultText } of resultsList) { + if (resultText) { + console.log(); + console.log( + chalk.red(`OpenAPI yaml file linting failed in ${relativeDir}:`), + ); + console.log(resultText.trimStart()); + + failed = true; + } + } + + if (failed) { + process.exit(1); + } else { + console.log(chalk.green('Linted all files.')); + } +} diff --git a/plugins/catalog-backend/src/schema/openapi.generated.ts b/plugins/catalog-backend/src/schema/openapi.generated.ts index e1853f252d..9af42325ea 100644 --- a/plugins/catalog-backend/src/schema/openapi.generated.ts +++ b/plugins/catalog-backend/src/schema/openapi.generated.ts @@ -708,6 +708,7 @@ export default { '/refresh': { post: { operationId: 'RefreshEntity', + description: 'Refresh the entity related to entityRef.', responses: { '200': { description: 'Refreshed', @@ -749,6 +750,7 @@ export default { '/entities': { get: { operationId: 'GetEntities', + description: 'Get all entities matching a given filter.', responses: { '200': { description: '', @@ -792,6 +794,7 @@ export default { '/entities/by-uid/{uid}': { get: { operationId: 'GetEntityByUid', + description: 'Get a single entity by the UID.', responses: { '200': { description: 'Ok', @@ -818,6 +821,7 @@ export default { }, delete: { operationId: 'DeleteEntityByUid', + description: 'Delete a single entity by UID.', responses: { '204': { description: 'Deleted successfully.', @@ -839,6 +843,7 @@ export default { '/entities/by-name/{kind}/{namespace}/{name}': { get: { operationId: 'GetEntityByName', + description: 'Get an entity by an entity ref.', responses: { '200': { description: 'Ok', @@ -873,6 +878,7 @@ export default { '/entities/by-name/{kind}/{namespace}/{name}/ancestry': { get: { operationId: 'GetEntityAncestryByName', + description: "Get an entity's ancestry by entity ref.", responses: { '200': { description: 'Ok', @@ -907,6 +913,8 @@ export default { '/entities/by-refs': { post: { operationId: 'GetEntitiesByRefs', + description: + 'Get a batch set of entities given an array of entityRefs.', responses: { '200': { description: 'Ok', @@ -960,6 +968,7 @@ export default { '/entities/by-query': { get: { operationId: 'GetEntitiesByQuery', + description: 'Search for entities by a given query.', responses: { '200': { description: 'Ok', @@ -1021,6 +1030,7 @@ export default { '/entity-facets': { get: { operationId: 'GetEntityFacets', + description: 'Get all entity facets that match the given filters.', responses: { '200': { description: 'Ok', @@ -1057,6 +1067,7 @@ export default { '/locations': { post: { operationId: 'CreateLocation', + description: 'Create a location for a given target.', responses: { '200': { description: 'Ok', @@ -1126,6 +1137,7 @@ export default { }, get: { operationId: 'GetLocations', + description: 'Get all locations', responses: { '200': { description: 'Ok', @@ -1159,6 +1171,7 @@ export default { '/locations/{id}': { get: { operationId: 'GetLocation', + description: 'Get a location by id.', responses: { '200': { description: 'Ok', @@ -1190,6 +1203,7 @@ export default { }, delete: { operationId: 'DeleteLocation', + description: 'Delete a location by id.', responses: { '204': { description: 'No content', @@ -1216,6 +1230,7 @@ export default { '/analyze-location': { post: { operationId: 'AnalyzeLocation', + description: 'Validate a given location.', responses: { '200': { description: 'Ok', @@ -1259,6 +1274,8 @@ export default { '/validate-entity': { post: { operationId: 'ValidateEntity', + description: + 'Validate that a passed in entity has no errors in schema.', responses: { '200': { description: 'Ok', diff --git a/plugins/catalog-backend/src/schema/openapi.yaml b/plugins/catalog-backend/src/schema/openapi.yaml index d2dd74fb33..701b4517bc 100644 --- a/plugins/catalog-backend/src/schema/openapi.yaml +++ b/plugins/catalog-backend/src/schema/openapi.yaml @@ -604,6 +604,7 @@ paths: /refresh: post: operationId: RefreshEntity + description: Refresh the entity related to entityRef. responses: '200': description: Refreshed @@ -630,6 +631,7 @@ paths: /entities: get: operationId: GetEntities + description: Get all entities matching a given filter. responses: '200': description: '' @@ -651,6 +653,7 @@ paths: /entities/by-uid/{uid}: get: operationId: GetEntityByUid + description: Get a single entity by the UID. responses: '200': description: Ok @@ -665,6 +668,7 @@ paths: - $ref: '#/components/parameters/uid' delete: operationId: DeleteEntityByUid + description: Delete a single entity by UID. responses: '204': description: Deleted successfully. @@ -676,6 +680,7 @@ paths: /entities/by-name/{kind}/{namespace}/{name}: get: operationId: GetEntityByName + description: Get an entity by an entity ref. responses: '200': description: Ok @@ -693,6 +698,7 @@ paths: /entities/by-name/{kind}/{namespace}/{name}/ancestry: get: operationId: GetEntityAncestryByName + description: Get an entity's ancestry by entity ref. responses: '200': description: Ok @@ -710,6 +716,7 @@ paths: /entities/by-refs: post: operationId: GetEntitiesByRefs + description: Get a batch set of entities given an array of entityRefs. responses: '200': description: Ok @@ -742,6 +749,7 @@ paths: /entities/by-query: get: operationId: GetEntitiesByQuery + description: Search for entities by a given query. responses: '200': description: Ok @@ -776,6 +784,7 @@ paths: /entity-facets: get: operationId: GetEntityFacets + description: Get all entity facets that match the given filters. responses: '200': description: Ok @@ -796,6 +805,7 @@ paths: /locations: post: operationId: CreateLocation + description: Create a location for a given target. responses: '200': description: Ok @@ -846,6 +856,7 @@ paths: - type get: operationId: GetLocations + description: Get all locations responses: '200': description: Ok @@ -867,6 +878,7 @@ paths: /locations/{id}: get: operationId: GetLocation + description: Get a location by id. responses: '200': description: Ok @@ -885,6 +897,7 @@ paths: type: string delete: operationId: DeleteLocation + description: Delete a location by id. responses: '204': description: No content @@ -900,6 +913,7 @@ paths: /analyze-location: post: operationId: AnalyzeLocation + description: Validate a given location. responses: '200': description: Ok @@ -928,6 +942,7 @@ paths: /validate-entity: post: operationId: ValidateEntity + description: Validate that a passed in entity has no errors in schema. responses: '200': description: Ok diff --git a/plugins/search-backend/src/schema/openapi.generated.ts b/plugins/search-backend/src/schema/openapi.generated.ts index b8f5f5b35e..28ca9b5339 100644 --- a/plugins/search-backend/src/schema/openapi.generated.ts +++ b/plugins/search-backend/src/schema/openapi.generated.ts @@ -61,6 +61,7 @@ export default { '/query': { get: { operationId: 'Query', + description: 'Query documents with a given filter.', responses: { '200': { description: 'Ok', diff --git a/plugins/search-backend/src/schema/openapi.yaml b/plugins/search-backend/src/schema/openapi.yaml index e7f44c9f11..4684ca58d8 100644 --- a/plugins/search-backend/src/schema/openapi.yaml +++ b/plugins/search-backend/src/schema/openapi.yaml @@ -33,6 +33,7 @@ paths: /query: get: operationId: Query + description: Query documents with a given filter. responses: '200': description: Ok diff --git a/yarn.lock b/yarn.lock index 55332fe496..e56221439f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -75,6 +75,16 @@ __metadata: languageName: node linkType: hard +"@apisyouwonthate/style-guide@npm:^1.4.0": + version: 1.4.0 + resolution: "@apisyouwonthate/style-guide@npm:1.4.0" + dependencies: + "@stoplight/spectral-formats": ^1.2.0 + "@stoplight/spectral-functions": ^1.6.1 + checksum: c17d7bb12977be4cf495ce661077c611abc473c555186bb6c61e26a06bf43aa66aebdee6711b2ee2bdac3e933fd0a2276cf1bf706d48ad48f736111548e2283b + languageName: node + linkType: hard + "@apollo/cache-control-types@npm:^1.0.2": version: 1.0.2 resolution: "@apollo/cache-control-types@npm:1.0.2" @@ -9937,6 +9947,7 @@ __metadata: resolution: "@backstage/repo-tools@workspace:packages/repo-tools" dependencies: "@apidevtools/swagger-parser": ^10.1.0 + "@apisyouwonthate/style-guide": ^1.4.0 "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@backstage/cli-node": "workspace:^" @@ -9945,6 +9956,13 @@ __metadata: "@manypkg/get-packages": ^1.1.3 "@microsoft/api-documenter": ^7.19.27 "@microsoft/api-extractor": ^7.33.7 + "@stoplight/spectral-core": ^1.18.0 + "@stoplight/spectral-formatters": ^1.1.0 + "@stoplight/spectral-functions": ^1.7.2 + "@stoplight/spectral-parsers": ^1.0.2 + "@stoplight/spectral-rulesets": ^1.16.0 + "@stoplight/spectral-runtime": ^1.1.2 + "@stoplight/types": ^13.14.0 "@types/is-glob": ^4.0.2 "@types/mock-fs": ^4.13.0 "@types/node": ^16.11.26 @@ -12708,6 +12726,24 @@ __metadata: languageName: node linkType: hard +"@jsep-plugin/regex@npm:^1.0.1": + version: 1.0.3 + resolution: "@jsep-plugin/regex@npm:1.0.3" + peerDependencies: + jsep: ^0.4.0||^1.0.0 + checksum: a57718ae5c86bd10ff5de51843a771b96a10a9c6b5c5f4e02aa5318257c3d5fdec96f8b389fcbe129c7a6ad6b0746d9a0fd934c949b80882230fbc14b548c922 + languageName: node + linkType: hard + +"@jsep-plugin/ternary@npm:^1.0.2": + version: 1.1.3 + resolution: "@jsep-plugin/ternary@npm:1.1.3" + peerDependencies: + jsep: ^0.4.0||^1.0.0 + checksum: c05408b0302844723f98b90787425beb4e8ad14029df3d98e88b9d61343d81201a7f0bf3db5806dcf0378c7be69f5b4c9fcd04f055bda282c73f4d1b425e502a + languageName: node + linkType: hard + "@juggle/resize-observer@npm:^3.3.1": version: 3.3.1 resolution: "@juggle/resize-observer@npm:3.3.1" @@ -15147,6 +15183,277 @@ __metadata: languageName: node linkType: hard +"@stoplight/better-ajv-errors@npm:1.0.3": + version: 1.0.3 + resolution: "@stoplight/better-ajv-errors@npm:1.0.3" + dependencies: + jsonpointer: ^5.0.0 + leven: ^3.1.0 + peerDependencies: + ajv: ">=8" + checksum: 642fe5636a72a86de72e4ffc7bbf07499fc09d8446b386f31d3667b07dd1849d921c38a74c109a9e2554d405b6e90dc150728a0c455bf93f158ff139e0538ddd + languageName: node + linkType: hard + +"@stoplight/json-ref-readers@npm:1.2.2": + version: 1.2.2 + resolution: "@stoplight/json-ref-readers@npm:1.2.2" + dependencies: + node-fetch: ^2.6.0 + tslib: ^1.14.1 + checksum: 31b0e78b119f7afd7dd84a4fbb0c4aaceeb6e889179e785ddb9880ee548d4d161dce5743451ef6dad4b7a902d9f0711909c87b63ad794bede234a144bcf2b2b4 + languageName: node + linkType: hard + +"@stoplight/json-ref-resolver@npm:~3.1.5": + version: 3.1.5 + resolution: "@stoplight/json-ref-resolver@npm:3.1.5" + dependencies: + "@stoplight/json": ^3.17.0 + "@stoplight/path": ^1.3.2 + "@stoplight/types": ^12.3.0 || ^13.0.0 + "@types/urijs": ^1.19.19 + dependency-graph: ~0.11.0 + fast-memoize: ^2.5.2 + immer: ^9.0.6 + lodash: ^4.17.21 + tslib: ^2.3.1 + urijs: ^1.19.11 + checksum: b2df82e899717ffa7bab9ec4c380f206511b3971d242724afd34e8b964e5aa7be2a52e32ba48d435548a9ac13a63a2271ca69182abec8506fc3bb3cc129f6380 + languageName: node + linkType: hard + +"@stoplight/json@npm:^3.17.0, @stoplight/json@npm:^3.17.1": + version: 3.21.0 + resolution: "@stoplight/json@npm:3.21.0" + dependencies: + "@stoplight/ordered-object-literal": ^1.0.3 + "@stoplight/path": ^1.3.2 + "@stoplight/types": ^13.6.0 + jsonc-parser: ~2.2.1 + lodash: ^4.17.21 + safe-stable-stringify: ^1.1 + checksum: 16fe56a6804cd47837bd82d85a8500c4226669558f3feda55d8fb0cd615ca2261622963700f04f049cf30a3a9764eb3c861516003d948743b6ae85dbbabf8a59 + languageName: node + linkType: hard + +"@stoplight/json@npm:~3.20.1": + version: 3.20.3 + resolution: "@stoplight/json@npm:3.20.3" + dependencies: + "@stoplight/ordered-object-literal": ^1.0.3 + "@stoplight/path": ^1.3.2 + "@stoplight/types": ^13.6.0 + jsonc-parser: ~2.2.1 + lodash: ^4.17.21 + safe-stable-stringify: ^1.1 + checksum: 52a4251deca0be91c98172287def5cb004ff2ab801c3b7bb24f02abe14ad0890ee453588f235401fa048c5fefe1a750d7f68857f681d57afb62dd5310f50d71a + languageName: node + linkType: hard + +"@stoplight/ordered-object-literal@npm:^1.0.1, @stoplight/ordered-object-literal@npm:^1.0.3": + version: 1.0.4 + resolution: "@stoplight/ordered-object-literal@npm:1.0.4" + checksum: 81afa24943880b0a213af3728a9fe0a28bd01d4840b9583d448f7823ced5b6e673628698b59d201cef50afebcbd89256e133714a174968d11b624d943e0c2c2f + languageName: node + linkType: hard + +"@stoplight/path@npm:1.3.2, @stoplight/path@npm:^1.3.2": + version: 1.3.2 + resolution: "@stoplight/path@npm:1.3.2" + checksum: 8a1143cef9edcf9fd8cb24ca3f250693d475ce1f635f0dc95e5b045aad303fbf4d702c939f0c4ed8d28a04208d1aa4471fb10912ef1e3a94a9e6810878a7cfbb + languageName: node + linkType: hard + +"@stoplight/spectral-core@npm:^1.15.1, @stoplight/spectral-core@npm:^1.18.0, @stoplight/spectral-core@npm:^1.7.0, @stoplight/spectral-core@npm:^1.8.0, @stoplight/spectral-core@npm:^1.8.1": + version: 1.18.0 + resolution: "@stoplight/spectral-core@npm:1.18.0" + dependencies: + "@stoplight/better-ajv-errors": 1.0.3 + "@stoplight/json": ~3.20.1 + "@stoplight/path": 1.3.2 + "@stoplight/spectral-parsers": ^1.0.0 + "@stoplight/spectral-ref-resolver": ^1.0.0 + "@stoplight/spectral-runtime": ^1.0.0 + "@stoplight/types": ~13.6.0 + "@types/es-aggregate-error": ^1.0.2 + "@types/json-schema": ^7.0.11 + ajv: ^8.6.0 + ajv-errors: ~3.0.0 + ajv-formats: ~2.1.0 + es-aggregate-error: ^1.0.7 + jsonpath-plus: 7.1.0 + lodash: ~4.17.21 + lodash.topath: ^4.5.2 + minimatch: 3.1.2 + nimma: 0.2.2 + pony-cause: ^1.0.0 + simple-eval: 1.0.0 + tslib: ^2.3.0 + checksum: 76ff9e2349c035fa2b98556c8bd67bb531f2b9c29e19e33484270d62f30900d36ceb51ef0075255479cc5071b45bcb7249088f568fff9d44cd159b5ee8f07cec + languageName: node + linkType: hard + +"@stoplight/spectral-formats@npm:^1.0.0, @stoplight/spectral-formats@npm:^1.2.0, @stoplight/spectral-formats@npm:^1.5.0": + version: 1.5.0 + resolution: "@stoplight/spectral-formats@npm:1.5.0" + dependencies: + "@stoplight/json": ^3.17.0 + "@stoplight/spectral-core": ^1.8.0 + "@types/json-schema": ^7.0.7 + tslib: ^2.3.1 + checksum: dc80c0ee37ff5708b2078aa588d3c8c895ba36b18e52f5813cd7f91d1a476629aa36f1ceaf62e8bd96987c0f7c51537bdb6780a08d32be982db230be5634c93e + languageName: node + linkType: hard + +"@stoplight/spectral-formatters@npm:^1.1.0": + version: 1.1.0 + resolution: "@stoplight/spectral-formatters@npm:1.1.0" + dependencies: + "@stoplight/path": ^1.3.2 + "@stoplight/spectral-core": ^1.15.1 + "@stoplight/spectral-runtime": ^1.1.0 + "@stoplight/types": ^13.15.0 + chalk: 4.1.2 + cliui: 7.0.4 + lodash: ^4.17.21 + strip-ansi: 6.0 + text-table: ^0.2.0 + tslib: ^2.5.0 + checksum: a72d9ecb423af1f911b654f48ae04c19f0707e8eb8542de57090299dbff19e58a1dff8f229614056fbf2b2f44636423cd9c980189c4cceb58961d84925d9ae7b + languageName: node + linkType: hard + +"@stoplight/spectral-functions@npm:^1.5.1, @stoplight/spectral-functions@npm:^1.6.1, @stoplight/spectral-functions@npm:^1.7.2": + version: 1.7.2 + resolution: "@stoplight/spectral-functions@npm:1.7.2" + dependencies: + "@stoplight/better-ajv-errors": 1.0.3 + "@stoplight/json": ^3.17.1 + "@stoplight/spectral-core": ^1.7.0 + "@stoplight/spectral-formats": ^1.0.0 + "@stoplight/spectral-runtime": ^1.1.0 + ajv: ^8.6.3 + ajv-draft-04: ~1.0.0 + ajv-errors: ~3.0.0 + ajv-formats: ~2.1.0 + lodash: ~4.17.21 + tslib: ^2.3.0 + checksum: f89d966d33dd484e5ea63a7971478d176c94215b4ffd2ef24eb8e507a2b60ed3bcfa391b9137793e939f3a10443914db6da62d081055fb8ba49d2d397f0d5907 + languageName: node + linkType: hard + +"@stoplight/spectral-parsers@npm:^1.0.0, @stoplight/spectral-parsers@npm:^1.0.2": + version: 1.0.2 + resolution: "@stoplight/spectral-parsers@npm:1.0.2" + dependencies: + "@stoplight/json": ~3.20.1 + "@stoplight/types": ^13.6.0 + "@stoplight/yaml": ~4.2.3 + tslib: ^2.3.1 + checksum: 89bc5c77ebeedca0abf9ffa9e074beed57d47b71814f23a1d65c03469aa6ea923007b42e7cb18ca7bcc4ff9fd399d604d32a41aa4c4c57a9cc3bebb4b24c3e34 + languageName: node + linkType: hard + +"@stoplight/spectral-ref-resolver@npm:^1.0.0": + version: 1.0.3 + resolution: "@stoplight/spectral-ref-resolver@npm:1.0.3" + dependencies: + "@stoplight/json-ref-readers": 1.2.2 + "@stoplight/json-ref-resolver": ~3.1.5 + "@stoplight/spectral-runtime": ^1.1.2 + dependency-graph: 0.11.0 + tslib: ^2.3.1 + checksum: efe93b1d1d32647b675c221530ecb20c55303dfcd1009efd8e036f6415eb1255fff19781358a74046160516a7b7088b6329885bb507a444c14db32fa23392bc9 + languageName: node + linkType: hard + +"@stoplight/spectral-rulesets@npm:^1.16.0": + version: 1.16.0 + resolution: "@stoplight/spectral-rulesets@npm:1.16.0" + dependencies: + "@asyncapi/specs": ^4.1.0 + "@stoplight/better-ajv-errors": 1.0.3 + "@stoplight/json": ^3.17.0 + "@stoplight/spectral-core": ^1.8.1 + "@stoplight/spectral-formats": ^1.5.0 + "@stoplight/spectral-functions": ^1.5.1 + "@stoplight/spectral-runtime": ^1.1.1 + "@stoplight/types": ^13.6.0 + "@types/json-schema": ^7.0.7 + ajv: ^8.8.2 + ajv-formats: ~2.1.0 + json-schema-traverse: ^1.0.0 + lodash: ~4.17.21 + tslib: ^2.3.0 + checksum: d6e47d4cb96c30d10571dcdbc24ed6bf53f09bdbccbd59bc9538ceb716d82eca68595780dd489f4ca5fcd4398c9adbd5dc931894f26040dcff33fd45b67463eb + languageName: node + linkType: hard + +"@stoplight/spectral-runtime@npm:^1.0.0, @stoplight/spectral-runtime@npm:^1.1.0, @stoplight/spectral-runtime@npm:^1.1.1, @stoplight/spectral-runtime@npm:^1.1.2": + version: 1.1.2 + resolution: "@stoplight/spectral-runtime@npm:1.1.2" + dependencies: + "@stoplight/json": ^3.17.0 + "@stoplight/path": ^1.3.2 + "@stoplight/types": ^12.3.0 + abort-controller: ^3.0.0 + lodash: ^4.17.21 + node-fetch: ^2.6.7 + tslib: ^2.3.1 + checksum: 35964a38f82384e6e0158988173a50ab7f473a2ed6e942073de023bd28fb696b5b913336a84d016b046346294be9cfa3a88c6a908c2622c0ceb36f16ca76e084 + languageName: node + linkType: hard + +"@stoplight/types@npm:^12.3.0": + version: 12.5.0 + resolution: "@stoplight/types@npm:12.5.0" + dependencies: + "@types/json-schema": ^7.0.4 + utility-types: ^3.10.0 + checksum: fe4a09df6e1c2f0cdb53f474b180cc7b8184e814e1ac4427d199642f10958335f597060530a908c0e5800ba2569d077afe124a51deaee466255ce942e1e03941 + languageName: node + linkType: hard + +"@stoplight/types@npm:^12.3.0 || ^13.0.0, @stoplight/types@npm:^13.0.0, @stoplight/types@npm:^13.14.0, @stoplight/types@npm:^13.15.0, @stoplight/types@npm:^13.6.0": + version: 13.15.0 + resolution: "@stoplight/types@npm:13.15.0" + dependencies: + "@types/json-schema": ^7.0.4 + utility-types: ^3.10.0 + checksum: 839f0bbedb791bd6792ef22b6a821ca504b14b705927f7c510c4cdcc591eddc8818c82b8857129501aa809d6f369b82e4487bfe18dfc5ce00e28317ecad2df9a + languageName: node + linkType: hard + +"@stoplight/types@npm:~13.6.0": + version: 13.6.0 + resolution: "@stoplight/types@npm:13.6.0" + dependencies: + "@types/json-schema": ^7.0.4 + utility-types: ^3.10.0 + checksum: 4cc81cf29decc0392f15c71b21fd11cd806bcf99168ae4509ed41c2b7dbcfbd5a83c7f9f320edb5a518cc483fd18dd8794c54b232fb6a6f2a7b6e9fb6ca20269 + languageName: node + linkType: hard + +"@stoplight/yaml-ast-parser@npm:0.0.48": + version: 0.0.48 + resolution: "@stoplight/yaml-ast-parser@npm:0.0.48" + checksum: 4e252a874636d4015ff78a638075c438ccf7b8b4b38e3df12f7b8381da2da0411dfff7a6de38354b8093a36a8911a9dd656264fb0d34453cb7bcf78a3627dfa0 + languageName: node + linkType: hard + +"@stoplight/yaml@npm:~4.2.3": + version: 4.2.3 + resolution: "@stoplight/yaml@npm:4.2.3" + dependencies: + "@stoplight/ordered-object-literal": ^1.0.1 + "@stoplight/types": ^13.0.0 + "@stoplight/yaml-ast-parser": 0.0.48 + tslib: ^2.2.0 + checksum: 8e61c4499c0849dafecf487e51e10d4d3e99192834dd87eba4b27c20c42d3fe1b5b022f9c3eb63b96249b46d7277ffb4ce37447d84d01d4768b88d142e3d0e15 + languageName: node + linkType: hard + "@sucrase/webpack-loader@npm:^2.0.0": version: 2.0.0 resolution: "@sucrase/webpack-loader@npm:2.0.0" @@ -16530,6 +16837,15 @@ __metadata: languageName: node linkType: hard +"@types/es-aggregate-error@npm:^1.0.2": + version: 1.0.2 + resolution: "@types/es-aggregate-error@npm:1.0.2" + dependencies: + "@types/node": "*" + checksum: 076fd59b595f33c8c7e7eb68ec55bd43cf8b2cf7bbc6778e25d7ae1a5fa0538a0a56f149015f403d7bbcefe59f1d8182351685b59c1fe719fd46d0dd8a9737fa + languageName: node + linkType: hard + "@types/eslint-scope@npm:^3.7.3": version: 3.7.3 resolution: "@types/eslint-scope@npm:3.7.3" @@ -17876,6 +18192,13 @@ __metadata: languageName: node linkType: hard +"@types/urijs@npm:^1.19.19": + version: 1.19.19 + resolution: "@types/urijs@npm:1.19.19" + checksum: 2c08d41782149a243b374b28be009ca461f541c440d8d47c9d75b1d3255ff7169b34bb721cf2dd6266c2c44be6b70fc6d67a1abad50c4dae369774042b1facd8 + languageName: node + linkType: hard + "@types/use-sync-external-store@npm:^0.0.3": version: 0.0.3 resolution: "@types/use-sync-external-store@npm:0.0.3" @@ -18688,7 +19011,7 @@ __metadata: languageName: node linkType: hard -"ajv-draft-04@npm:^1.0.0": +"ajv-draft-04@npm:^1.0.0, ajv-draft-04@npm:~1.0.0": version: 1.0.0 resolution: "ajv-draft-04@npm:1.0.0" peerDependencies: @@ -18700,6 +19023,15 @@ __metadata: languageName: node linkType: hard +"ajv-errors@npm:~3.0.0": + version: 3.0.0 + resolution: "ajv-errors@npm:3.0.0" + peerDependencies: + ajv: ^8.0.1 + checksum: f3d1610a104fa776c2f90534acbe2113842a40d5ee446062da9e956ae6de6959afc997da1e3948c47316faa225255fc2d9d97aacd0803f47998fb38156d3d03c + languageName: node + linkType: hard + "ajv-formats-draft2019@npm:^1.6.1": version: 1.6.1 resolution: "ajv-formats-draft2019@npm:1.6.1" @@ -18714,7 +19046,7 @@ __metadata: languageName: node linkType: hard -"ajv-formats@npm:^2.1.1": +"ajv-formats@npm:^2.1.1, ajv-formats@npm:~2.1.0": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" dependencies: @@ -18760,7 +19092,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.12.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0": +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.12.0, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0, ajv@npm:^8.8.2": version: 8.12.0 resolution: "ajv@npm:8.12.0" dependencies: @@ -19218,6 +19550,15 @@ __metadata: languageName: node linkType: hard +"astring@npm:^1.8.1": + version: 1.8.6 + resolution: "astring@npm:1.8.6" + bin: + astring: bin/astring + checksum: 6f034d2acef1dac8bb231e7cc26c573d3c14e1975ea6e04f20312b43d4f462f963209bc64187d25d477a182dc3c33277959a0156ab7a3617aa79b1eac4d88e1f + languageName: node + linkType: hard + "async-lock@npm:^1.1.0": version: 1.2.4 resolution: "async-lock@npm:1.2.4" @@ -20853,6 +21194,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:7.0.4, cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: ^4.2.0 + strip-ansi: ^6.0.0 + wrap-ansi: ^7.0.0 + checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f + languageName: node + linkType: hard + "cliui@npm:^3.2.0": version: 3.2.0 resolution: "cliui@npm:3.2.0" @@ -20875,17 +21227,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^7.0.2": - version: 7.0.4 - resolution: "cliui@npm:7.0.4" - dependencies: - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - wrap-ansi: ^7.0.0 - checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f - languageName: node - linkType: hard - "clone-buffer@npm:^1.0.0": version: 1.0.0 resolution: "clone-buffer@npm:1.0.0" @@ -22793,7 +23134,7 @@ __metadata: languageName: node linkType: hard -"dependency-graph@npm:^0.11.0": +"dependency-graph@npm:0.11.0, dependency-graph@npm:^0.11.0, dependency-graph@npm:~0.11.0": version: 0.11.0 resolution: "dependency-graph@npm:0.11.0" checksum: 477204beaa9be69e642bc31ffe7a8c383d0cf48fa27acbc91c5df01431ab913e65c154213d2ef83d034c98d77280743ec85e5da018a97a18dd43d3c0b78b28cd @@ -23549,6 +23890,21 @@ __metadata: languageName: node linkType: hard +"es-aggregate-error@npm:^1.0.7": + version: 1.0.9 + resolution: "es-aggregate-error@npm:1.0.9" + dependencies: + define-properties: ^1.1.4 + es-abstract: ^1.20.4 + function-bind: ^1.1.1 + functions-have-names: ^1.2.3 + get-intrinsic: ^1.1.3 + globalthis: ^1.0.3 + has-property-descriptors: ^1.0.0 + checksum: bef86c4fcd3b924929e8d89d288dc0a577b31bb17d6a3f0a7676f22c5d7ffa4e1ff08bb393f06b15e1baad132ae725a8c8692728a5f73cd2b78a1c49ce664605 + languageName: node + linkType: hard + "es-get-iterator@npm:^1.1.2": version: 1.1.2 resolution: "es-get-iterator@npm:1.1.2" @@ -25113,6 +25469,13 @@ __metadata: languageName: node linkType: hard +"fast-memoize@npm:^2.5.2": + version: 2.5.2 + resolution: "fast-memoize@npm:2.5.2" + checksum: 79fa759719ba4eac7e8c22fb3b0eb3f18f4a31e218c00b1eb4a5b53c5781921133a6b84472d59ec5a6ea8f26ad57b43cd99a350c0547ccce51489bc9a5f0b28d + languageName: node + linkType: hard + "fast-querystring@npm:^1.1.1": version: 1.1.1 resolution: "fast-querystring@npm:1.1.1" @@ -25875,7 +26238,7 @@ __metadata: languageName: node linkType: hard -"functions-have-names@npm:^1.2.2": +"functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" checksum: c3f1f5ba20f4e962efb71344ce0a40722163e85bee2101ce25f88214e78182d2d2476aa85ef37950c579eb6cf6ee811c17b3101bb84004bb75655f3e33f3fdb5 @@ -26281,6 +26644,15 @@ __metadata: languageName: node linkType: hard +"globalthis@npm:^1.0.3": + version: 1.0.3 + resolution: "globalthis@npm:1.0.3" + dependencies: + define-properties: ^1.1.3 + checksum: fbd7d760dc464c886d0196166d92e5ffb4c84d0730846d6621a39fbbc068aeeb9c8d1421ad330e94b7bca4bb4ea092f5f21f3d36077812af5d098b4dc006c998 + languageName: node + linkType: hard + "globby@npm:^11.0.0, globby@npm:^11.0.1, globby@npm:^11.0.3, globby@npm:^11.0.4, globby@npm:^11.1.0": version: 11.1.0 resolution: "globby@npm:11.1.0" @@ -27324,7 +27696,7 @@ __metadata: languageName: node linkType: hard -"immer@npm:^9.0.1, immer@npm:^9.0.7": +"immer@npm:^9.0.1, immer@npm:^9.0.6, immer@npm:^9.0.7": version: 9.0.21 resolution: "immer@npm:9.0.21" checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432 @@ -29403,6 +29775,13 @@ __metadata: languageName: node linkType: hard +"jsep@npm:^1.1.2, jsep@npm:^1.2.0": + version: 1.3.8 + resolution: "jsep@npm:1.3.8" + checksum: d6de7f3bc3aa93e71b6a8fd5436db87efd11d7081230bf072c3359c5f9ff1e36dd01e4e09b09f10cacf35d5dbaf2f32ea5cf98ffe41717ea7bd489d580bbab83 + languageName: node + linkType: hard + "jsesc@npm:^2.5.1": version: 2.5.2 resolution: "jsesc@npm:2.5.2" @@ -29626,6 +30005,13 @@ __metadata: languageName: node linkType: hard +"jsonc-parser@npm:~2.2.1": + version: 2.2.1 + resolution: "jsonc-parser@npm:2.2.1" + checksum: c113878b5edd4232ba0742c7e0ddefb22a2a8ef1aafa1674c0eb4c5df0be11ed02bc8288f52ebe44b1696de336e1bc06e7bbc1458d0f910540d72b57ee7c8084 + languageName: node + linkType: hard + "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -29665,6 +30051,13 @@ __metadata: languageName: node linkType: hard +"jsonpath-plus@npm:7.1.0": + version: 7.1.0 + resolution: "jsonpath-plus@npm:7.1.0" + checksum: a4005dc860c6b7e339229842537ceb6eb839d87a3447f989792b9c64f2564bbbd40663515f9481fb5a1b6cb0f988afba5b0b150e0285c463b794a45ed1aaf555 + languageName: node + linkType: hard + "jsonpath-plus@npm:^5.0.7": version: 5.1.0 resolution: "jsonpath-plus@npm:5.1.0" @@ -29672,6 +30065,13 @@ __metadata: languageName: node linkType: hard +"jsonpath-plus@npm:^6.0.1": + version: 6.0.1 + resolution: "jsonpath-plus@npm:6.0.1" + checksum: bddec34b742249c5b38077dfcd8eb479fab4e077943253017326503ce4f527ef66938288c728712fd923907493d6eaba69a43015dc3dd9fdf48d89028ae7f466 + languageName: node + linkType: hard + "jsonpath-plus@npm:^7.2.0": version: 7.2.0 resolution: "jsonpath-plus@npm:7.2.0" @@ -30690,6 +31090,13 @@ __metadata: languageName: node linkType: hard +"lodash.topath@npm:^4.5.2": + version: 4.5.2 + resolution: "lodash.topath@npm:4.5.2" + checksum: 04583e220f4bb1c4ac0008ff8f46d9cb4ddce0ea1090085790da30a41f4cb1b904d885cb73257fca619fa825cd96f9bb97c67d039635cb76056e18f5e08bfdee + languageName: node + linkType: hard + "lodash.union@npm:^4.6.0": version: 4.6.0 resolution: "lodash.union@npm:4.6.0" @@ -30704,7 +31111,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0, lodash@npm:~4.17.0, lodash@npm:~4.17.15": +"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0, lodash@npm:~4.17.0, lodash@npm:~4.17.15, lodash@npm:~4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -32468,6 +32875,25 @@ __metadata: languageName: node linkType: hard +"nimma@npm:0.2.2": + version: 0.2.2 + resolution: "nimma@npm:0.2.2" + dependencies: + "@jsep-plugin/regex": ^1.0.1 + "@jsep-plugin/ternary": ^1.0.2 + astring: ^1.8.1 + jsep: ^1.2.0 + jsonpath-plus: ^6.0.1 + lodash.topath: ^4.5.2 + dependenciesMeta: + jsonpath-plus: + optional: true + lodash.topath: + optional: true + checksum: 09369253a962e6cdddd37c4994d414a5fa00abc955c4d91946140b45b57465749a9f05663a64812ad5ac70caacb7ca22a8fc7c8db002032d0768c83dbba7b3ad + languageName: node + linkType: hard + "nise@npm:^5.1.2": version: 5.1.2 resolution: "nise@npm:5.1.2" @@ -34438,6 +34864,13 @@ __metadata: languageName: node linkType: hard +"pony-cause@npm:^1.0.0": + version: 1.1.1 + resolution: "pony-cause@npm:1.1.1" + checksum: 5ff8878b808be48db801d52246a99d7e4789e52d20575ba504ede30c818fd85d38a033915e02c15fa9b6dce72448836dc1a47094acf8f1c21c4f04a4603b0cfb + languageName: node + linkType: hard + "popper.js@npm:1.16.1-lts": version: 1.16.1-lts resolution: "popper.js@npm:1.16.1-lts" @@ -37514,6 +37947,13 @@ __metadata: languageName: node linkType: hard +"safe-stable-stringify@npm:^1.1": + version: 1.1.1 + resolution: "safe-stable-stringify@npm:1.1.1" + checksum: e32a30720e8a2e3043b8b96733f015c1aa7a21a5a328074ce917b8afe4d26b4308c186c74fa92131e5f794b1efc63caa32defafceaa2981accaaedbc8b2c861c + languageName: node + linkType: hard + "safe-stable-stringify@npm:^2.2.0, safe-stable-stringify@npm:^2.3.1": version: 2.3.1 resolution: "safe-stable-stringify@npm:2.3.1" @@ -38038,6 +38478,15 @@ __metadata: languageName: node linkType: hard +"simple-eval@npm:1.0.0": + version: 1.0.0 + resolution: "simple-eval@npm:1.0.0" + dependencies: + jsep: ^1.1.2 + checksum: 0f0719ae3a84d4b9c19366dc03065b1fe9638c982ed3e9d44ba541d25e3454e99419e3239034974fd6c5074b79c119419168b8f343fef4da6d7e35227cfd1f87 + languageName: node + linkType: hard + "simple-get@npm:^3.0.3": version: 3.1.1 resolution: "simple-get@npm:3.1.1" @@ -38907,7 +39356,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:6.0, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -40092,7 +40541,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.10.0, tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": +"tslib@npm:^1.10.0, tslib@npm:^1.11.1, tslib@npm:^1.14.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd @@ -40698,6 +41147,13 @@ __metadata: languageName: node linkType: hard +"urijs@npm:^1.19.11": + version: 1.19.11 + resolution: "urijs@npm:1.19.11" + checksum: f9b95004560754d30fd7dbee44b47414d662dc9863f1cf5632a7c7983648df11d23c0be73b9b4f9554463b61d5b0a520b70df9e1ee963ebb4af02e6da2cc80f3 + languageName: node + linkType: hard + "url-parse@npm:^1.5.10": version: 1.5.10 resolution: "url-parse@npm:1.5.10" @@ -40866,6 +41322,13 @@ __metadata: languageName: node linkType: hard +"utility-types@npm:^3.10.0": + version: 3.10.0 + resolution: "utility-types@npm:3.10.0" + checksum: 8f274415c6196ab62883b8bd98c9d2f8829b58016e4269aaa1ebd84184ac5dda7dc2ca45800c0d5e0e0650966ba063bf9a412aaeaea6850ca4440a391283d5c8 + languageName: node + linkType: hard + "utils-merge@npm:1.0.1, utils-merge@npm:1.x.x, utils-merge@npm:^1.0.1": version: 1.0.1 resolution: "utils-merge@npm:1.0.1"