From b606b9dc04806189a47d1cd45b7e039624cf5bad Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 21:39:45 +0200 Subject: [PATCH 01/14] fix: setup --- packages/schema/package.json | 56 ++++++++++++++++++++++++++++ packages/schema/tests/config/c8.json | 8 ++++ packages/schema/tests/config/tap.yml | 8 ++++ 3 files changed, 72 insertions(+) create mode 100644 packages/schema/package.json create mode 100644 packages/schema/tests/config/c8.json create mode 100644 packages/schema/tests/config/tap.yml diff --git a/packages/schema/package.json b/packages/schema/package.json new file mode 100644 index 000000000..eb82c0c8f --- /dev/null +++ b/packages/schema/package.json @@ -0,0 +1,56 @@ +{ + "name": "@orama/schema", + "version": "1.0.0", + "description": "Schema utilities for Orama", + "keywords": [ + "orama", + "search", + "schema" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/oramasearch/orama" + }, + "bugs": { + "url": "https://github.com/oramasearch/orama" + }, + "type": "module", + "sideEffects": false, + "main": "./dist/commonjs.cjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/commonjs.cjs" + } + }, + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "dev": "swc --delete-dir-on-start -s -w --extensions .ts,.cts -d dist src", + "build": "swc --delete-dir-on-start --extensions .ts,.cts -d dist src", + "postbuild": "tsc -p . --emitDeclarationOnly && tsc -p tsconfig.cjs.json --emitDeclarationOnly && mv dist/commonjs.js dist/commonjs.cjs && mv dist/commonjs.js.map dist/commonjs.cjs.map", + "test": "c8 -c test/config/c8.json tap --rcfile=test/config/tap.yml test/*.test.ts" + }, + "dependencies": { + "@orama/orama": "workspace:*" + }, + "devDependencies": { + "@swc/cli": "^0.1.59", + "@swc/core": "^1.3.27", + "@types/node": "^18.11.18", + "@types/tap": "^15.0.7", + "c8": "^7.12.0", + "tap": "^16.3.4", + "tsx": "^3.12.2", + "typescript": "^4.9.4" + }, + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } + } +} diff --git a/packages/schema/tests/config/c8.json b/packages/schema/tests/config/c8.json new file mode 100644 index 000000000..14bc5e00e --- /dev/null +++ b/packages/schema/tests/config/c8.json @@ -0,0 +1,8 @@ +{ + "check-coverage": true, + "reporter": ["text", "json"], + "branches": 80, + "functions": 80, + "lines": 80, + "statements": 80 +} diff --git a/packages/schema/tests/config/tap.yml b/packages/schema/tests/config/tap.yml new file mode 100644 index 000000000..ee28002fa --- /dev/null +++ b/packages/schema/tests/config/tap.yml @@ -0,0 +1,8 @@ +--- +jobs: 5 +timeout: 120 +reporter: spec +coverage: false +node-arg: + - --loader=tsx + - --no-warnings=loader From 02e2bd1ea6ef16c0b2dae429bc9e8debe8ac106f Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 22:13:16 +0200 Subject: [PATCH 02/14] feat: first implementation --- packages/schema/package.json | 3 +- packages/schema/src/index.ts | 3 ++ packages/schema/src/jsonSchema.ts | 45 ++++++++++++++++++++++ pnpm-lock.yaml | 63 +++++++++++++++++++++++-------- 4 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 packages/schema/src/index.ts create mode 100644 packages/schema/src/jsonSchema.ts diff --git a/packages/schema/package.json b/packages/schema/package.json index eb82c0c8f..c484b642f 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -1,6 +1,6 @@ { "name": "@orama/schema", - "version": "1.0.0", + "version": "0.0.1", "description": "Schema utilities for Orama", "keywords": [ "orama", @@ -41,6 +41,7 @@ "devDependencies": { "@swc/cli": "^0.1.59", "@swc/core": "^1.3.27", + "@types/json-schema": "^7.0.12", "@types/node": "^18.11.18", "@types/tap": "^15.0.7", "c8": "^7.12.0", diff --git a/packages/schema/src/index.ts b/packages/schema/src/index.ts new file mode 100644 index 000000000..c6721f5c4 --- /dev/null +++ b/packages/schema/src/index.ts @@ -0,0 +1,3 @@ +import { schemaFromJson } from './jsonSchema' + +export { schemaFromJson } diff --git a/packages/schema/src/jsonSchema.ts b/packages/schema/src/jsonSchema.ts new file mode 100644 index 000000000..dbdbe7b49 --- /dev/null +++ b/packages/schema/src/jsonSchema.ts @@ -0,0 +1,45 @@ +import type { JSONSchema4 } from 'json-schema'; +import type { Schema } from '@orama/orama'; + +const assertTypeObject = (jsonSchema: JSONSchema4) => { + if (jsonSchema.type !== 'object') { + throw new Error('Provided schema must be an object type'); + } +} + +const assertProperties = (jsonSchema: JSONSchema4) => { + if (!jsonSchema.properties) { + throw new Error('Provided must have properties'); + } +} + +const ORAMA_SUPPORTED_TYPES: Set = new Set(['string', 'number', 'boolean']) + +const isArraySupportedByOrama = (jsonSchema: JSONSchema4) => { + if (jsonSchema.type === 'array' && jsonSchema.items && !Array.isArray(jsonSchema.items)) { + return ORAMA_SUPPORTED_TYPES.has(jsonSchema.items.type); + } + return false +} + +const isSupportedByOrama = (jsonSchema: JSONSchema4) => { + return ORAMA_SUPPORTED_TYPES.has(jsonSchema.type) || isArraySupportedByOrama(jsonSchema); +} + +const extractOramaType = (jsonSchema: JSONSchema4) => { + return ORAMA_SUPPORTED_TYPES.has(jsonSchema.type) ? jsonSchema.type : `${(jsonSchema.items as JSONSchema4)!.type}[]` +} + +export const schemaFromJson = (jsonSchema: JSONSchema4) => { + assertTypeObject(jsonSchema) + + assertProperties(jsonSchema) + + const oramaSchema: Schema = {} + + for (const [propertyName, propertyDefinition] of Object.entries(jsonSchema.properties!)) { + if (isSupportedByOrama(propertyDefinition)) { + oramaSchema[propertyName] = extractOramaType(propertyDefinition) + } + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 850c9ee6c..fa4fbd90c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true @@ -542,6 +542,40 @@ importers: specifier: ^4.9.4 version: 4.9.4 + packages/schema: + dependencies: + '@orama/orama': + specifier: workspace:* + version: link:../orama + devDependencies: + '@swc/cli': + specifier: ^0.1.59 + version: 0.1.59(@swc/core@1.3.27) + '@swc/core': + specifier: ^1.3.27 + version: 1.3.27 + '@types/json-schema': + specifier: ^7.0.12 + version: 7.0.12 + '@types/node': + specifier: ^18.11.18 + version: 18.11.18 + '@types/tap': + specifier: ^15.0.7 + version: 15.0.7 + c8: + specifier: ^7.12.0 + version: 7.12.0 + tap: + specifier: ^16.3.4 + version: 16.3.4(ts-node@10.9.1)(typescript@4.9.4) + tsx: + specifier: ^3.12.2 + version: 3.12.2 + typescript: + specifier: ^4.9.4 + version: 4.9.4 + packages/stemmers: devDependencies: '@swc/core': @@ -2603,7 +2637,7 @@ packages: react-router-config: 5.1.1(react-router@5.3.4)(react@17.0.2) react-router-dom: 5.3.4(react@17.0.2) rtl-detect: 1.0.4 - semver: 7.3.8 + semver: 7.5.0 serve-handler: 6.1.5 shelljs: 0.8.5 terser-webpack-plugin: 5.3.9(@swc/core@1.3.27)(webpack@5.75.0) @@ -4102,7 +4136,7 @@ packages: bin-wrapper: 4.1.0 commander: 7.2.0 fast-glob: 3.2.12 - semver: 7.3.8 + semver: 7.5.0 slash: 3.0.0 source-map: 0.7.4 dev: true @@ -4746,7 +4780,7 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.0 tsutils: 3.21.0(typescript@4.9.4) typescript: 4.9.4 transitivePeerDependencies: @@ -4767,7 +4801,7 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.0 tsutils: 3.21.0(typescript@4.9.4) typescript: 4.9.4 transitivePeerDependencies: @@ -4788,7 +4822,7 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.0 tsutils: 3.21.0(typescript@4.9.4) typescript: 4.9.4 transitivePeerDependencies: @@ -4812,7 +4846,7 @@ packages: eslint: 8.32.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0(eslint@8.32.0) - semver: 7.3.8 + semver: 7.5.0 transitivePeerDependencies: - supports-color - typescript @@ -4835,7 +4869,7 @@ packages: '@typescript-eslint/typescript-estree': 5.59.9(typescript@4.9.4) eslint: 8.32.0 eslint-scope: 5.1.1 - semver: 7.3.8 + semver: 7.5.0 transitivePeerDependencies: - supports-color - typescript @@ -5797,7 +5831,7 @@ packages: /builtins@5.0.1: resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} dependencies: - semver: 7.3.8 + semver: 7.5.0 dev: true /bundle-name@3.0.0: @@ -6585,7 +6619,7 @@ packages: postcss-modules-scope: 3.0.0(postcss@8.4.24) postcss-modules-values: 4.0.0(postcss@8.4.24) postcss-value-parser: 4.2.0 - semver: 7.3.8 + semver: 7.5.0 webpack: 5.75.0(@swc/core@1.3.27) dev: false @@ -8492,7 +8526,7 @@ packages: memfs: 3.5.3 minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.3.8 + semver: 7.5.0 tapable: 1.1.3 typescript: 4.9.4 webpack: 5.75.0(@swc/core@1.3.27) @@ -11781,7 +11815,7 @@ packages: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.12.1 - semver: 7.3.8 + semver: 7.5.0 validate-npm-package-license: 3.0.4 dev: true @@ -12546,7 +12580,7 @@ packages: jiti: 1.18.2 klona: 2.0.6 postcss: 8.4.24 - semver: 7.3.8 + semver: 7.5.0 webpack: 5.75.0(@swc/core@1.3.27) dev: false @@ -14219,7 +14253,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} @@ -15784,7 +15817,7 @@ packages: is-yarn-global: 0.3.0 latest-version: 5.1.0 pupa: 2.1.1 - semver: 7.3.8 + semver: 7.5.0 semver-diff: 3.1.1 xdg-basedir: 4.0.0 dev: false From cd1732a4da04dad39f9b56cdf75b59ca2a69328d Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 22:32:28 +0200 Subject: [PATCH 03/14] fix: basic tests --- packages/schema/src/index.ts | 2 +- packages/schema/src/jsonSchema.ts | 16 ++-- .../schema/{tests => test}/config/c8.json | 0 .../schema/{tests => test}/config/tap.yml | 0 packages/schema/test/index.test.ts | 90 +++++++++++++++++++ 5 files changed, 96 insertions(+), 12 deletions(-) rename packages/schema/{tests => test}/config/c8.json (100%) rename packages/schema/{tests => test}/config/tap.yml (100%) create mode 100644 packages/schema/test/index.test.ts diff --git a/packages/schema/src/index.ts b/packages/schema/src/index.ts index c6721f5c4..22ec20055 100644 --- a/packages/schema/src/index.ts +++ b/packages/schema/src/index.ts @@ -1,3 +1,3 @@ -import { schemaFromJson } from './jsonSchema' +import { schemaFromJson } from './jsonSchema.js' export { schemaFromJson } diff --git a/packages/schema/src/jsonSchema.ts b/packages/schema/src/jsonSchema.ts index dbdbe7b49..595e6596e 100644 --- a/packages/schema/src/jsonSchema.ts +++ b/packages/schema/src/jsonSchema.ts @@ -1,15 +1,9 @@ -import type { JSONSchema4 } from 'json-schema'; import type { Schema } from '@orama/orama'; +import type { JSONSchema4 } from 'json-schema'; const assertTypeObject = (jsonSchema: JSONSchema4) => { if (jsonSchema.type !== 'object') { - throw new Error('Provided schema must be an object type'); - } -} - -const assertProperties = (jsonSchema: JSONSchema4) => { - if (!jsonSchema.properties) { - throw new Error('Provided must have properties'); + throw new Error('Provided JSON schema must be an object type'); } } @@ -33,13 +27,13 @@ const extractOramaType = (jsonSchema: JSONSchema4) => { export const schemaFromJson = (jsonSchema: JSONSchema4) => { assertTypeObject(jsonSchema) - assertProperties(jsonSchema) - const oramaSchema: Schema = {} - for (const [propertyName, propertyDefinition] of Object.entries(jsonSchema.properties!)) { + for (const [propertyName, propertyDefinition] of Object.entries(jsonSchema.properties || {})) { if (isSupportedByOrama(propertyDefinition)) { oramaSchema[propertyName] = extractOramaType(propertyDefinition) } } + + return oramaSchema; } \ No newline at end of file diff --git a/packages/schema/tests/config/c8.json b/packages/schema/test/config/c8.json similarity index 100% rename from packages/schema/tests/config/c8.json rename to packages/schema/test/config/c8.json diff --git a/packages/schema/tests/config/tap.yml b/packages/schema/test/config/tap.yml similarity index 100% rename from packages/schema/tests/config/tap.yml rename to packages/schema/test/config/tap.yml diff --git a/packages/schema/test/index.test.ts b/packages/schema/test/index.test.ts new file mode 100644 index 000000000..4c1ea01ea --- /dev/null +++ b/packages/schema/test/index.test.ts @@ -0,0 +1,90 @@ +import t from 'tap' +import { schemaFromJson } from '../src/index.js' + +t.test("it should throw for non-object json schema", async t => { + const jsonSchema = { + type: 'array', + items: { + type: 'string' + } + } as const + + t.throws(() => schemaFromJson(jsonSchema), Error, 'Provided JSON schema must be an object type'); +}) + +t.test("it should convert type string", async t => { + const jsonSchema = { + type: 'object', + properties: { + myString: { + type: 'string' + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myString: 'string' + }) +}) + +t.test("it should convert type number", async t => { + const jsonSchema = { + type: 'object', + properties: { + myNumber: { + type: 'number' + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myNumber: 'number' + }) +}) + + +t.test("it should convert type boolean", async t => { + const jsonSchema = { + type: 'object', + properties: { + myBoolean: { + type: 'boolean' + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myBoolean: 'boolean' + }) +}) + +t.test("it should convert all types", async t => { + const jsonSchema = { + type: 'object', + properties: { + myString: { + type: 'string' + }, + myNumber: { + type: 'number' + }, + myBoolean: { + type: 'boolean' + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myString: 'string', + myNumber: 'number', + myBoolean: 'boolean' + }) +}) \ No newline at end of file From 14fbb5f36695261e784da5cf3ca81eb7064aa327 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 22:35:37 +0200 Subject: [PATCH 04/14] feat: basic tests --- packages/schema/test/index.test.ts | 144 ++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/packages/schema/test/index.test.ts b/packages/schema/test/index.test.ts index 4c1ea01ea..4d9c16a3f 100644 --- a/packages/schema/test/index.test.ts +++ b/packages/schema/test/index.test.ts @@ -1,5 +1,5 @@ -import t from 'tap' -import { schemaFromJson } from '../src/index.js' +import t from 'tap'; +import { schemaFromJson } from '../src/index.js'; t.test("it should throw for non-object json schema", async t => { const jsonSchema = { @@ -87,4 +87,144 @@ t.test("it should convert all types", async t => { myNumber: 'number', myBoolean: 'boolean' }) +}) + +t.test("it should convert type string[]", async t => { + const jsonSchema = { + type: 'object', + properties: { + myStringArray: { + type: 'array', + items: { + type: 'string' + } + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myStringArray: 'string[]' + }) +}) + +t.test("it should convert type number[]", async t => { + const jsonSchema = { + type: 'object', + properties: { + myNumberArray: { + type: 'array', + items: { + type: 'number' + } + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myNumberArray: 'number[]' + }) +}) + +t.test("it should convert type boolean[]", async t => { + const jsonSchema = { + type: 'object', + properties: { + myBooleanArray: { + type: 'array', + items: { + type: 'boolean' + } + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myBooleanArray: 'boolean[]' + }) +}) + +t.test("it should convert type array", async t => { + const jsonSchema = { + type: 'object', + properties: { + myStringArray: { + type: 'array', + items: { + type: 'string' + } + }, + myNumberArray: { + type: 'array', + items: { + type: 'number' + } + }, + myBooleanArray: { + type: 'array', + items: { + type: 'boolean' + } + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myStringArray: 'string[]', + myNumberArray: 'number[]', + myBooleanArray: 'boolean[]' + }) +}) + +t.test("it should convert all types", async t => { + const jsonSchema = { + type: 'object', + properties: { + myString: { + type: 'string' + }, + myNumber: { + type: 'number' + }, + myBoolean: { + type: 'boolean' + }, + myStringArray: { + type: 'array', + items: { + type: 'string' + } + }, + myNumberArray: { + type: 'array', + items: { + type: 'number' + } + }, + myBooleanArray: { + type: 'array', + items: { + type: 'boolean' + } + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myString: 'string', + myNumber: 'number', + myBoolean: 'boolean', + myStringArray: 'string[]', + myNumberArray: 'number[]', + myBooleanArray: 'boolean[]' + }) }) \ No newline at end of file From 9ea79328614ad99b4cafaefe35aa2948ad004635 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 22:37:13 +0200 Subject: [PATCH 05/14] chore: additional object test --- packages/schema/test/index.test.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/schema/test/index.test.ts b/packages/schema/test/index.test.ts index 4d9c16a3f..e6eb38efc 100644 --- a/packages/schema/test/index.test.ts +++ b/packages/schema/test/index.test.ts @@ -227,4 +227,24 @@ t.test("it should convert all types", async t => { myNumberArray: 'number[]', myBooleanArray: 'boolean[]' }) +}) + +t.test("it should skip unknown types", async t => { + const jsonSchema = { + type: 'object', + properties: { + myBoolean: { + type: 'boolean' + }, + myObject: { + type: 'object' + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myBoolean: 'boolean' + }) }) \ No newline at end of file From 01ebfe43b72fce0ae9a22891f778c3609e6edc11 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 22:38:09 +0200 Subject: [PATCH 06/14] chore: missing properties test --- packages/schema/test/index.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/schema/test/index.test.ts b/packages/schema/test/index.test.ts index e6eb38efc..500086dcc 100644 --- a/packages/schema/test/index.test.ts +++ b/packages/schema/test/index.test.ts @@ -12,6 +12,16 @@ t.test("it should throw for non-object json schema", async t => { t.throws(() => schemaFromJson(jsonSchema), Error, 'Provided JSON schema must be an object type'); }) +t.test("it should return empty object for missing properties", async t => { + const jsonSchema = { + type: 'object', + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, {}) +}) + t.test("it should convert type string", async t => { const jsonSchema = { type: 'object', From ead2ebc1e0cb1ea5009677a3e24b1dc3d33550d7 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Fri, 21 Jul 2023 22:41:45 +0200 Subject: [PATCH 07/14] fix: mising tsconfig --- packages/schema/tsconfig.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 packages/schema/tsconfig.json diff --git a/packages/schema/tsconfig.json b/packages/schema/tsconfig.json new file mode 100644 index 000000000..012a0b3ee --- /dev/null +++ b/packages/schema/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "allowJs": true, + "target": "ESNext", + "module": "ESNext", + "outDir": "dist", + "lib": ["ESNext", "DOM"], + "esModuleInterop": true, + "declaration": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "sourceMap": true, + "moduleResolution": "nodenext" + }, + "include": ["src/*.ts", "src/**/*.ts"] +} From adb4df899a3b7c995aea44240d9f5098e1052d4b Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Sat, 22 Jul 2023 11:06:02 +0000 Subject: [PATCH 08/14] fix: ts types --- packages/schema/src/jsonSchema.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/schema/src/jsonSchema.ts b/packages/schema/src/jsonSchema.ts index 595e6596e..ea0271c64 100644 --- a/packages/schema/src/jsonSchema.ts +++ b/packages/schema/src/jsonSchema.ts @@ -1,4 +1,4 @@ -import type { Schema } from '@orama/orama'; +import type { Schema, SearchableType } from '@orama/orama'; import type { JSONSchema4 } from 'json-schema'; const assertTypeObject = (jsonSchema: JSONSchema4) => { @@ -9,19 +9,21 @@ const assertTypeObject = (jsonSchema: JSONSchema4) => { const ORAMA_SUPPORTED_TYPES: Set = new Set(['string', 'number', 'boolean']) -const isArraySupportedByOrama = (jsonSchema: JSONSchema4) => { +const isArraySupportedByOrama = (jsonSchema: JSONSchema4): boolean => { if (jsonSchema.type === 'array' && jsonSchema.items && !Array.isArray(jsonSchema.items)) { return ORAMA_SUPPORTED_TYPES.has(jsonSchema.items.type); } return false } -const isSupportedByOrama = (jsonSchema: JSONSchema4) => { +const isSupportedByOrama = (jsonSchema: JSONSchema4): boolean => { return ORAMA_SUPPORTED_TYPES.has(jsonSchema.type) || isArraySupportedByOrama(jsonSchema); } -const extractOramaType = (jsonSchema: JSONSchema4) => { - return ORAMA_SUPPORTED_TYPES.has(jsonSchema.type) ? jsonSchema.type : `${(jsonSchema.items as JSONSchema4)!.type}[]` +const extractOramaType = (jsonSchema: JSONSchema4): SearchableType => { + const oramaType = ORAMA_SUPPORTED_TYPES.has(jsonSchema.type) ? jsonSchema.type : `${(jsonSchema.items as JSONSchema4)!.type}[]` + + return oramaType as SearchableType } export const schemaFromJson = (jsonSchema: JSONSchema4) => { From 7644e8797a6ca89273c7ad4cc91dad75c10b7edd Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Sat, 22 Jul 2023 11:18:03 +0000 Subject: [PATCH 09/14] fix: tsc build --- packages/schema/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schema/package.json b/packages/schema/package.json index c484b642f..788d38e71 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -32,7 +32,7 @@ "scripts": { "dev": "swc --delete-dir-on-start -s -w --extensions .ts,.cts -d dist src", "build": "swc --delete-dir-on-start --extensions .ts,.cts -d dist src", - "postbuild": "tsc -p . --emitDeclarationOnly && tsc -p tsconfig.cjs.json --emitDeclarationOnly && mv dist/commonjs.js dist/commonjs.cjs && mv dist/commonjs.js.map dist/commonjs.cjs.map", + "postbuild": "tsc -p . --emitDeclarationOnly", "test": "c8 -c test/config/c8.json tap --rcfile=test/config/tap.yml test/*.test.ts" }, "dependencies": { From aecdf64ec828cc0d5767475cac153e627d24e374 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Sat, 22 Jul 2023 11:22:10 +0000 Subject: [PATCH 10/14] feat: support for nested objects --- packages/schema/src/jsonSchema.ts | 6 +++++- packages/schema/test/index.test.ts | 32 ++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/schema/src/jsonSchema.ts b/packages/schema/src/jsonSchema.ts index ea0271c64..1f8fea20e 100644 --- a/packages/schema/src/jsonSchema.ts +++ b/packages/schema/src/jsonSchema.ts @@ -1,8 +1,10 @@ import type { Schema, SearchableType } from '@orama/orama'; import type { JSONSchema4 } from 'json-schema'; +const isJsonObject = (jsonSchema: JSONSchema4) => jsonSchema.type === 'object' + const assertTypeObject = (jsonSchema: JSONSchema4) => { - if (jsonSchema.type !== 'object') { + if (!isJsonObject(jsonSchema)) { throw new Error('Provided JSON schema must be an object type'); } } @@ -34,6 +36,8 @@ export const schemaFromJson = (jsonSchema: JSONSchema4) => { for (const [propertyName, propertyDefinition] of Object.entries(jsonSchema.properties || {})) { if (isSupportedByOrama(propertyDefinition)) { oramaSchema[propertyName] = extractOramaType(propertyDefinition) + } else if (isJsonObject(propertyDefinition)) { + oramaSchema[propertyName] = schemaFromJson(propertyDefinition) } } diff --git a/packages/schema/test/index.test.ts b/packages/schema/test/index.test.ts index 500086dcc..37c0d2795 100644 --- a/packages/schema/test/index.test.ts +++ b/packages/schema/test/index.test.ts @@ -246,8 +246,8 @@ t.test("it should skip unknown types", async t => { myBoolean: { type: 'boolean' }, - myObject: { - type: 'object' + myAny: { + type: 'any' } } } as const @@ -257,4 +257,32 @@ t.test("it should skip unknown types", async t => { t.same(oramaSchema, { myBoolean: 'boolean' }) +}) + +t.test("it should convert nested objects", async t => { + const jsonSchema = { + type: 'object', + properties: { + myBoolean: { + type: 'boolean' + }, + myObject: { + type: 'object', + properties: { + myString: { + type: 'string' + } + } + } + } + } as const + + const oramaSchema = schemaFromJson(jsonSchema) + + t.same(oramaSchema, { + myBoolean: 'boolean', + myObject: { + myString: 'string' + } + }) }) \ No newline at end of file From bf8ea3fb87c29b772e9d20b994da1edce1466261 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Thu, 27 Jul 2023 13:34:07 +0200 Subject: [PATCH 11/14] fix: make function async --- packages/schema/src/jsonSchema.ts | 6 +++--- packages/schema/test/index.test.ts | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/schema/src/jsonSchema.ts b/packages/schema/src/jsonSchema.ts index 1f8fea20e..062126883 100644 --- a/packages/schema/src/jsonSchema.ts +++ b/packages/schema/src/jsonSchema.ts @@ -28,7 +28,7 @@ const extractOramaType = (jsonSchema: JSONSchema4): SearchableType => { return oramaType as SearchableType } -export const schemaFromJson = (jsonSchema: JSONSchema4) => { +export const schemaFromJson = async (jsonSchema: JSONSchema4): Promise => { assertTypeObject(jsonSchema) const oramaSchema: Schema = {} @@ -37,9 +37,9 @@ export const schemaFromJson = (jsonSchema: JSONSchema4) => { if (isSupportedByOrama(propertyDefinition)) { oramaSchema[propertyName] = extractOramaType(propertyDefinition) } else if (isJsonObject(propertyDefinition)) { - oramaSchema[propertyName] = schemaFromJson(propertyDefinition) + oramaSchema[propertyName] = await schemaFromJson(propertyDefinition) } } - return oramaSchema; + return Promise.resolve(oramaSchema); } \ No newline at end of file diff --git a/packages/schema/test/index.test.ts b/packages/schema/test/index.test.ts index 37c0d2795..d43127a42 100644 --- a/packages/schema/test/index.test.ts +++ b/packages/schema/test/index.test.ts @@ -17,7 +17,7 @@ t.test("it should return empty object for missing properties", async t => { type: 'object', } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, {}) }) @@ -32,7 +32,7 @@ t.test("it should convert type string", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myString: 'string' @@ -49,7 +49,7 @@ t.test("it should convert type number", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myNumber: 'number' @@ -67,7 +67,7 @@ t.test("it should convert type boolean", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myBoolean: 'boolean' @@ -90,7 +90,7 @@ t.test("it should convert all types", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myString: 'string', @@ -112,7 +112,7 @@ t.test("it should convert type string[]", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myStringArray: 'string[]' @@ -132,7 +132,7 @@ t.test("it should convert type number[]", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myNumberArray: 'number[]' @@ -152,7 +152,7 @@ t.test("it should convert type boolean[]", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myBooleanArray: 'boolean[]' @@ -184,7 +184,7 @@ t.test("it should convert type array", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myStringArray: 'string[]', @@ -227,7 +227,7 @@ t.test("it should convert all types", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myString: 'string', @@ -252,7 +252,7 @@ t.test("it should skip unknown types", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myBoolean: 'boolean' @@ -277,7 +277,7 @@ t.test("it should convert nested objects", async t => { } } as const - const oramaSchema = schemaFromJson(jsonSchema) + const oramaSchema = await schemaFromJson(jsonSchema) t.same(oramaSchema, { myBoolean: 'boolean', From 9ce40151782ecfe4641c7dbe3376161bcd6dc805 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Thu, 27 Jul 2023 13:35:36 +0200 Subject: [PATCH 12/14] fix: package name --- packages/schema/package.json | 5 +++-- packages/schema/src/jsonSchema.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/schema/package.json b/packages/schema/package.json index 788d38e71..91ec70dda 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -1,11 +1,12 @@ { - "name": "@orama/schema", + "name": "@orama/plugin-json-schema", "version": "0.0.1", "description": "Schema utilities for Orama", "keywords": [ "orama", "search", - "schema" + "schema", + "json" ], "license": "MIT", "repository": { diff --git a/packages/schema/src/jsonSchema.ts b/packages/schema/src/jsonSchema.ts index 062126883..a70c9c093 100644 --- a/packages/schema/src/jsonSchema.ts +++ b/packages/schema/src/jsonSchema.ts @@ -41,5 +41,5 @@ export const schemaFromJson = async (jsonSchema: JSONSchema4): Promise = } } - return Promise.resolve(oramaSchema); + return oramaSchema; } \ No newline at end of file From bac4c9029e4293ae2d55d89985634615a206c46e Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Thu, 27 Jul 2023 13:43:10 +0000 Subject: [PATCH 13/14] fix: license and readme --- packages/plugin-json-schema/LICENSE.md | 21 +++++ packages/plugin-json-schema/README.md | 13 +++ .../package.json | 0 .../src/index.ts | 0 .../src/jsonSchema.ts | 0 .../test/config/c8.json | 0 .../test/config/tap.yml | 0 .../test/index.test.ts | 0 .../tsconfig.json | 0 pnpm-lock.yaml | 89 +++++++++---------- 10 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 packages/plugin-json-schema/LICENSE.md create mode 100644 packages/plugin-json-schema/README.md rename packages/{schema => plugin-json-schema}/package.json (100%) rename packages/{schema => plugin-json-schema}/src/index.ts (100%) rename packages/{schema => plugin-json-schema}/src/jsonSchema.ts (100%) rename packages/{schema => plugin-json-schema}/test/config/c8.json (100%) rename packages/{schema => plugin-json-schema}/test/config/tap.yml (100%) rename packages/{schema => plugin-json-schema}/test/index.test.ts (100%) rename packages/{schema => plugin-json-schema}/tsconfig.json (100%) diff --git a/packages/plugin-json-schema/LICENSE.md b/packages/plugin-json-schema/LICENSE.md new file mode 100644 index 000000000..40fba3ce6 --- /dev/null +++ b/packages/plugin-json-schema/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 OramaSearch Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/plugin-json-schema/README.md b/packages/plugin-json-schema/README.md new file mode 100644 index 000000000..bf6c158b0 --- /dev/null +++ b/packages/plugin-json-schema/README.md @@ -0,0 +1,13 @@ +# JSON Schema plugin + +[![Tests](https://github.com/oramasearch/orama/actions/workflows/turbo.yml/badge.svg)](https://github.com/oramasearch/orama/actions/workflows/turbo.yml) + +Official plugin to convert JSON schema into Orama schema! + +# Usage + +For the complete usage guide, please refer to the [official plugin documentation](https://docs.oramasearch.com/plugins/plugin-json-schema). + +# License + +[MIT](/LICENSE.md) diff --git a/packages/schema/package.json b/packages/plugin-json-schema/package.json similarity index 100% rename from packages/schema/package.json rename to packages/plugin-json-schema/package.json diff --git a/packages/schema/src/index.ts b/packages/plugin-json-schema/src/index.ts similarity index 100% rename from packages/schema/src/index.ts rename to packages/plugin-json-schema/src/index.ts diff --git a/packages/schema/src/jsonSchema.ts b/packages/plugin-json-schema/src/jsonSchema.ts similarity index 100% rename from packages/schema/src/jsonSchema.ts rename to packages/plugin-json-schema/src/jsonSchema.ts diff --git a/packages/schema/test/config/c8.json b/packages/plugin-json-schema/test/config/c8.json similarity index 100% rename from packages/schema/test/config/c8.json rename to packages/plugin-json-schema/test/config/c8.json diff --git a/packages/schema/test/config/tap.yml b/packages/plugin-json-schema/test/config/tap.yml similarity index 100% rename from packages/schema/test/config/tap.yml rename to packages/plugin-json-schema/test/config/tap.yml diff --git a/packages/schema/test/index.test.ts b/packages/plugin-json-schema/test/index.test.ts similarity index 100% rename from packages/schema/test/index.test.ts rename to packages/plugin-json-schema/test/index.test.ts diff --git a/packages/schema/tsconfig.json b/packages/plugin-json-schema/tsconfig.json similarity index 100% rename from packages/schema/tsconfig.json rename to packages/plugin-json-schema/tsconfig.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fa4fbd90c..88f199099 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -114,7 +114,7 @@ importers: version: link:../plugin-nextra next: specifier: ^13.3.0 - version: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + version: 13.3.0(react-dom@18.2.0)(react@18.2.0) nextra: specifier: ^2.4.0 version: 2.4.0(next@13.3.0)(react-dom@18.2.0)(react@18.2.0) @@ -407,6 +407,40 @@ importers: specifier: ^5.75.0 version: 5.75.0(@swc/core@1.3.27) + packages/plugin-json-schema: + dependencies: + '@orama/orama': + specifier: workspace:* + version: link:../orama + devDependencies: + '@swc/cli': + specifier: ^0.1.59 + version: 0.1.59(@swc/core@1.3.27) + '@swc/core': + specifier: ^1.3.27 + version: 1.3.27 + '@types/json-schema': + specifier: ^7.0.12 + version: 7.0.12 + '@types/node': + specifier: ^18.11.18 + version: 18.11.18 + '@types/tap': + specifier: ^15.0.7 + version: 15.0.7 + c8: + specifier: ^7.12.0 + version: 7.12.0 + tap: + specifier: ^16.3.4 + version: 16.3.4(ts-node@10.9.1)(typescript@4.9.4) + tsx: + specifier: ^3.12.2 + version: 3.12.2 + typescript: + specifier: ^4.9.4 + version: 4.9.4 + packages/plugin-match-highlight: dependencies: '@orama/orama': @@ -451,7 +485,7 @@ importers: version: 2.3.2 next: specifier: ^13.2.4 - version: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + version: 13.3.0(react-dom@18.2.0)(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -542,40 +576,6 @@ importers: specifier: ^4.9.4 version: 4.9.4 - packages/schema: - dependencies: - '@orama/orama': - specifier: workspace:* - version: link:../orama - devDependencies: - '@swc/cli': - specifier: ^0.1.59 - version: 0.1.59(@swc/core@1.3.27) - '@swc/core': - specifier: ^1.3.27 - version: 1.3.27 - '@types/json-schema': - specifier: ^7.0.12 - version: 7.0.12 - '@types/node': - specifier: ^18.11.18 - version: 18.11.18 - '@types/tap': - specifier: ^15.0.7 - version: 15.0.7 - c8: - specifier: ^7.12.0 - version: 7.12.0 - tap: - specifier: ^16.3.4 - version: 16.3.4(ts-node@10.9.1)(typescript@4.9.4) - tsx: - specifier: ^3.12.2 - version: 3.12.2 - typescript: - specifier: ^4.9.4 - version: 4.9.4 - packages/stemmers: devDependencies: '@swc/core': @@ -11609,7 +11609,7 @@ packages: react: '>=16.0.0' react-dom: '>=16.0.0' dependencies: - next: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.3.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -11621,12 +11621,12 @@ packages: react: '*' react-dom: '*' dependencies: - next: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.3.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /next@13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): + /next@13.3.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OVTw8MpIPa12+DCUkPqRGPS3thlJPcwae2ZL4xti3iBff27goH024xy4q2lhlsdoYiKOi8Kz6uJoLW/GXwgfOA==} engines: {node: '>=14.6.0'} hasBin: true @@ -11654,7 +11654,7 @@ packages: postcss: 8.4.14 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(@babel/core@7.22.5)(react@18.2.0) + styled-jsx: 5.1.1(react@18.2.0) optionalDependencies: '@next/swc-darwin-arm64': 13.3.0 '@next/swc-darwin-x64': 13.3.0 @@ -11682,7 +11682,7 @@ packages: react-cusdis: optional: true dependencies: - next: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.3.0(react-dom@18.2.0)(react@18.2.0) next-themes: 0.2.1(next@13.3.0)(react-dom@18.2.0)(react@18.2.0) nextra: 2.4.0(next@13.3.0)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 @@ -11705,7 +11705,7 @@ packages: git-url-parse: 13.1.0 intersection-observer: 0.12.2 match-sorter: 6.3.1 - next: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.3.0(react-dom@18.2.0)(react@18.2.0) next-seo: 5.15.0(next@13.3.0)(react-dom@18.2.0)(react@18.2.0) next-themes: 0.2.1(next@13.3.0)(react-dom@18.2.0)(react@18.2.0) nextra: 2.4.0(next@13.3.0)(react-dom@18.2.0)(react@18.2.0) @@ -11731,7 +11731,7 @@ packages: gray-matter: 4.0.3 katex: 0.16.7 lodash.get: 4.4.2 - next: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.3.0(react-dom@18.2.0)(react@18.2.0) next-mdx-remote: 4.4.1(react-dom@18.2.0)(react@18.2.0) p-limit: 3.1.0 react: 18.2.0 @@ -14843,7 +14843,7 @@ packages: inline-style-parser: 0.1.1 dev: false - /styled-jsx@5.1.1(@babel/core@7.22.5)(react@18.2.0): + /styled-jsx@5.1.1(react@18.2.0): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -14856,7 +14856,6 @@ packages: babel-plugin-macros: optional: true dependencies: - '@babel/core': 7.22.5 client-only: 0.0.1 react: 18.2.0 dev: false From 39d2718b7a25274401e33bcd9a5863d87cf338b8 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Thu, 27 Jul 2023 13:55:03 +0000 Subject: [PATCH 14/14] feat: doc --- .../docs/pages/plugins/plugin-json-schema.mdx | 47 +++++++++++++++++++ .../plugin-json-schema/test/index.test.ts | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 packages/docs/pages/plugins/plugin-json-schema.mdx diff --git a/packages/docs/pages/plugins/plugin-json-schema.mdx b/packages/docs/pages/plugins/plugin-json-schema.mdx new file mode 100644 index 000000000..226c59adb --- /dev/null +++ b/packages/docs/pages/plugins/plugin-json-schema.mdx @@ -0,0 +1,47 @@ +import { Tab, Tabs } from 'nextra-theme-docs' + +# JSON Schema plugin + +[JSON Schema](https://json-schema.org/) is a declarative language that allows you to annotate and validate JSON documents. + +Orama provides its own official plugin to convert JSON Schema to Orama schema. + +## Installation + +You can install the plugin using any major Node.js package manager: + + + + ```bash copy + npm install @orama/plugin-json-schema + ``` + + + ```bash copy + yarn add @orama/plugin-json-schema + ``` + + + ```bash copy + pnpm add @orama/plugin-json-schema + ``` + + + + +## Usage + +When you configure Orama, you'll also import the `schemaFromJson` function from this plguin: + +```js +import { create } from '@orama/orama' +import { schemaFromJson } from '@orama/plugin-json-schema' + +const jsonSchema = { ... } + +const db = await create({ + schema: schemaFromJson(jsonSchema), +}) +``` + +And that's it! The Orama plugin will do the rest for you. \ No newline at end of file diff --git a/packages/plugin-json-schema/test/index.test.ts b/packages/plugin-json-schema/test/index.test.ts index d43127a42..7d9484178 100644 --- a/packages/plugin-json-schema/test/index.test.ts +++ b/packages/plugin-json-schema/test/index.test.ts @@ -9,7 +9,7 @@ t.test("it should throw for non-object json schema", async t => { } } as const - t.throws(() => schemaFromJson(jsonSchema), Error, 'Provided JSON schema must be an object type'); + t.rejects(() => schemaFromJson(jsonSchema), Error, 'Provided JSON schema must be an object type'); }) t.test("it should return empty object for missing properties", async t => {