@mostajs/orm-adapter 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +1 -1
- package/dist/adapters/jsonschema.adapter.d.ts +44 -0
- package/dist/adapters/jsonschema.adapter.d.ts.map +1 -0
- package/dist/adapters/jsonschema.adapter.js +319 -0
- package/dist/adapters/jsonschema.adapter.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/jsonschema-flatten.d.ts +17 -0
- package/dist/utils/jsonschema-flatten.d.ts.map +1 -0
- package/dist/utils/jsonschema-flatten.js +63 -0
- package/dist/utils/jsonschema-flatten.js.map +1 -0
- package/dist/utils/jsonschema-type-mapper.d.ts +11 -0
- package/dist/utils/jsonschema-type-mapper.d.ts.map +1 -0
- package/dist/utils/jsonschema-type-mapper.js +113 -0
- package/dist/utils/jsonschema-type-mapper.js.map +1 -0
- package/dist/utils/jsonschema-types.d.ts +95 -0
- package/dist/utils/jsonschema-types.d.ts.map +1 -0
- package/dist/utils/jsonschema-types.js +41 -0
- package/dist/utils/jsonschema-types.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@mostajs/orm-adapter` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.0] — 2026-04-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **JsonSchemaAdapter** : converts JSON Schema to `EntitySchema[]`
|
|
10
|
+
- Drafts : Draft-07, Draft 2019-09, Draft 2020-12 (auto-detected via `$schema` URL)
|
|
11
|
+
- Types : `string`, `integer`, `number`, `boolean`, `array`, `object`, `null`
|
|
12
|
+
- Formats : `date-time`, `date`, `time`, `email`, `uuid`, `uri`, `uri-reference`, `ipv4`, `ipv6`, `regex`, `binary`, `byte`
|
|
13
|
+
- Nullable : both OpenAPI `nullable: true` and array form `type: [T, "null"]`
|
|
14
|
+
- Constraints : `enum`, `const`, `default`, `minLength`/`maxLength`, `pattern`, `minimum`/`maximum`
|
|
15
|
+
- Annotations : `readOnly`, `writeOnly`, `deprecated`, `title`, `description` (preserved)
|
|
16
|
+
- **allOf flattening** : merges parent properties into child (inheritance pattern)
|
|
17
|
+
- **oneOf discriminator** : maps to `EntitySchema.discriminator` + `discriminatorValue`
|
|
18
|
+
- **Entity detection** : top-level title/x-mostajs-entity + all `$defs` / `definitions`
|
|
19
|
+
- **$ref resolution** : internal + external via `@apidevtools/json-schema-ref-parser`
|
|
20
|
+
- **Cycle detection** : self-references flagged via CYCLIC_REFERENCE warning
|
|
21
|
+
- **Extensions** (all `x-*`) :
|
|
22
|
+
- `x-mostajs-entity` : `{ tableName, timestamps, softDelete, discriminator, discriminatorValue }`
|
|
23
|
+
- `x-mostajs-relation` : `{ type, target, foreignKey, otherKey, through, onDelete }`
|
|
24
|
+
- `x-primary`, `x-unique`, `x-index`, `x-indexes` (composite)
|
|
25
|
+
- `x-autoIncrement`
|
|
26
|
+
- **Auto-relation detection** :
|
|
27
|
+
- Property is object with title matching an entity → `many-to-one`
|
|
28
|
+
- Array items `$ref` to an entity → `one-to-many`
|
|
29
|
+
- Explicit `x-mostajs-relation` always wins
|
|
30
|
+
- **Input forms** : plain object, JSON string, or `$ref`-laden schema (auto-dereferenced)
|
|
31
|
+
- **Utils** : `jsonschema-types` (shared types + draft detection), `jsonschema-type-mapper`, `jsonschema-flatten`
|
|
32
|
+
- **Public types re-exports** : `JsonSchema`, `JsonSchemaType`, `XMostajsEntity`, `XMostajsRelation`, `DraftVersion`
|
|
33
|
+
- 60 new unit tests on 4 fixtures :
|
|
34
|
+
- `user-2020-12.json` (Draft 2020-12 + relations + indexes + x-mostajs-*)
|
|
35
|
+
- `post-draft-07.json` (Draft-07 compat + auto-relation via $ref title)
|
|
36
|
+
- `allof-composition.json` (allOf merge + required merge)
|
|
37
|
+
- `validators.json` (all validators + composite x-indexes)
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `createDefaultRegistry()` now includes JsonSchemaAdapter in the detection chain
|
|
42
|
+
|
|
43
|
+
### Warnings emitted (new)
|
|
44
|
+
|
|
45
|
+
- `PREVIEW_FEATURE` on Draft-04/06 (legacy drafts)
|
|
46
|
+
- `LOSSY_CONVERSION` on `int64` format, tuple `items`, binary/byte format
|
|
47
|
+
- `AMBIGUOUS_MAPPING` on allOf property redefinition (last-wins)
|
|
48
|
+
- `CYCLIC_REFERENCE` on self-referencing entities
|
|
49
|
+
- `FALLBACK_APPLIED` on non-object $defs entries
|
|
50
|
+
|
|
5
51
|
## [0.2.0] — 2026-04-12
|
|
6
52
|
|
|
7
53
|
### Added
|
package/README.md
CHANGED
|
@@ -146,7 +146,7 @@ export class MyCustomAdapter extends AbstractAdapter {
|
|
|
146
146
|
|
|
147
147
|
- **v0.1.0** — NativeAdapter + core (AbstractAdapter, Registry) ✅
|
|
148
148
|
- **v0.2.0** — PrismaAdapter (scalars, relations, enums, implicit M-N) ✅
|
|
149
|
-
- **v0.3.0** — JsonSchemaAdapter (Draft 2020-12 + Draft-07)
|
|
149
|
+
- **v0.3.0** — JsonSchemaAdapter (Draft 2020-12 + Draft-07 + allOf + x-mostajs-*) ✅
|
|
150
150
|
- **v0.4.0** — OpenApiAdapter (3.1 with 3.0 normalization)
|
|
151
151
|
- **v1.0.0** — Production-ready, all 4 adapters with reverse conversion
|
|
152
152
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EntitySchema } from '@mostajs/orm';
|
|
2
|
+
import { AbstractAdapter } from '../core/abstract.adapter.js';
|
|
3
|
+
import { type AdapterOptions } from '../core/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* JsonSchemaAdapter — converts JSON Schema to EntitySchema[].
|
|
6
|
+
*
|
|
7
|
+
* Supports (MVP v0.3.0):
|
|
8
|
+
* - Draft-07, Draft 2019-09, Draft 2020-12 (auto-detected)
|
|
9
|
+
* - type: string/integer/number/boolean/array/object/null (including array form)
|
|
10
|
+
* - formats: date-time, date, time, email, uuid, uri, ipv4, regex, binary
|
|
11
|
+
* - Constraints: enum, const, default, minLength/maxLength, pattern, min/max
|
|
12
|
+
* - Nullable (both OpenAPI nullable: true and type: [T, "null"])
|
|
13
|
+
* - readOnly / writeOnly / deprecated (annotations preserved)
|
|
14
|
+
* - allOf flattening (inheritance merge)
|
|
15
|
+
* - oneOf + discriminator → discriminator + discriminatorValue
|
|
16
|
+
* - Entity detection : top-level (title+x-mostajs-entity) + all $defs
|
|
17
|
+
* - Extensions : x-mostajs-entity, x-mostajs-relation, x-primary, x-unique, x-index, x-indexes
|
|
18
|
+
* - $ref resolution (cycles detected, self-relation auto-created)
|
|
19
|
+
*
|
|
20
|
+
* Not yet supported (v0.4+):
|
|
21
|
+
* - $dynamicRef / $dynamicAnchor late-binding
|
|
22
|
+
* - patternProperties as structured mapping (falls back to json)
|
|
23
|
+
* - if/then/else conditional
|
|
24
|
+
* - External $ref resolution (HTTP/file beyond basic dereference)
|
|
25
|
+
*/
|
|
26
|
+
export declare class JsonSchemaAdapter extends AbstractAdapter {
|
|
27
|
+
readonly name = "jsonschema";
|
|
28
|
+
readonly vendor = "json-schema.org";
|
|
29
|
+
readonly version = "0.3.0";
|
|
30
|
+
canParse(input: string | object): boolean;
|
|
31
|
+
toEntitySchema(input: string | object, opts?: AdapterOptions): Promise<EntitySchema[]>;
|
|
32
|
+
private collectEntities;
|
|
33
|
+
private nameFromId;
|
|
34
|
+
private convertEntity;
|
|
35
|
+
private processProperty;
|
|
36
|
+
private mapXMostajsRelation;
|
|
37
|
+
private toFieldDef;
|
|
38
|
+
/**
|
|
39
|
+
* Generate indexes from x-index and x-unique on individual fields.
|
|
40
|
+
*/
|
|
41
|
+
private applyFieldIndexes;
|
|
42
|
+
private tryParseJson;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=jsonschema.adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/jsonschema.adapter.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAA4D,MAAM,cAAc,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAe,KAAK,cAAc,EAAuB,MAAM,kBAAkB,CAAC;AAmBzF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,MAAM,qBAAqB;IACpC,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAoBnC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAwC5F,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,aAAa;IAwErB,OAAO,CAAC,eAAe;IAgDvB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,UAAU;IAgDlB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,YAAY;CAQrB"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// jsonschema.adapter.ts
|
|
2
|
+
// Converts JSON Schema (Draft-07, 2019-09, 2020-12) to EntitySchema[].
|
|
3
|
+
// Parser : @apidevtools/json-schema-ref-parser.
|
|
4
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
5
|
+
// License: AGPL-3.0-or-later
|
|
6
|
+
import $RefParser from '@apidevtools/json-schema-ref-parser';
|
|
7
|
+
import { AbstractAdapter } from '../core/abstract.adapter.js';
|
|
8
|
+
import { WarningCode } from '../core/types.js';
|
|
9
|
+
import { InvalidSchemaError } from '../core/errors.js';
|
|
10
|
+
import { detectDraft, getDefinitions, primaryType, isNullable, } from '../utils/jsonschema-types.js';
|
|
11
|
+
import { mapJsonSchemaType, mapArrayItems } from '../utils/jsonschema-type-mapper.js';
|
|
12
|
+
import { flattenAllOf, detectDiscriminator } from '../utils/jsonschema-flatten.js';
|
|
13
|
+
/**
|
|
14
|
+
* JsonSchemaAdapter — converts JSON Schema to EntitySchema[].
|
|
15
|
+
*
|
|
16
|
+
* Supports (MVP v0.3.0):
|
|
17
|
+
* - Draft-07, Draft 2019-09, Draft 2020-12 (auto-detected)
|
|
18
|
+
* - type: string/integer/number/boolean/array/object/null (including array form)
|
|
19
|
+
* - formats: date-time, date, time, email, uuid, uri, ipv4, regex, binary
|
|
20
|
+
* - Constraints: enum, const, default, minLength/maxLength, pattern, min/max
|
|
21
|
+
* - Nullable (both OpenAPI nullable: true and type: [T, "null"])
|
|
22
|
+
* - readOnly / writeOnly / deprecated (annotations preserved)
|
|
23
|
+
* - allOf flattening (inheritance merge)
|
|
24
|
+
* - oneOf + discriminator → discriminator + discriminatorValue
|
|
25
|
+
* - Entity detection : top-level (title+x-mostajs-entity) + all $defs
|
|
26
|
+
* - Extensions : x-mostajs-entity, x-mostajs-relation, x-primary, x-unique, x-index, x-indexes
|
|
27
|
+
* - $ref resolution (cycles detected, self-relation auto-created)
|
|
28
|
+
*
|
|
29
|
+
* Not yet supported (v0.4+):
|
|
30
|
+
* - $dynamicRef / $dynamicAnchor late-binding
|
|
31
|
+
* - patternProperties as structured mapping (falls back to json)
|
|
32
|
+
* - if/then/else conditional
|
|
33
|
+
* - External $ref resolution (HTTP/file beyond basic dereference)
|
|
34
|
+
*/
|
|
35
|
+
export class JsonSchemaAdapter extends AbstractAdapter {
|
|
36
|
+
name = 'jsonschema';
|
|
37
|
+
vendor = 'json-schema.org';
|
|
38
|
+
version = '0.3.0';
|
|
39
|
+
canParse(input) {
|
|
40
|
+
const obj = this.tryParseJson(input);
|
|
41
|
+
if (!obj || typeof obj !== 'object')
|
|
42
|
+
return false;
|
|
43
|
+
// Strongest indicator : $schema URL
|
|
44
|
+
if (typeof obj.$schema === 'string' &&
|
|
45
|
+
/json-schema\.org/.test(obj.$schema)) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
// Fallback : has type + properties (or $defs / definitions)
|
|
49
|
+
const o = obj;
|
|
50
|
+
if ((o.type === 'object' || Array.isArray(o.type)) &&
|
|
51
|
+
(!!o.properties || !!o.$defs || !!o.definitions)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// OpenAPI components/schemas shape — let OpenApiAdapter handle first
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
async toEntitySchema(input, opts) {
|
|
58
|
+
const raw = this.tryParseJson(input);
|
|
59
|
+
if (!raw || typeof raw !== 'object') {
|
|
60
|
+
throw new InvalidSchemaError('JsonSchemaAdapter expects an object or JSON string');
|
|
61
|
+
}
|
|
62
|
+
let resolved;
|
|
63
|
+
try {
|
|
64
|
+
// Dereference : resolves all $ref into inline schemas.
|
|
65
|
+
// We clone to avoid mutating caller's input.
|
|
66
|
+
resolved = await $RefParser.dereference(JSON.parse(JSON.stringify(raw)));
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
throw new InvalidSchemaError(`Failed to dereference JSON Schema: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
70
|
+
}
|
|
71
|
+
const draft = detectDraft(resolved);
|
|
72
|
+
if (draft === 'draft-04' || draft === 'draft-06') {
|
|
73
|
+
this.warn(opts, {
|
|
74
|
+
code: WarningCode.PREVIEW_FEATURE,
|
|
75
|
+
message: `Legacy draft ${draft} — mapping may be incomplete. Recommend upgrading to Draft 2020-12.`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Collect entity candidates : root schema + all $defs/definitions
|
|
79
|
+
const candidates = this.collectEntities(resolved, opts);
|
|
80
|
+
// Convert each candidate
|
|
81
|
+
const seen = new Set(); // for cycle detection
|
|
82
|
+
const entities = candidates.map(c => this.convertEntity(c, candidates, seen, opts));
|
|
83
|
+
return entities;
|
|
84
|
+
}
|
|
85
|
+
// ============================================================
|
|
86
|
+
// Entity collection
|
|
87
|
+
// ============================================================
|
|
88
|
+
collectEntities(root, opts) {
|
|
89
|
+
const out = [];
|
|
90
|
+
// 1. Root if it's an object with title OR x-mostajs-entity
|
|
91
|
+
const rootIsObject = primaryType(root) === 'object';
|
|
92
|
+
const rootName = root.title ?? this.nameFromId(root.$id);
|
|
93
|
+
const rootHasEntityMarker = !!root['x-mostajs-entity'];
|
|
94
|
+
if (rootIsObject && (rootHasEntityMarker || rootName)) {
|
|
95
|
+
out.push({ name: rootName ?? 'RootEntity', schema: root });
|
|
96
|
+
}
|
|
97
|
+
// 2. All $defs / definitions that are objects
|
|
98
|
+
const defs = getDefinitions(root);
|
|
99
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
100
|
+
if (primaryType(def) === 'object') {
|
|
101
|
+
out.push({ name: def.title ?? key, schema: def });
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.warn(opts, {
|
|
105
|
+
code: WarningCode.FALLBACK_APPLIED,
|
|
106
|
+
message: `$defs["${key}"] is not an object — ignored as entity candidate`,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Deduplicate by name (last-wins)
|
|
111
|
+
const byName = new Map();
|
|
112
|
+
for (const c of out)
|
|
113
|
+
byName.set(this.pascalCase(c.name), c);
|
|
114
|
+
return Array.from(byName.values()).map(c => ({ ...c, name: this.pascalCase(c.name) }));
|
|
115
|
+
}
|
|
116
|
+
nameFromId(id) {
|
|
117
|
+
if (!id)
|
|
118
|
+
return undefined;
|
|
119
|
+
const segments = id.replace(/\.json$/, '').split(/[/#]/);
|
|
120
|
+
return segments[segments.length - 1] || undefined;
|
|
121
|
+
}
|
|
122
|
+
// ============================================================
|
|
123
|
+
// Candidate → EntitySchema
|
|
124
|
+
// ============================================================
|
|
125
|
+
convertEntity(candidate, allCandidates, seen, opts) {
|
|
126
|
+
const name = candidate.name;
|
|
127
|
+
if (seen.has(name)) {
|
|
128
|
+
this.warn(opts, {
|
|
129
|
+
code: WarningCode.CYCLIC_REFERENCE,
|
|
130
|
+
message: `Cyclic entity reference detected at "${name}"`,
|
|
131
|
+
entity: name,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
seen.add(name);
|
|
135
|
+
// Flatten allOf composition
|
|
136
|
+
const schema = flattenAllOf(candidate.schema, w => this.warn(opts, w), name);
|
|
137
|
+
// Extract x-mostajs-entity metadata
|
|
138
|
+
const entityMeta = schema['x-mostajs-entity'] ?? {};
|
|
139
|
+
const tableName = entityMeta.tableName ?? this.snakeCase(name);
|
|
140
|
+
const entity = {
|
|
141
|
+
name,
|
|
142
|
+
collection: tableName,
|
|
143
|
+
fields: {},
|
|
144
|
+
relations: {},
|
|
145
|
+
indexes: [],
|
|
146
|
+
timestamps: entityMeta.timestamps ?? false,
|
|
147
|
+
};
|
|
148
|
+
if (entityMeta.softDelete)
|
|
149
|
+
entity.softDelete = true;
|
|
150
|
+
if (entityMeta.discriminator)
|
|
151
|
+
entity.discriminator = entityMeta.discriminator;
|
|
152
|
+
if (entityMeta.discriminatorValue)
|
|
153
|
+
entity.discriminatorValue = entityMeta.discriminatorValue;
|
|
154
|
+
// Also detect discriminator from OpenAPI-style discriminator property
|
|
155
|
+
if (!entity.discriminator) {
|
|
156
|
+
const d = detectDiscriminator(schema);
|
|
157
|
+
if (d)
|
|
158
|
+
entity.discriminator = d.propertyName;
|
|
159
|
+
}
|
|
160
|
+
// Process properties
|
|
161
|
+
const required = new Set(schema.required ?? []);
|
|
162
|
+
const entityNames = new Set(allCandidates.map(c => c.name));
|
|
163
|
+
for (const [key, propSchema] of Object.entries(schema.properties ?? {})) {
|
|
164
|
+
this.processProperty(key, propSchema, entity, required.has(key), entityNames, opts);
|
|
165
|
+
}
|
|
166
|
+
// Process x-indexes (model-level composite indexes)
|
|
167
|
+
const xIndexes = schema['x-indexes'];
|
|
168
|
+
if (Array.isArray(xIndexes)) {
|
|
169
|
+
for (const idx of xIndexes) {
|
|
170
|
+
const fields = {};
|
|
171
|
+
for (const f of idx.fields)
|
|
172
|
+
fields[f] = 'asc';
|
|
173
|
+
entity.indexes.push({ fields, unique: !!idx.unique });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Auto-timestamps detection
|
|
177
|
+
if (!entity.timestamps &&
|
|
178
|
+
'createdAt' in entity.fields && 'updatedAt' in entity.fields) {
|
|
179
|
+
entity.timestamps = true;
|
|
180
|
+
}
|
|
181
|
+
return entity;
|
|
182
|
+
}
|
|
183
|
+
// ============================================================
|
|
184
|
+
// Property → Field or Relation
|
|
185
|
+
// ============================================================
|
|
186
|
+
processProperty(key, propSchema, entity, required, entityNames, opts) {
|
|
187
|
+
// 1. Explicit x-mostajs-relation always wins
|
|
188
|
+
const xRel = propSchema['x-mostajs-relation'];
|
|
189
|
+
if (xRel) {
|
|
190
|
+
entity.relations[key] = this.mapXMostajsRelation(xRel, required);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
// 2. Detection by shape : object with title matching an entity = belongsTo
|
|
194
|
+
if (primaryType(propSchema) === 'object' && propSchema.title &&
|
|
195
|
+
entityNames.has(this.pascalCase(propSchema.title))) {
|
|
196
|
+
entity.relations[key] = {
|
|
197
|
+
target: this.pascalCase(propSchema.title),
|
|
198
|
+
type: 'many-to-one',
|
|
199
|
+
required: required && !isNullable(propSchema),
|
|
200
|
+
nullable: isNullable(propSchema),
|
|
201
|
+
};
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// 3. Array of entities = hasMany
|
|
205
|
+
if (primaryType(propSchema) === 'array' && !Array.isArray(propSchema.items)) {
|
|
206
|
+
const item = propSchema.items;
|
|
207
|
+
if (item && primaryType(item) === 'object' && item.title &&
|
|
208
|
+
entityNames.has(this.pascalCase(item.title))) {
|
|
209
|
+
entity.relations[key] = {
|
|
210
|
+
target: this.pascalCase(item.title),
|
|
211
|
+
type: 'one-to-many',
|
|
212
|
+
};
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// 4. Regular field
|
|
217
|
+
const field = this.toFieldDef(key, propSchema, required, entity.name, opts);
|
|
218
|
+
if (field) {
|
|
219
|
+
entity.fields[key] = field;
|
|
220
|
+
this.applyFieldIndexes(key, propSchema, entity);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
mapXMostajsRelation(xRel, required) {
|
|
224
|
+
const typeMap = {
|
|
225
|
+
belongsTo: 'many-to-one',
|
|
226
|
+
hasOne: 'one-to-one',
|
|
227
|
+
hasMany: 'one-to-many',
|
|
228
|
+
belongsToMany: 'many-to-many',
|
|
229
|
+
};
|
|
230
|
+
const rel = {
|
|
231
|
+
target: xRel.target,
|
|
232
|
+
type: typeMap[xRel.type],
|
|
233
|
+
};
|
|
234
|
+
if (xRel.required ?? required)
|
|
235
|
+
rel.required = true;
|
|
236
|
+
if (xRel.nullable)
|
|
237
|
+
rel.nullable = true;
|
|
238
|
+
if (xRel.foreignKey)
|
|
239
|
+
rel.joinColumn = xRel.foreignKey;
|
|
240
|
+
if (xRel.otherKey)
|
|
241
|
+
rel.inverseJoinColumn = xRel.otherKey;
|
|
242
|
+
if (xRel.through)
|
|
243
|
+
rel.through = xRel.through;
|
|
244
|
+
if (xRel.onDelete)
|
|
245
|
+
rel.onDelete = xRel.onDelete;
|
|
246
|
+
return rel;
|
|
247
|
+
}
|
|
248
|
+
toFieldDef(key, schema, required, entityName, opts) {
|
|
249
|
+
const type = mapJsonSchemaType(schema, key, entityName, w => this.warn(opts, w));
|
|
250
|
+
if (!type) {
|
|
251
|
+
this.warn(opts, {
|
|
252
|
+
code: WarningCode.UNSUPPORTED_FEATURE,
|
|
253
|
+
message: `Cannot map property "${key}" — no type information`,
|
|
254
|
+
entity: entityName,
|
|
255
|
+
field: key,
|
|
256
|
+
});
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const nullable = isNullable(schema);
|
|
260
|
+
const fd = {
|
|
261
|
+
type,
|
|
262
|
+
required: required && !nullable,
|
|
263
|
+
};
|
|
264
|
+
// Array : resolve arrayOf
|
|
265
|
+
if (type === 'array') {
|
|
266
|
+
const inner = mapArrayItems(schema, key, entityName, w => this.warn(opts, w));
|
|
267
|
+
if (inner)
|
|
268
|
+
fd.arrayOf = inner;
|
|
269
|
+
}
|
|
270
|
+
// Enum
|
|
271
|
+
if (schema.enum?.length) {
|
|
272
|
+
fd.enum = schema.enum.filter(v => v != null).map(String);
|
|
273
|
+
}
|
|
274
|
+
// Default
|
|
275
|
+
if (schema.default !== undefined) {
|
|
276
|
+
fd.default = schema.default;
|
|
277
|
+
}
|
|
278
|
+
else if (schema.const !== undefined) {
|
|
279
|
+
fd.default = schema.const;
|
|
280
|
+
}
|
|
281
|
+
// x-primary / x-unique
|
|
282
|
+
if (schema['x-unique'] === true)
|
|
283
|
+
fd.unique = true;
|
|
284
|
+
return fd;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Generate indexes from x-index and x-unique on individual fields.
|
|
288
|
+
*/
|
|
289
|
+
applyFieldIndexes(key, schema, entity) {
|
|
290
|
+
const xIndex = schema['x-index'];
|
|
291
|
+
const xUnique = schema['x-unique'] === true;
|
|
292
|
+
if (xIndex === true) {
|
|
293
|
+
entity.indexes.push({ fields: { [key]: 'asc' } });
|
|
294
|
+
}
|
|
295
|
+
else if (xIndex && typeof xIndex === 'object') {
|
|
296
|
+
entity.indexes.push({
|
|
297
|
+
fields: { [key]: 'asc' },
|
|
298
|
+
unique: !!xIndex.unique,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
else if (xUnique) {
|
|
302
|
+
entity.indexes.push({ fields: { [key]: 'asc' }, unique: true });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// ============================================================
|
|
306
|
+
// Utilities
|
|
307
|
+
// ============================================================
|
|
308
|
+
tryParseJson(input) {
|
|
309
|
+
if (typeof input !== 'string')
|
|
310
|
+
return input;
|
|
311
|
+
try {
|
|
312
|
+
return JSON.parse(input);
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=jsonschema.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema.adapter.js","sourceRoot":"","sources":["../../src/adapters/jsonschema.adapter.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,uEAAuE;AACvE,gDAAgD;AAChD,wCAAwC;AACxC,6BAA6B;AAE7B,OAAO,UAAU,MAAM,qCAAqC,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAA4C,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAIL,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAOnF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IAC3C,IAAI,GAAG,YAAY,CAAC;IACpB,MAAM,GAAG,iBAAiB,CAAC;IAC3B,OAAO,GAAG,OAAO,CAAC;IAE3B,QAAQ,CAAC,KAAsB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAElD,oCAAoC;QACpC,IAAI,OAAQ,GAAkB,CAAC,OAAO,KAAK,QAAQ;YAC/C,kBAAkB,CAAC,IAAI,CAAE,GAAkB,CAAC,OAAQ,CAAC,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,4DAA4D;QAC5D,MAAM,CAAC,GAAG,GAAiB,CAAC;QAC5B,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,qEAAqE;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAsB,EAAE,IAAqB;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,IAAI,kBAAkB,CAAC,oDAAoD,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,QAAoB,CAAC;QACzB,IAAI,CAAC;YACH,uDAAuD;YACvD,6CAA6C;YAC7C,QAAQ,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAe,CAAC;QACzF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,kBAAkB,CAC1B,sCAAsC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAClF,EAAE,KAAK,EAAE,CAAC,EAAE,CACb,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACd,IAAI,EAAE,WAAW,CAAC,eAAe;gBACjC,OAAO,EAAE,gBAAgB,KAAK,qEAAqE;aACpG,CAAC,CAAC;QACL,CAAC;QAED,kEAAkE;QAClE,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAExD,yBAAyB;QACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC,CAAE,sBAAsB;QACvD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAEpF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,+DAA+D;IAC/D,oBAAoB;IACpB,+DAA+D;IAEvD,eAAe,CAAC,IAAgB,EAAE,IAAgC;QACxE,MAAM,GAAG,GAAsB,EAAE,CAAC;QAElC,2DAA2D;QAC3D,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzD,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAEvD,IAAI,YAAY,IAAI,CAAC,mBAAmB,IAAI,QAAQ,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,8CAA8C;QAC9C,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAClC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBACd,IAAI,EAAE,WAAW,CAAC,gBAAgB;oBAClC,OAAO,EAAE,UAAU,GAAG,mDAAmD;iBAC1E,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,GAAG;YAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACzF,CAAC;IAEO,UAAU,CAAC,EAAsB;QACvC,IAAI,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QAC1B,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzD,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;IACpD,CAAC;IAED,+DAA+D;IAC/D,2BAA2B;IAC3B,+DAA+D;IAEvD,aAAa,CACnB,SAA0B,EAC1B,aAAgC,EAChC,IAAiB,EACjB,IAAgC;QAEhC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACd,IAAI,EAAE,WAAW,CAAC,gBAAgB;gBAClC,OAAO,EAAE,wCAAwC,IAAI,GAAG;gBACxD,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEf,4BAA4B;QAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAE7E,oCAAoC;QACpC,MAAM,UAAU,GAAG,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAiB;YAC3B,IAAI;YACJ,UAAU,EAAE,SAAS;YACrB,MAAM,EAAE,EAAE;YACV,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,KAAK;SAC3C,CAAC;QAEF,IAAI,UAAU,CAAC,UAAU;YAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QACpD,IAAI,UAAU,CAAC,aAAa;YAAE,MAAM,CAAC,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC;QAC9E,IAAI,UAAU,CAAC,kBAAkB;YAAE,MAAM,CAAC,kBAAkB,GAAG,UAAU,CAAC,kBAAkB,CAAC;QAE7F,sEAAsE;QACtE,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,CAAC;gBAAE,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC,YAAY,CAAC;QAC/C,CAAC;QAED,qBAAqB;QACrB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QACtF,CAAC;QAED,oDAAoD;QACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAA8B,EAAE,CAAC;gBAC7C,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM;oBAAE,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;gBAC9C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC,MAAM,CAAC,UAAU;YAClB,WAAW,IAAI,MAAM,CAAC,MAAM,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACjE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC3B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+DAA+D;IAC/D,+BAA+B;IAC/B,+DAA+D;IAEvD,eAAe,CACrB,GAAW,EACX,UAAsB,EACtB,MAAoB,EACpB,QAAiB,EACjB,WAAwB,EACxB,IAAgC;QAEhC,6CAA6C;QAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;QAC9C,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,2EAA2E;QAC3E,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,UAAU,CAAC,KAAK;YACxD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG;gBACtB,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;gBACzC,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,QAAQ,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;gBAC7C,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC;aACjC,CAAC;YACF,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5E,MAAM,IAAI,GAAG,UAAU,CAAC,KAA+B,CAAC;YACxD,IAAI,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK;gBACpD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG;oBACtB,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;oBACnC,IAAI,EAAE,aAAa;iBACpB,CAAC;gBACF,OAAO;YACT,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5E,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,IAAsB,EAAE,QAAiB;QACnE,MAAM,OAAO,GAAmD;YAC9D,SAAS,EAAM,aAAa;YAC5B,MAAM,EAAS,YAAY;YAC3B,OAAO,EAAQ,aAAa;YAC5B,aAAa,EAAE,cAAc;SAC9B,CAAC;QACF,MAAM,GAAG,GAAgB;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;SACzB,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,IAAI,QAAQ;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC;QACnD,IAAI,IAAI,CAAC,QAAQ;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU;YAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACtD,IAAI,IAAI,CAAC,QAAQ;YAAE,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzD,IAAI,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7C,IAAI,IAAI,CAAC,QAAQ;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAChD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,UAAU,CAChB,GAAW,EACX,MAAkB,EAClB,QAAiB,EACjB,UAAkB,EAClB,IAAgC;QAEhC,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACd,IAAI,EAAE,WAAW,CAAC,mBAAmB;gBACrC,OAAO,EAAE,wBAAwB,GAAG,yBAAyB;gBAC7D,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,EAAE,GAAa;YACnB,IAAI;YACJ,QAAQ,EAAE,QAAQ,IAAI,CAAC,QAAQ;SAChC,CAAC;QAEF,0BAA0B;QAC1B,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9E,IAAI,KAAK;gBAAE,EAAE,CAAC,OAAO,GAAG,KAAK,CAAC;QAChC,CAAC;QAED,OAAO;QACP,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YACxB,EAAE,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC;QAED,UAAU;QACV,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,EAAE,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACtC,EAAE,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;QAC5B,CAAC;QAED,uBAAuB;QACvB,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI;YAAE,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC;QAElD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACK,iBAAiB,CACvB,GAAW,EACX,MAAkB,EAClB,MAAoB;QAEpB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;QAE5C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;gBAClB,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE;gBACxB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM;aACxB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,YAAY;IACZ,+DAA+D;IAEvD,YAAY,CAAC,KAAc;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,9 @@ export { AdapterRegistry } from './core/registry.js';
|
|
|
5
5
|
export { AdapterError, NoAdapterFoundError, InvalidSchemaError, StrictWarningError, } from './core/errors.js';
|
|
6
6
|
export { NativeAdapter } from './adapters/native.adapter.js';
|
|
7
7
|
export { PrismaAdapter } from './adapters/prisma.adapter.js';
|
|
8
|
+
export { JsonSchemaAdapter } from './adapters/jsonschema.adapter.js';
|
|
8
9
|
export { DefaultSentinel } from './utils/prisma-default-mapper.js';
|
|
10
|
+
export type { JsonSchema, JsonSchemaType, XMostajsEntity, XMostajsRelation, DraftVersion, } from './utils/jsonschema-types.js';
|
|
9
11
|
import { AdapterRegistry } from './core/registry.js';
|
|
10
12
|
/**
|
|
11
13
|
* Create a registry with all standard adapters pre-registered.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,YAAY,EACV,QAAQ,EACR,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,YAAY,EACV,QAAQ,EACR,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGnE,YAAY,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,YAAY,GACb,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAOvD"}
|
package/dist/index.js
CHANGED
|
@@ -9,12 +9,14 @@ export { AdapterError, NoAdapterFoundError, InvalidSchemaError, StrictWarningErr
|
|
|
9
9
|
// --- Concrete adapters ---
|
|
10
10
|
export { NativeAdapter } from './adapters/native.adapter.js';
|
|
11
11
|
export { PrismaAdapter } from './adapters/prisma.adapter.js';
|
|
12
|
+
export { JsonSchemaAdapter } from './adapters/jsonschema.adapter.js';
|
|
12
13
|
// --- Default-value sentinels (Prisma @default semantics) ---
|
|
13
14
|
export { DefaultSentinel } from './utils/prisma-default-mapper.js';
|
|
14
15
|
// --- Convenience factory ---
|
|
15
16
|
import { AdapterRegistry } from './core/registry.js';
|
|
16
17
|
import { NativeAdapter } from './adapters/native.adapter.js';
|
|
17
18
|
import { PrismaAdapter } from './adapters/prisma.adapter.js';
|
|
19
|
+
import { JsonSchemaAdapter } from './adapters/jsonschema.adapter.js';
|
|
18
20
|
/**
|
|
19
21
|
* Create a registry with all standard adapters pre-registered.
|
|
20
22
|
* Detection order (first registered = last priority) :
|
|
@@ -26,7 +28,8 @@ export function createDefaultRegistry() {
|
|
|
26
28
|
const registry = new AdapterRegistry();
|
|
27
29
|
registry.register(new NativeAdapter());
|
|
28
30
|
registry.register(new PrismaAdapter());
|
|
29
|
-
|
|
31
|
+
registry.register(new JsonSchemaAdapter());
|
|
32
|
+
// TODO: register OpenApiAdapter when ready
|
|
30
33
|
return registry;
|
|
31
34
|
}
|
|
32
35
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,+CAA+C;AAC/C,wCAAwC;AACxC,6BAA6B;AAW7B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,4BAA4B;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,+CAA+C;AAC/C,wCAAwC;AACxC,6BAA6B;AAW7B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,4BAA4B;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAWnE,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC3C,2CAA2C;IAC3C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { JsonSchema } from './jsonschema-types.js';
|
|
2
|
+
import { type AdapterWarning } from '../core/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Flatten allOf composition recursively.
|
|
5
|
+
* Merges all properties, requireds, indexes from allOf members into a single schema.
|
|
6
|
+
* Later entries overwrite earlier (last-wins on conflicts).
|
|
7
|
+
*/
|
|
8
|
+
export declare function flattenAllOf(schema: JsonSchema, emitWarning: (w: AdapterWarning) => void, entityName?: string): JsonSchema;
|
|
9
|
+
/**
|
|
10
|
+
* Detect oneOf with discriminator and return the discriminator mapping.
|
|
11
|
+
* Used to build polymorphism (EntitySchema.discriminator + discriminatorValue).
|
|
12
|
+
*/
|
|
13
|
+
export declare function detectDiscriminator(schema: JsonSchema): {
|
|
14
|
+
propertyName: string;
|
|
15
|
+
mapping?: Record<string, string>;
|
|
16
|
+
} | null;
|
|
17
|
+
//# sourceMappingURL=jsonschema-flatten.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema-flatten.d.ts","sourceRoot":"","sources":["../../src/utils/jsonschema-flatten.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,EACxC,UAAU,CAAC,EAAE,MAAM,GAClB,UAAU,CA6CZ;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,GACjB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAKnE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// jsonschema-flatten.ts
|
|
2
|
+
// Flattens allOf composition, merging parent properties into the target schema.
|
|
3
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
|
+
// License: AGPL-3.0-or-later
|
|
5
|
+
import { WarningCode } from '../core/types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Flatten allOf composition recursively.
|
|
8
|
+
* Merges all properties, requireds, indexes from allOf members into a single schema.
|
|
9
|
+
* Later entries overwrite earlier (last-wins on conflicts).
|
|
10
|
+
*/
|
|
11
|
+
export function flattenAllOf(schema, emitWarning, entityName) {
|
|
12
|
+
if (!schema.allOf || schema.allOf.length === 0)
|
|
13
|
+
return schema;
|
|
14
|
+
const merged = {
|
|
15
|
+
...schema,
|
|
16
|
+
properties: { ...(schema.properties ?? {}) },
|
|
17
|
+
required: [...(schema.required ?? [])],
|
|
18
|
+
};
|
|
19
|
+
for (const sub of schema.allOf) {
|
|
20
|
+
const subFlat = flattenAllOf(sub, emitWarning, entityName);
|
|
21
|
+
// Merge properties
|
|
22
|
+
if (subFlat.properties) {
|
|
23
|
+
for (const [key, val] of Object.entries(subFlat.properties)) {
|
|
24
|
+
if (merged.properties && key in merged.properties && entityName) {
|
|
25
|
+
emitWarning({
|
|
26
|
+
code: WarningCode.AMBIGUOUS_MAPPING,
|
|
27
|
+
message: `Property "${key}" redefined in allOf; last-wins`,
|
|
28
|
+
entity: entityName,
|
|
29
|
+
field: key,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (!merged.properties)
|
|
33
|
+
merged.properties = {};
|
|
34
|
+
merged.properties[key] = val;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Merge required
|
|
38
|
+
if (subFlat.required) {
|
|
39
|
+
merged.required = Array.from(new Set([...(merged.required ?? []), ...subFlat.required]));
|
|
40
|
+
}
|
|
41
|
+
// Inherit type from first allOf entry if parent doesn't have one
|
|
42
|
+
if (!merged.type && subFlat.type)
|
|
43
|
+
merged.type = subFlat.type;
|
|
44
|
+
// Merge x-mostajs-entity metadata (parent wins)
|
|
45
|
+
if (subFlat['x-mostajs-entity'] && !merged['x-mostajs-entity']) {
|
|
46
|
+
merged['x-mostajs-entity'] = subFlat['x-mostajs-entity'];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Remove the allOf after merging
|
|
50
|
+
delete merged.allOf;
|
|
51
|
+
return merged;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Detect oneOf with discriminator and return the discriminator mapping.
|
|
55
|
+
* Used to build polymorphism (EntitySchema.discriminator + discriminatorValue).
|
|
56
|
+
*/
|
|
57
|
+
export function detectDiscriminator(schema) {
|
|
58
|
+
if (schema.discriminator && schema.discriminator.propertyName) {
|
|
59
|
+
return schema.discriminator;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=jsonschema-flatten.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema-flatten.js","sourceRoot":"","sources":["../../src/utils/jsonschema-flatten.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,gFAAgF;AAChF,wCAAwC;AACxC,6BAA6B;AAG7B,OAAO,EAAE,WAAW,EAAuB,MAAM,kBAAkB,CAAC;AAEpE;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAkB,EAClB,WAAwC,EACxC,UAAmB;IAEnB,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAE9D,MAAM,MAAM,GAAe;QACzB,GAAG,MAAM;QACT,UAAU,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE;QAC5C,QAAQ,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;KACvC,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAE3D,mBAAmB;QACnB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5D,IAAI,MAAM,CAAC,UAAU,IAAI,GAAG,IAAI,MAAM,CAAC,UAAU,IAAI,UAAU,EAAE,CAAC;oBAChE,WAAW,CAAC;wBACV,IAAI,EAAE,WAAW,CAAC,iBAAiB;wBACnC,OAAO,EAAE,aAAa,GAAG,iCAAiC;wBAC1D,MAAM,EAAE,UAAU;wBAClB,KAAK,EAAE,GAAG;qBACX,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,UAAU;oBAAE,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;gBAC/C,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC3F,CAAC;QAED,iEAAiE;QACjE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAE7D,gDAAgD;QAChD,IAAI,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC/D,MAAM,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,OAAO,MAAM,CAAC,KAAK,CAAC;IACpB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAkB;IAElB,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QAC9D,OAAO,MAAM,CAAC,aAAa,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FieldType } from '@mostajs/orm';
|
|
2
|
+
import type { JsonSchema } from './jsonschema-types.js';
|
|
3
|
+
import { type AdapterWarning } from '../core/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Map a JSON Schema value to a FieldType.
|
|
6
|
+
* Returns null if the schema is not a leaf scalar (e.g., object, array, $ref unresolved).
|
|
7
|
+
*/
|
|
8
|
+
export declare function mapJsonSchemaType(schema: JsonSchema, fieldName: string, entityName: string, emitWarning: (w: AdapterWarning) => void): FieldType | null;
|
|
9
|
+
/** Resolve arrayOf from items (single schema only — tuple not supported in EntitySchema) */
|
|
10
|
+
export declare function mapArrayItems(schema: JsonSchema, fieldName: string, entityName: string, emitWarning: (w: AdapterWarning) => void): FieldType | null;
|
|
11
|
+
//# sourceMappingURL=jsonschema-type-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema-type-mapper.d.ts","sourceRoot":"","sources":["../../src/utils/jsonschema-type-mapper.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,GACvC,SAAS,GAAG,IAAI,CA0ClB;AAgDD,4FAA4F;AAC5F,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,GACvC,SAAS,GAAG,IAAI,CAqBlB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// jsonschema-type-mapper.ts
|
|
2
|
+
// Maps JSON Schema types + formats to @mostajs/orm FieldType.
|
|
3
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
|
+
// License: AGPL-3.0-or-later
|
|
5
|
+
import { primaryType } from './jsonschema-types.js';
|
|
6
|
+
import { WarningCode } from '../core/types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Map a JSON Schema value to a FieldType.
|
|
9
|
+
* Returns null if the schema is not a leaf scalar (e.g., object, array, $ref unresolved).
|
|
10
|
+
*/
|
|
11
|
+
export function mapJsonSchemaType(schema, fieldName, entityName, emitWarning) {
|
|
12
|
+
const t = primaryType(schema);
|
|
13
|
+
switch (t) {
|
|
14
|
+
case 'string':
|
|
15
|
+
return mapStringFormat(schema, fieldName, entityName, emitWarning);
|
|
16
|
+
case 'integer':
|
|
17
|
+
case 'number':
|
|
18
|
+
if (schema.format === 'int64' || schema.format === 'int32') {
|
|
19
|
+
// No precision distinction in EntitySchema — warn for int64
|
|
20
|
+
if (schema.format === 'int64') {
|
|
21
|
+
emitWarning({
|
|
22
|
+
code: WarningCode.LOSSY_CONVERSION,
|
|
23
|
+
message: `int64 format on "${fieldName}" mapped to number; precision loss > 2^53`,
|
|
24
|
+
entity: entityName,
|
|
25
|
+
field: fieldName,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return 'number';
|
|
30
|
+
case 'boolean':
|
|
31
|
+
return 'boolean';
|
|
32
|
+
case 'array':
|
|
33
|
+
// Caller must handle with arrayOf
|
|
34
|
+
return 'array';
|
|
35
|
+
case 'object':
|
|
36
|
+
// Object → json column (unless it's an entity to be detected separately)
|
|
37
|
+
return 'json';
|
|
38
|
+
case 'null':
|
|
39
|
+
return null;
|
|
40
|
+
default:
|
|
41
|
+
// No type info — default to string
|
|
42
|
+
if (schema.enum?.length)
|
|
43
|
+
return 'string';
|
|
44
|
+
if (schema.const !== undefined)
|
|
45
|
+
return mapConstType(schema.const);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Map string + format to FieldType */
|
|
50
|
+
function mapStringFormat(schema, fieldName, entityName, emitWarning) {
|
|
51
|
+
switch (schema.format) {
|
|
52
|
+
case 'date-time':
|
|
53
|
+
case 'date':
|
|
54
|
+
case 'time':
|
|
55
|
+
return 'date';
|
|
56
|
+
case 'binary':
|
|
57
|
+
case 'byte':
|
|
58
|
+
emitWarning({
|
|
59
|
+
code: WarningCode.LOSSY_CONVERSION,
|
|
60
|
+
message: `binary/byte format on "${fieldName}" mapped to string (base64); blob handling is application's responsibility`,
|
|
61
|
+
entity: entityName,
|
|
62
|
+
field: fieldName,
|
|
63
|
+
});
|
|
64
|
+
return 'string';
|
|
65
|
+
// text-heavy formats → text
|
|
66
|
+
case 'uri':
|
|
67
|
+
case 'iri':
|
|
68
|
+
case 'uri-reference':
|
|
69
|
+
case 'iri-reference':
|
|
70
|
+
return 'string';
|
|
71
|
+
// All other formats (email, uuid, ipv4, regex, hostname, etc.) → string
|
|
72
|
+
default:
|
|
73
|
+
return 'string';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Infer type from a const value */
|
|
77
|
+
function mapConstType(value) {
|
|
78
|
+
if (typeof value === 'string')
|
|
79
|
+
return 'string';
|
|
80
|
+
if (typeof value === 'number')
|
|
81
|
+
return 'number';
|
|
82
|
+
if (typeof value === 'boolean')
|
|
83
|
+
return 'boolean';
|
|
84
|
+
if (Array.isArray(value))
|
|
85
|
+
return 'array';
|
|
86
|
+
if (value && typeof value === 'object')
|
|
87
|
+
return 'json';
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/** Resolve arrayOf from items (single schema only — tuple not supported in EntitySchema) */
|
|
91
|
+
export function mapArrayItems(schema, fieldName, entityName, emitWarning) {
|
|
92
|
+
let items = schema.items;
|
|
93
|
+
if (Array.isArray(items)) {
|
|
94
|
+
emitWarning({
|
|
95
|
+
code: WarningCode.LOSSY_CONVERSION,
|
|
96
|
+
message: `Tuple "items" (array form) on "${fieldName}" not supported; using first item type`,
|
|
97
|
+
entity: entityName,
|
|
98
|
+
field: fieldName,
|
|
99
|
+
});
|
|
100
|
+
items = items[0];
|
|
101
|
+
}
|
|
102
|
+
if (!items) {
|
|
103
|
+
emitWarning({
|
|
104
|
+
code: WarningCode.MISSING_METADATA,
|
|
105
|
+
message: `Array "${fieldName}" has no items definition`,
|
|
106
|
+
entity: entityName,
|
|
107
|
+
field: fieldName,
|
|
108
|
+
});
|
|
109
|
+
return 'string'; // fallback
|
|
110
|
+
}
|
|
111
|
+
return mapJsonSchemaType(items, fieldName, entityName, emitWarning);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=jsonschema-type-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema-type-mapper.js","sourceRoot":"","sources":["../../src/utils/jsonschema-type-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export type JsonSchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null';
|
|
2
|
+
export interface JsonSchemaFormat {
|
|
3
|
+
format?: string;
|
|
4
|
+
}
|
|
5
|
+
/** A JSON Schema object (union of all common keywords across drafts) */
|
|
6
|
+
export interface JsonSchema extends JsonSchemaFormat {
|
|
7
|
+
$schema?: string;
|
|
8
|
+
$id?: string;
|
|
9
|
+
$ref?: string;
|
|
10
|
+
$defs?: Record<string, JsonSchema>;
|
|
11
|
+
definitions?: Record<string, JsonSchema>;
|
|
12
|
+
$anchor?: string;
|
|
13
|
+
type?: JsonSchemaType | JsonSchemaType[];
|
|
14
|
+
const?: unknown;
|
|
15
|
+
enum?: unknown[];
|
|
16
|
+
default?: unknown;
|
|
17
|
+
minLength?: number;
|
|
18
|
+
maxLength?: number;
|
|
19
|
+
pattern?: string;
|
|
20
|
+
minimum?: number;
|
|
21
|
+
maximum?: number;
|
|
22
|
+
exclusiveMinimum?: number | boolean;
|
|
23
|
+
exclusiveMaximum?: number | boolean;
|
|
24
|
+
multipleOf?: number;
|
|
25
|
+
properties?: Record<string, JsonSchema>;
|
|
26
|
+
patternProperties?: Record<string, JsonSchema>;
|
|
27
|
+
additionalProperties?: boolean | JsonSchema;
|
|
28
|
+
required?: string[];
|
|
29
|
+
minProperties?: number;
|
|
30
|
+
maxProperties?: number;
|
|
31
|
+
items?: JsonSchema | JsonSchema[];
|
|
32
|
+
prefixItems?: JsonSchema[];
|
|
33
|
+
minItems?: number;
|
|
34
|
+
maxItems?: number;
|
|
35
|
+
uniqueItems?: boolean;
|
|
36
|
+
allOf?: JsonSchema[];
|
|
37
|
+
anyOf?: JsonSchema[];
|
|
38
|
+
oneOf?: JsonSchema[];
|
|
39
|
+
not?: JsonSchema;
|
|
40
|
+
if?: JsonSchema;
|
|
41
|
+
then?: JsonSchema;
|
|
42
|
+
else?: JsonSchema;
|
|
43
|
+
title?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
examples?: unknown[];
|
|
46
|
+
deprecated?: boolean;
|
|
47
|
+
readOnly?: boolean;
|
|
48
|
+
writeOnly?: boolean;
|
|
49
|
+
nullable?: boolean;
|
|
50
|
+
discriminator?: {
|
|
51
|
+
propertyName: string;
|
|
52
|
+
mapping?: Record<string, string>;
|
|
53
|
+
};
|
|
54
|
+
'x-mostajs-entity'?: XMostajsEntity;
|
|
55
|
+
'x-mostajs-relation'?: XMostajsRelation;
|
|
56
|
+
'x-primary'?: boolean;
|
|
57
|
+
'x-unique'?: boolean;
|
|
58
|
+
'x-index'?: boolean | {
|
|
59
|
+
unique?: boolean;
|
|
60
|
+
};
|
|
61
|
+
'x-indexes'?: Array<{
|
|
62
|
+
fields: string[];
|
|
63
|
+
unique?: boolean;
|
|
64
|
+
name?: string;
|
|
65
|
+
}>;
|
|
66
|
+
'x-autoIncrement'?: boolean;
|
|
67
|
+
[extensionKey: `x-${string}`]: unknown;
|
|
68
|
+
}
|
|
69
|
+
export interface XMostajsEntity {
|
|
70
|
+
tableName?: string;
|
|
71
|
+
timestamps?: boolean;
|
|
72
|
+
softDelete?: boolean;
|
|
73
|
+
discriminator?: string;
|
|
74
|
+
discriminatorValue?: string;
|
|
75
|
+
}
|
|
76
|
+
export interface XMostajsRelation {
|
|
77
|
+
type: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';
|
|
78
|
+
target: string;
|
|
79
|
+
foreignKey?: string;
|
|
80
|
+
otherKey?: string;
|
|
81
|
+
through?: string;
|
|
82
|
+
onDelete?: 'cascade' | 'set-null' | 'restrict' | 'no-action';
|
|
83
|
+
required?: boolean;
|
|
84
|
+
nullable?: boolean;
|
|
85
|
+
}
|
|
86
|
+
/** Inferred draft version from $schema URL */
|
|
87
|
+
export type DraftVersion = 'draft-04' | 'draft-06' | 'draft-07' | 'draft-2019-09' | 'draft-2020-12' | 'unknown';
|
|
88
|
+
export declare function detectDraft(schema: JsonSchema): DraftVersion;
|
|
89
|
+
/** Get sub-schemas regardless of draft ($defs vs definitions) */
|
|
90
|
+
export declare function getDefinitions(schema: JsonSchema): Record<string, JsonSchema>;
|
|
91
|
+
/** First type if type is an array, else the type itself */
|
|
92
|
+
export declare function primaryType(schema: JsonSchema): JsonSchemaType | undefined;
|
|
93
|
+
/** Is nullable (either OpenAPI nullable: true, or type array includes null) */
|
|
94
|
+
export declare function isNullable(schema: JsonSchema): boolean;
|
|
95
|
+
//# sourceMappingURL=jsonschema-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema-types.d.ts","sourceRoot":"","sources":["../../src/utils/jsonschema-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// jsonschema-types.ts
|
|
2
|
+
// Type definitions for JSON Schema structures we navigate.
|
|
3
|
+
// Covers Draft-07, Draft 2019-09, Draft 2020-12 (superset shape).
|
|
4
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
5
|
+
// License: AGPL-3.0-or-later
|
|
6
|
+
export function detectDraft(schema) {
|
|
7
|
+
const url = schema.$schema ?? '';
|
|
8
|
+
if (/2020-12/.test(url))
|
|
9
|
+
return 'draft-2020-12';
|
|
10
|
+
if (/2019-09/.test(url))
|
|
11
|
+
return 'draft-2019-09';
|
|
12
|
+
if (/draft-07/.test(url))
|
|
13
|
+
return 'draft-07';
|
|
14
|
+
if (/draft-06/.test(url))
|
|
15
|
+
return 'draft-06';
|
|
16
|
+
if (/draft-04/.test(url))
|
|
17
|
+
return 'draft-04';
|
|
18
|
+
return 'unknown';
|
|
19
|
+
}
|
|
20
|
+
/** Get sub-schemas regardless of draft ($defs vs definitions) */
|
|
21
|
+
export function getDefinitions(schema) {
|
|
22
|
+
return schema.$defs ?? schema.definitions ?? {};
|
|
23
|
+
}
|
|
24
|
+
/** First type if type is an array, else the type itself */
|
|
25
|
+
export function primaryType(schema) {
|
|
26
|
+
const t = schema.type;
|
|
27
|
+
if (!t)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (Array.isArray(t))
|
|
30
|
+
return t.find(x => x !== 'null');
|
|
31
|
+
return t;
|
|
32
|
+
}
|
|
33
|
+
/** Is nullable (either OpenAPI nullable: true, or type array includes null) */
|
|
34
|
+
export function isNullable(schema) {
|
|
35
|
+
if (schema.nullable === true)
|
|
36
|
+
return true;
|
|
37
|
+
if (Array.isArray(schema.type))
|
|
38
|
+
return schema.type.includes('null');
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=jsonschema-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonschema-types.js","sourceRoot":"","sources":["../../src/utils/jsonschema-types.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,2DAA2D;AAC3D,kEAAkE;AAClE,wCAAwC;AACxC,6BAA6B;AA6G7B,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACjC,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,eAAe,CAAC;IAChD,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,eAAe,CAAC;IAChD,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,OAAO,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;AAClD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IACvD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/orm-adapter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Third-party schema adapters for @mostajs/orm — convert Prisma, JSON Schema, OpenAPI to EntitySchema",
|
|
5
5
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|