From 4754117bc62c889ba961fe80f9193757642727dc Mon Sep 17 00:00:00 2001 From: ignaciolarranaga Date: Thu, 25 May 2023 14:34:40 -0300 Subject: [PATCH 1/3] Adding support for ObjectId. --- src/compile.test.ts | 17 +++++++++++++++++ src/compile.ts | 25 +++++++++++++++---------- src/expected/bson-types-object-id.ts | 17 +++++++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 src/expected/bson-types-object-id.ts diff --git a/src/compile.test.ts b/src/compile.test.ts index 55abfce..39d175b 100644 --- a/src/compile.test.ts +++ b/src/compile.test.ts @@ -204,6 +204,23 @@ describe("compileBSON", () => { getExpected("bson-types-with-imports-2") ); }); + + test(`BSON types ObjectId`, async () => { + const schema = { + title: "UserDoc", + description: "User object", + bsonType: "object", + additionalProperties: false, + required: [], + properties: { + _id: { + bsonType: "objectId", + }, + }, + }; + + expect(await compileBSON(schema)).toBe(getExpected("bson-types-object-id")); + }); }); describe("compileBSON with banner comments", () => { diff --git a/src/compile.ts b/src/compile.ts index 051ec4b..fa13855 100644 --- a/src/compile.ts +++ b/src/compile.ts @@ -32,7 +32,7 @@ function format(text: string, options?: prettier.Options): string { * [ ] array * [ ] binData * [ ] undefined -- Deprecated - * [ ] objectId + * [x] objectId * [X] bool * [X] date * [X] null @@ -58,6 +58,7 @@ const bsonToTs = new Map([ ["null", "null"], ["int", "number"], ["decimal", "Decimal128"], + ["objectId", "ObjectId"], ]); /** @@ -111,22 +112,22 @@ function setTsType(schema: JsonValue): JsonValue { /** * Recursively checks if a schema relies on the Decimal128 BSON type anywhere */ -function hasDecimal128(schema: JsonValue): boolean { +function hasType(schema: JsonValue, typeName: string): boolean { if (schema === null || typeof schema !== "object") { return false; } if (Array.isArray(schema)) { - return schema.some(hasDecimal128); + return schema.some((schema) => hasType(schema, typeName)); } return Object.entries(schema).some(([key, value]) => { if (key === "bsonType") { - if (value === "decimal") return true; - if (Array.isArray(value)) return value.includes("decimal"); + if (value === typeName) return true; + if (Array.isArray(value)) return value.includes(typeName); } - if (typeof value === "object") return hasDecimal128(value); + if (typeof value === "object") return hasType(value, typeName); return false; }); @@ -148,10 +149,14 @@ export async function compileBSON( const baseBanner = options?.bannerComment || defaultOptions.bannerComment; // Import Decimal128 if the type annotations use it - const bannerComment = (hasDecimal128(schema) - ? [...baseBanner, `import { Decimal128 } from "mongodb";`] - : baseBanner - ).join("\n"); + let comments = baseBanner; + if (hasType(schema, "decimal")) { + comments.push(`import { Decimal128 } from "mongodb";`); + } + if (hasType(schema, "objectId")) { + comments.push(`import { ObjectId } from "mongodb";`); + } + const bannerComment = comments.join("\n"); const compileJSONOptions: Partial = { bannerComment, diff --git a/src/expected/bson-types-object-id.ts b/src/expected/bson-types-object-id.ts new file mode 100644 index 0000000..9a34e03 --- /dev/null +++ b/src/expected/bson-types-object-id.ts @@ -0,0 +1,17 @@ +/* eslint-disable */ + +/** + * This file was automatically generated by bson-schema-to-typescript. + * https://www.npmjs.com/package/bson-schema-to-typescript + * + * Do not modify it by hand. Instead, modify the MongoDB $jsonSchema validator, + * and run bson2ts to regenerate this file. + */ +import { ObjectId } from "mongodb"; + +/** + * User object + */ +export interface UserDoc { + _id?: ObjectId; +} From 4cc58045018babcbf8b50aec7f37693603c9b397 Mon Sep 17 00:00:00 2001 From: ignaciolarranaga Date: Thu, 25 May 2023 14:46:24 -0300 Subject: [PATCH 2/3] Minor fix. --- src/compile.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compile.ts b/src/compile.ts index fa13855..4628aff 100644 --- a/src/compile.ts +++ b/src/compile.ts @@ -149,12 +149,13 @@ export async function compileBSON( const baseBanner = options?.bannerComment || defaultOptions.bannerComment; // Import Decimal128 if the type annotations use it - let comments = baseBanner; + let comments = [...baseBanner]; if (hasType(schema, "decimal")) { - comments.push(`import { Decimal128 } from "mongodb";`); + comments.push('import { Decimal128 } from "mongodb";'); } + // Import ObjectId if the type annotations use it if (hasType(schema, "objectId")) { - comments.push(`import { ObjectId } from "mongodb";`); + comments.push('import { ObjectId } from "mongodb";'); } const bannerComment = comments.join("\n"); From 08c1e01d47e5a7ea481f3ccd718498f71e2f5cf3 Mon Sep 17 00:00:00 2001 From: ignaciolarranaga Date: Thu, 25 May 2023 14:55:43 -0300 Subject: [PATCH 3/3] Adding support for double. --- src/compile.test.ts | 46 +++++++++++++++++++++++ src/compile.ts | 3 +- src/expected/bson-types-geo-json.ts | 20 ++++++++++ src/expected/bson-types-with-imports-1.ts | 4 ++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/expected/bson-types-geo-json.ts diff --git a/src/compile.test.ts b/src/compile.test.ts index 39d175b..3184d22 100644 --- a/src/compile.test.ts +++ b/src/compile.test.ts @@ -140,6 +140,10 @@ describe("compileBSON", () => { description: "Number", bsonType: "number", }, + double: { + description: "Double", + bsonType: "double", + }, boolean: { description: "Boolean", bsonType: "bool", @@ -221,6 +225,48 @@ describe("compileBSON", () => { expect(await compileBSON(schema)).toBe(getExpected("bson-types-object-id")); }); + + test(`BSON types geo-json`, async () => { + const schema = { + title: "UserDoc", + description: "User object", + bsonType: "object", + additionalProperties: false, + required: [], + properties: { + // https://www.leighhalliday.com/mongodb-geojson-schema-validation + location: { + bsonType: "object", + required: ["type", "coordinates"], + properties: { + type: { + bsonType: "string", + enum: ["Point"], + }, + coordinates: { + bsonType: ["array"], + minItems: 2, + maxItems: 2, + items: [ + { + bsonType: "double", + minimum: -180, + maximum: 180, + }, + { + bsonType: "double", + minimum: -90, + maximum: 90, + }, + ], + }, + }, + }, + }, + }; + + expect(await compileBSON(schema)).toBe(getExpected("bson-types-geo-json")); + }); }); describe("compileBSON with banner comments", () => { diff --git a/src/compile.ts b/src/compile.ts index 4628aff..178e65d 100644 --- a/src/compile.ts +++ b/src/compile.ts @@ -26,7 +26,7 @@ function format(text: string, options?: prettier.Options): string { * https://docs.mongodb.com/manual/reference/operator/query/type/#document-type-available-types * * [X] number - * [ ] double + * [x] double * [X] string * [ ] object * [ ] array @@ -55,6 +55,7 @@ const bsonToTs = new Map([ ["string", "string"], ["bool", "boolean"], ["date", "Date"], + ["double", "number"], ["null", "null"], ["int", "number"], ["decimal", "Decimal128"], diff --git a/src/expected/bson-types-geo-json.ts b/src/expected/bson-types-geo-json.ts new file mode 100644 index 0000000..9149f74 --- /dev/null +++ b/src/expected/bson-types-geo-json.ts @@ -0,0 +1,20 @@ +/* eslint-disable */ + +/** + * This file was automatically generated by bson-schema-to-typescript. + * https://www.npmjs.com/package/bson-schema-to-typescript + * + * Do not modify it by hand. Instead, modify the MongoDB $jsonSchema validator, + * and run bson2ts to regenerate this file. + */ + +/** + * User object + */ +export interface UserDoc { + location?: { + type: "Point"; + coordinates: [number, number]; + [k: string]: unknown; + }; +} diff --git a/src/expected/bson-types-with-imports-1.ts b/src/expected/bson-types-with-imports-1.ts index 8ba5bbf..275eca1 100644 --- a/src/expected/bson-types-with-imports-1.ts +++ b/src/expected/bson-types-with-imports-1.ts @@ -21,6 +21,10 @@ export interface UserDoc { * Number */ number?: number; + /** + * Double + */ + double?: number; /** * Boolean */