@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.
@@ -0,0 +1,220 @@
1
+ // openapi.adapter.ts
2
+ // Converts OpenAPI 3.0 / 3.1 specifications to EntitySchema[].
3
+ // Extracts components/schemas and feeds them through the JsonSchema pipeline.
4
+ // Parser : @readme/openapi-parser (supports 2.0, 3.0, 3.1 complet).
5
+ // Author: Dr Hamid MADANI drmdh@msn.com
6
+ // License: AGPL-3.0-or-later
7
+ import { dereference, validate } from '@readme/openapi-parser';
8
+ import { AbstractAdapter } from '../core/abstract.adapter.js';
9
+ import { WarningCode } from '../core/types.js';
10
+ import { InvalidSchemaError } from '../core/errors.js';
11
+ import { JsonSchemaAdapter } from './jsonschema.adapter.js';
12
+ import { normalizeComponentsSchemas, isOpenApi30 } from '../utils/openapi-normalize.js';
13
+ /**
14
+ * OpenApiAdapter — converts OpenAPI specs to EntitySchema[].
15
+ *
16
+ * Supported (MVP v0.4.0) :
17
+ * - OpenAPI 3.0.x (auto-normalized to 3.1 shape before conversion)
18
+ * - OpenAPI 3.1.x (JSON Schema 2020-12 compliant)
19
+ * - Extracts all `components/schemas` as entities
20
+ * - All features of JsonSchemaAdapter (allOf, discriminator, $ref, x-mostajs-*, etc.)
21
+ * - 3.0→3.1 normalizations :
22
+ * - `nullable: true` → `type: [T, "null"]`
23
+ * - `example: X` → `examples: [X]`
24
+ * - `exclusiveMinimum: true` → `exclusiveMinimum: <number>`
25
+ * - Input : object, JSON string, YAML string, or file path (via @readme/openapi-parser)
26
+ *
27
+ * Not supported yet (v0.5+) :
28
+ * - paths → CRUD endpoint deduction (opt-in flag planned)
29
+ * - Inline schemas inside `paths` (only `components/schemas` become entities)
30
+ * - Webhooks (detected, parsed, but not mapped to entities)
31
+ * - `pathItems` components (parsed, not used for entities)
32
+ * - File upload body (kept as string with warning)
33
+ */
34
+ export class OpenApiAdapter extends AbstractAdapter {
35
+ name = 'openapi';
36
+ vendor = 'openapis.org';
37
+ version = '0.4.0';
38
+ /** Internal JsonSchemaAdapter used to convert normalized schemas */
39
+ jsonSchemaAdapter = new JsonSchemaAdapter();
40
+ canParse(input) {
41
+ const obj = this.tryParseAny(input);
42
+ if (!obj || typeof obj !== 'object')
43
+ return false;
44
+ const doc = obj;
45
+ // Strongest indicator : `openapi: "3.x.y"` field
46
+ if (typeof doc.openapi === 'string' && /^3\./.test(doc.openapi))
47
+ return true;
48
+ // Swagger 2.0 shape (not yet supported but let us detect and warn)
49
+ if (obj.swagger === '2.0')
50
+ return true;
51
+ return false;
52
+ }
53
+ async toEntitySchema(input, opts) {
54
+ // 1. Normalize input to object (parse JSON string if needed).
55
+ // @readme/openapi-parser treats strings as file paths — we want inline parsing.
56
+ const specInput = this.resolveInput(input);
57
+ // 2. Pre-annotate components.schemas with title = key, so dereference propagates names.
58
+ this.injectSchemaTitles(specInput);
59
+ // 3. Pre-extract x-mostajs-relation from $ref-bearing properties before dereference.
60
+ // json-schema-ref-parser strips siblings when resolving $ref.
61
+ const relationOverrides = this.extractRelationOverrides(specInput);
62
+ // 4. Parse + dereference via @readme/openapi-parser
63
+ let spec;
64
+ try {
65
+ // We validate first for diagnostics, but don't fail on warnings
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ const report = await validate(this.cloneForParser(specInput));
68
+ if (!report.valid) {
69
+ this.warn(opts, {
70
+ code: WarningCode.FALLBACK_APPLIED,
71
+ message: `OpenAPI spec has validation issues; proceeding anyway`,
72
+ });
73
+ }
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ spec = (await dereference(this.cloneForParser(specInput)));
76
+ }
77
+ catch (e) {
78
+ throw new InvalidSchemaError(`Failed to parse OpenAPI spec: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
79
+ }
80
+ // 4b. Re-attach x-mostajs-relation overrides on each property
81
+ this.reattachRelationOverrides(spec, relationOverrides);
82
+ // 2. Warn if Swagger 2.0 (not fully supported)
83
+ if (spec.swagger === '2.0') {
84
+ this.warn(opts, {
85
+ code: WarningCode.PREVIEW_FEATURE,
86
+ message: `Swagger 2.0 input — conversion may be incomplete. Consider migrating to OpenAPI 3.1.`,
87
+ });
88
+ }
89
+ const version = spec.openapi;
90
+ if (isOpenApi30(version)) {
91
+ // Handled by normalize below — just informational
92
+ }
93
+ // 3. Extract components.schemas
94
+ const rawSchemas = spec.components?.schemas;
95
+ if (!rawSchemas || Object.keys(rawSchemas).length === 0) {
96
+ this.warn(opts, {
97
+ code: WarningCode.MISSING_METADATA,
98
+ message: `OpenAPI spec has no components.schemas — no entities extracted`,
99
+ });
100
+ return [];
101
+ }
102
+ // 4. Normalize 3.0 → 3.1 if needed
103
+ const normalized = normalizeComponentsSchemas(spec.components, version, w => this.warn(opts, w));
104
+ if (!normalized)
105
+ return [];
106
+ // 5. Ensure each schema has a title so inline detection works post-dereference
107
+ const titled = {};
108
+ for (const [name, schema] of Object.entries(normalized)) {
109
+ titled[name] = schema.title ? schema : { ...schema, title: name };
110
+ }
111
+ // 6. Delegate to JsonSchemaAdapter
112
+ return this.jsonSchemaAdapter.schemasToEntities(titled, opts);
113
+ }
114
+ /**
115
+ * Walk the ORIGINAL (pre-dereference) spec and record all x-mostajs-relation
116
+ * extensions on properties that also have a $ref. These siblings are stripped
117
+ * during dereference, so we capture them here and re-attach after.
118
+ */
119
+ extractRelationOverrides(doc) {
120
+ const map = new Map(); // schemaName -> propName -> xRel
121
+ const schemas = doc.components?.schemas;
122
+ if (!schemas)
123
+ return map;
124
+ for (const [schemaName, schema] of Object.entries(schemas)) {
125
+ if (!schema?.properties)
126
+ continue;
127
+ const propMap = new Map();
128
+ for (const [propName, prop] of Object.entries(schema.properties)) {
129
+ const p = prop;
130
+ if (p['x-mostajs-relation']) {
131
+ propMap.set(propName, p['x-mostajs-relation']);
132
+ }
133
+ }
134
+ if (propMap.size > 0)
135
+ map.set(schemaName, propMap);
136
+ }
137
+ return map;
138
+ }
139
+ /**
140
+ * After dereference, re-attach the x-mostajs-relation extensions we extracted.
141
+ * The property schema becomes `{ ...inlinedRef, 'x-mostajs-relation': saved }`.
142
+ */
143
+ reattachRelationOverrides(doc, overrides) {
144
+ const schemas = doc.components?.schemas;
145
+ if (!schemas)
146
+ return;
147
+ for (const [schemaName, propMap] of overrides) {
148
+ const schema = schemas[schemaName];
149
+ if (!schema?.properties)
150
+ continue;
151
+ for (const [propName, xRel] of propMap) {
152
+ const prop = schema.properties[propName];
153
+ if (prop && typeof prop === 'object') {
154
+ prop['x-mostajs-relation'] = xRel;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ // ============================================================
160
+ // Utilities
161
+ // ============================================================
162
+ /** Clone input for the parser (must not mutate caller's input) */
163
+ cloneForParser(input) {
164
+ return typeof structuredClone === 'function'
165
+ ? structuredClone(input)
166
+ : JSON.parse(JSON.stringify(input));
167
+ }
168
+ /**
169
+ * Normalize input to object form.
170
+ * @readme/openapi-parser treats strings as file paths (not content),
171
+ * so we JSON.parse strings ourselves here.
172
+ */
173
+ resolveInput(input) {
174
+ if (typeof input !== 'string')
175
+ return input;
176
+ const trimmed = input.trim();
177
+ if (trimmed.startsWith('{')) {
178
+ try {
179
+ return JSON.parse(trimmed);
180
+ }
181
+ catch (e) {
182
+ throw new InvalidSchemaError(`Invalid JSON input: ${e instanceof Error ? e.message : String(e)}`);
183
+ }
184
+ }
185
+ // YAML parsing not implemented yet — recommend pre-parsing
186
+ throw new InvalidSchemaError('OpenApiAdapter accepts objects or JSON strings. For YAML, pre-parse with js-yaml.');
187
+ }
188
+ /**
189
+ * Ensure each schema in components.schemas has `title: <key>`.
190
+ * After dereference, inlined schemas need a title for JsonSchemaAdapter's
191
+ * relation detection (which matches property schema titles against entity names).
192
+ */
193
+ injectSchemaTitles(doc) {
194
+ const schemas = doc.components?.schemas;
195
+ if (!schemas)
196
+ return;
197
+ for (const [name, schema] of Object.entries(schemas)) {
198
+ if (schema && typeof schema === 'object' && !schema.title) {
199
+ schema.title = name;
200
+ }
201
+ }
202
+ }
203
+ /** Parse JSON string if necessary — used for canParse detection only */
204
+ tryParseAny(input) {
205
+ if (typeof input !== 'string')
206
+ return input;
207
+ const trimmed = input.trim();
208
+ if (trimmed.startsWith('{')) {
209
+ try {
210
+ return JSON.parse(trimmed);
211
+ }
212
+ catch { /* fall through */ }
213
+ }
214
+ if (/^\s*openapi\s*:\s*['"]?3\./m.test(trimmed)) {
215
+ return { openapi: '3.0.0' }; // placeholder to pass canParse
216
+ }
217
+ return null;
218
+ }
219
+ }
220
+ //# sourceMappingURL=openapi.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.adapter.js","sourceRoot":"","sources":["../../src/adapters/openapi.adapter.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,7 +5,10 @@ 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';
9
+ export { OpenApiAdapter } from './adapters/openapi.adapter.js';
8
10
  export { DefaultSentinel } from './utils/prisma-default-mapper.js';
11
+ export type { JsonSchema, JsonSchemaType, XMostajsEntity, XMostajsRelation, DraftVersion, } from './utils/jsonschema-types.js';
9
12
  import { AdapterRegistry } from './core/registry.js';
10
13
  /**
11
14
  * Create a registry with all standard adapters pre-registered.
@@ -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;AAG7D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAIrD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAMvD"}
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;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D,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;AAMrD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAOvD"}
package/dist/index.js CHANGED
@@ -9,12 +9,16 @@ 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';
13
+ export { OpenApiAdapter } from './adapters/openapi.adapter.js';
12
14
  // --- Default-value sentinels (Prisma @default semantics) ---
13
15
  export { DefaultSentinel } from './utils/prisma-default-mapper.js';
14
16
  // --- Convenience factory ---
15
17
  import { AdapterRegistry } from './core/registry.js';
16
18
  import { NativeAdapter } from './adapters/native.adapter.js';
17
19
  import { PrismaAdapter } from './adapters/prisma.adapter.js';
20
+ import { JsonSchemaAdapter } from './adapters/jsonschema.adapter.js';
21
+ import { OpenApiAdapter } from './adapters/openapi.adapter.js';
18
22
  /**
19
23
  * Create a registry with all standard adapters pre-registered.
20
24
  * Detection order (first registered = last priority) :
@@ -26,7 +30,8 @@ export function createDefaultRegistry() {
26
30
  const registry = new AdapterRegistry();
27
31
  registry.register(new NativeAdapter());
28
32
  registry.register(new PrismaAdapter());
29
- // TODO: register JsonSchemaAdapter / OpenApiAdapter when ready
33
+ registry.register(new JsonSchemaAdapter());
34
+ registry.register(new OpenApiAdapter());
30
35
  return registry;
31
36
  }
32
37
  //# 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;AAE7D,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,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;AAE7D;;;;;;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,+DAA+D;IAC/D,OAAO,QAAQ,CAAC;AAClB,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;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,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;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D;;;;;;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,QAAQ,CAAC,QAAQ,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC;IACxC,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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"}