Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[plugin]: orama schema from json schema #452

Closed
wants to merge 15 commits into from
57 changes: 57 additions & 0 deletions packages/schema/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@orama/schema",
ilteoood marked this conversation as resolved.
Show resolved Hide resolved
"version": "0.0.1",
"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",
"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/json-schema": "^7.0.12",
"@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"
}
}
}
3 changes: 3 additions & 0 deletions packages/schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { schemaFromJson } from './jsonSchema.js'

export { schemaFromJson }
45 changes: 45 additions & 0 deletions packages/schema/src/jsonSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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 (!isJsonObject(jsonSchema)) {
throw new Error('Provided JSON schema must be an object type');
}
}

const ORAMA_SUPPORTED_TYPES: Set<JSONSchema4['type']> = new Set(['string', 'number', 'boolean'])

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): boolean => {
return ORAMA_SUPPORTED_TYPES.has(jsonSchema.type) || isArraySupportedByOrama(jsonSchema);
}

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) => {
ilteoood marked this conversation as resolved.
Show resolved Hide resolved
assertTypeObject(jsonSchema)

const oramaSchema: Schema = {}

for (const [propertyName, propertyDefinition] of Object.entries(jsonSchema.properties || {})) {
if (isSupportedByOrama(propertyDefinition)) {
oramaSchema[propertyName] = extractOramaType(propertyDefinition)
} else if (isJsonObject(propertyDefinition)) {
oramaSchema[propertyName] = schemaFromJson(propertyDefinition)
}
ilteoood marked this conversation as resolved.
Show resolved Hide resolved
}

return oramaSchema;
}
8 changes: 8 additions & 0 deletions packages/schema/test/config/c8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"check-coverage": true,
"reporter": ["text", "json"],
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
8 changes: 8 additions & 0 deletions packages/schema/test/config/tap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
jobs: 5
timeout: 120
reporter: spec
coverage: false
node-arg:
- --loader=tsx
- --no-warnings=loader
Loading