From c47ff1c4fcfdb5e8135a6ee2fe34d12d1b0653bd Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Mon, 20 Jan 2025 12:47:47 +0100 Subject: [PATCH 01/10] wip --- src/schema-convertors.ts | 14 +- .../internalToMongodb.test.ts | 367 ++++++++++++++++++ src/schema-convertors/internalToMongodb.ts | 68 ++++ 3 files changed, 438 insertions(+), 11 deletions(-) create mode 100644 src/schema-convertors/internalToMongodb.test.ts create mode 100644 src/schema-convertors/internalToMongodb.ts diff --git a/src/schema-convertors.ts b/src/schema-convertors.ts index 435e991..fd26a93 100644 --- a/src/schema-convertors.ts +++ b/src/schema-convertors.ts @@ -1,5 +1,6 @@ +import internalSchemaToMongoDB from './schema-convertors/internalToMongoDB'; import { Schema as InternalSchema } from './schema-analyzer'; -import { ExtendedJSONSchema, MongoDBJSONSchema, StandardJSONSchema } from './types'; +import { ExtendedJSONSchema, StandardJSONSchema } from './types'; function internalSchemaToStandard( internalSchema: InternalSchema, @@ -7,16 +8,7 @@ function internalSchemaToStandard( signal?: AbortSignal }): StandardJSONSchema { // TODO: COMPASS-8700 - return {}; -} - -function internalSchemaToMongoDB( - internalSchema: InternalSchema, - options: { - signal?: AbortSignal -}): MongoDBJSONSchema { - // TODO: COMPASS-8701 - return {} as MongoDBJSONSchema; + return {} as StandardJSONSchema; } function internalSchemaToExtended( diff --git a/src/schema-convertors/internalToMongodb.test.ts b/src/schema-convertors/internalToMongodb.test.ts new file mode 100644 index 0000000..be07930 --- /dev/null +++ b/src/schema-convertors/internalToMongodb.test.ts @@ -0,0 +1,367 @@ +import assert from 'assert'; +import internalSchemaToStandard from './internalToMongodb'; + +describe.only('internalSchemaToStandard', function() { + describe('Converts: ', function() { + it('document/object', function() { + const internal = { + count: 2, + fields: [ + { + name: 'author', + path: [ + 'author' + ], + count: 1, + type: [ + 'Document', + 'Undefined' + ], + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'Document', + path: [ + 'author' + ], + count: 1, + probability: 0.5, + bsonType: 'Document', + fields: [ + { + name: 'name', + path: [ + 'author', + 'name' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'author', + 'name' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'Peter Sonder' + ], + bsonType: 'String' + } + ] + }, + { + name: 'rating', + path: [ + 'author', + 'rating' + ], + count: 1, + type: 'Double', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'Double', + path: [ + 'author', + 'rating' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 1.3 + ], + bsonType: 'Double' + } + ] + } + ] + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'author' + ], + count: 1, + probability: 0.5 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: ['author'], + properties: { + author: { + bsonType: 'object', + required: ['name', 'rating'], + properties: { + name: { + bsonType: 'string' + }, + rating: { + bsonType: 'double' + } + } + } + } + }); + }); + + it('array - single type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'genres', + path: [ + 'genres' + ], + count: 1, + type: [ + 'array', + 'Undefined' + ], + probability: 0.5, + hasDuplicates: false, + types: [ + { + name: 'array', + path: [ + 'genres' + ], + count: 1, + probability: 0.5, + bsonType: 'Array', + types: [ + { + name: 'String', + path: [ + 'genres' + ], + count: 2, + probability: 1, + unique: 2, + hasDuplicates: false, + values: [ + 'crimi', + 'comedy' + ], + bsonType: 'String' + } + ], + totalCount: 2, + lengths: [ + 2 + ], + averageLength: 2 + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'genres' + ], + count: 1, + probability: 0.5 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + genres: { + bsonType: 'array', + items: { + bsonType: 'string' + } + } + } + }); + }); + + it('array - complex mixed type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'genres', + path: [ + 'genres' + ], + count: 1, + type: [ + 'Array', + 'Undefined' + ], + probability: 0.5, + hasDuplicates: false, + types: [ + { + name: 'Array', + path: [ + 'genres' + ], + count: 1, + probability: 0.5, + bsonType: 'Array', + types: [ + { + name: 'String', + path: [ + 'genres' + ], + count: 2, + probability: 0.6666666666666666, + unique: 2, + hasDuplicates: false, + values: [ + 'crimi', + 'comedy' + ], + bsonType: 'String' + }, + { + name: 'Document', + path: [ + 'genres' + ], + count: 1, + probability: 0.3333333333333333, + bsonType: 'Document', + fields: [ + { + name: 'long', + path: [ + 'genres', + 'long' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'genres', + 'long' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'science fiction' + ], + bsonType: 'String' + } + ] + }, + { + name: 'short', + path: [ + 'genres', + 'short' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'genres', + 'short' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'scifi' + ], + bsonType: 'String' + } + ] + } + ] + } + ], + totalCount: 3, + lengths: [ + 3 + ], + averageLength: 3 + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'genres' + ], + count: 1, + probability: 0.5 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + genres: { + bsonType: 'array', + items: { + anyOf: [ + { + bsonType: 'string' + }, + { + bsonType: 'object', + required: ['long', 'short'], + properties: { + long: { + bsonType: 'string' + }, + short: { + bsonType: 'string' + } + } + } + ] + } + } + } + }); + }); + + // TODO: array - simple mixed type + }); +}); diff --git a/src/schema-convertors/internalToMongodb.ts b/src/schema-convertors/internalToMongodb.ts new file mode 100644 index 0000000..38220e3 --- /dev/null +++ b/src/schema-convertors/internalToMongodb.ts @@ -0,0 +1,68 @@ +import { ArraySchemaType, DocumentSchemaType, Schema as InternalSchema, SchemaType } from '../schema-analyzer'; +import { MongodbJSONSchema } from '../types'; + +const internalTypeToBsonType = (type: string) => type === 'Document' ? 'object' : type.toLowerCase(); + +function parseType(type: SchemaType, signal?: AbortSignal): MongodbJSONSchema { + if (signal?.aborted) throw new Error('Operation aborted'); + const schema: MongodbJSONSchema = { + bsonType: internalTypeToBsonType(type.bsonType) + }; + switch (type.bsonType) { + case 'Array': + schema.items = parseTypes((type as ArraySchemaType).types); + break; + case 'Document': + Object.assign(schema, + parseFields((type as DocumentSchemaType).fields, signal) + ); + break; + } + + return schema; +} + +function parseTypes(types: SchemaType[], signal?: AbortSignal): MongodbJSONSchema { + if (signal?.aborted) throw new Error('Operation aborted'); + const definedTypes = types.filter(type => type.bsonType.toLowerCase() !== 'undefined'); + const isSingleType = definedTypes.length === 1; + if (isSingleType) { + return parseType(definedTypes[0], signal); + } + const parsedTypes = definedTypes.map(type => parseType(type, signal)); + if (definedTypes.some(type => ['Document', 'Array'].includes(type.bsonType))) { + return { + anyOf: parsedTypes + }; + } + return { + bsonType: definedTypes.map((type) => type.bsonType) + }; +} + +function parseFields(fields: DocumentSchemaType['fields'], signal?: AbortSignal): { + required: MongodbJSONSchema['required'], + properties: MongodbJSONSchema['properties'], +} { + const required = []; + const properties: MongodbJSONSchema['properties'] = {}; + for (const field of fields) { + if (signal?.aborted) throw new Error('Operation aborted'); + if (field.probability === 1) required.push(field.name); + properties[field.name] = parseTypes(field.types, signal); + } + + return { required, properties }; +} + +export default function internalSchemaToMongodb( + internalSchema: InternalSchema, + options: { + signal?: AbortSignal +} = {}): MongodbJSONSchema { + const schema: MongodbJSONSchema = { + bsonType: 'object', + ...parseFields(internalSchema.fields, options.signal) + }; + return schema; +} From 51d76444ef68e6d9cf7099eec05049b6deb100f5 Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Mon, 20 Jan 2025 15:14:19 +0100 Subject: [PATCH 02/10] add more tests --- .../internalToMongoDB.test.ts | 652 ++++++++++++++++++ ...ernalToMongodb.ts => internalToMongoDB.ts} | 20 +- .../internalToMongodb.test.ts | 367 ---------- 3 files changed, 662 insertions(+), 377 deletions(-) create mode 100644 src/schema-convertors/internalToMongoDB.test.ts rename src/schema-convertors/{internalToMongodb.ts => internalToMongoDB.ts} (81%) delete mode 100644 src/schema-convertors/internalToMongodb.test.ts diff --git a/src/schema-convertors/internalToMongoDB.test.ts b/src/schema-convertors/internalToMongoDB.test.ts new file mode 100644 index 0000000..ebba086 --- /dev/null +++ b/src/schema-convertors/internalToMongoDB.test.ts @@ -0,0 +1,652 @@ +import assert from 'assert'; +import internalSchemaToStandard from './internalToMongoDB'; + +describe.only('internalSchemaToStandard', function() { + describe('Converts: ', function() { + it('document/object', function() { + const internal = { + count: 2, + fields: [ + { + name: 'author', + path: [ + 'author' + ], + count: 1, + type: [ + 'Document', + 'Undefined' + ], + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'Document', + path: [ + 'author' + ], + count: 1, + probability: 0.5, + bsonType: 'Document', + fields: [ + { + name: 'name', + path: [ + 'author', + 'name' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'author', + 'name' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'Peter Sonder' + ], + bsonType: 'String' + } + ] + }, + { + name: 'rating', + path: [ + 'author', + 'rating' + ], + count: 1, + type: 'Double', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'Double', + path: [ + 'author', + 'rating' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 1.3 + ], + bsonType: 'Double' + } + ] + } + ] + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'author' + ], + count: 1, + probability: 0.5 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: ['author'], + properties: { + author: { + bsonType: 'object', + required: ['name', 'rating'], + properties: { + name: { + bsonType: 'string' + }, + rating: { + bsonType: 'double' + } + } + } + } + }); + }); + + describe('arrays', function() { + it('array - single type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'genres', + path: [ + 'genres' + ], + count: 1, + type: [ + 'array', + 'Undefined' + ], + probability: 0.5, + hasDuplicates: false, + types: [ + { + name: 'array', + path: [ + 'genres' + ], + count: 1, + probability: 0.5, + bsonType: 'Array', + types: [ + { + name: 'String', + path: [ + 'genres' + ], + count: 2, + probability: 1, + unique: 2, + hasDuplicates: false, + values: [ + 'crimi', + 'comedy' + ], + bsonType: 'String' + } + ], + totalCount: 2, + lengths: [ + 2 + ], + averageLength: 2 + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'genres' + ], + count: 1, + probability: 0.5 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + genres: { + bsonType: 'array', + items: { + bsonType: 'string' + } + } + } + }); + }); + + it('array - complex mixed type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'genres', + path: [ + 'genres' + ], + count: 1, + type: [ + 'Array', + 'Undefined' + ], + probability: 0.5, + hasDuplicates: false, + types: [ + { + name: 'Array', + path: [ + 'genres' + ], + count: 1, + probability: 0.5, + bsonType: 'Array', + types: [ + { + name: 'String', + path: [ + 'genres' + ], + count: 2, + probability: 0.6666666666666666, + unique: 2, + hasDuplicates: false, + values: [ + 'crimi', + 'comedy' + ], + bsonType: 'String' + }, + { + name: 'Document', + path: [ + 'genres' + ], + count: 1, + probability: 0.3333333333333333, + bsonType: 'Document', + fields: [ + { + name: 'long', + path: [ + 'genres', + 'long' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'genres', + 'long' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'science fiction' + ], + bsonType: 'String' + } + ] + }, + { + name: 'short', + path: [ + 'genres', + 'short' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'genres', + 'short' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'scifi' + ], + bsonType: 'String' + } + ] + } + ] + } + ], + totalCount: 3, + lengths: [ + 3 + ], + averageLength: 3 + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'genres' + ], + count: 1, + probability: 0.5 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + genres: { + bsonType: 'array', + items: { + anyOf: [ + { + bsonType: 'string' + }, + { + bsonType: 'object', + required: ['long', 'short'], + properties: { + long: { + bsonType: 'string' + }, + short: { + bsonType: 'string' + } + } + } + ] + } + } + } + }); + }); + + it('array - simple mixed type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'arrayMixedType', + path: [ + 'arrayMixedType' + ], + count: 1, + type: 'Array', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'Array', + path: [ + 'arrayMixedType' + ], + count: 1, + probability: 1, + bsonType: 'Array', + types: [ + { + name: 'int32', + path: [ + 'arrayMixedType' + ], + count: 2, + probability: 0.6666666666666666, + unique: 2, + hasDuplicates: false, + values: [ + 1, + 3 + ], + bsonType: 'Int32' + }, + { + name: 'String', + path: [ + 'arrayMixedType' + ], + count: 1, + probability: 0.3333333333333333, + unique: 1, + hasDuplicates: false, + values: [ + '2' + ], + bsonType: 'string' + } + ], + totalCount: 3, + lengths: [ + 3 + ], + averageLength: 3 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: ['arrayMixedType'], + properties: { + arrayMixedType: { + bsonType: 'array', + items: { + bsonType: ['int32', 'string'] + } + } + } + }); + }); + }); + + describe('mixed types', function() { + it('simple mixed type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'mixedType', + path: [ + 'mixedType' + ], + count: 2, + type: [ + 'Int32', + 'String', + 'Undefined' + ], + probability: 0.6666666666666666, + hasDuplicates: false, + types: [ + { + name: 'Int32', + path: [ + 'mixedType' + ], + count: 1, + probability: 0.3333333333333333, + unique: 1, + hasDuplicates: false, + values: [ + 1 + ], + bsonType: 'Int32' + }, + { + name: 'String', + path: [ + 'mixedType' + ], + count: 1, + probability: 0.3333333333333333, + unique: 1, + hasDuplicates: false, + values: [ + 'abc' + ], + bsonType: 'String' + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'mixedType' + ], + count: 1, + probability: 0.3333333333333333 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + mixedType: { + bsonType: ['int32', 'string'] + } + } + }); + }); + + it('complex mixed type', function() { + const internal = { + count: 2, + fields: [ + { + name: 'mixedComplexType', + path: [ + 'mixedComplexType' + ], + count: 2, + type: [ + 'Array', + 'Document', + 'Undefined' + ], + probability: 0.6666666666666666, + hasDuplicates: false, + types: [ + { + name: 'Array', + path: [ + 'mixedComplexType' + ], + count: 1, + probability: 0.3333333333333333, + bsonType: 'Array', + types: [ + { + name: 'Int32', + path: [ + 'mixedComplexType' + ], + count: 3, + probability: 1, + unique: 3, + hasDuplicates: false, + values: [ + 1, + 2, + 3 + ], + bsonType: 'Int32' + } + ], + totalCount: 3, + lengths: [ + 3 + ], + averageLength: 3 + }, + { + name: 'Document', + path: [ + 'mixedComplexType' + ], + count: 1, + probability: 0.3333333333333333, + bsonType: 'Document', + fields: [ + { + name: 'a', + path: [ + 'mixedComplexType', + 'a' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'mixedComplexType', + 'a' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'bc' + ], + bsonType: 'String' + } + ] + } + ] + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'mixedComplexType' + ], + count: 1, + probability: 0.3333333333333333 + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + mixedComplexType: { + anyOf: [ + { + bsonType: 'array', + items: { + bsonType: 'int32' + } + }, + { + bsonType: 'object', + required: ['a'], + properties: { + a: { + bsonType: 'string' + } + } + } + ] + } + } + }); + }); + }); + }); +}); diff --git a/src/schema-convertors/internalToMongodb.ts b/src/schema-convertors/internalToMongoDB.ts similarity index 81% rename from src/schema-convertors/internalToMongodb.ts rename to src/schema-convertors/internalToMongoDB.ts index 38220e3..d120243 100644 --- a/src/schema-convertors/internalToMongodb.ts +++ b/src/schema-convertors/internalToMongoDB.ts @@ -1,11 +1,11 @@ import { ArraySchemaType, DocumentSchemaType, Schema as InternalSchema, SchemaType } from '../schema-analyzer'; -import { MongodbJSONSchema } from '../types'; +import { MongoDBJSONSchema } from '../types'; const internalTypeToBsonType = (type: string) => type === 'Document' ? 'object' : type.toLowerCase(); -function parseType(type: SchemaType, signal?: AbortSignal): MongodbJSONSchema { +function parseType(type: SchemaType, signal?: AbortSignal): MongoDBJSONSchema { if (signal?.aborted) throw new Error('Operation aborted'); - const schema: MongodbJSONSchema = { + const schema: MongoDBJSONSchema = { bsonType: internalTypeToBsonType(type.bsonType) }; switch (type.bsonType) { @@ -22,7 +22,7 @@ function parseType(type: SchemaType, signal?: AbortSignal): MongodbJSONSchema { return schema; } -function parseTypes(types: SchemaType[], signal?: AbortSignal): MongodbJSONSchema { +function parseTypes(types: SchemaType[], signal?: AbortSignal): MongoDBJSONSchema { if (signal?.aborted) throw new Error('Operation aborted'); const definedTypes = types.filter(type => type.bsonType.toLowerCase() !== 'undefined'); const isSingleType = definedTypes.length === 1; @@ -36,16 +36,16 @@ function parseTypes(types: SchemaType[], signal?: AbortSignal): MongodbJSONSchem }; } return { - bsonType: definedTypes.map((type) => type.bsonType) + bsonType: definedTypes.map((type) => internalTypeToBsonType(type.bsonType)) }; } function parseFields(fields: DocumentSchemaType['fields'], signal?: AbortSignal): { - required: MongodbJSONSchema['required'], - properties: MongodbJSONSchema['properties'], + required: MongoDBJSONSchema['required'], + properties: MongoDBJSONSchema['properties'], } { const required = []; - const properties: MongodbJSONSchema['properties'] = {}; + const properties: MongoDBJSONSchema['properties'] = {}; for (const field of fields) { if (signal?.aborted) throw new Error('Operation aborted'); if (field.probability === 1) required.push(field.name); @@ -59,8 +59,8 @@ export default function internalSchemaToMongodb( internalSchema: InternalSchema, options: { signal?: AbortSignal -} = {}): MongodbJSONSchema { - const schema: MongodbJSONSchema = { +} = {}): MongoDBJSONSchema { + const schema: MongoDBJSONSchema = { bsonType: 'object', ...parseFields(internalSchema.fields, options.signal) }; diff --git a/src/schema-convertors/internalToMongodb.test.ts b/src/schema-convertors/internalToMongodb.test.ts deleted file mode 100644 index be07930..0000000 --- a/src/schema-convertors/internalToMongodb.test.ts +++ /dev/null @@ -1,367 +0,0 @@ -import assert from 'assert'; -import internalSchemaToStandard from './internalToMongodb'; - -describe.only('internalSchemaToStandard', function() { - describe('Converts: ', function() { - it('document/object', function() { - const internal = { - count: 2, - fields: [ - { - name: 'author', - path: [ - 'author' - ], - count: 1, - type: [ - 'Document', - 'Undefined' - ], - probability: 1, - hasDuplicates: false, - types: [ - { - name: 'Document', - path: [ - 'author' - ], - count: 1, - probability: 0.5, - bsonType: 'Document', - fields: [ - { - name: 'name', - path: [ - 'author', - 'name' - ], - count: 1, - type: 'String', - probability: 1, - hasDuplicates: false, - types: [ - { - name: 'String', - path: [ - 'author', - 'name' - ], - count: 1, - probability: 1, - unique: 1, - hasDuplicates: false, - values: [ - 'Peter Sonder' - ], - bsonType: 'String' - } - ] - }, - { - name: 'rating', - path: [ - 'author', - 'rating' - ], - count: 1, - type: 'Double', - probability: 1, - hasDuplicates: false, - types: [ - { - name: 'Double', - path: [ - 'author', - 'rating' - ], - count: 1, - probability: 1, - unique: 1, - hasDuplicates: false, - values: [ - 1.3 - ], - bsonType: 'Double' - } - ] - } - ] - }, - { - name: 'Undefined', - bsonType: 'Undefined', - unique: 1, - hasDuplicates: false, - path: [ - 'author' - ], - count: 1, - probability: 0.5 - } - ] - } - ] - }; - const standard = internalSchemaToStandard(internal); - assert.deepStrictEqual(standard, { - bsonType: 'object', - required: ['author'], - properties: { - author: { - bsonType: 'object', - required: ['name', 'rating'], - properties: { - name: { - bsonType: 'string' - }, - rating: { - bsonType: 'double' - } - } - } - } - }); - }); - - it('array - single type', function() { - const internal = { - count: 2, - fields: [ - { - name: 'genres', - path: [ - 'genres' - ], - count: 1, - type: [ - 'array', - 'Undefined' - ], - probability: 0.5, - hasDuplicates: false, - types: [ - { - name: 'array', - path: [ - 'genres' - ], - count: 1, - probability: 0.5, - bsonType: 'Array', - types: [ - { - name: 'String', - path: [ - 'genres' - ], - count: 2, - probability: 1, - unique: 2, - hasDuplicates: false, - values: [ - 'crimi', - 'comedy' - ], - bsonType: 'String' - } - ], - totalCount: 2, - lengths: [ - 2 - ], - averageLength: 2 - }, - { - name: 'Undefined', - bsonType: 'Undefined', - unique: 1, - hasDuplicates: false, - path: [ - 'genres' - ], - count: 1, - probability: 0.5 - } - ] - } - ] - }; - const standard = internalSchemaToStandard(internal); - assert.deepStrictEqual(standard, { - bsonType: 'object', - required: [], - properties: { - genres: { - bsonType: 'array', - items: { - bsonType: 'string' - } - } - } - }); - }); - - it('array - complex mixed type', function() { - const internal = { - count: 2, - fields: [ - { - name: 'genres', - path: [ - 'genres' - ], - count: 1, - type: [ - 'Array', - 'Undefined' - ], - probability: 0.5, - hasDuplicates: false, - types: [ - { - name: 'Array', - path: [ - 'genres' - ], - count: 1, - probability: 0.5, - bsonType: 'Array', - types: [ - { - name: 'String', - path: [ - 'genres' - ], - count: 2, - probability: 0.6666666666666666, - unique: 2, - hasDuplicates: false, - values: [ - 'crimi', - 'comedy' - ], - bsonType: 'String' - }, - { - name: 'Document', - path: [ - 'genres' - ], - count: 1, - probability: 0.3333333333333333, - bsonType: 'Document', - fields: [ - { - name: 'long', - path: [ - 'genres', - 'long' - ], - count: 1, - type: 'String', - probability: 1, - hasDuplicates: false, - types: [ - { - name: 'String', - path: [ - 'genres', - 'long' - ], - count: 1, - probability: 1, - unique: 1, - hasDuplicates: false, - values: [ - 'science fiction' - ], - bsonType: 'String' - } - ] - }, - { - name: 'short', - path: [ - 'genres', - 'short' - ], - count: 1, - type: 'String', - probability: 1, - hasDuplicates: false, - types: [ - { - name: 'String', - path: [ - 'genres', - 'short' - ], - count: 1, - probability: 1, - unique: 1, - hasDuplicates: false, - values: [ - 'scifi' - ], - bsonType: 'String' - } - ] - } - ] - } - ], - totalCount: 3, - lengths: [ - 3 - ], - averageLength: 3 - }, - { - name: 'Undefined', - bsonType: 'Undefined', - unique: 1, - hasDuplicates: false, - path: [ - 'genres' - ], - count: 1, - probability: 0.5 - } - ] - } - ] - }; - const standard = internalSchemaToStandard(internal); - assert.deepStrictEqual(standard, { - bsonType: 'object', - required: [], - properties: { - genres: { - bsonType: 'array', - items: { - anyOf: [ - { - bsonType: 'string' - }, - { - bsonType: 'object', - required: ['long', 'short'], - properties: { - long: { - bsonType: 'string' - }, - short: { - bsonType: 'string' - } - } - } - ] - } - } - } - }); - }); - - // TODO: array - simple mixed type - }); -}); From fb81f4398872248307fea56ec40ee9e73502c88c Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Mon, 20 Jan 2025 17:02:07 +0100 Subject: [PATCH 03/10] add test --- .../internalToMongoDB.test.ts | 1005 ++++++++++++++++- 1 file changed, 1004 insertions(+), 1 deletion(-) diff --git a/src/schema-convertors/internalToMongoDB.test.ts b/src/schema-convertors/internalToMongoDB.test.ts index ebba086..07f9652 100644 --- a/src/schema-convertors/internalToMongoDB.test.ts +++ b/src/schema-convertors/internalToMongoDB.test.ts @@ -3,7 +3,1010 @@ import internalSchemaToStandard from './internalToMongoDB'; describe.only('internalSchemaToStandard', function() { describe('Converts: ', function() { - it('document/object', function() { + it('get me analyzed thing', async function() { + const internal = { + count: 1, + fields: [ + { + name: '_id', + path: [ + '_id' + ], + count: 1, + type: 'ObjectId', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'ObjectId', + path: [ + '_id' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + '642d766b7300158b1f22e972' + ], + bsonType: 'ObjectId' + } + ] + }, + { + name: 'array', + path: [ + 'array' + ], + count: 1, + type: 'Array', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Array', + path: [ + 'array' + ], + count: 1, + probability: 0.8, + bsonType: 'Array', + types: [ + { + name: 'Number', + path: [ + 'array' + ], + count: 3, + probability: 0.8, + unique: 3, + hasDuplicates: false, + values: [ + 1, + 2, + 3 + ], + bsonType: 'Number' + } + ], + totalCount: 3, + lengths: [ + 3 + ], + averageLength: 3 + } + ] + }, + { + name: 'binaries', + path: [ + 'binaries' + ], + count: 1, + type: 'Document', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Document', + path: [ + 'binaries' + ], + count: 1, + probability: 0.8, + bsonType: 'Document', + fields: [ + { + name: 'binaryOld', + path: [ + 'binaries', + 'binaryOld' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'binaryOld' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + '//8=' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'compressedTimeSeries', + path: [ + 'binaries', + 'compressedTimeSeries' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'compressedTimeSeries' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'c//SZESzTGmQ6OfR38A11A==' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'custom', + path: [ + 'binaries', + 'custom' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'custom' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + '//8=' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'encrypted', + path: [ + 'binaries', + 'encrypted' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'encrypted' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'c//SZESzTGmQ6OfR38A11A==' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'functionData', + path: [ + 'binaries', + 'functionData' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'functionData' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + '//8=' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'generic', + path: [ + 'binaries', + 'generic' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'generic' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'AQID' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'md5', + path: [ + 'binaries', + 'md5' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'md5' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'c//SZESzTGmQ6OfR38A11A==' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'uuid', + path: [ + 'binaries', + 'uuid' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'uuid' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'uuidOld', + path: [ + 'binaries', + 'uuidOld' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binaries', + 'uuidOld' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'c//SZESzTGmQ6OfR38A11A==' + ], + bsonType: 'Binary' + } + ] + } + ] + } + ] + }, + { + name: 'binData', + path: [ + 'binData' + ], + count: 1, + type: 'Binary', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Binary', + path: [ + 'binData' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'AQID' + ], + bsonType: 'Binary' + } + ] + }, + { + name: 'boolean', + path: [ + 'boolean' + ], + count: 1, + type: 'Boolean', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Boolean', + path: [ + 'boolean' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + true + ], + bsonType: 'Boolean' + } + ] + }, + { + name: 'date', + path: [ + 'date' + ], + count: 1, + type: 'Date', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Date', + path: [ + 'date' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + '2023-04-05T13:25:08.445Z' + ], + bsonType: 'Date' + } + ] + }, + { + name: 'dbRef', + path: [ + 'dbRef' + ], + count: 1, + type: 'DBRef', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'DBRef', + path: [ + 'dbRef' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + $ref: 'namespace', + $id: '642d76b4b7ebfab15d3c4a78' + } + ], + bsonType: 'DBRef' + } + ] + }, + { + name: 'decimal', + path: [ + 'decimal' + ], + count: 1, + type: 'Decimal128', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Decimal128', + path: [ + 'decimal' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + $numberDecimal: '5.477284286264328586719275128128001E-4088' + } + ], + bsonType: 'Decimal128' + } + ] + }, + { + name: 'double', + path: [ + 'double' + ], + count: 1, + type: 'Double', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Double', + path: [ + 'double' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 1.2 + ], + bsonType: 'Double' + } + ] + }, + { + name: 'int', + path: [ + 'int' + ], + count: 1, + type: 'Int32', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Int32', + path: [ + 'int' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 12345 + ], + bsonType: 'Int32' + } + ] + }, + { + name: 'javascript', + path: [ + 'javascript' + ], + count: 1, + type: 'Code', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Code', + path: [ + 'javascript' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + code: 'function() {}' + } + ], + bsonType: 'Code' + } + ] + }, + { + name: 'javascriptWithScope', + path: [ + 'javascriptWithScope' + ], + count: 1, + type: 'Code', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Code', + path: [ + 'javascriptWithScope' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + code: 'function() {}', + scope: { + foo: 1, + bar: 'a' + } + } + ], + bsonType: 'Code' + } + ] + }, + { + name: 'long', + path: [ + 'long' + ], + count: 1, + type: 'Long', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Long', + path: [ + 'long' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + low: -1395630315, + high: 28744523, + unsigned: false + } + ], + bsonType: 'Long' + } + ] + }, + { + name: 'maxKey', + path: [ + 'maxKey' + ], + count: 1, + type: 'MaxKey', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'MaxKey', + path: [ + 'maxKey' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + {} + ], + bsonType: 'MaxKey' + } + ] + }, + { + name: 'minKey', + path: [ + 'minKey' + ], + count: 1, + type: 'MinKey', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'MinKey', + path: [ + 'minKey' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + {} + ], + bsonType: 'MinKey' + } + ] + }, + { + name: 'null', + path: [ + 'null' + ], + count: 1, + type: 'Null', + probability: 0.8, + hasDuplicates: true, + types: [ + { + name: 'Null', + path: [ + 'null' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: true, + bsonType: 'Null' + } + ] + }, + { + name: 'object', + path: [ + 'object' + ], + count: 1, + type: 'Document', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Document', + path: [ + 'object' + ], + count: 1, + probability: 0.8, + bsonType: 'Document', + fields: [ + { + name: 'key', + path: [ + 'object', + 'key' + ], + count: 1, + type: 'String', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'object', + 'key' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'value' + ], + bsonType: 'String' + } + ] + } + ] + } + ] + }, + { + name: 'objectId', + path: [ + 'objectId' + ], + count: 1, + type: 'ObjectId', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'ObjectId', + path: [ + 'objectId' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + '642d766c7300158b1f22e975' + ], + bsonType: 'ObjectId' + } + ] + }, + { + name: 'regex', + path: [ + 'regex' + ], + count: 1, + type: 'BSONRegExp', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'BSONRegExp', + path: [ + 'regex' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + pattern: 'pattern', + options: 'i' + } + ], + bsonType: 'BSONRegExp' + } + ] + }, + { + name: 'string', + path: [ + 'string' + ], + count: 1, + type: 'String', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'string' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'Hello, world!' + ], + bsonType: 'String' + } + ] + }, + { + name: 'symbol', + path: [ + 'symbol' + ], + count: 1, + type: 'BSONSymbol', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'BSONSymbol', + path: [ + 'symbol' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + 'symbol' + ], + bsonType: 'BSONSymbol' + } + ] + }, + { + name: 'timestamp', + path: [ + 'timestamp' + ], + count: 1, + type: 'Timestamp', + probability: 0.8, + hasDuplicates: false, + types: [ + { + name: 'Timestamp', + path: [ + 'timestamp' + ], + count: 1, + probability: 0.8, + unique: 1, + hasDuplicates: false, + values: [ + { + $timestamp: '7218556297505931265' + } + ], + bsonType: 'Timestamp' + } + ] + } + ] + }; + const standard = internalSchemaToStandard(internal); + assert.deepStrictEqual(standard, { + bsonType: 'object', + required: [], + properties: { + _id: { + bsonType: 'objectid' + }, + array: { + bsonType: 'array', + items: { + bsonType: 'number' + } + }, + binData: { + bsonType: 'binary' + }, + binaries: { + bsonType: 'object', + properties: { + binaryOld: { + bsonType: 'binary' + }, + compressedTimeSeries: { + bsonType: 'binary' + }, + custom: { + bsonType: 'binary' + }, + encrypted: { + bsonType: 'binary' + }, + functionData: { + bsonType: 'binary' + }, + generic: { + bsonType: 'binary' + }, + md5: { + bsonType: 'binary' + }, + uuid: { + bsonType: 'binary' + }, + uuidOld: { + bsonType: 'binary' + } + }, + required: [] + }, + boolean: { + bsonType: 'boolean' + }, + date: { + bsonType: 'date' + }, + dbRef: { + bsonType: 'dbref' + }, + decimal: { + bsonType: 'decimal128' + }, + double: { + bsonType: 'double' + }, + int: { + bsonType: 'int32' + }, + javascript: { + bsonType: 'code' + }, + javascriptWithScope: { + bsonType: 'code' + }, + long: { + bsonType: 'long' + }, + maxKey: { + bsonType: 'maxkey' + }, + minKey: { + bsonType: 'minkey' + }, + null: { + bsonType: 'null' + }, + object: { + bsonType: 'object', + properties: { + key: { + bsonType: 'string' + } + }, + required: [] + }, + objectId: { + bsonType: 'objectid' + }, + regex: { + bsonType: 'bsonregexp' + }, + string: { + bsonType: 'string' + }, + symbol: { + bsonType: 'bsonsymbol' + }, + timestamp: { + bsonType: 'timestamp' + } + } + }); + }); + + it('nested document/object', function() { const internal = { count: 2, fields: [ From 5151b113e8f4e4837a0a24acfd3a5a02f807d036 Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Wed, 22 Jan 2025 11:36:53 +0100 Subject: [PATCH 04/10] cleanup --- package.json | 2 +- src/index.ts | 4 +-- src/schema-accessor.ts | 10 +++---- src/schema-convertors.ts | 27 ------------------- src/schema-convertors/index.ts | 9 +++++++ src/schema-convertors/internalToExpanded.ts | 11 ++++++++ .../internalToMongoDB.test.ts | 2 +- src/schema-convertors/internalToStandard.ts | 11 ++++++++ src/types.ts | 2 +- test/analyze-documents.test.ts | 8 +++--- tsconfig.json | 3 ++- 11 files changed, 47 insertions(+), 42 deletions(-) delete mode 100644 src/schema-convertors.ts create mode 100644 src/schema-convertors/index.ts create mode 100644 src/schema-convertors/internalToExpanded.ts create mode 100644 src/schema-convertors/internalToStandard.ts diff --git a/package.json b/package.json index aa169a0..5bfc874 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ ".esm-wrapper.mjs" ], "scripts": { - "test": "nyc mocha --timeout 5000 --colors -r ts-node/register test/*.ts", + "test": "nyc mocha --timeout 5000 --colors -r ts-node/register test/*.ts src/**/*.test.ts", "test-example-parse-from-file": "ts-node examples/parse-from-file.ts", "test-example-parse-schema": "ts-node examples/parse-schema.ts", "test-time": "ts-node ./test/time-testing.ts", diff --git a/src/index.ts b/src/index.ts index 3dfc6ed..f4c6e44 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ import type { SimplifiedSchema } from './schema-analyzer'; import * as schemaStats from './stats'; -import { AnyIterable, StandardJSONSchema, MongoDBJSONSchema, ExtendedJSONSchema } from './types'; +import { AnyIterable, StandardJSONSchema, MongoDBJSONSchema, ExpandedJSONSchema } from './types'; /** * Analyze documents - schema can be retrieved in different formats. @@ -77,7 +77,7 @@ export type { SimplifiedSchema, StandardJSONSchema, MongoDBJSONSchema, - ExtendedJSONSchema + ExpandedJSONSchema }; export { diff --git a/src/schema-accessor.ts b/src/schema-accessor.ts index cd70681..f833705 100644 --- a/src/schema-accessor.ts +++ b/src/schema-accessor.ts @@ -1,11 +1,11 @@ import { Schema as InternalSchema } from './schema-analyzer'; import convertors from './schema-convertors'; -import { ExtendedJSONSchema, MongoDBJSONSchema, StandardJSONSchema } from './types'; +import { ExpandedJSONSchema, MongoDBJSONSchema, StandardJSONSchema } from './types'; export interface SchemaAccessor { getStandardJsonSchema: () => Promise; getMongoDBJsonSchema: () => Promise; - getExtendedJsonSchema: () => Promise; + getExpandedJSONSchema: () => Promise; getInternalSchema: () => Promise; } @@ -23,7 +23,7 @@ export class InternalSchemaBasedAccessor implements SchemaAccessor { private internalSchema: InternalSchema; private standardJSONSchema?: StandardJSONSchema; private mongodbJSONSchema?: MongoDBJSONSchema; - private extendedJSONSchema?: ExtendedJSONSchema; + private ExpandedJSONSchema?: ExpandedJSONSchema; constructor(internalSchema: InternalSchema) { this.internalSchema = internalSchema; @@ -41,7 +41,7 @@ export class InternalSchemaBasedAccessor implements SchemaAccessor { return this.mongodbJSONSchema ??= await convertors.internalSchemaToMongoDB(this.internalSchema, options); } - async getExtendedJsonSchema(options: Options = {}): Promise { - return this.extendedJSONSchema ??= await convertors.internalSchemaToExtended(this.internalSchema, options); + async getExpandedJSONSchema(options: Options = {}): Promise { + return this.ExpandedJSONSchema ??= await convertors.internalSchemaToExpanded(this.internalSchema, options); } } diff --git a/src/schema-convertors.ts b/src/schema-convertors.ts deleted file mode 100644 index fd26a93..0000000 --- a/src/schema-convertors.ts +++ /dev/null @@ -1,27 +0,0 @@ -import internalSchemaToMongoDB from './schema-convertors/internalToMongoDB'; -import { Schema as InternalSchema } from './schema-analyzer'; -import { ExtendedJSONSchema, StandardJSONSchema } from './types'; - -function internalSchemaToStandard( - internalSchema: InternalSchema, - options: { - signal?: AbortSignal -}): StandardJSONSchema { - // TODO: COMPASS-8700 - return {} as StandardJSONSchema; -} - -function internalSchemaToExtended( - internalSchema: InternalSchema, - options: { - signal?: AbortSignal -}): ExtendedJSONSchema { - // TODO: COMPASS-8702 - return {} as ExtendedJSONSchema; -} - -export default { - internalSchemaToStandard, - internalSchemaToMongoDB, - internalSchemaToExtended -}; diff --git a/src/schema-convertors/index.ts b/src/schema-convertors/index.ts new file mode 100644 index 0000000..153c19f --- /dev/null +++ b/src/schema-convertors/index.ts @@ -0,0 +1,9 @@ +import internalSchemaToExpanded from './internalToExpanded'; +import internalSchemaToMongoDB from './internalToMongoDB'; +import internalSchemaToStandard from './internalToStandard'; + +export default { + internalSchemaToStandard, + internalSchemaToMongoDB, + internalSchemaToExpanded +}; diff --git a/src/schema-convertors/internalToExpanded.ts b/src/schema-convertors/internalToExpanded.ts new file mode 100644 index 0000000..3bb3d82 --- /dev/null +++ b/src/schema-convertors/internalToExpanded.ts @@ -0,0 +1,11 @@ +import { InternalSchema } from '..'; +import { ExpandedJSONSchema } from '../types'; + +export default function internalSchemaToExpanded( + internalSchema: InternalSchema, + options: { + signal?: AbortSignal +}): ExpandedJSONSchema { + // TODO: COMPASS-8702 + return {} as ExpandedJSONSchema; +} diff --git a/src/schema-convertors/internalToMongoDB.test.ts b/src/schema-convertors/internalToMongoDB.test.ts index 07f9652..f263a75 100644 --- a/src/schema-convertors/internalToMongoDB.test.ts +++ b/src/schema-convertors/internalToMongoDB.test.ts @@ -1,7 +1,7 @@ import assert from 'assert'; import internalSchemaToStandard from './internalToMongoDB'; -describe.only('internalSchemaToStandard', function() { +describe('internalSchemaToStandard', function() { describe('Converts: ', function() { it('get me analyzed thing', async function() { const internal = { diff --git a/src/schema-convertors/internalToStandard.ts b/src/schema-convertors/internalToStandard.ts new file mode 100644 index 0000000..2f69275 --- /dev/null +++ b/src/schema-convertors/internalToStandard.ts @@ -0,0 +1,11 @@ +import { InternalSchema } from '..'; +import { StandardJSONSchema } from '../types'; + +export default function internalSchemaToStandard( + internalSchema: InternalSchema, + options: { + signal?: AbortSignal +}): StandardJSONSchema { + // TODO: COMPASS-8700 + return {} as StandardJSONSchema; +} diff --git a/src/types.ts b/src/types.ts index 2b6c0c3..5cd51e2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,7 +9,7 @@ export type MongoDBJSONSchema = Pick Date: Wed, 22 Jan 2025 13:08:04 +0100 Subject: [PATCH 05/10] eslint --- src/schema-accessor.ts | 2 +- src/schema-convertors/internalToExpanded.ts | 1 + src/schema-convertors/internalToStandard.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/schema-accessor.ts b/src/schema-accessor.ts index f833705..7dd3e39 100644 --- a/src/schema-accessor.ts +++ b/src/schema-accessor.ts @@ -29,7 +29,7 @@ export class InternalSchemaBasedAccessor implements SchemaAccessor { this.internalSchema = internalSchema; } - async getInternalSchema(options?: Options): Promise { + async getInternalSchema(): Promise { return this.internalSchema; } diff --git a/src/schema-convertors/internalToExpanded.ts b/src/schema-convertors/internalToExpanded.ts index 3bb3d82..a2fbdab 100644 --- a/src/schema-convertors/internalToExpanded.ts +++ b/src/schema-convertors/internalToExpanded.ts @@ -2,6 +2,7 @@ import { InternalSchema } from '..'; import { ExpandedJSONSchema } from '../types'; export default function internalSchemaToExpanded( + /* eslint @typescript-eslint/no-unused-vars: 0 */ internalSchema: InternalSchema, options: { signal?: AbortSignal diff --git a/src/schema-convertors/internalToStandard.ts b/src/schema-convertors/internalToStandard.ts index 2f69275..d50aa5b 100644 --- a/src/schema-convertors/internalToStandard.ts +++ b/src/schema-convertors/internalToStandard.ts @@ -2,6 +2,7 @@ import { InternalSchema } from '..'; import { StandardJSONSchema } from '../types'; export default function internalSchemaToStandard( + /* eslint @typescript-eslint/no-unused-vars: 0 */ internalSchema: InternalSchema, options: { signal?: AbortSignal From 2d53b85aaf27b67a6361c3b6e67326c256ca75aa Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Wed, 22 Jan 2025 13:41:51 +0100 Subject: [PATCH 06/10] type conversion --- .../internalToMongoDB.test.ts | 54 +++++++++---------- src/schema-convertors/internalToMongoDB.ts | 40 ++++++++++++-- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/schema-convertors/internalToMongoDB.test.ts b/src/schema-convertors/internalToMongoDB.test.ts index f263a75..276c14c 100644 --- a/src/schema-convertors/internalToMongoDB.test.ts +++ b/src/schema-convertors/internalToMongoDB.test.ts @@ -898,82 +898,82 @@ describe('internalSchemaToStandard', function() { required: [], properties: { _id: { - bsonType: 'objectid' + bsonType: 'objectId' }, array: { bsonType: 'array', items: { - bsonType: 'number' + bsonType: 'double' } }, binData: { - bsonType: 'binary' + bsonType: 'binData' }, binaries: { bsonType: 'object', properties: { binaryOld: { - bsonType: 'binary' + bsonType: 'binData' }, compressedTimeSeries: { - bsonType: 'binary' + bsonType: 'binData' }, custom: { - bsonType: 'binary' + bsonType: 'binData' }, encrypted: { - bsonType: 'binary' + bsonType: 'binData' }, functionData: { - bsonType: 'binary' + bsonType: 'binData' }, generic: { - bsonType: 'binary' + bsonType: 'binData' }, md5: { - bsonType: 'binary' + bsonType: 'binData' }, uuid: { - bsonType: 'binary' + bsonType: 'binData' }, uuidOld: { - bsonType: 'binary' + bsonType: 'binData' } }, required: [] }, boolean: { - bsonType: 'boolean' + bsonType: 'bool' }, date: { bsonType: 'date' }, dbRef: { - bsonType: 'dbref' + bsonType: 'dbPointer' }, decimal: { - bsonType: 'decimal128' + bsonType: 'decimal' }, double: { bsonType: 'double' }, int: { - bsonType: 'int32' + bsonType: 'int' }, javascript: { - bsonType: 'code' + bsonType: 'javascript' }, javascriptWithScope: { - bsonType: 'code' + bsonType: 'javascript' }, long: { bsonType: 'long' }, maxKey: { - bsonType: 'maxkey' + bsonType: 'maxKey' }, minKey: { - bsonType: 'minkey' + bsonType: 'minKey' }, null: { bsonType: 'null' @@ -988,16 +988,16 @@ describe('internalSchemaToStandard', function() { required: [] }, objectId: { - bsonType: 'objectid' + bsonType: 'objectId' }, regex: { - bsonType: 'bsonregexp' + bsonType: 'regex' }, string: { bsonType: 'string' }, symbol: { - bsonType: 'bsonsymbol' + bsonType: 'symbol' }, timestamp: { bsonType: 'timestamp' @@ -1416,7 +1416,7 @@ describe('internalSchemaToStandard', function() { values: [ '2' ], - bsonType: 'string' + bsonType: 'String' } ], totalCount: 3, @@ -1437,7 +1437,7 @@ describe('internalSchemaToStandard', function() { arrayMixedType: { bsonType: 'array', items: { - bsonType: ['int32', 'string'] + bsonType: ['int', 'string'] } } } @@ -1513,7 +1513,7 @@ describe('internalSchemaToStandard', function() { required: [], properties: { mixedType: { - bsonType: ['int32', 'string'] + bsonType: ['int', 'string'] } } }); @@ -1633,7 +1633,7 @@ describe('internalSchemaToStandard', function() { { bsonType: 'array', items: { - bsonType: 'int32' + bsonType: 'int' } }, { diff --git a/src/schema-convertors/internalToMongoDB.ts b/src/schema-convertors/internalToMongoDB.ts index d120243..89be183 100644 --- a/src/schema-convertors/internalToMongoDB.ts +++ b/src/schema-convertors/internalToMongoDB.ts @@ -1,12 +1,46 @@ +import { BSONRegExp } from 'bson'; import { ArraySchemaType, DocumentSchemaType, Schema as InternalSchema, SchemaType } from '../schema-analyzer'; import { MongoDBJSONSchema } from '../types'; -const internalTypeToBsonType = (type: string) => type === 'Document' ? 'object' : type.toLowerCase(); +const InternalTypeToBsonTypeMap: Record< + SchemaType['name'] | 'Double' | 'BSONSymbol', + string +> = { + Double: 'double', + Number: 'double', + String: 'string', + Document: 'object', + Array: 'array', + Binary: 'binData', + Undefined: 'undefined', + ObjectId: 'objectId', + Boolean: 'bool', + Date: 'date', + Null: 'null', + RegExp: 'regex', + BSONRegExp: 'regex', + DBRef: 'dbPointer', + BSONSymbol: 'symbol', + Symbol: 'symbol', + Code: 'javascript', + Int32: 'int', + Timestamp: 'timestamp', + Long: 'long', + Decimal128: 'decimal', + MinKey: 'minKey', + MaxKey: 'maxKey' +}; + +const convertInternalType = (type: string) => { + const bsonType = InternalTypeToBsonTypeMap[type]; + if (!bsonType) throw new Error(`Encountered unknown type: ${type}`); + return bsonType; +}; function parseType(type: SchemaType, signal?: AbortSignal): MongoDBJSONSchema { if (signal?.aborted) throw new Error('Operation aborted'); const schema: MongoDBJSONSchema = { - bsonType: internalTypeToBsonType(type.bsonType) + bsonType: convertInternalType(type.bsonType) }; switch (type.bsonType) { case 'Array': @@ -36,7 +70,7 @@ function parseTypes(types: SchemaType[], signal?: AbortSignal): MongoDBJSONSchem }; } return { - bsonType: definedTypes.map((type) => internalTypeToBsonType(type.bsonType)) + bsonType: definedTypes.map((type) => convertInternalType(type.bsonType)) }; } From 6d4879b5fcb7d615be2ec0eed028d78b84ef47f1 Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Wed, 22 Jan 2025 13:47:56 +0100 Subject: [PATCH 07/10] cleanup --- src/schema-convertors/internalToMongoDB.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/schema-convertors/internalToMongoDB.ts b/src/schema-convertors/internalToMongoDB.ts index 89be183..85b2b5e 100644 --- a/src/schema-convertors/internalToMongoDB.ts +++ b/src/schema-convertors/internalToMongoDB.ts @@ -1,4 +1,3 @@ -import { BSONRegExp } from 'bson'; import { ArraySchemaType, DocumentSchemaType, Schema as InternalSchema, SchemaType } from '../schema-analyzer'; import { MongoDBJSONSchema } from '../types'; From 01e65bd9cfeaf8779fa65476c232cff1c4812832 Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Thu, 23 Jan 2025 22:22:31 +0100 Subject: [PATCH 08/10] Update src/schema-convertors/internalToMongoDB.ts Co-authored-by: Anna Henningsen --- src/schema-convertors/internalToMongoDB.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema-convertors/internalToMongoDB.ts b/src/schema-convertors/internalToMongoDB.ts index 85b2b5e..56958c7 100644 --- a/src/schema-convertors/internalToMongoDB.ts +++ b/src/schema-convertors/internalToMongoDB.ts @@ -56,7 +56,7 @@ function parseType(type: SchemaType, signal?: AbortSignal): MongoDBJSONSchema { } function parseTypes(types: SchemaType[], signal?: AbortSignal): MongoDBJSONSchema { - if (signal?.aborted) throw new Error('Operation aborted'); + if (signal?.aborted) throw signal.reason ?? new Error('Operation aborted'); const definedTypes = types.filter(type => type.bsonType.toLowerCase() !== 'undefined'); const isSingleType = definedTypes.length === 1; if (isSingleType) { From 2050d5a37e6fe622bd4df2bb76df938b86809770 Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Tue, 28 Jan 2025 14:44:46 +0100 Subject: [PATCH 09/10] abort with timeout --- src/schema-accessor.ts | 2 +- src/schema-convertors/index.ts | 2 +- .../internalToMongoDB.test.ts | 151 +++++++++++++++--- src/schema-convertors/internalToMongoDB.ts | 38 +++-- test/analyze-documents.test.ts | 2 +- 5 files changed, 159 insertions(+), 36 deletions(-) diff --git a/src/schema-accessor.ts b/src/schema-accessor.ts index 7dd3e39..88f79e6 100644 --- a/src/schema-accessor.ts +++ b/src/schema-accessor.ts @@ -1,5 +1,5 @@ import { Schema as InternalSchema } from './schema-analyzer'; -import convertors from './schema-convertors'; +import { convertors } from './schema-convertors'; import { ExpandedJSONSchema, MongoDBJSONSchema, StandardJSONSchema } from './types'; export interface SchemaAccessor { diff --git a/src/schema-convertors/index.ts b/src/schema-convertors/index.ts index 153c19f..273310d 100644 --- a/src/schema-convertors/index.ts +++ b/src/schema-convertors/index.ts @@ -2,7 +2,7 @@ import internalSchemaToExpanded from './internalToExpanded'; import internalSchemaToMongoDB from './internalToMongoDB'; import internalSchemaToStandard from './internalToStandard'; -export default { +export const convertors = { internalSchemaToStandard, internalSchemaToMongoDB, internalSchemaToExpanded diff --git a/src/schema-convertors/internalToMongoDB.test.ts b/src/schema-convertors/internalToMongoDB.test.ts index 276c14c..42813bc 100644 --- a/src/schema-convertors/internalToMongoDB.test.ts +++ b/src/schema-convertors/internalToMongoDB.test.ts @@ -1,9 +1,9 @@ import assert from 'assert'; -import internalSchemaToStandard from './internalToMongoDB'; +import internalSchemaToMongoDB from './internalToMongoDB'; -describe('internalSchemaToStandard', function() { - describe('Converts: ', function() { - it('get me analyzed thing', async function() { +describe('internalSchemaToMongoDB', async function() { + describe('Converts: ', async function() { + it('all the types', async function() { const internal = { count: 1, fields: [ @@ -892,7 +892,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: [], @@ -1006,7 +1006,7 @@ describe('internalSchemaToStandard', function() { }); }); - it('nested document/object', function() { + it('nested document/object', async function() { const internal = { count: 2, fields: [ @@ -1105,7 +1105,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: ['author'], @@ -1126,8 +1126,8 @@ describe('internalSchemaToStandard', function() { }); }); - describe('arrays', function() { - it('array - single type', function() { + describe('arrays', async function() { + it('array - single type', async function() { const internal = { count: 2, fields: [ @@ -1190,7 +1190,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: [], @@ -1205,7 +1205,7 @@ describe('internalSchemaToStandard', function() { }); }); - it('array - complex mixed type', function() { + it('array - complex mixed type', async function() { const internal = { count: 2, fields: [ @@ -1335,7 +1335,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: [], @@ -1366,7 +1366,7 @@ describe('internalSchemaToStandard', function() { }); }); - it('array - simple mixed type', function() { + it('array - simple mixed type', async function() { const internal = { count: 2, fields: [ @@ -1429,7 +1429,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: ['arrayMixedType'], @@ -1445,8 +1445,8 @@ describe('internalSchemaToStandard', function() { }); }); - describe('mixed types', function() { - it('simple mixed type', function() { + describe('mixed types', async function() { + it('simple mixed type', async function() { const internal = { count: 2, fields: [ @@ -1507,7 +1507,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: [], @@ -1519,7 +1519,7 @@ describe('internalSchemaToStandard', function() { }); }); - it('complex mixed type', function() { + it('complex mixed type', async function() { const internal = { count: 2, fields: [ @@ -1623,7 +1623,7 @@ describe('internalSchemaToStandard', function() { } ] }; - const standard = internalSchemaToStandard(internal); + const standard = await internalSchemaToMongoDB(internal); assert.deepStrictEqual(standard, { bsonType: 'object', required: [], @@ -1651,5 +1651,118 @@ describe('internalSchemaToStandard', function() { }); }); }); + + it('can be aborted', async function() { + const internal = { + count: 2, + fields: [ + { + name: 'mixedComplexType', + path: [ + 'mixedComplexType' + ], + count: 2, + type: [ + 'Array', + 'Document', + 'Undefined' + ], + probability: 0.6666666666666666, + hasDuplicates: false, + types: [ + { + name: 'Array', + path: [ + 'mixedComplexType' + ], + count: 1, + probability: 0.3333333333333333, + bsonType: 'Array', + types: [ + { + name: 'Int32', + path: [ + 'mixedComplexType' + ], + count: 3, + probability: 1, + unique: 3, + hasDuplicates: false, + values: [ + 1, + 2, + 3 + ], + bsonType: 'Int32' + } + ], + totalCount: 3, + lengths: [ + 3 + ], + averageLength: 3 + }, + { + name: 'Document', + path: [ + 'mixedComplexType' + ], + count: 1, + probability: 0.3333333333333333, + bsonType: 'Document', + fields: [ + { + name: 'a', + path: [ + 'mixedComplexType', + 'a' + ], + count: 1, + type: 'String', + probability: 1, + hasDuplicates: false, + types: [ + { + name: 'String', + path: [ + 'mixedComplexType', + 'a' + ], + count: 1, + probability: 1, + unique: 1, + hasDuplicates: false, + values: [ + 'bc' + ], + bsonType: 'String' + } + ] + } + ] + }, + { + name: 'Undefined', + bsonType: 'Undefined', + unique: 1, + hasDuplicates: false, + path: [ + 'mixedComplexType' + ], + count: 1, + probability: 0.3333333333333333 + } + ] + } + ] + }; + const abortController = new AbortController(); + const promise = internalSchemaToMongoDB(internal, { signal: abortController.signal }); + abortController.abort(new Error('Too long, didn\'t wait.')); + await assert.rejects(promise, { + name: 'Error', + message: 'Too long, didn\'t wait.' + }); + }); }); }); diff --git a/src/schema-convertors/internalToMongoDB.ts b/src/schema-convertors/internalToMongoDB.ts index 56958c7..7727c84 100644 --- a/src/schema-convertors/internalToMongoDB.ts +++ b/src/schema-convertors/internalToMongoDB.ts @@ -36,18 +36,27 @@ const convertInternalType = (type: string) => { return bsonType; }; -function parseType(type: SchemaType, signal?: AbortSignal): MongoDBJSONSchema { - if (signal?.aborted) throw new Error('Operation aborted'); +async function allowAbort(signal?: AbortSignal) { + return new Promise((resolve, reject) => + setTimeout(() => { + if (signal?.aborted) return reject(signal?.reason || new Error('Operation aborted')); + resolve(); + }) + ); +} + +async function parseType(type: SchemaType, signal?: AbortSignal): Promise { + await allowAbort(signal); const schema: MongoDBJSONSchema = { bsonType: convertInternalType(type.bsonType) }; switch (type.bsonType) { case 'Array': - schema.items = parseTypes((type as ArraySchemaType).types); + schema.items = await parseTypes((type as ArraySchemaType).types); break; case 'Document': Object.assign(schema, - parseFields((type as DocumentSchemaType).fields, signal) + await parseFields((type as DocumentSchemaType).fields, signal) ); break; } @@ -55,14 +64,14 @@ function parseType(type: SchemaType, signal?: AbortSignal): MongoDBJSONSchema { return schema; } -function parseTypes(types: SchemaType[], signal?: AbortSignal): MongoDBJSONSchema { - if (signal?.aborted) throw signal.reason ?? new Error('Operation aborted'); +async function parseTypes(types: SchemaType[], signal?: AbortSignal): Promise { + await allowAbort(signal); const definedTypes = types.filter(type => type.bsonType.toLowerCase() !== 'undefined'); const isSingleType = definedTypes.length === 1; if (isSingleType) { return parseType(definedTypes[0], signal); } - const parsedTypes = definedTypes.map(type => parseType(type, signal)); + const parsedTypes = await Promise.all(definedTypes.map(type => parseType(type, signal))); if (definedTypes.some(type => ['Document', 'Array'].includes(type.bsonType))) { return { anyOf: parsedTypes @@ -73,29 +82,30 @@ function parseTypes(types: SchemaType[], signal?: AbortSignal): MongoDBJSONSchem }; } -function parseFields(fields: DocumentSchemaType['fields'], signal?: AbortSignal): { +async function parseFields(fields: DocumentSchemaType['fields'], signal?: AbortSignal): Promise<{ required: MongoDBJSONSchema['required'], properties: MongoDBJSONSchema['properties'], -} { +}> { const required = []; const properties: MongoDBJSONSchema['properties'] = {}; for (const field of fields) { - if (signal?.aborted) throw new Error('Operation aborted'); if (field.probability === 1) required.push(field.name); - properties[field.name] = parseTypes(field.types, signal); + properties[field.name] = await parseTypes(field.types, signal); } return { required, properties }; } -export default function internalSchemaToMongodb( +export default async function internalSchemaToMongodb( internalSchema: InternalSchema, options: { signal?: AbortSignal -} = {}): MongoDBJSONSchema { +} = {}): Promise { + const { required, properties } = await parseFields(internalSchema.fields, options.signal); const schema: MongoDBJSONSchema = { bsonType: 'object', - ...parseFields(internalSchema.fields, options.signal) + required, + properties }; return schema; } diff --git a/test/analyze-documents.test.ts b/test/analyze-documents.test.ts index 56b4397..da24545 100644 --- a/test/analyze-documents.test.ts +++ b/test/analyze-documents.test.ts @@ -1,5 +1,5 @@ import { analyzeDocuments } from '../src'; -import convertors from '../src/schema-convertors'; +import { convertors } from '../src/schema-convertors'; import sinon from 'sinon'; import assert from 'assert'; From 8f3adbbf8e65c1cad10686ee58b6a1c57b0fea79 Mon Sep 17 00:00:00 2001 From: Paula Stachova Date: Tue, 28 Jan 2025 14:47:37 +0100 Subject: [PATCH 10/10] function signature --- src/schema-convertors/internalToExpanded.ts | 4 ++-- src/schema-convertors/internalToStandard.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/schema-convertors/internalToExpanded.ts b/src/schema-convertors/internalToExpanded.ts index a2fbdab..be91d93 100644 --- a/src/schema-convertors/internalToExpanded.ts +++ b/src/schema-convertors/internalToExpanded.ts @@ -6,7 +6,7 @@ export default function internalSchemaToExpanded( internalSchema: InternalSchema, options: { signal?: AbortSignal -}): ExpandedJSONSchema { +}): Promise { // TODO: COMPASS-8702 - return {} as ExpandedJSONSchema; + return Promise.resolve({} as ExpandedJSONSchema); } diff --git a/src/schema-convertors/internalToStandard.ts b/src/schema-convertors/internalToStandard.ts index d50aa5b..3d58125 100644 --- a/src/schema-convertors/internalToStandard.ts +++ b/src/schema-convertors/internalToStandard.ts @@ -6,7 +6,7 @@ export default function internalSchemaToStandard( internalSchema: InternalSchema, options: { signal?: AbortSignal -}): StandardJSONSchema { +}): Promise { // TODO: COMPASS-8700 - return {} as StandardJSONSchema; + return Promise.resolve({} as StandardJSONSchema); }