@mostajs/orm-adapter 0.2.0 → 0.4.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 CHANGED
@@ -2,6 +2,89 @@
2
2
 
3
3
  All notable changes to `@mostajs/orm-adapter` will be documented in this file.
4
4
 
5
+ ## [0.4.0] — 2026-04-12
6
+
7
+ ### Added
8
+
9
+ - **OpenApiAdapter** : converts OpenAPI 2.0/3.0/3.1 specs to `EntitySchema[]`
10
+ - OpenAPI 3.1 : full JSON Schema 2020-12 semantics
11
+ - OpenAPI 3.0.x : auto-normalized to 3.1 shape before conversion
12
+ - `nullable: true` → `type: [T, "null"]`
13
+ - `example: X` → `examples: [X]`
14
+ - `exclusiveMinimum: true` + `minimum: X` → `exclusiveMinimum: X`
15
+ - Swagger 2.0 detected with PREVIEW_FEATURE warning
16
+ - Extracts all `components/schemas` as entities
17
+ - Delegates to JsonSchemaAdapter for the schema conversion pipeline
18
+ - **x-mostajs-relation preservation** : re-attaches extensions on $ref-bearing properties (dereference strips siblings)
19
+ - **Title injection** : auto-adds `title: <key>` to each schema for relation detection
20
+ - **Input forms** : object, JSON string (YAML requires pre-parsing)
21
+ - Uses `@readme/openapi-parser` for validation + dereferencing
22
+ - **Utils** : `openapi-normalize` (3.0 → 3.1 transformations)
23
+ - **JsonSchemaAdapter.schemasToEntities()** : public method to convert a named schema map without root-detection heuristic
24
+ - 50 new unit tests on 3 fixtures :
25
+ - `petstore-3.1.json` (3 entities, relations, discriminator, x-mostajs-*)
26
+ - `petstore-3.0.json` (legacy with all normalizations)
27
+ - `discriminator.json` (oneOf polymorphism)
28
+
29
+ ### Changed
30
+
31
+ - `createDefaultRegistry()` now includes OpenApiAdapter (4 adapters total)
32
+ - `JsonSchemaAdapter.toEntitySchema()` : uses `structuredClone` instead of JSON.parse/stringify to handle circular refs from OpenAPI's dereferenced tree
33
+
34
+ ### Total test coverage
35
+
36
+ 196 tests across 4 adapters :
37
+ - 31 native
38
+ - 55 prisma
39
+ - 60 jsonschema
40
+ - 50 openapi
41
+
42
+ ## [0.3.0] — 2026-04-12
43
+
44
+ ### Added
45
+
46
+ - **JsonSchemaAdapter** : converts JSON Schema to `EntitySchema[]`
47
+ - Drafts : Draft-07, Draft 2019-09, Draft 2020-12 (auto-detected via `$schema` URL)
48
+ - Types : `string`, `integer`, `number`, `boolean`, `array`, `object`, `null`
49
+ - Formats : `date-time`, `date`, `time`, `email`, `uuid`, `uri`, `uri-reference`, `ipv4`, `ipv6`, `regex`, `binary`, `byte`
50
+ - Nullable : both OpenAPI `nullable: true` and array form `type: [T, "null"]`
51
+ - Constraints : `enum`, `const`, `default`, `minLength`/`maxLength`, `pattern`, `minimum`/`maximum`
52
+ - Annotations : `readOnly`, `writeOnly`, `deprecated`, `title`, `description` (preserved)
53
+ - **allOf flattening** : merges parent properties into child (inheritance pattern)
54
+ - **oneOf discriminator** : maps to `EntitySchema.discriminator` + `discriminatorValue`
55
+ - **Entity detection** : top-level title/x-mostajs-entity + all `$defs` / `definitions`
56
+ - **$ref resolution** : internal + external via `@apidevtools/json-schema-ref-parser`
57
+ - **Cycle detection** : self-references flagged via CYCLIC_REFERENCE warning
58
+ - **Extensions** (all `x-*`) :
59
+ - `x-mostajs-entity` : `{ tableName, timestamps, softDelete, discriminator, discriminatorValue }`
60
+ - `x-mostajs-relation` : `{ type, target, foreignKey, otherKey, through, onDelete }`
61
+ - `x-primary`, `x-unique`, `x-index`, `x-indexes` (composite)
62
+ - `x-autoIncrement`
63
+ - **Auto-relation detection** :
64
+ - Property is object with title matching an entity → `many-to-one`
65
+ - Array items `$ref` to an entity → `one-to-many`
66
+ - Explicit `x-mostajs-relation` always wins
67
+ - **Input forms** : plain object, JSON string, or `$ref`-laden schema (auto-dereferenced)
68
+ - **Utils** : `jsonschema-types` (shared types + draft detection), `jsonschema-type-mapper`, `jsonschema-flatten`
69
+ - **Public types re-exports** : `JsonSchema`, `JsonSchemaType`, `XMostajsEntity`, `XMostajsRelation`, `DraftVersion`
70
+ - 60 new unit tests on 4 fixtures :
71
+ - `user-2020-12.json` (Draft 2020-12 + relations + indexes + x-mostajs-*)
72
+ - `post-draft-07.json` (Draft-07 compat + auto-relation via $ref title)
73
+ - `allof-composition.json` (allOf merge + required merge)
74
+ - `validators.json` (all validators + composite x-indexes)
75
+
76
+ ### Changed
77
+
78
+ - `createDefaultRegistry()` now includes JsonSchemaAdapter in the detection chain
79
+
80
+ ### Warnings emitted (new)
81
+
82
+ - `PREVIEW_FEATURE` on Draft-04/06 (legacy drafts)
83
+ - `LOSSY_CONVERSION` on `int64` format, tuple `items`, binary/byte format
84
+ - `AMBIGUOUS_MAPPING` on allOf property redefinition (last-wins)
85
+ - `CYCLIC_REFERENCE` on self-referencing entities
86
+ - `FALLBACK_APPLIED` on non-object $defs entries
87
+
5
88
  ## [0.2.0] — 2026-04-12
6
89
 
7
90
  ### Added
package/README.md CHANGED
@@ -146,10 +146,29 @@ 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)
150
- - **v0.4.0** — OpenApiAdapter (3.1 with 3.0 normalization)
149
+ - **v0.3.0** — JsonSchemaAdapter (Draft 2020-12 + Draft-07 + allOf + x-mostajs-*)
150
+ - **v0.4.0** — OpenApiAdapter (3.1 + 3.0 normalization + Swagger 2.0 detect)
151
151
  - **v1.0.0** — Production-ready, all 4 adapters with reverse conversion
152
152
 
153
+ ## OpenApiAdapter example
154
+
155
+ ```ts
156
+ import { OpenApiAdapter } from '@mostajs/orm-adapter';
157
+ import { readFileSync } from 'fs';
158
+
159
+ const spec = JSON.parse(readFileSync('./openapi.json', 'utf8'));
160
+ const adapter = new OpenApiAdapter();
161
+ const entities = await adapter.toEntitySchema(spec);
162
+
163
+ // Extracts every components/schemas entry as an EntitySchema.
164
+ // Auto-handles:
165
+ // - OpenAPI 3.0 → 3.1 normalization (nullable, exclusiveMin, examples)
166
+ // - $ref resolution (internal)
167
+ // - allOf flattening (inheritance)
168
+ // - discriminator → EntitySchema.discriminator
169
+ // - x-mostajs-relation on $ref-bearing properties (preserved across dereference)
170
+ ```
171
+
153
172
  ## PrismaAdapter example
154
173
 
155
174
  ```ts
@@ -0,0 +1,51 @@
1
+ import type { EntitySchema } from '@mostajs/orm';
2
+ import { AbstractAdapter } from '../core/abstract.adapter.js';
3
+ import { type AdapterOptions } from '../core/types.js';
4
+ import { type JsonSchema } from '../utils/jsonschema-types.js';
5
+ /**
6
+ * JsonSchemaAdapter — converts JSON Schema to EntitySchema[].
7
+ *
8
+ * Supports (MVP v0.3.0):
9
+ * - Draft-07, Draft 2019-09, Draft 2020-12 (auto-detected)
10
+ * - type: string/integer/number/boolean/array/object/null (including array form)
11
+ * - formats: date-time, date, time, email, uuid, uri, ipv4, regex, binary
12
+ * - Constraints: enum, const, default, minLength/maxLength, pattern, min/max
13
+ * - Nullable (both OpenAPI nullable: true and type: [T, "null"])
14
+ * - readOnly / writeOnly / deprecated (annotations preserved)
15
+ * - allOf flattening (inheritance merge)
16
+ * - oneOf + discriminator → discriminator + discriminatorValue
17
+ * - Entity detection : top-level (title+x-mostajs-entity) + all $defs
18
+ * - Extensions : x-mostajs-entity, x-mostajs-relation, x-primary, x-unique, x-index, x-indexes
19
+ * - $ref resolution (cycles detected, self-relation auto-created)
20
+ *
21
+ * Not yet supported (v0.4+):
22
+ * - $dynamicRef / $dynamicAnchor late-binding
23
+ * - patternProperties as structured mapping (falls back to json)
24
+ * - if/then/else conditional
25
+ * - External $ref resolution (HTTP/file beyond basic dereference)
26
+ */
27
+ export declare class JsonSchemaAdapter extends AbstractAdapter {
28
+ readonly name = "jsonschema";
29
+ readonly vendor = "json-schema.org";
30
+ readonly version = "0.3.0";
31
+ canParse(input: string | object): boolean;
32
+ toEntitySchema(input: string | object, opts?: AdapterOptions): Promise<EntitySchema[]>;
33
+ /**
34
+ * Convert a named map of schemas directly to EntitySchema[].
35
+ * Used by OpenApiAdapter when it has already extracted components.schemas.
36
+ * Skips the "root entity" detection heuristic.
37
+ */
38
+ schemasToEntities(schemas: Record<string, JsonSchema>, opts?: AdapterOptions): Promise<EntitySchema[]>;
39
+ private collectEntities;
40
+ private nameFromId;
41
+ private convertEntity;
42
+ private processProperty;
43
+ private mapXMostajsRelation;
44
+ private toFieldDef;
45
+ /**
46
+ * Generate indexes from x-index and x-unique on individual fields.
47
+ */
48
+ private applyFieldIndexes;
49
+ private tryParseJson;
50
+ }
51
+ //# 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;AAEzF,OAAO,EACL,KAAK,UAAU,EAOhB,MAAM,8BAA8B,CAAC;AAStC;;;;;;;;;;;;;;;;;;;;;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;;;;OAIG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACnC,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC;IAa1B,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,336 @@
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
+ // structuredClone handles circular references (unlike JSON.parse/stringify)
66
+ // which matter when this adapter is called from OpenApiAdapter on already-dereferenced specs.
67
+ const cloned = typeof structuredClone === 'function'
68
+ ? structuredClone(raw)
69
+ : JSON.parse(JSON.stringify(raw));
70
+ resolved = await $RefParser.dereference(cloned);
71
+ }
72
+ catch (e) {
73
+ throw new InvalidSchemaError(`Failed to dereference JSON Schema: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
74
+ }
75
+ const draft = detectDraft(resolved);
76
+ if (draft === 'draft-04' || draft === 'draft-06') {
77
+ this.warn(opts, {
78
+ code: WarningCode.PREVIEW_FEATURE,
79
+ message: `Legacy draft ${draft} — mapping may be incomplete. Recommend upgrading to Draft 2020-12.`,
80
+ });
81
+ }
82
+ // Collect entity candidates : root schema + all $defs/definitions
83
+ const candidates = this.collectEntities(resolved, opts);
84
+ // Convert each candidate
85
+ const seen = new Set(); // for cycle detection
86
+ const entities = candidates.map(c => this.convertEntity(c, candidates, seen, opts));
87
+ return entities;
88
+ }
89
+ /**
90
+ * Convert a named map of schemas directly to EntitySchema[].
91
+ * Used by OpenApiAdapter when it has already extracted components.schemas.
92
+ * Skips the "root entity" detection heuristic.
93
+ */
94
+ async schemasToEntities(schemas, opts) {
95
+ const candidates = Object.entries(schemas).map(([name, schema]) => ({
96
+ name: this.pascalCase(name),
97
+ schema,
98
+ }));
99
+ const seen = new Set();
100
+ return candidates.map(c => this.convertEntity(c, candidates, seen, opts));
101
+ }
102
+ // ============================================================
103
+ // Entity collection
104
+ // ============================================================
105
+ collectEntities(root, opts) {
106
+ const out = [];
107
+ // 1. Root if it's an object with title OR x-mostajs-entity
108
+ const rootIsObject = primaryType(root) === 'object';
109
+ const rootName = root.title ?? this.nameFromId(root.$id);
110
+ const rootHasEntityMarker = !!root['x-mostajs-entity'];
111
+ if (rootIsObject && (rootHasEntityMarker || rootName)) {
112
+ out.push({ name: rootName ?? 'RootEntity', schema: root });
113
+ }
114
+ // 2. All $defs / definitions that are objects
115
+ const defs = getDefinitions(root);
116
+ for (const [key, def] of Object.entries(defs)) {
117
+ if (primaryType(def) === 'object') {
118
+ out.push({ name: def.title ?? key, schema: def });
119
+ }
120
+ else {
121
+ this.warn(opts, {
122
+ code: WarningCode.FALLBACK_APPLIED,
123
+ message: `$defs["${key}"] is not an object — ignored as entity candidate`,
124
+ });
125
+ }
126
+ }
127
+ // Deduplicate by name (last-wins)
128
+ const byName = new Map();
129
+ for (const c of out)
130
+ byName.set(this.pascalCase(c.name), c);
131
+ return Array.from(byName.values()).map(c => ({ ...c, name: this.pascalCase(c.name) }));
132
+ }
133
+ nameFromId(id) {
134
+ if (!id)
135
+ return undefined;
136
+ const segments = id.replace(/\.json$/, '').split(/[/#]/);
137
+ return segments[segments.length - 1] || undefined;
138
+ }
139
+ // ============================================================
140
+ // Candidate → EntitySchema
141
+ // ============================================================
142
+ convertEntity(candidate, allCandidates, seen, opts) {
143
+ const name = candidate.name;
144
+ if (seen.has(name)) {
145
+ this.warn(opts, {
146
+ code: WarningCode.CYCLIC_REFERENCE,
147
+ message: `Cyclic entity reference detected at "${name}"`,
148
+ entity: name,
149
+ });
150
+ }
151
+ seen.add(name);
152
+ // Flatten allOf composition
153
+ const schema = flattenAllOf(candidate.schema, w => this.warn(opts, w), name);
154
+ // Extract x-mostajs-entity metadata
155
+ const entityMeta = schema['x-mostajs-entity'] ?? {};
156
+ const tableName = entityMeta.tableName ?? this.snakeCase(name);
157
+ const entity = {
158
+ name,
159
+ collection: tableName,
160
+ fields: {},
161
+ relations: {},
162
+ indexes: [],
163
+ timestamps: entityMeta.timestamps ?? false,
164
+ };
165
+ if (entityMeta.softDelete)
166
+ entity.softDelete = true;
167
+ if (entityMeta.discriminator)
168
+ entity.discriminator = entityMeta.discriminator;
169
+ if (entityMeta.discriminatorValue)
170
+ entity.discriminatorValue = entityMeta.discriminatorValue;
171
+ // Also detect discriminator from OpenAPI-style discriminator property
172
+ if (!entity.discriminator) {
173
+ const d = detectDiscriminator(schema);
174
+ if (d)
175
+ entity.discriminator = d.propertyName;
176
+ }
177
+ // Process properties
178
+ const required = new Set(schema.required ?? []);
179
+ const entityNames = new Set(allCandidates.map(c => c.name));
180
+ for (const [key, propSchema] of Object.entries(schema.properties ?? {})) {
181
+ this.processProperty(key, propSchema, entity, required.has(key), entityNames, opts);
182
+ }
183
+ // Process x-indexes (model-level composite indexes)
184
+ const xIndexes = schema['x-indexes'];
185
+ if (Array.isArray(xIndexes)) {
186
+ for (const idx of xIndexes) {
187
+ const fields = {};
188
+ for (const f of idx.fields)
189
+ fields[f] = 'asc';
190
+ entity.indexes.push({ fields, unique: !!idx.unique });
191
+ }
192
+ }
193
+ // Auto-timestamps detection
194
+ if (!entity.timestamps &&
195
+ 'createdAt' in entity.fields && 'updatedAt' in entity.fields) {
196
+ entity.timestamps = true;
197
+ }
198
+ return entity;
199
+ }
200
+ // ============================================================
201
+ // Property → Field or Relation
202
+ // ============================================================
203
+ processProperty(key, propSchema, entity, required, entityNames, opts) {
204
+ // 1. Explicit x-mostajs-relation always wins
205
+ const xRel = propSchema['x-mostajs-relation'];
206
+ if (xRel) {
207
+ entity.relations[key] = this.mapXMostajsRelation(xRel, required);
208
+ return;
209
+ }
210
+ // 2. Detection by shape : object with title matching an entity = belongsTo
211
+ if (primaryType(propSchema) === 'object' && propSchema.title &&
212
+ entityNames.has(this.pascalCase(propSchema.title))) {
213
+ entity.relations[key] = {
214
+ target: this.pascalCase(propSchema.title),
215
+ type: 'many-to-one',
216
+ required: required && !isNullable(propSchema),
217
+ nullable: isNullable(propSchema),
218
+ };
219
+ return;
220
+ }
221
+ // 3. Array of entities = hasMany
222
+ if (primaryType(propSchema) === 'array' && !Array.isArray(propSchema.items)) {
223
+ const item = propSchema.items;
224
+ if (item && primaryType(item) === 'object' && item.title &&
225
+ entityNames.has(this.pascalCase(item.title))) {
226
+ entity.relations[key] = {
227
+ target: this.pascalCase(item.title),
228
+ type: 'one-to-many',
229
+ };
230
+ return;
231
+ }
232
+ }
233
+ // 4. Regular field
234
+ const field = this.toFieldDef(key, propSchema, required, entity.name, opts);
235
+ if (field) {
236
+ entity.fields[key] = field;
237
+ this.applyFieldIndexes(key, propSchema, entity);
238
+ }
239
+ }
240
+ mapXMostajsRelation(xRel, required) {
241
+ const typeMap = {
242
+ belongsTo: 'many-to-one',
243
+ hasOne: 'one-to-one',
244
+ hasMany: 'one-to-many',
245
+ belongsToMany: 'many-to-many',
246
+ };
247
+ const rel = {
248
+ target: xRel.target,
249
+ type: typeMap[xRel.type],
250
+ };
251
+ if (xRel.required ?? required)
252
+ rel.required = true;
253
+ if (xRel.nullable)
254
+ rel.nullable = true;
255
+ if (xRel.foreignKey)
256
+ rel.joinColumn = xRel.foreignKey;
257
+ if (xRel.otherKey)
258
+ rel.inverseJoinColumn = xRel.otherKey;
259
+ if (xRel.through)
260
+ rel.through = xRel.through;
261
+ if (xRel.onDelete)
262
+ rel.onDelete = xRel.onDelete;
263
+ return rel;
264
+ }
265
+ toFieldDef(key, schema, required, entityName, opts) {
266
+ const type = mapJsonSchemaType(schema, key, entityName, w => this.warn(opts, w));
267
+ if (!type) {
268
+ this.warn(opts, {
269
+ code: WarningCode.UNSUPPORTED_FEATURE,
270
+ message: `Cannot map property "${key}" — no type information`,
271
+ entity: entityName,
272
+ field: key,
273
+ });
274
+ return null;
275
+ }
276
+ const nullable = isNullable(schema);
277
+ const fd = {
278
+ type,
279
+ required: required && !nullable,
280
+ };
281
+ // Array : resolve arrayOf
282
+ if (type === 'array') {
283
+ const inner = mapArrayItems(schema, key, entityName, w => this.warn(opts, w));
284
+ if (inner)
285
+ fd.arrayOf = inner;
286
+ }
287
+ // Enum
288
+ if (schema.enum?.length) {
289
+ fd.enum = schema.enum.filter(v => v != null).map(String);
290
+ }
291
+ // Default
292
+ if (schema.default !== undefined) {
293
+ fd.default = schema.default;
294
+ }
295
+ else if (schema.const !== undefined) {
296
+ fd.default = schema.const;
297
+ }
298
+ // x-primary / x-unique
299
+ if (schema['x-unique'] === true)
300
+ fd.unique = true;
301
+ return fd;
302
+ }
303
+ /**
304
+ * Generate indexes from x-index and x-unique on individual fields.
305
+ */
306
+ applyFieldIndexes(key, schema, entity) {
307
+ const xIndex = schema['x-index'];
308
+ const xUnique = schema['x-unique'] === true;
309
+ if (xIndex === true) {
310
+ entity.indexes.push({ fields: { [key]: 'asc' } });
311
+ }
312
+ else if (xIndex && typeof xIndex === 'object') {
313
+ entity.indexes.push({
314
+ fields: { [key]: 'asc' },
315
+ unique: !!xIndex.unique,
316
+ });
317
+ }
318
+ else if (xUnique) {
319
+ entity.indexes.push({ fields: { [key]: 'asc' }, unique: true });
320
+ }
321
+ }
322
+ // ============================================================
323
+ // Utilities
324
+ // ============================================================
325
+ tryParseJson(input) {
326
+ if (typeof input !== 'string')
327
+ return input;
328
+ try {
329
+ return JSON.parse(input);
330
+ }
331
+ catch {
332
+ return null;
333
+ }
334
+ }
335
+ }
336
+ //# sourceMappingURL=jsonschema.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonschema.adapter.js","sourceRoot":"","sources":["../../src/adapters/jsonschema.adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
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
+ * OpenApiAdapter — converts OpenAPI specs to EntitySchema[].
6
+ *
7
+ * Supported (MVP v0.4.0) :
8
+ * - OpenAPI 3.0.x (auto-normalized to 3.1 shape before conversion)
9
+ * - OpenAPI 3.1.x (JSON Schema 2020-12 compliant)
10
+ * - Extracts all `components/schemas` as entities
11
+ * - All features of JsonSchemaAdapter (allOf, discriminator, $ref, x-mostajs-*, etc.)
12
+ * - 3.0→3.1 normalizations :
13
+ * - `nullable: true` → `type: [T, "null"]`
14
+ * - `example: X` → `examples: [X]`
15
+ * - `exclusiveMinimum: true` → `exclusiveMinimum: <number>`
16
+ * - Input : object, JSON string, YAML string, or file path (via @readme/openapi-parser)
17
+ *
18
+ * Not supported yet (v0.5+) :
19
+ * - paths → CRUD endpoint deduction (opt-in flag planned)
20
+ * - Inline schemas inside `paths` (only `components/schemas` become entities)
21
+ * - Webhooks (detected, parsed, but not mapped to entities)
22
+ * - `pathItems` components (parsed, not used for entities)
23
+ * - File upload body (kept as string with warning)
24
+ */
25
+ export declare class OpenApiAdapter extends AbstractAdapter {
26
+ readonly name = "openapi";
27
+ readonly vendor = "openapis.org";
28
+ readonly version = "0.4.0";
29
+ /** Internal JsonSchemaAdapter used to convert normalized schemas */
30
+ private readonly jsonSchemaAdapter;
31
+ canParse(input: string | object): boolean;
32
+ toEntitySchema(input: string | object, opts?: AdapterOptions): Promise<EntitySchema[]>;
33
+ /**
34
+ * Walk the ORIGINAL (pre-dereference) spec and record all x-mostajs-relation
35
+ * extensions on properties that also have a $ref. These siblings are stripped
36
+ * during dereference, so we capture them here and re-attach after.
37
+ */
38
+ private extractRelationOverrides;
39
+ /**
40
+ * After dereference, re-attach the x-mostajs-relation extensions we extracted.
41
+ * The property schema becomes `{ ...inlinedRef, 'x-mostajs-relation': saved }`.
42
+ */
43
+ private reattachRelationOverrides;
44
+ /** Clone input for the parser (must not mutate caller's input) */
45
+ private cloneForParser;
46
+ /**
47
+ * Normalize input to object form.
48
+ * @readme/openapi-parser treats strings as file paths (not content),
49
+ * so we JSON.parse strings ourselves here.
50
+ */
51
+ private resolveInput;
52
+ /**
53
+ * Ensure each schema in components.schemas has `title: <key>`.
54
+ * After dereference, inlined schemas need a title for JsonSchemaAdapter's
55
+ * relation detection (which matches property schema titles against entity names).
56
+ */
57
+ private injectSchemaTitles;
58
+ /** Parse JSON string if necessary — used for canParse detection only */
59
+ private tryParseAny;
60
+ }
61
+ //# sourceMappingURL=openapi.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/openapi.adapter.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAe,KAAK,cAAc,EAAuB,MAAM,kBAAkB,CAAC;AAkBzF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,cAAe,SAAQ,eAAe;IACjD,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,MAAM,kBAAkB;IACjC,QAAQ,CAAC,OAAO,WAAW;IAE3B,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAE7D,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAcnC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA8E5F;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAuBjC,kEAAkE;IAClE,OAAO,CAAC,cAAc;IAMtB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAkBpB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAU1B,wEAAwE;IACxE,OAAO,CAAC,WAAW;CAWpB"}