ormbridge 0.11.0 → 0.12.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,311 @@
1
+ import { findModel } from '../ir.js';
2
+ import { enumValuesOf, mapFieldType, } from './neo4jTypes.js';
3
+ import { labelOf, NameRegistry, oneLine, propertyKeyOf, relationshipTypeOf, } from './neo4jNames.js';
4
+ /** IR names (fields and relations) that make up the primary key of a model. */
5
+ export function primaryKeyNamesOf(model) {
6
+ if (model.compositePrimaryKey !== undefined &&
7
+ model.compositePrimaryKey.length > 0) {
8
+ return model.compositePrimaryKey;
9
+ }
10
+ return [
11
+ ...model.fields
12
+ .filter((field) => field.isPrimaryKey)
13
+ .map((field) => field.name),
14
+ ...model.relations
15
+ .filter((relation) => relation.isPrimaryKey === true)
16
+ .map((relation) => relation.name),
17
+ ];
18
+ }
19
+ /** The field a foreign key points at: `toField`, or the single primary key field of the target. */
20
+ export function referencedField(schema, relation) {
21
+ const target = findModel(schema, relation.targetModel);
22
+ if (target === undefined) {
23
+ return undefined;
24
+ }
25
+ if (relation.toField !== undefined) {
26
+ return target.fields.find((field) => field.name === relation.toField || field.columnName === relation.toField);
27
+ }
28
+ const keys = target.fields.filter((field) => field.isPrimaryKey);
29
+ return keys.length === 1 ? keys[0] : undefined;
30
+ }
31
+ function describeDefault(field) {
32
+ const value = field.default;
33
+ if (value === undefined) {
34
+ return undefined;
35
+ }
36
+ switch (value.kind) {
37
+ case 'literal':
38
+ return `the default ${JSON.stringify(value.value)}`;
39
+ case 'autoIncrement':
40
+ return undefined;
41
+ case 'now':
42
+ return 'the default of the current time';
43
+ case 'uuid':
44
+ return 'the default of a generated UUID';
45
+ case 'enumValue':
46
+ return `the default "${value.value}"`;
47
+ case 'clientGenerated':
48
+ return `the ${value.generator}() default`;
49
+ case 'dbExpression':
50
+ return `the database default ${oneLine(value.expression)}`;
51
+ }
52
+ }
53
+ function fieldWarnings(context, model, field, mapping) {
54
+ const label = `${model.name}.${field.name}`;
55
+ if (mapping.warning !== undefined) {
56
+ context.warnings.push(`${label}: ${mapping.warning}`);
57
+ }
58
+ const defaultText = describeDefault(field);
59
+ if (defaultText !== undefined) {
60
+ context.warnings.push(`${label}: ${defaultText} has no Neo4j schema representation and was dropped; set the value when you create the node.`);
61
+ }
62
+ if (field.default?.kind === 'autoIncrement') {
63
+ context.warnings.push(`${label}: auto-increment has no Neo4j equivalent; supply the value yourself (or use randomUUID() and a STRING key).`);
64
+ }
65
+ if (field.generated !== undefined) {
66
+ context.warnings.push(`${label}: the generated column expression (${oneLine(field.generated.expression)}) is not computed by Neo4j; the property is a plain value.`);
67
+ }
68
+ if (field.isAutoUpdated) {
69
+ context.warnings.push(`${label}: the value is refreshed on every save in the source; Neo4j has no such feature, so set it in your queries.`);
70
+ }
71
+ }
72
+ function fieldProperty(context, model, field) {
73
+ const mapping = mapFieldType(field);
74
+ fieldWarnings(context, model, field, mapping);
75
+ const notes = [];
76
+ if (field.isPrimaryKey) {
77
+ notes.push('primary key');
78
+ }
79
+ else if (field.isUnique) {
80
+ notes.push('unique');
81
+ }
82
+ const values = enumValuesOf(field, context.schema.enums);
83
+ if (values.length > 0) {
84
+ notes.push(`one of: ${values.map((value) => `"${oneLine(value)}"`).join(', ')}`);
85
+ }
86
+ if (field.type === 'decimal' && field.maxDigits !== undefined) {
87
+ notes.push(`decimal with ${field.maxDigits} digits${field.decimalPlaces === undefined
88
+ ? ''
89
+ : `, ${field.decimalPlaces} after the point`}`);
90
+ }
91
+ return {
92
+ key: propertyKeyOf(field.columnName, context.options.camelFields),
93
+ irName: field.name,
94
+ type: mapping.type,
95
+ required: !field.isNullable,
96
+ notes,
97
+ };
98
+ }
99
+ /** Maps a foreign key to a property typed like the column it references. */
100
+ function foreignKeyProperty(context, relation, targetKey) {
101
+ const referenced = referencedField(context.schema, relation);
102
+ const type = referenced === undefined
103
+ ? { name: 'INTEGER', constrainable: true }
104
+ : mapFieldType({ ...referenced, arrayDepth: undefined }).type;
105
+ const notes = [
106
+ `foreign key to ${relation.targetModel}${targetKey === undefined ? '' : `.${targetKey}`}`,
107
+ ];
108
+ if (relation.isPrimaryKey === true) {
109
+ notes.unshift('primary key');
110
+ }
111
+ return {
112
+ key: propertyKeyOf(relation.columnName, context.options.camelFields),
113
+ irName: relation.name,
114
+ type,
115
+ required: !relation.isNullable,
116
+ notes,
117
+ };
118
+ }
119
+ function targetKeyName(context, relation) {
120
+ const referenced = referencedField(context.schema, relation);
121
+ return referenced === undefined
122
+ ? undefined
123
+ : propertyKeyOf(referenced.columnName, context.options.camelFields);
124
+ }
125
+ /** Properties of a model: its columns, then one property per foreign key column. */
126
+ function buildProperties(context, model) {
127
+ const properties = [];
128
+ const keys = new Map();
129
+ const foreignKeys = [];
130
+ const taken = new Set();
131
+ for (const field of model.fields) {
132
+ const property = fieldProperty(context, model, field);
133
+ keys.set(field.name, property.key);
134
+ keys.set(field.columnName, property.key);
135
+ if (!taken.has(property.key)) {
136
+ taken.add(property.key);
137
+ properties.push(property);
138
+ }
139
+ }
140
+ for (const relation of model.relations) {
141
+ if (relation.kind === 'manyToMany') {
142
+ continue;
143
+ }
144
+ const property = foreignKeyProperty(context, relation, targetKeyName(context, relation));
145
+ keys.set(relation.name, property.key);
146
+ keys.set(relation.columnName, property.key);
147
+ if (!taken.has(property.key)) {
148
+ taken.add(property.key);
149
+ properties.push(property);
150
+ foreignKeys.push(property);
151
+ }
152
+ }
153
+ return { properties, keys, foreignKeys };
154
+ }
155
+ function maxLengthWarning(model) {
156
+ const names = model.fields
157
+ .filter((field) => field.maxLength !== undefined)
158
+ .map((field) => field.name);
159
+ return names.length === 0
160
+ ? undefined
161
+ : `${model.name}: the maximum length of ${names.join(', ')} has no Neo4j schema representation and was dropped.`;
162
+ }
163
+ function referencedElsewhere(schema, model) {
164
+ return schema.models.some((other) => other.relations.some((relation) => relation.targetModel === model.name) ||
165
+ (other.compositeForeignKeys ?? []).some((key) => key.targetModel === model.name));
166
+ }
167
+ function relationMatches(relation, name) {
168
+ return relation.name === name || relation.columnName === name;
169
+ }
170
+ function hasUniquePair(model, a, b) {
171
+ return model.indexes.some((index) => index.isUnique &&
172
+ index.kind === undefined &&
173
+ index.fields.length === 2 &&
174
+ index.fields.some((name) => relationMatches(a, name)) &&
175
+ index.fields.some((name) => relationMatches(b, name)));
176
+ }
177
+ /**
178
+ * A pure join table has exactly two required foreign keys, nothing else refers to it, and either the
179
+ * two keys together are its primary key or a surrogate key column is paired with a unique pair of
180
+ * the two keys (the table Django and Prisma write for a many-to-many field).
181
+ */
182
+ function joinCandidate(schema, model) {
183
+ if (model.isView === true ||
184
+ (model.compositeForeignKeys ?? []).length > 0 ||
185
+ model.relations.length !== 2 ||
186
+ referencedElsewhere(schema, model)) {
187
+ return undefined;
188
+ }
189
+ const [from, to] = model.relations;
190
+ if (from === undefined ||
191
+ to === undefined ||
192
+ from.kind !== 'foreignKey' ||
193
+ to.kind !== 'foreignKey' ||
194
+ from.isNullable ||
195
+ to.isNullable) {
196
+ return undefined;
197
+ }
198
+ const keyNames = primaryKeyNamesOf(model);
199
+ const keyIsPair = keyNames.length === 2 &&
200
+ keyNames.every((name) => relationMatches(from, name) || relationMatches(to, name));
201
+ if (keyIsPair) {
202
+ return { model, from, to };
203
+ }
204
+ const surrogate = keyNames.length === 1
205
+ ? model.fields.find((field) => field.name === keyNames[0])
206
+ : undefined;
207
+ if (surrogate !== undefined &&
208
+ (model.isJoinTable === true || hasUniquePair(model, from, to))) {
209
+ return { model, from, to, surrogateKey: surrogate };
210
+ }
211
+ return undefined;
212
+ }
213
+ function joinType(join) {
214
+ return relationshipTypeOf(join.from.relatedName ?? join.to.name);
215
+ }
216
+ /**
217
+ * Derives the graph model. Warnings for dropped or approximated details are added to `warnings`
218
+ * in model order.
219
+ */
220
+ export function buildGraph(schema, options, warnings) {
221
+ const context = { schema, options, warnings };
222
+ const candidates = new Map();
223
+ for (const model of schema.models) {
224
+ const candidate = joinCandidate(schema, model);
225
+ if (candidate !== undefined) {
226
+ candidates.set(model.name, candidate);
227
+ }
228
+ }
229
+ // A join table that points at another join table stays an ordinary node, so both ends exist.
230
+ for (const [name, candidate] of [...candidates]) {
231
+ if (candidates.has(candidate.from.targetModel) ||
232
+ candidates.has(candidate.to.targetModel) ||
233
+ findModel(schema, candidate.from.targetModel) === undefined ||
234
+ findModel(schema, candidate.to.targetModel) === undefined) {
235
+ candidates.delete(name);
236
+ }
237
+ }
238
+ const labels = new NameRegistry();
239
+ const nodes = [];
240
+ const joins = [];
241
+ const byModel = new Map();
242
+ for (const model of schema.models) {
243
+ const candidate = candidates.get(model.name);
244
+ if (candidate !== undefined) {
245
+ continue;
246
+ }
247
+ const wanted = labelOf(model.name);
248
+ const label = labels.claim(wanted);
249
+ if (label !== wanted) {
250
+ warnings.push(`${model.name}: the label ${wanted} is already used by another model; this model uses ${label}.`);
251
+ }
252
+ const built = buildProperties(context, model);
253
+ const node = {
254
+ model,
255
+ label,
256
+ properties: built.properties,
257
+ keys: built.keys,
258
+ foreignKeys: built.foreignKeys,
259
+ };
260
+ nodes.push(node);
261
+ byModel.set(model.name, node);
262
+ const lengths = maxLengthWarning(model);
263
+ if (lengths !== undefined) {
264
+ warnings.push(lengths);
265
+ }
266
+ }
267
+ for (const model of schema.models) {
268
+ const candidate = candidates.get(model.name);
269
+ if (candidate === undefined) {
270
+ continue;
271
+ }
272
+ joins.push(buildJoin(context, candidate));
273
+ }
274
+ return { nodes, joins, byModel };
275
+ }
276
+ function buildJoin(context, candidate) {
277
+ const { model, from, to, surrogateKey } = candidate;
278
+ const extras = model.fields
279
+ .filter((field) => field !== surrogateKey)
280
+ .map((field) => fieldProperty(context, model, field));
281
+ const keys = new Map();
282
+ for (const field of model.fields) {
283
+ keys.set(field.name, propertyKeyOf(field.columnName, context.options.camelFields));
284
+ }
285
+ if (surrogateKey !== undefined) {
286
+ context.warnings.push(`${model.name}: the join table became a relationship, so its surrogate key ${surrogateKey.name} was dropped.`);
287
+ }
288
+ const lengths = maxLengthWarning(model);
289
+ if (lengths !== undefined) {
290
+ context.warnings.push(lengths);
291
+ }
292
+ const pairColumns = [
293
+ propertyKeyOf(from.columnName, context.options.camelFields),
294
+ propertyKeyOf(to.columnName, context.options.camelFields),
295
+ ];
296
+ keys.set(from.name, pairColumns[0]);
297
+ keys.set(from.columnName, pairColumns[0]);
298
+ keys.set(to.name, pairColumns[1]);
299
+ keys.set(to.columnName, pairColumns[1]);
300
+ return {
301
+ model,
302
+ from,
303
+ to,
304
+ type: joinType(candidate),
305
+ ...(surrogateKey === undefined ? {} : { surrogateKey }),
306
+ extras,
307
+ pairColumns,
308
+ keys,
309
+ };
310
+ }
311
+ //# sourceMappingURL=neo4jGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo4jGraph.js","sourceRoot":"","sources":["../../src/emitters/neo4jGraph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Writes a label, relationship type, property key or constraint name. Names that are not plain
3
+ * identifiers are wrapped in backticks, and a backtick inside the name is doubled.
4
+ */
5
+ export declare function quoteIdentifier(name: string): string;
6
+ /** Collapses line breaks and runs of whitespace so text can sit safely inside a one-line `//` comment. */
7
+ export declare function oneLine(text: string): string;
8
+ /** Node label of a model: PascalCase and singular (`blog_posts` and `BlogPosts` both give `BlogPost`). */
9
+ export declare function labelOf(modelName: string): string;
10
+ /** Relationship type of a relation field: UPPER_SNAKE_CASE (`edited_by` and `editedBy` give `EDITED_BY`). */
11
+ export declare function relationshipTypeOf(relationName: string): string;
12
+ /**
13
+ * Property key of a column. The `preserve` naming mode keeps the column name; `normalize` uses
14
+ * camelCase, the Neo4j convention. A name with no letters or digits is kept as it is.
15
+ */
16
+ export declare function propertyKeyOf(columnName: string, camelCase: boolean): string;
17
+ /** Hands out names that are unique within one namespace (labels, or constraint and index names). */
18
+ export declare class NameRegistry {
19
+ private readonly used;
20
+ /** Reserves `base`, or `base2`, `base3`, ... when it is taken, and returns the name reserved. */
21
+ claim(base: string): string;
22
+ has(name: string): boolean;
23
+ }
24
+ /** snake_case words for a constraint or index name (`x` when the text has no letters or digits). */
25
+ export declare function nameWords(text: string): string;
@@ -0,0 +1,58 @@
1
+ import { singularize, toCamelCase, toPascalCase, toSnakeCase, } from '../naming.js';
2
+ const PLAIN_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
3
+ /**
4
+ * Writes a label, relationship type, property key or constraint name. Names that are not plain
5
+ * identifiers are wrapped in backticks, and a backtick inside the name is doubled.
6
+ */
7
+ export function quoteIdentifier(name) {
8
+ return PLAIN_IDENTIFIER.test(name) ? name : `\`${name.replace(/`/g, '``')}\``;
9
+ }
10
+ /** Collapses line breaks and runs of whitespace so text can sit safely inside a one-line `//` comment. */
11
+ export function oneLine(text) {
12
+ return text.replace(/\s+/g, ' ').trim();
13
+ }
14
+ /** Node label of a model: PascalCase and singular (`blog_posts` and `BlogPosts` both give `BlogPost`). */
15
+ export function labelOf(modelName) {
16
+ const label = toPascalCase(singularize(toSnakeCase(modelName)));
17
+ return label === '' ? modelName : label;
18
+ }
19
+ /** Relationship type of a relation field: UPPER_SNAKE_CASE (`edited_by` and `editedBy` give `EDITED_BY`). */
20
+ export function relationshipTypeOf(relationName) {
21
+ const type = toSnakeCase(relationName).toUpperCase();
22
+ return type === '' ? 'RELATED_TO' : type;
23
+ }
24
+ /**
25
+ * Property key of a column. The `preserve` naming mode keeps the column name; `normalize` uses
26
+ * camelCase, the Neo4j convention. A name with no letters or digits is kept as it is.
27
+ */
28
+ export function propertyKeyOf(columnName, camelCase) {
29
+ if (!camelCase) {
30
+ return columnName;
31
+ }
32
+ const camel = toCamelCase(columnName);
33
+ return camel === '' ? columnName : camel;
34
+ }
35
+ /** Hands out names that are unique within one namespace (labels, or constraint and index names). */
36
+ export class NameRegistry {
37
+ used = new Set();
38
+ /** Reserves `base`, or `base2`, `base3`, ... when it is taken, and returns the name reserved. */
39
+ claim(base) {
40
+ let candidate = base;
41
+ let suffix = 2;
42
+ while (this.used.has(candidate)) {
43
+ candidate = `${base}${suffix}`;
44
+ suffix += 1;
45
+ }
46
+ this.used.add(candidate);
47
+ return candidate;
48
+ }
49
+ has(name) {
50
+ return this.used.has(name);
51
+ }
52
+ }
53
+ /** snake_case words for a constraint or index name (`x` when the text has no letters or digits). */
54
+ export function nameWords(text) {
55
+ const words = toSnakeCase(text);
56
+ return words === '' ? 'x' : words;
57
+ }
58
+ //# sourceMappingURL=neo4jNames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo4jNames.js","sourceRoot":"","sources":["../../src/emitters/neo4jNames.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,MAAM,gBAAgB,GAAW,0BAA0B,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,OAAO,CAAC,SAAiB;IACvC,MAAM,KAAK,GAAW,YAAY,CAAC,WAAW,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,MAAM,IAAI,GAAW,WAAW,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7D,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,SAAkB;IAClE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,KAAK,GAAW,WAAW,CAAC,UAAU,CAAC,CAAC;IAC9C,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3C,CAAC;AAED,oGAAoG;AACpG,MAAM,OAAO,YAAY;IACN,IAAI,GAAgB,IAAI,GAAG,EAAU,CAAC;IAEvD,iGAAiG;IACjG,KAAK,CAAC,IAAY;QAChB,IAAI,SAAS,GAAW,IAAI,CAAC;QAC7B,IAAI,MAAM,GAAW,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,SAAS,GAAG,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,oGAAoG;AACpG,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,KAAK,GAAW,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACpC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { IrSchema } from '../ir.js';
2
+ import { type Graph } from './neo4jGraph.js';
3
+ import { type StatementWriter } from './neo4jStatements.js';
4
+ /**
5
+ * Writes the relationship section. Cypher has no relationship schema, so each foreign key, relation
6
+ * and join table becomes a comment block that names the pattern, the cardinality, the referential
7
+ * action and a query that creates the relationships from the foreign key properties. Only a join
8
+ * table with unique columns gets real statements (relationship property constraints).
9
+ */
10
+ export interface RelationshipSection {
11
+ /** Comment lines and statements, one entry per line, blank lines included. */
12
+ lines: string[];
13
+ }
14
+ /** Writes every relationship block, then the join table constraint statements that follow their block. */
15
+ export declare function writeRelationships(schema: IrSchema, graph: Graph, writer: StatementWriter, warnings: string[]): RelationshipSection;