diff --git a/packages/@ama-openapi/core/src/constants.mts b/packages/@ama-openapi/core/src/constants.mts index 96aa67c8fa..e3cbf01ee6 100644 --- a/packages/@ama-openapi/core/src/constants.mts +++ b/packages/@ama-openapi/core/src/constants.mts @@ -15,13 +15,13 @@ export const DEFAULT_MANIFEST_FILENAMES = [ 'package.json' ] as const; -/** Default directory where generate the JSON Schemas */ +/** Default directory where to generate the JSON Schemas */ export const DEFAULT_SCHEMA_OUTPUT_DIRECTORY = 'schemas'; /** NPM keywords to identify a specification package */ export const OPENAPI_NPM_KEYWORDS = ['openapi'] as const; -/** Name of the manifest schema file. */ +/** Name of the JSON schema validating the manifest file */ export const MANIFEST_SCHEMA_FILE = 'manifest.schema.json'; // Internal property keys : diff --git a/packages/@ama-openapi/core/src/core/file-system/write-model.mts b/packages/@ama-openapi/core/src/core/file-system/write-model.mts index 92d8a89131..75dbb2274e 100644 --- a/packages/@ama-openapi/core/src/core/file-system/write-model.mts +++ b/packages/@ama-openapi/core/src/core/file-system/write-model.mts @@ -20,7 +20,7 @@ import type { * @param retrievedModel * @param context */ -export const writeModelFile = async (retrievedModel: RetrievedDependencyModel, context: Context) => { +export const writeModelFile = async (retrievedModel: Pick, context: Context) => { const { outputFilePath, content } = retrievedModel; const { logger } = context; const directory = dirname(outputFilePath); diff --git a/packages/@ama-openapi/core/src/core/serialization.mts b/packages/@ama-openapi/core/src/core/serialization.mts index 5f034998a1..25f4b10da6 100644 --- a/packages/@ama-openapi/core/src/core/serialization.mts +++ b/packages/@ama-openapi/core/src/core/serialization.mts @@ -11,7 +11,7 @@ import type { * @param specification * @param model */ -export const deserialize = (specification: string, model: RetrievedDependencyModel): any => { +export const deserialize = (specification: string, model: Pick): any => { if (model.isInputJson) { return JSON.parse(specification); } @@ -23,7 +23,7 @@ export const deserialize = (specification: string, model: RetrievedDependencyMod * @param specification * @param model */ -export const serialize = (specification: any, model: RetrievedDependencyModel): string => { +export const serialize = (specification: any, model: Pick): string => { if (model.isOutputJson) { return JSON.stringify(specification, null, 2); } diff --git a/packages/@ama-openapi/core/src/generate-schemas.mts b/packages/@ama-openapi/core/src/generate-schemas.mts index 2ed5cb0f74..303b4422a3 100644 --- a/packages/@ama-openapi/core/src/generate-schemas.mts +++ b/packages/@ama-openapi/core/src/generate-schemas.mts @@ -3,6 +3,7 @@ import { promises as fs, } from 'node:fs'; import { + dirname, resolve, } from 'node:path'; import * as process from 'node:process'; @@ -46,5 +47,9 @@ export const generateValidationSchemaFiles = async (cwd = process.cwd(), options if (!existsSync(directory)) { await fs.mkdir(directory, { recursive: true }); } - await fs.writeFile(resolve(outputDirectory, MANIFEST_SCHEMA_FILE), JSON.stringify(manifestSchemaObj), { encoding: 'utf8' }); + await fs.writeFile(resolve(outputDirectory, MANIFEST_SCHEMA_FILE), JSON.stringify(manifestSchemaObj.manifest), { encoding: 'utf8' }); + await Promise.all( + manifestSchemaObj.masks + .map(({ mask, fileName }) => fs.writeFile(resolve(outputDirectory, dirname(MANIFEST_SCHEMA_FILE), fileName), JSON.stringify(mask), { encoding: 'utf8' })) + ); }; diff --git a/packages/@ama-openapi/core/src/schema/generate-model-name.mts b/packages/@ama-openapi/core/src/schema/generate-model-name.mts new file mode 100644 index 0000000000..d2661c772c --- /dev/null +++ b/packages/@ama-openapi/core/src/schema/generate-model-name.mts @@ -0,0 +1,26 @@ +import { + sanitizePackagePath, +} from '../core/manifest/extract-dependency-models.mjs'; + +/** + * Generate a reference name from a model definition + * @param artifactName + * @param modelPath + */ +export const generateModelNameRef = (artifactName: string, modelPath: string): string => { + const sanitizedArtifactName = sanitizePackagePath(artifactName); + const [filePath, innerPath] = modelPath.split('#/'); + const modelName = (filePath.replace(/\.(json|ya?ml)$/, '') + (innerPath ?? '')) + .replace(/^\.+\//, '') + .replace(/-/g, '_') + .replace(/\//g, '-'); + return `${sanitizedArtifactName}-${modelName}`; +}; + +/** + * Generate a mask schema file name from a model definition + * @param modelNameRef + */ +export const getMaskFileName = (modelNameRef: string) => { + return `mask-${modelNameRef}.json`; +}; diff --git a/packages/@ama-openapi/core/src/schema/generate-model-name.spec.ts b/packages/@ama-openapi/core/src/schema/generate-model-name.spec.ts new file mode 100644 index 0000000000..c1450f5ec3 --- /dev/null +++ b/packages/@ama-openapi/core/src/schema/generate-model-name.spec.ts @@ -0,0 +1,62 @@ +import { + sanitizePackagePath, +} from '../core/manifest/extract-dependency-models.mjs'; +import { + generateModelNameRef, + getMaskFileName, +} from './generate-model-name.mjs'; + +jest.mock('../core/manifest/extract-dependency-models.mjs', () => ({ + sanitizePackagePath: jest.fn() +})); + +describe('generateModelNameRef', () => { + const sanitizePackagePathMock = + sanitizePackagePath as jest.MockedFunction; + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should build model reference using sanitized artifact name and model file path without inner path', () => { + sanitizePackagePathMock.mockReturnValue('sanitized-pkg'); + + const artifactName = '@scope/my-pkg'; + const modelPath = '/schemas/user.json'; + + const result = generateModelNameRef(artifactName, modelPath); + + expect(result).toBe('sanitized-pkg--schemas-user'); + }); + + it('should handle innerPath references, replacing separators as expected', () => { + sanitizePackagePathMock.mockReturnValue('pkg'); + + const artifactName = 'my-package'; + const modelPath = 'schemas/user.json#/components/schemas/User'; + + const result = generateModelNameRef(artifactName, modelPath); + + expect(result).toBe('pkg-schemas-usercomponents-schemas-User'); + }); + + it('should remove leading relative segments and normalize dashes/paths', () => { + sanitizePackagePathMock.mockReturnValue('pkg_sanitized'); + + const artifactName = 'pkg-with-dash'; + const modelPath = './nested-dir/my-model-name.yaml#/inner-path/value'; + + const result = generateModelNameRef(artifactName, modelPath); + + expect(result).toBe('pkg_sanitized-nested_dir-my_model_nameinner_path-value'); + }); +}); + +describe('getMaskFileName', () => { + it('should prefix modelNameRef with mask- and suffix with .json', () => { + const modelNameRef = 'pkg-schemas-user'; + const result = getMaskFileName(modelNameRef); + + expect(result).toBe('mask-pkg-schemas-user.json'); + }); +}); diff --git a/packages/@ama-openapi/core/src/schema/generate-schema.mts b/packages/@ama-openapi/core/src/schema/generate-schema.mts index 8989070034..eb574f6e5d 100644 --- a/packages/@ama-openapi/core/src/schema/generate-schema.mts +++ b/packages/@ama-openapi/core/src/schema/generate-schema.mts @@ -2,27 +2,22 @@ import type { Context, } from '../context.mjs'; import { - sanitizePackagePath, -} from '../core/manifest/extract-dependency-models.mjs'; + generateModelNameRef, + getMaskFileName, +} from './generate-model-name.mjs'; import { type ListDependenciesOptions, listSpecificationArtifacts, } from './list-artifacts.mjs'; +import { + FIELD_SCHEMA_DEFINITION, + generateMaskSchemaModelAt, +} from './mask/generate-mask-from-model.mjs'; /** Options for Generate OpenAPI Manifest Schema function */ export interface GenerateOpenApiManifestSchemaOptions extends ListDependenciesOptions { } -const generateModelNameRef = (artifactName: string, modelPath: string): string => { - const sanitizedArtifactName = sanitizePackagePath(artifactName); - const modelName = modelPath - .replace(/\.(json|ya?ml)$/, '') - .replace(/^\.+\//, '') - .replace(/\//g, '-') - .replace(/-/g, '_'); - return `${sanitizedArtifactName}-${modelName}`; -}; - /** * Generate Ama-openapi Manifest schema to provide autocompletion and structure validation * @param options @@ -35,6 +30,9 @@ export const generateOpenApiManifestSchema = async (options: GenerateOpenApiMani const refModels = models .filter((modelObj) => !!modelObj) .map(({ model }) => `model-${generateModelNameRef(packageManifest.name!, model)}`); + if (refModels.length === 0) { + return []; + } return [ packageManifest.name!, { @@ -65,7 +63,6 @@ export const generateOpenApiManifestSchema = async (options: GenerateOpenApiMani }] : [], { - type: 'string', const: model }, { @@ -73,7 +70,6 @@ export const generateOpenApiManifestSchema = async (options: GenerateOpenApiMani description: 'Detailed model inclusion with optional transformations to apply', properties: { path: { - type: 'string', const: model, description: "Path to the specific model to include as is. The path is relative to the artifact root (e.g., 'models/ExampleModel.v1.yaml')" }, @@ -99,6 +95,7 @@ export const generateOpenApiManifestSchema = async (options: GenerateOpenApiMani .filter((modelObj) => !!modelObj) .map(({ model }) => { const modelRef = generateModelNameRef(packageManifest.name!, model); + const maskSchemaFileName = getMaskFileName(modelRef); return [ `transform-${modelRef}`, { @@ -107,9 +104,11 @@ export const generateOpenApiManifestSchema = async (options: GenerateOpenApiMani $ref: '#/definitions/baseTransform' }, { - mask: { // TODO: generate mask file, issue #3780 - type: 'object', - description: 'Mask to apply' + type: 'object', + properties: { + mask: { + $ref: `./${maskSchemaFileName}` + } } } ] @@ -119,40 +118,74 @@ export const generateOpenApiManifestSchema = async (options: GenerateOpenApiMani }) ); + const masks = (await Promise.all( + artifacts.map(({ packageManifest, models }) => { + const filteredModels = models + .filter((modelObj) => !!modelObj); + const modelPaths = Object.fromEntries(filteredModels.map((m) => ([m.modelPath, m.model]))); + return Promise.all(filteredModels + .map(async ({ model, modelPath }) => { + const modelRef = generateModelNameRef(packageManifest.name!, model); + const fileName = getMaskFileName(modelRef); + const ctx = { + ...options, + modelPaths, + packageName: packageManifest.name! + }; + return { + mask: { + $schema: 'http://json-schema.org/draft-07/schema#', + title: `OpenApi specification mask ${modelRef}`, + $id: `@ama-openapi/core/schemas/${fileName}`, + ...await generateMaskSchemaModelAt(modelPath, ctx), + definitions: { + ...FIELD_SCHEMA_DEFINITION + } + }, + fileName + }; + }) + ); + }) + )).flat(); + return { - $schema: 'http://json-schema.org/draft-07/schema#', - title: 'OpenApi specification package manifest', - $id: '@ama-openapi/core/schemas/manifest.schema.json', - type: 'object', - properties: { - models: { - type: 'object', - description: 'Dependency package containing the specification to include', - properties: modelsProperties - } - }, - additionalProperties: true, - definitions: { - baseTransform: { - type: 'object', - examples: [ - { - rename: 'MyPrefix_$1' - } - ], - properties: { - rename: { - type: 'string', - description: 'Rename the outputted file. The keyword `$1` can be used to refer to the original name (ex: a prefix would be `my-prefix-$1`)', - examples: [ - 'my-prefix-$1', - 'myModel.v1.yaml' - ] - } + masks, + manifest: { + $schema: 'http://json-schema.org/draft-07/schema#', + title: 'OpenApi specification package manifest', + $id: '@ama-openapi/core/schemas/manifest.schema.json', + type: 'object', + properties: { + models: { + type: 'object', + description: 'Dependency package containing the specification to include', + properties: modelsProperties } }, - ...modelDefinitions, - ...transformDefinitions + additionalProperties: true, + definitions: { + baseTransform: { + type: 'object', + examples: [ + { + rename: 'MyPrefix_$1' + } + ], + properties: { + rename: { + type: 'string', + description: 'Rename the outputted file. The keyword `$1` can be used to refer to the original name (ex: a prefix would be `my-prefix-$1`)', + examples: [ + 'my-prefix-$1', + 'myModel.v1.yaml' + ] + } + } + }, + ...modelDefinitions, + ...transformDefinitions + } } }; }; diff --git a/packages/@ama-openapi/core/src/schema/mask/generate-mask-from-model.mts b/packages/@ama-openapi/core/src/schema/mask/generate-mask-from-model.mts new file mode 100644 index 0000000000..232e11d290 --- /dev/null +++ b/packages/@ama-openapi/core/src/schema/mask/generate-mask-from-model.mts @@ -0,0 +1,172 @@ +import { + dirname, + posix, + sep, +} from 'node:path'; +import type { + Context, +} from '../../context.mjs'; +import { + parseFile, +} from '../../core/file-system/parse-file.mjs'; +import { + generateModelNameRef, + getMaskFileName, +} from '../generate-model-name.mjs'; + +/** Mask context */ +export interface MaskContext extends Context { + /** Path to the current file being parsed */ + filePath?: string; + /** List of files already parsed */ + parsedFiles?: string[]; + /** List of model paths to be resolved for the current package */ + modelPaths: Record; + /** Package name */ + packageName: string; +} + +const FIELD_SCHEMA_NAME = 'baseMaskField'; + +const FIELD_SCHEMA_REF = `#/definitions/${FIELD_SCHEMA_NAME}`; + +/** Field schema definition */ +export const FIELD_SCHEMA_DEFINITION = { + [FIELD_SCHEMA_NAME]: { + oneOf: [ + { type: 'boolean' }, + { const: {} }, + { const: null } + ] + } +}; + +/** + * Generate a mask schema from a model definition + * @param modelPath + * @param ctx + */ +export const generateMaskSchemaModelAt = async (modelPath: string, ctx: MaskContext) => { + const { logger } = ctx; + + modelPath = modelPath.replaceAll(sep, '/'); + if (ctx.filePath) { + modelPath = posix.resolve(dirname(ctx.filePath).replaceAll(sep, '/'), modelPath); + } + + if (ctx.parsedFiles?.includes(modelPath)) { + logger?.warn(`The reference ${modelPath} is circular, it will be resolve to "any"`); + return {}; + } + + const [filePath, innerPath] = modelPath.split('#/'); + let model = await parseFile(filePath); + + if (ctx.filePath && ctx.modelPaths[filePath]) { + const schemaInnerPath = innerPath?.replaceAll('/', '/properties/'); + + return { + description: model.description, + oneOf: [ + { + $ref: FIELD_SCHEMA_REF + }, + { + $ref: `./${getMaskFileName(generateModelNameRef(ctx.packageName, ctx.modelPaths[filePath]))}${schemaInnerPath ? `#/${schemaInnerPath}` : ''}` + } + ] + }; + } + + if (!filePath && innerPath) { + const schemaInnerPath = innerPath?.replaceAll('/', '/properties/'); + return { + description: model.description, + oneOf: [ + { + $ref: FIELD_SCHEMA_REF + }, + { + $ref: schemaInnerPath ? `#/${schemaInnerPath}` : '' + } + ] + }; + } + + if (innerPath) { + model = innerPath.split('/').reduce((acc, pathItem) => acc?.[pathItem], model); + } + + return generateMaskSchemaFromModel(model, { + ...ctx, + filePath, + parsedFiles: [...(ctx.parsedFiles ?? []), modelPath] + }); +}; + +/** + * Generate a mask schema from a model definition + * @param model + * @param ctx + */ +export const generateMaskSchemaFromModel = async (model: any, ctx: MaskContext): Promise => { + if (typeof model !== 'object' || !model) { + return { + default: model, + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + ...(typeof model === 'object' ? [] : [{ type: typeof model }]) + ] + }; + } + + if (Array.isArray(model)) { + return { + type: 'array', + prefixItems: model + .map((item) => generateMaskSchemaFromModel(item, ctx)) + }; + } + + if (model.$ref) { + return generateMaskSchemaModelAt(model.$ref, ctx); + } else if (model.type === 'object') { + return { + type: 'object', + description: model.description, + properties: { + ...model.properties + ? { + properties: { + type: 'object', + properties: Object.fromEntries( + await Promise.all( + Object.entries(model.properties).map(async ([key, value]) => ([key, await generateMaskSchemaFromModel(value, ctx)])) + ) + ) + } + } + : {}, + ...Object.fromEntries( + await Promise.all( + Object.entries(model) + .filter(([key]) => !['properties', 'type', '$ref'].includes(key)) + .map(async ([key, value]) => ([key, await generateMaskSchemaFromModel(value, ctx)])) + ) + ) + } + }; + } + + return { + description: model.description, + oneOf: [ + { + $ref: FIELD_SCHEMA_REF + }, + { + type: model.type + } + ] + }; +}; diff --git a/packages/@ama-openapi/core/src/schema/mask/generate-mask-from-model.spec.ts b/packages/@ama-openapi/core/src/schema/mask/generate-mask-from-model.spec.ts new file mode 100644 index 0000000000..3de13f3646 --- /dev/null +++ b/packages/@ama-openapi/core/src/schema/mask/generate-mask-from-model.spec.ts @@ -0,0 +1,322 @@ +import { + join, + posix, +} from 'node:path'; +import { + parseFile, +} from '../../core/file-system/parse-file.mjs'; +import { + generateModelNameRef, + getMaskFileName, +} from '../generate-model-name.mjs'; +import type { + MaskContext, +} from './generate-mask-from-model.mjs'; +import { + generateMaskSchemaFromModel, + generateMaskSchemaModelAt, +} from './generate-mask-from-model.mjs'; + +jest.mock('../../core/file-system/parse-file.mjs', () => ({ + parseFile: jest.fn() +})); + +jest.mock('../generate-model-name.mjs', () => ({ + generateModelNameRef: jest.fn(), + getMaskFileName: jest.fn() +})); + +const FIELD_SCHEMA_REF = '#/definitions/baseMaskField'; + +const createBaseCtx = (overrides: Partial = {}): MaskContext => ({ + logger: { + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + error: jest.fn() + } as any, + modelPaths: {}, + packageName: 'test-package', + ...overrides +} as any); + +describe('generateMaskSchemaModelAt', () => { + const parseFileMock = parseFile as jest.MockedFunction; + const generateModelNameRefMock = + generateModelNameRef as jest.MockedFunction; + const getMaskFileNameMock = + getMaskFileName as jest.MockedFunction; + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should resolve circular references using parsedFiles and log a warning', async () => { + const modelPath = '/models/user.json'; + const ctx = createBaseCtx({ + parsedFiles: [modelPath] + }); + + const result = await generateMaskSchemaModelAt(modelPath, ctx); + + expect(ctx.logger?.warn).toHaveBeenCalledWith( + `The reference ${modelPath} is circular, it will be resolve to "any"` + ); + expect(result).toEqual({}); + expect(parseFileMock).not.toHaveBeenCalled(); + }); + + it('should resolve modelPath relative to ctx.filePath', async () => { + const ctxFilePath = join('root', 'schemas', 'root.json'); + const relativeModelPath = './models/user.json'; + const expectedResolved = posix.resolve('root/schemas', relativeModelPath); + + parseFileMock.mockResolvedValueOnce({ + description: 'User model' + }); + + const ctx = createBaseCtx({ + filePath: ctxFilePath, + modelPaths: {} + }); + + await generateMaskSchemaModelAt(relativeModelPath, ctx); + + expect(parseFileMock).toHaveBeenCalledWith(expectedResolved); + }); + + it('should build a mask $ref when modelPaths has an entry for the filePath', async () => { + const filePath = '/root/schemas/user.json'; + const modelPath = `${filePath}#/User`; + const description = 'User model'; + + parseFileMock.mockResolvedValueOnce({ description }); + + const ctx = createBaseCtx({ + filePath: '/root/schemas/root.json', + packageName: 'my-pkg', + modelPaths: { + [filePath]: 'models/user.ts' + } + }); + + generateModelNameRefMock.mockReturnValue('MyPkgUser'); + getMaskFileNameMock.mockReturnValue('my-pkg-user.mask.json'); + + const result = await generateMaskSchemaModelAt(modelPath, ctx); + + const expectedInnerPath = 'User'; + const expectedRef = `./my-pkg-user.mask.json#/${expectedInnerPath}`; + + expect(result).toEqual({ + description, + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { $ref: expectedRef } + ] + }); + + expect(generateModelNameRefMock).toHaveBeenCalledWith( + 'my-pkg', + 'models/user.ts' + ); + expect(getMaskFileNameMock).toHaveBeenCalledWith('MyPkgUser'); + }); + + it('should handle innerPath-only references (no filePath)', async () => { + const modelPath = '#/User/details'; + const description = 'Inline root schema'; + + // filePath is empty string here, but we still mock parseFile. + parseFileMock.mockResolvedValueOnce({ description }); + + const ctx = createBaseCtx({ + filePath: undefined, + modelPaths: {} + }); + + const result = await generateMaskSchemaModelAt(modelPath, ctx); + + expect(result).toEqual({ + description, + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { + $ref: '#/User/properties/details' + } + ] + }); + }); + + it('should drill down into model using innerPath when no modelPaths entry is present', async () => { + const filePath = '/root/schemas/user.json'; + const modelPath = `${filePath}#/components/schemas/User`; + const model = { + components: { + schemas: { + User: { + type: 'string', + description: 'User id' + } + } + } + }; + + parseFileMock.mockResolvedValueOnce(model); + + const ctx = createBaseCtx({ + filePath: '/root/schemas/root.json', + modelPaths: {} // no entry for filePath to hit the fallback branch + }); + + const result = await generateMaskSchemaModelAt(modelPath, ctx); + + // It should eventually wrap the leaf model as a mask schema. + expect(result).toEqual({ + description: 'User id', + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { type: 'string' } + ] + }); + }); +}); + +describe('generateMaskSchemaFromModel', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should return FIELD_SCHEMA_REF for non-object or null model', async () => { + const ctx = createBaseCtx(); + + const resString = await generateMaskSchemaFromModel('foo' as any, ctx); + const resNumber = await generateMaskSchemaFromModel(123 as any, ctx); + const resNull = await generateMaskSchemaFromModel(null as any, ctx); + + expect(resString).toEqual({ + oneOf: [ + { + $ref: FIELD_SCHEMA_REF + }, + { + type: 'string' + } + ], default: 'foo' }); + expect(resNumber).toEqual({ + oneOf: [ + { + $ref: FIELD_SCHEMA_REF + }, + { + type: 'number' + } + ], default: 123 + }); + expect(resNull).toEqual({ + default: null, + oneOf: [ + { + $ref: FIELD_SCHEMA_REF + } + ] + }); + }); + + it('should return array schema with prefixItems as promises for array model', async () => { + const ctx = createBaseCtx(); + const model = [ + { type: 'string', description: 'name' }, + { type: 'number', description: 'age' } + ]; + + const result = await generateMaskSchemaFromModel(model as any, ctx); + + expect(result.type).toBe('array'); + expect(Array.isArray(result.prefixItems)).toBe(true); + // Because implementation does not await the recursive calls, + // prefixItems are Promises. + expect(result.prefixItems[0]).toBeInstanceOf(Promise); + expect(result.prefixItems[1]).toBeInstanceOf(Promise); + + const resolved = await Promise.all(result.prefixItems); + expect(resolved).toEqual([ + { + description: 'name', + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { type: 'string' } + ] + }, + { + description: 'age', + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { type: 'number' } + ] + } + ]); + }); + + it('should build object schema for type "object" with nested properties and non-property fields', async () => { + const ctx = createBaseCtx(); + const model = { + type: 'object', + properties: { + foo: { + type: 'string', + description: 'Foo field' + } + }, + extra: { + type: 'number', + description: 'Extra field' + } + }; + + const result = await generateMaskSchemaFromModel(model as any, ctx); + + expect(result).toEqual({ + type: 'object', + properties: { + properties: { + type: 'object', + properties: { + foo: { + description: 'Foo field', + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { type: 'string' } + ] + } + } + }, + extra: { + description: 'Extra field', + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { type: 'number' } + ] + } + } + }); + }); + + it('should return mask schema for leaf model without $ref or type object', async () => { + const ctx = createBaseCtx(); + const model = { + type: 'string', + description: 'Simple string' + }; + + const result = await generateMaskSchemaFromModel(model as any, ctx); + + expect(result).toEqual({ + description: 'Simple string', + oneOf: [ + { $ref: FIELD_SCHEMA_REF }, + { type: 'string' } + ] + }); + }); +}); diff --git a/packages/@ama-sdk/schematics/package.json b/packages/@ama-sdk/schematics/package.json index 631fc5815b..79e1ec4c3a 100644 --- a/packages/@ama-sdk/schematics/package.json +++ b/packages/@ama-sdk/schematics/package.json @@ -141,7 +141,7 @@ "@swc/cli": "~0.7.9", "@swc/core": "~1.15.3", "@swc/helpers": "~0.5.17", - "@typescript-eslint/eslint-plugin": "~8.50.0", + "@typescript-eslint/eslint-plugin": "~8.51.0", "jest-junit": "~16.0.0", "lint-staged": "^16.0.0", "minimist": "^1.2.6", diff --git a/packages/@o3r/core/package.json b/packages/@o3r/core/package.json index 40c045e244..bdedc2cd69 100644 --- a/packages/@o3r/core/package.json +++ b/packages/@o3r/core/package.json @@ -166,8 +166,8 @@ "@o3r/store-sync": "workspace:~", "@stylistic/eslint-plugin": "~5.6.0", "@types/jest": "~30.0.0", - "@typescript-eslint/eslint-plugin": "~8.50.0", - "@typescript-eslint/parser": "~8.50.0", + "@typescript-eslint/eslint-plugin": "~8.51.0", + "@typescript-eslint/parser": "~8.51.0", "angular-eslint": "~20.6.0", "cpy-cli": "^6.0.0", "eslint": "~9.39.0", @@ -175,7 +175,7 @@ "eslint-import-resolver-typescript": "~4.4.0", "eslint-plugin-import": "~2.32.0", "eslint-plugin-import-newlines": "~1.4.0", - "eslint-plugin-jest": "~29.10.0", + "eslint-plugin-jest": "~29.11.0", "eslint-plugin-jsdoc": "~54.7.0", "eslint-plugin-prefer-arrow": "~1.2.3", "eslint-plugin-unicorn": "~60.0.0", @@ -189,7 +189,7 @@ "jsonc-eslint-parser": "~2.4.0", "nx": "~21.6.0", "ts-jest": "~29.4.0", - "typescript-eslint": "~8.50.0", + "typescript-eslint": "~8.51.0", "zone.js": "~0.15.0" }, "engines": { diff --git a/yarn.lock b/yarn.lock index 63a871a2a4..8c95cb3d16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2259,7 +2259,7 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/core@npm:20.3.13, @angular-devkit/core@npm:>= 20.0.0 < 21.0.0, @angular-devkit/core@npm:~20.3.13": +"@angular-devkit/core@npm:20.3.13, @angular-devkit/core@npm:~20.3.13": version: 20.3.13 resolution: "@angular-devkit/core@npm:20.3.13" dependencies: @@ -2297,6 +2297,25 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/core@npm:>= 20.0.0 < 21.0.0": + version: 20.3.7 + resolution: "@angular-devkit/core@npm:20.3.7" + dependencies: + ajv: "npm:8.17.1" + ajv-formats: "npm:3.0.1" + jsonc-parser: "npm:3.3.1" + picomatch: "npm:4.0.3" + rxjs: "npm:7.8.2" + source-map: "npm:0.7.6" + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + checksum: 10/cd820426ac9e14f9ed01acfda0902cdd76a6dbc4605be146d5387070fcba3c247cfb41459910db4490fd318bd4ea58867621fa0e8b8c36ef5bc2a88f2330d014 + languageName: node + linkType: hard + "@angular-devkit/schematics-cli@npm:~20.3.13": version: 20.3.13 resolution: "@angular-devkit/schematics-cli@npm:20.3.13" @@ -4493,7 +4512,17 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.4.4": + version: 7.28.4 + resolution: "@babel/types@npm:7.28.4" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + checksum: 10/db50bf257aafa5d845ad16dae0587f57d596e4be4cbb233ea539976a4c461f9fbcc0bf3d37adae3f8ce5dcb4001462aa608f3558161258b585f6ce6ce21a2e45 + languageName: node + linkType: hard + +"@babel/types@npm:^7.28.5": version: 7.28.5 resolution: "@babel/types@npm:7.28.5" dependencies: @@ -6687,7 +6716,7 @@ __metadata: languageName: node linkType: hard -"@inquirer/type@npm:^3.0.10, @inquirer/type@npm:^3.0.7, @inquirer/type@npm:^3.0.8": +"@inquirer/type@npm:^3.0.10": version: 3.0.10 resolution: "@inquirer/type@npm:3.0.10" peerDependencies: @@ -6699,6 +6728,18 @@ __metadata: languageName: node linkType: hard +"@inquirer/type@npm:^3.0.7, @inquirer/type@npm:^3.0.8": + version: 3.0.9 + resolution: "@inquirer/type@npm:3.0.9" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10/960ba4737405f70bac17e7cdc4696c60064b06c8dd13a4b3d0783763ba1714bdadbd598b88d537ab9415b7d5d61e011ac042cfbd1438b2a35298e2868724b853 + languageName: node + linkType: hard + "@ioredis/commands@npm:1.4.0": version: 1.4.0 resolution: "@ioredis/commands@npm:1.4.0" @@ -8708,6 +8749,23 @@ __metadata: languageName: node linkType: hard +"@nx/devkit@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/devkit@npm:21.6.6" + dependencies: + ejs: "npm:^3.1.7" + enquirer: "npm:~2.3.6" + ignore: "npm:^5.0.4" + minimatch: "npm:9.0.3" + semver: "npm:^7.5.3" + tslib: "npm:^2.3.0" + yargs-parser: "npm:21.1.1" + peerDependencies: + nx: ">= 20 <= 22" + checksum: 10/35c4898b4bfbb63f2e3bc5a10562888798cac82a2259f42400d626f71482f237a7a043556d0509ec699df733c5f3742e89e05eb928f4cb9d35df7c0814b09d41 + languageName: node + linkType: hard + "@nx/eslint-plugin@npm:~21.6.0": version: 21.6.10 resolution: "@nx/eslint-plugin@npm:21.6.10" @@ -8733,7 +8791,7 @@ __metadata: languageName: node linkType: hard -"@nx/eslint@npm:21.6.10, @nx/eslint@npm:~21.6.0": +"@nx/eslint@npm:21.6.10": version: 21.6.10 resolution: "@nx/eslint@npm:21.6.10" dependencies: @@ -8752,6 +8810,25 @@ __metadata: languageName: node linkType: hard +"@nx/eslint@npm:~21.6.0": + version: 21.6.6 + resolution: "@nx/eslint@npm:21.6.6" + dependencies: + "@nx/devkit": "npm:21.6.6" + "@nx/js": "npm:21.6.6" + semver: "npm:^7.5.3" + tslib: "npm:^2.3.0" + typescript: "npm:~5.9.2" + peerDependencies: + "@zkochan/js-yaml": 0.0.7 + eslint: ^8.0.0 || ^9.0.0 + peerDependenciesMeta: + "@zkochan/js-yaml": + optional: true + checksum: 10/595bd200d3337a257e06bcd18d972000495530ef0c63262b34d02a21f4942597967bd8b9c34f0ead6a6f88eb513531d334266242d436eaa81d581ae8568216b5 + languageName: node + linkType: hard + "@nx/jest@npm:~21.6.0": version: 21.6.10 resolution: "@nx/jest@npm:21.6.10" @@ -8775,7 +8852,7 @@ __metadata: languageName: node linkType: hard -"@nx/js@npm:21.6.10, @nx/js@npm:~21.6.0": +"@nx/js@npm:21.6.10": version: 21.6.10 resolution: "@nx/js@npm:21.6.10" dependencies: @@ -8817,6 +8894,48 @@ __metadata: languageName: node linkType: hard +"@nx/js@npm:21.6.6, @nx/js@npm:~21.6.0": + version: 21.6.6 + resolution: "@nx/js@npm:21.6.6" + dependencies: + "@babel/core": "npm:^7.23.2" + "@babel/plugin-proposal-decorators": "npm:^7.22.7" + "@babel/plugin-transform-class-properties": "npm:^7.22.5" + "@babel/plugin-transform-runtime": "npm:^7.23.2" + "@babel/preset-env": "npm:^7.23.2" + "@babel/preset-typescript": "npm:^7.22.5" + "@babel/runtime": "npm:^7.22.6" + "@nx/devkit": "npm:21.6.6" + "@nx/workspace": "npm:21.6.6" + "@zkochan/js-yaml": "npm:0.0.7" + babel-plugin-const-enum: "npm:^1.0.1" + babel-plugin-macros: "npm:^3.1.0" + babel-plugin-transform-typescript-metadata: "npm:^0.3.1" + chalk: "npm:^4.1.0" + columnify: "npm:^1.6.0" + detect-port: "npm:^1.5.1" + enquirer: "npm:~2.3.6" + ignore: "npm:^5.0.4" + js-tokens: "npm:^4.0.0" + jsonc-parser: "npm:3.2.0" + npm-package-arg: "npm:11.0.1" + npm-run-path: "npm:^4.0.1" + ora: "npm:5.3.0" + picocolors: "npm:^1.1.0" + picomatch: "npm:4.0.2" + semver: "npm:^7.5.3" + source-map-support: "npm:0.5.19" + tinyglobby: "npm:^0.2.12" + tslib: "npm:^2.3.0" + peerDependencies: + verdaccio: ^6.0.5 + peerDependenciesMeta: + verdaccio: + optional: true + checksum: 10/97b01a14745feaff17e86e0f8385cd788eaf13bc79bde4285ccf5be45e999d253544bc5b0d44d32920b62349ce036c6613390f88f4d04678c30e8657dcd73e7c + languageName: node + linkType: hard + "@nx/module-federation@npm:21.6.10": version: 21.6.10 resolution: "@nx/module-federation@npm:21.6.10" @@ -8844,6 +8963,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-darwin-arm64@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-darwin-arm64@npm:21.6.6" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@nx/nx-darwin-x64@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-darwin-x64@npm:21.6.10" @@ -8851,6 +8977,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-darwin-x64@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-darwin-x64@npm:21.6.6" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@nx/nx-freebsd-x64@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-freebsd-x64@npm:21.6.10" @@ -8858,6 +8991,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-freebsd-x64@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-freebsd-x64@npm:21.6.6" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@nx/nx-linux-arm-gnueabihf@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-linux-arm-gnueabihf@npm:21.6.10" @@ -8865,6 +9005,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-linux-arm-gnueabihf@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-linux-arm-gnueabihf@npm:21.6.6" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@nx/nx-linux-arm64-gnu@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-linux-arm64-gnu@npm:21.6.10" @@ -8872,6 +9019,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-linux-arm64-gnu@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-linux-arm64-gnu@npm:21.6.6" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@nx/nx-linux-arm64-musl@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-linux-arm64-musl@npm:21.6.10" @@ -8879,6 +9033,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-linux-arm64-musl@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-linux-arm64-musl@npm:21.6.6" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@nx/nx-linux-x64-gnu@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-linux-x64-gnu@npm:21.6.10" @@ -8886,6 +9047,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-linux-x64-gnu@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-linux-x64-gnu@npm:21.6.6" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@nx/nx-linux-x64-musl@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-linux-x64-musl@npm:21.6.10" @@ -8893,6 +9061,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-linux-x64-musl@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-linux-x64-musl@npm:21.6.6" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@nx/nx-win32-arm64-msvc@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-win32-arm64-msvc@npm:21.6.10" @@ -8900,6 +9075,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-win32-arm64-msvc@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-win32-arm64-msvc@npm:21.6.6" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@nx/nx-win32-x64-msvc@npm:21.6.10": version: 21.6.10 resolution: "@nx/nx-win32-x64-msvc@npm:21.6.10" @@ -8907,6 +9089,13 @@ __metadata: languageName: node linkType: hard +"@nx/nx-win32-x64-msvc@npm:21.6.6": + version: 21.6.6 + resolution: "@nx/nx-win32-x64-msvc@npm:21.6.6" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@nx/rspack@npm:21.6.10": version: 21.6.10 resolution: "@nx/rspack@npm:21.6.10" @@ -9007,7 +9196,7 @@ __metadata: languageName: node linkType: hard -"@nx/workspace@npm:21.6.10, @nx/workspace@npm:~21.6.0": +"@nx/workspace@npm:21.6.10": version: 21.6.10 resolution: "@nx/workspace@npm:21.6.10" dependencies: @@ -9024,6 +9213,23 @@ __metadata: languageName: node linkType: hard +"@nx/workspace@npm:21.6.6, @nx/workspace@npm:~21.6.0": + version: 21.6.6 + resolution: "@nx/workspace@npm:21.6.6" + dependencies: + "@nx/devkit": "npm:21.6.6" + "@zkochan/js-yaml": "npm:0.0.7" + chalk: "npm:^4.1.0" + enquirer: "npm:~2.3.6" + nx: "npm:21.6.6" + picomatch: "npm:4.0.2" + semver: "npm:^7.6.3" + tslib: "npm:^2.3.0" + yargs-parser: "npm:21.1.1" + checksum: 10/fc80b183bc95fc96d3c2bae3a57439c88f940f38fc822422593242004eda20e66433e7fd40770b7873ca6b522cdfc2e6e9b5429df8bd50ab49be75d1b27c14a6 + languageName: node + linkType: hard + "@o3r-training/showcase-sdk@workspace:packages/@o3r-training/showcase-sdk, @o3r-training/showcase-sdk@workspace:~": version: 0.0.0-use.local resolution: "@o3r-training/showcase-sdk@workspace:packages/@o3r-training/showcase-sdk" @@ -17059,6 +17265,19 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/project-service@npm:8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/project-service@npm:8.45.0" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.45.0" + "@typescript-eslint/types": "npm:^8.45.0" + debug: "npm:^4.3.4" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/919c8260dae79eaec79de84a5ae66fbb09c2ab7aca8c3b7785cb011582a2864c8091e64c84013b05bce812e522fbc4a5ae1c68f86404e078fc84da0fe80247ce + languageName: node + linkType: hard + "@typescript-eslint/project-service@npm:8.51.0": version: 8.51.0 resolution: "@typescript-eslint/project-service@npm:8.51.0" @@ -17099,6 +17318,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/scope-manager@npm:8.45.0" + dependencies: + "@typescript-eslint/types": "npm:8.45.0" + "@typescript-eslint/visitor-keys": "npm:8.45.0" + checksum: 10/e45d63a0109eca00f6b431d87e73eacfa03b1795905f123e9144bcacb5abb83888167d1849317c6f90ba1f3553196b2eab13e5e7cdd1050d7a84eaadb65ba801 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:8.51.0": version: 8.51.0 resolution: "@typescript-eslint/scope-manager@npm:8.51.0" @@ -17109,6 +17338,15 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/tsconfig-utils@npm:8.45.0, @typescript-eslint/tsconfig-utils@npm:^8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.45.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/91696bbc34758749d3647236986bf418bacdc0de0e27c2d39cd7c2408c404c35ed18c47c2a55aea0bb9525cc7eb656586359c4e651144603f3438ce93fe80081 + languageName: node + linkType: hard + "@typescript-eslint/tsconfig-utils@npm:8.51.0, @typescript-eslint/tsconfig-utils@npm:^8.51.0": version: 8.51.0 resolution: "@typescript-eslint/tsconfig-utils@npm:8.51.0" @@ -17118,7 +17356,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.51.0, @typescript-eslint/type-utils@npm:^8.0.0": +"@typescript-eslint/type-utils@npm:8.51.0": version: 8.51.0 resolution: "@typescript-eslint/type-utils@npm:8.51.0" dependencies: @@ -17134,6 +17372,22 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/type-utils@npm:^8.0.0": + version: 8.45.0 + resolution: "@typescript-eslint/type-utils@npm:8.45.0" + dependencies: + "@typescript-eslint/types": "npm:8.45.0" + "@typescript-eslint/typescript-estree": "npm:8.45.0" + "@typescript-eslint/utils": "npm:8.45.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/81017b3f4780a65a4e4268ab208f1cb8891c1ced9ade23d8eb4575b18aeb99fe59a0d0ddbb4eea9c086567a1b4515d3466e850d4c81ec0d2d88658c43877a6cf + languageName: node + linkType: hard + "@typescript-eslint/types@npm:6.21.0": version: 6.21.0 resolution: "@typescript-eslint/types@npm:6.21.0" @@ -17141,6 +17395,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.45.0, @typescript-eslint/types@npm:^8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/types@npm:8.45.0" + checksum: 10/889ded2b9bf376c876611b2a37f89051fdc8ec501314a4b97832caefa4305bffc4b752548941ce2e7f9659a81336d096d439d4c2ed236c99fefdf60b715593dd + languageName: node + linkType: hard + "@typescript-eslint/types@npm:8.51.0, @typescript-eslint/types@npm:^8.0.0, @typescript-eslint/types@npm:^8.15.0, @typescript-eslint/types@npm:^8.42.0, @typescript-eslint/types@npm:^8.47.0, @typescript-eslint/types@npm:^8.51.0": version: 8.51.0 resolution: "@typescript-eslint/types@npm:8.51.0" @@ -17167,6 +17428,26 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.45.0" + dependencies: + "@typescript-eslint/project-service": "npm:8.45.0" + "@typescript-eslint/tsconfig-utils": "npm:8.45.0" + "@typescript-eslint/types": "npm:8.45.0" + "@typescript-eslint/visitor-keys": "npm:8.45.0" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/2fb4e63ad6128afbada8eabaabfe7d5a8f1a1f387bb13d7d3209103493ba974b518bf47b17e9a853beba10ec81efd5582ebf628c2eb77a924cf67d4d85466e5e + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:8.51.0": version: 8.51.0 resolution: "@typescript-eslint/typescript-estree@npm:8.51.0" @@ -17186,6 +17467,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/utils@npm:8.45.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.45.0" + "@typescript-eslint/types": "npm:8.45.0" + "@typescript-eslint/typescript-estree": "npm:8.45.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/9e675a0da4434bd434901f9ba3e1e91d4d7ad542d7fcf8c23534a67f2f9039a569da20929e67a6562e3a263be226ad424cd0c1ac80f7828f4285f7f34e361926 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:8.51.0, @typescript-eslint/utils@npm:^8.0.0, @typescript-eslint/utils@npm:~8.51.0": version: 8.51.0 resolution: "@typescript-eslint/utils@npm:8.51.0" @@ -17228,6 +17524,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.45.0": + version: 8.45.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.45.0" + dependencies: + "@typescript-eslint/types": "npm:8.45.0" + eslint-visitor-keys: "npm:^4.2.1" + checksum: 10/8ae7e19c69c1f67fa8f952c18a09ad42a8cba492545d6e1dca6750e760893773f69ec6b1a96d0997e833c82aecc5ff7fb9546c5abd6c4427d91206670cf8ff37 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:8.51.0": version: 8.51.0 resolution: "@typescript-eslint/visitor-keys@npm:8.51.0" @@ -25217,7 +25523,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:3.3.3, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.3": +"fast-glob@npm:3.3.3, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -29976,7 +30282,7 @@ __metadata: languageName: node linkType: hard -"loader-runner@npm:^4.2.0, loader-runner@npm:^4.3.1": +"loader-runner@npm:^4.2.0": version: 4.3.1 resolution: "loader-runner@npm:4.3.1" checksum: 10/d77127497c3f91fdba351e3e91156034e6e590e9f050b40df6c38ac16c54b5c903f7e2e141e09fefd046ee96b26fb50773c695ebc0aa205a4918683b124b04ba @@ -32127,7 +32433,7 @@ __metadata: languageName: node linkType: hard -"nx@npm:21.6.10, nx@npm:~21.6.0": +"nx@npm:21.6.10": version: 21.6.10 resolution: "nx@npm:21.6.10" dependencies: @@ -32212,6 +32518,91 @@ __metadata: languageName: node linkType: hard +"nx@npm:21.6.6, nx@npm:~21.6.0": + version: 21.6.6 + resolution: "nx@npm:21.6.6" + dependencies: + "@napi-rs/wasm-runtime": "npm:0.2.4" + "@nx/nx-darwin-arm64": "npm:21.6.6" + "@nx/nx-darwin-x64": "npm:21.6.6" + "@nx/nx-freebsd-x64": "npm:21.6.6" + "@nx/nx-linux-arm-gnueabihf": "npm:21.6.6" + "@nx/nx-linux-arm64-gnu": "npm:21.6.6" + "@nx/nx-linux-arm64-musl": "npm:21.6.6" + "@nx/nx-linux-x64-gnu": "npm:21.6.6" + "@nx/nx-linux-x64-musl": "npm:21.6.6" + "@nx/nx-win32-arm64-msvc": "npm:21.6.6" + "@nx/nx-win32-x64-msvc": "npm:21.6.6" + "@yarnpkg/lockfile": "npm:^1.1.0" + "@yarnpkg/parsers": "npm:3.0.2" + "@zkochan/js-yaml": "npm:0.0.7" + axios: "npm:^1.12.0" + chalk: "npm:^4.1.0" + cli-cursor: "npm:3.1.0" + cli-spinners: "npm:2.6.1" + cliui: "npm:^8.0.1" + dotenv: "npm:~16.4.5" + dotenv-expand: "npm:~11.0.6" + enquirer: "npm:~2.3.6" + figures: "npm:3.2.0" + flat: "npm:^5.0.2" + front-matter: "npm:^4.0.2" + ignore: "npm:^5.0.4" + jest-diff: "npm:^30.0.2" + jsonc-parser: "npm:3.2.0" + lines-and-columns: "npm:2.0.3" + minimatch: "npm:9.0.3" + node-machine-id: "npm:1.1.12" + npm-run-path: "npm:^4.0.1" + open: "npm:^8.4.0" + ora: "npm:5.3.0" + resolve.exports: "npm:2.0.3" + semver: "npm:^7.5.3" + string-width: "npm:^4.2.3" + tar-stream: "npm:~2.2.0" + tmp: "npm:~0.2.1" + tree-kill: "npm:^1.2.2" + tsconfig-paths: "npm:^4.1.2" + tslib: "npm:^2.3.0" + yaml: "npm:^2.6.0" + yargs: "npm:^17.6.2" + yargs-parser: "npm:21.1.1" + peerDependencies: + "@swc-node/register": ^1.8.0 + "@swc/core": ^1.3.85 + dependenciesMeta: + "@nx/nx-darwin-arm64": + optional: true + "@nx/nx-darwin-x64": + optional: true + "@nx/nx-freebsd-x64": + optional: true + "@nx/nx-linux-arm-gnueabihf": + optional: true + "@nx/nx-linux-arm64-gnu": + optional: true + "@nx/nx-linux-arm64-musl": + optional: true + "@nx/nx-linux-x64-gnu": + optional: true + "@nx/nx-linux-x64-musl": + optional: true + "@nx/nx-win32-arm64-msvc": + optional: true + "@nx/nx-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc-node/register": + optional: true + "@swc/core": + optional: true + bin: + nx: bin/nx.js + nx-cloud: bin/nx-cloud.js + checksum: 10/2e492601b10535b06ed9ba5f9aeb35557fe3d2877935b23f495601d8b6b35550ced8df23e45f7a6eade79daa78ece8f805e93299d7f744238f192a043cd1b0b2 + languageName: node + linkType: hard + "oauth-sign@npm:~0.9.0": version: 0.9.0 resolution: "oauth-sign@npm:0.9.0" @@ -35823,15 +36214,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-all-unknown@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-all-unknown@npm:1.96.0" - dependencies: - sass: "npm:1.96.0" - conditions: (!cpu=arm | !cpu=arm64 | !cpu=riscv64 | !cpu=x64) - languageName: node - linkType: hard - "sass-embedded-android-arm64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-android-arm64@npm:1.93.3" @@ -35839,13 +36221,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-android-arm64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-android-arm64@npm:1.96.0" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "sass-embedded-android-arm@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-android-arm@npm:1.93.3" @@ -35853,13 +36228,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-android-arm@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-android-arm@npm:1.96.0" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "sass-embedded-android-riscv64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-android-riscv64@npm:1.93.3" @@ -35867,13 +36235,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-android-riscv64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-android-riscv64@npm:1.96.0" - conditions: os=android & cpu=riscv64 - languageName: node - linkType: hard - "sass-embedded-android-x64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-android-x64@npm:1.93.3" @@ -35881,13 +36242,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-android-x64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-android-x64@npm:1.96.0" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "sass-embedded-darwin-arm64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-darwin-arm64@npm:1.93.3" @@ -35895,13 +36249,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-darwin-arm64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-darwin-arm64@npm:1.96.0" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "sass-embedded-darwin-x64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-darwin-x64@npm:1.93.3" @@ -35909,13 +36256,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-darwin-x64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-darwin-x64@npm:1.96.0" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "sass-embedded-linux-arm64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-arm64@npm:1.93.3" @@ -35923,13 +36263,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-arm64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-arm64@npm:1.96.0" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "sass-embedded-linux-arm@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-arm@npm:1.93.3" @@ -35937,13 +36270,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-arm@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-arm@npm:1.96.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "sass-embedded-linux-musl-arm64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-musl-arm64@npm:1.93.3" @@ -35951,13 +36277,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-musl-arm64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-musl-arm64@npm:1.96.0" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "sass-embedded-linux-musl-arm@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-musl-arm@npm:1.93.3" @@ -35965,13 +36284,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-musl-arm@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-musl-arm@npm:1.96.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "sass-embedded-linux-musl-riscv64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-musl-riscv64@npm:1.93.3" @@ -35979,13 +36291,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-musl-riscv64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-musl-riscv64@npm:1.96.0" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "sass-embedded-linux-musl-x64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-musl-x64@npm:1.93.3" @@ -35993,13 +36298,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-musl-x64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-musl-x64@npm:1.96.0" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "sass-embedded-linux-riscv64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-riscv64@npm:1.93.3" @@ -36007,13 +36305,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-riscv64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-riscv64@npm:1.96.0" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "sass-embedded-linux-x64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-linux-x64@npm:1.93.3" @@ -36021,13 +36312,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-linux-x64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-linux-x64@npm:1.96.0" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "sass-embedded-unknown-all@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-unknown-all@npm:1.93.3" @@ -36037,15 +36321,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-unknown-all@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-unknown-all@npm:1.96.0" - dependencies: - sass: "npm:1.96.0" - conditions: (!os=android | !os=darwin | !os=linux | !os=win32) - languageName: node - linkType: hard - "sass-embedded-win32-arm64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-win32-arm64@npm:1.93.3" @@ -36053,13 +36328,6 @@ __metadata: languageName: node linkType: hard -"sass-embedded-win32-arm64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-win32-arm64@npm:1.96.0" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "sass-embedded-win32-x64@npm:1.93.3": version: 1.93.3 resolution: "sass-embedded-win32-x64@npm:1.93.3" @@ -36067,87 +36335,7 @@ __metadata: languageName: node linkType: hard -"sass-embedded-win32-x64@npm:1.96.0": - version: 1.96.0 - resolution: "sass-embedded-win32-x64@npm:1.96.0" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"sass-embedded@npm:^1.83.4": - version: 1.96.0 - resolution: "sass-embedded@npm:1.96.0" - dependencies: - "@bufbuild/protobuf": "npm:^2.5.0" - buffer-builder: "npm:^0.2.0" - colorjs.io: "npm:^0.5.0" - immutable: "npm:^5.0.2" - rxjs: "npm:^7.4.0" - sass-embedded-all-unknown: "npm:1.96.0" - sass-embedded-android-arm: "npm:1.96.0" - sass-embedded-android-arm64: "npm:1.96.0" - sass-embedded-android-riscv64: "npm:1.96.0" - sass-embedded-android-x64: "npm:1.96.0" - sass-embedded-darwin-arm64: "npm:1.96.0" - sass-embedded-darwin-x64: "npm:1.96.0" - sass-embedded-linux-arm: "npm:1.96.0" - sass-embedded-linux-arm64: "npm:1.96.0" - sass-embedded-linux-musl-arm: "npm:1.96.0" - sass-embedded-linux-musl-arm64: "npm:1.96.0" - sass-embedded-linux-musl-riscv64: "npm:1.96.0" - sass-embedded-linux-musl-x64: "npm:1.96.0" - sass-embedded-linux-riscv64: "npm:1.96.0" - sass-embedded-linux-x64: "npm:1.96.0" - sass-embedded-unknown-all: "npm:1.96.0" - sass-embedded-win32-arm64: "npm:1.96.0" - sass-embedded-win32-x64: "npm:1.96.0" - supports-color: "npm:^8.1.1" - sync-child-process: "npm:^1.0.2" - varint: "npm:^6.0.0" - dependenciesMeta: - sass-embedded-all-unknown: - optional: true - sass-embedded-android-arm: - optional: true - sass-embedded-android-arm64: - optional: true - sass-embedded-android-riscv64: - optional: true - sass-embedded-android-x64: - optional: true - sass-embedded-darwin-arm64: - optional: true - sass-embedded-darwin-x64: - optional: true - sass-embedded-linux-arm: - optional: true - sass-embedded-linux-arm64: - optional: true - sass-embedded-linux-musl-arm: - optional: true - sass-embedded-linux-musl-arm64: - optional: true - sass-embedded-linux-musl-riscv64: - optional: true - sass-embedded-linux-musl-x64: - optional: true - sass-embedded-linux-riscv64: - optional: true - sass-embedded-linux-x64: - optional: true - sass-embedded-unknown-all: - optional: true - sass-embedded-win32-arm64: - optional: true - sass-embedded-win32-x64: - optional: true - bin: - sass: dist/bin/sass.js - checksum: 10/b7ea4769ae40aaefb116f83a1b2728d75f25567e05bddc35d1029cf825a9dd61fc43ec8e98defe13d6e92beb2c9310450dcf56678fb1a76b0ee29b91234d8804 - languageName: node - linkType: hard - -"sass-embedded@npm:~1.93.0": +"sass-embedded@npm:^1.83.4, sass-embedded@npm:~1.93.0": version: 1.93.3 resolution: "sass-embedded@npm:1.93.3" dependencies: @@ -36306,9 +36494,9 @@ __metadata: languageName: node linkType: hard -"sass@npm:1.96.0, sass@npm:^1.81.0, sass@npm:^1.85.0": - version: 1.96.0 - resolution: "sass@npm:1.96.0" +"sass@npm:^1.81.0, sass@npm:^1.85.0": + version: 1.94.2 + resolution: "sass@npm:1.94.2" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -36319,7 +36507,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10/be4c0030f8f973fff5ee10bc4fdf5026a63a66a06bc540c9efffb91bead7b22c13174af765196cb73d2f175dd5f4f879afd027312bf600158c7ced6c2de1c1aa + checksum: 10/e60c214ea93677740c9ddfad55c77fd433255bbfdd9faba137acf1215bed5ba6ad9d83efea81feb87a89283931d01f0435227e3fff37c65c263e0ee05f885328 languageName: node linkType: hard @@ -38570,7 +38758,7 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^29.4.0, ts-jest@npm:~29.4.0": +"ts-jest@npm:^29.4.0": version: 29.4.6 resolution: "ts-jest@npm:29.4.6" dependencies: @@ -38610,6 +38798,46 @@ __metadata: languageName: node linkType: hard +"ts-jest@npm:~29.4.0": + version: 29.4.5 + resolution: "ts-jest@npm:29.4.5" + dependencies: + bs-logger: "npm:^0.2.6" + fast-json-stable-stringify: "npm:^2.1.0" + handlebars: "npm:^4.7.8" + json5: "npm:^2.2.3" + lodash.memoize: "npm:^4.1.2" + make-error: "npm:^1.3.6" + semver: "npm:^7.7.3" + type-fest: "npm:^4.41.0" + yargs-parser: "npm:^21.1.1" + peerDependencies: + "@babel/core": ">=7.0.0-beta.0 <8" + "@jest/transform": ^29.0.0 || ^30.0.0 + "@jest/types": ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: ">=4.3 <6" + peerDependenciesMeta: + "@babel/core": + optional: true + "@jest/transform": + optional: true + "@jest/types": + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + bin: + ts-jest: cli.js + checksum: 10/48d867e0707474241b6339336cbe57d85122d6018fef957c8c095ff365e5d9428f112fe2cb11a8301343bbd32cec3ff639523d9bf9eea3a371734aa9a100f8a2 + languageName: node + linkType: hard + "ts-loader@npm:^9.3.1, ts-loader@npm:^9.5.2": version: 9.5.4 resolution: "ts-loader@npm:9.5.4" @@ -40095,45 +40323,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.101.3": - version: 5.103.0 - resolution: "webpack@npm:5.103.0" - dependencies: - "@types/eslint-scope": "npm:^3.7.7" - "@types/estree": "npm:^1.0.8" - "@types/json-schema": "npm:^7.0.15" - "@webassemblyjs/ast": "npm:^1.14.1" - "@webassemblyjs/wasm-edit": "npm:^1.14.1" - "@webassemblyjs/wasm-parser": "npm:^1.14.1" - acorn: "npm:^8.15.0" - acorn-import-phases: "npm:^1.0.3" - browserslist: "npm:^4.26.3" - chrome-trace-event: "npm:^1.0.2" - enhanced-resolve: "npm:^5.17.3" - es-module-lexer: "npm:^1.2.1" - eslint-scope: "npm:5.1.1" - events: "npm:^3.2.0" - glob-to-regexp: "npm:^0.4.1" - graceful-fs: "npm:^4.2.11" - json-parse-even-better-errors: "npm:^2.3.1" - loader-runner: "npm:^4.3.1" - mime-types: "npm:^2.1.27" - neo-async: "npm:^2.6.2" - schema-utils: "npm:^4.3.3" - tapable: "npm:^2.3.0" - terser-webpack-plugin: "npm:^5.3.11" - watchpack: "npm:^2.4.4" - webpack-sources: "npm:^3.3.3" - peerDependenciesMeta: - webpack-cli: - optional: true - bin: - webpack: bin/webpack.js - checksum: 10/0018e77d159da412aa8cc1c3ac1d7c0b44228d0f5ce3939b4f424c04feba69747d8490541bcf8143b358a64afbbd69daad95e573ec9c4a90a99bef55d51dd43e - languageName: node - linkType: hard - -"webpack@npm:~5.102.0": +"webpack@npm:^5.101.3, webpack@npm:~5.102.0": version: 5.102.1 resolution: "webpack@npm:5.102.1" dependencies: