ormbridge 0.8.0 → 0.9.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/README.md +1 -0
- package/dist/cliRunner.js +3 -3
- package/dist/cliRunner.js.map +1 -1
- package/dist/config.d.ts +3 -2
- package/dist/config.js.map +1 -1
- package/dist/emitters/efcore.d.ts +40 -0
- package/dist/emitters/efcore.js +686 -0
- package/dist/emitters/efcore.js.map +1 -0
- package/dist/emitters/efcoreColumns.d.ts +75 -0
- package/dist/emitters/efcoreColumns.js +492 -0
- package/dist/emitters/efcoreColumns.js.map +1 -0
- package/dist/emitters/efcoreNames.d.ts +30 -0
- package/dist/emitters/efcoreNames.js +268 -0
- package/dist/emitters/efcoreNames.js.map +1 -0
- package/dist/emitters/efcoreRender.d.ts +2 -0
- package/dist/emitters/efcoreRender.js +570 -0
- package/dist/emitters/efcoreRender.js.map +1 -0
- package/dist/emitters/efcoreTypes.d.ts +114 -0
- package/dist/emitters/efcoreTypes.js +2 -0
- package/dist/emitters/efcoreTypes.js.map +1 -0
- package/dist/formats.d.ts +7 -4
- package/dist/formats.js +34 -0
- package/dist/formats.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/io.js +25 -1
- package/dist/io.js.map +1 -1
- package/dist/parsers/csharpChains.d.ts +36 -0
- package/dist/parsers/csharpChains.js +157 -0
- package/dist/parsers/csharpChains.js.map +1 -0
- package/dist/parsers/csharpDeclarations.d.ts +3 -0
- package/dist/parsers/csharpDeclarations.js +293 -0
- package/dist/parsers/csharpDeclarations.js.map +1 -0
- package/dist/parsers/csharpSyntax.d.ts +130 -0
- package/dist/parsers/csharpSyntax.js +339 -0
- package/dist/parsers/csharpSyntax.js.map +1 -0
- package/dist/parsers/efcore.d.ts +17 -0
- package/dist/parsers/efcore.js +265 -0
- package/dist/parsers/efcore.js.map +1 -0
- package/dist/parsers/efcoreAnnotations.d.ts +19 -0
- package/dist/parsers/efcoreAnnotations.js +293 -0
- package/dist/parsers/efcoreAnnotations.js.map +1 -0
- package/dist/parsers/efcoreBuild.d.ts +13 -0
- package/dist/parsers/efcoreBuild.js +523 -0
- package/dist/parsers/efcoreBuild.js.map +1 -0
- package/dist/parsers/efcoreEntities.d.ts +13 -0
- package/dist/parsers/efcoreEntities.js +468 -0
- package/dist/parsers/efcoreEntities.js.map +1 -0
- package/dist/parsers/efcoreFields.d.ts +22 -0
- package/dist/parsers/efcoreFields.js +285 -0
- package/dist/parsers/efcoreFields.js.map +1 -0
- package/dist/parsers/efcoreFluent.d.ts +47 -0
- package/dist/parsers/efcoreFluent.js +375 -0
- package/dist/parsers/efcoreFluent.js.map +1 -0
- package/dist/parsers/efcoreModel.d.ts +209 -0
- package/dist/parsers/efcoreModel.js +2 -0
- package/dist/parsers/efcoreModel.js.map +1 -0
- package/dist/parsers/efcoreRelations.d.ts +46 -0
- package/dist/parsers/efcoreRelations.js +317 -0
- package/dist/parsers/efcoreRelations.js.map +1 -0
- package/dist/parsers/efcoreSteps.d.ts +89 -0
- package/dist/parsers/efcoreSteps.js +793 -0
- package/dist/parsers/efcoreSteps.js.map +1 -0
- package/dist/parsers/efcoreTypes.d.ts +35 -0
- package/dist/parsers/efcoreTypes.js +404 -0
- package/dist/parsers/efcoreTypes.js.map +1 -0
- package/dist/styles.d.ts +3 -2
- package/dist/styles.js +4 -1
- package/dist/styles.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { bodyStatements, flattenChain, } from './csharpChains.js';
|
|
2
|
+
import { annotateEntity, newEntityConfig } from './efcoreAnnotations.js';
|
|
3
|
+
import { FluentSteps, NONE } from './efcoreSteps.js';
|
|
4
|
+
const MAX_CALL_DEPTH = 8;
|
|
5
|
+
/** The entity configurations of a project, built from data annotations and then the fluent API. */
|
|
6
|
+
export class ConfigStore extends FluentSteps {
|
|
7
|
+
project;
|
|
8
|
+
consts;
|
|
9
|
+
chainOf;
|
|
10
|
+
entities = new Map();
|
|
11
|
+
/** Entity names in the order they were discovered. */
|
|
12
|
+
entityOrder = [];
|
|
13
|
+
/** Set by a loop that assigns `DeleteBehavior` to every foreign key. */
|
|
14
|
+
globalDeleteBehavior;
|
|
15
|
+
applied = new Set();
|
|
16
|
+
unknown = new Set();
|
|
17
|
+
callDepth = 0;
|
|
18
|
+
navigationNameCache;
|
|
19
|
+
constructor(project, consts, chainOf) {
|
|
20
|
+
super();
|
|
21
|
+
this.project = project;
|
|
22
|
+
this.consts = consts;
|
|
23
|
+
this.chainOf = chainOf;
|
|
24
|
+
}
|
|
25
|
+
warn(message) {
|
|
26
|
+
this.project.warnings.push(message);
|
|
27
|
+
}
|
|
28
|
+
/** Reports a fluent call that is not interpreted, once per call name and place. */
|
|
29
|
+
unknownCall(name, place, detail = '') {
|
|
30
|
+
const key = `${place}|${name}`;
|
|
31
|
+
if (this.unknown.has(key)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.unknown.add(key);
|
|
35
|
+
this.warn(`${place}: the call ${name}(...) is not interpreted and was ignored${detail === '' ? '' : ` (${detail})`}.`);
|
|
36
|
+
}
|
|
37
|
+
/** The configuration of an entity, created from its data annotations on first use. */
|
|
38
|
+
entity(name) {
|
|
39
|
+
const existing = this.entities.get(name);
|
|
40
|
+
if (existing !== undefined) {
|
|
41
|
+
return existing;
|
|
42
|
+
}
|
|
43
|
+
const cls = this.project.classes.get(name);
|
|
44
|
+
if (cls === undefined || cls.kind === 'interface') {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const config = newEntityConfig(name);
|
|
48
|
+
annotateEntity(this.chainOf(cls), config, this.consts, (message) => this.warn(message));
|
|
49
|
+
this.entities.set(name, config);
|
|
50
|
+
this.entityOrder.push(name);
|
|
51
|
+
return config;
|
|
52
|
+
}
|
|
53
|
+
/** Adds an entity that was found by a convention (a DbSet, an annotation or a navigation). */
|
|
54
|
+
addEntity(name) {
|
|
55
|
+
return this.entity(name);
|
|
56
|
+
}
|
|
57
|
+
has(name) {
|
|
58
|
+
return this.entities.has(name);
|
|
59
|
+
}
|
|
60
|
+
// -------------------------------------------------------------------------
|
|
61
|
+
// Running configuration code
|
|
62
|
+
// -------------------------------------------------------------------------
|
|
63
|
+
/** Reads `OnModelCreating` of a context. */
|
|
64
|
+
runContext(context) {
|
|
65
|
+
for (const method of context.methods) {
|
|
66
|
+
const place = `${context.name}.${method.name}`;
|
|
67
|
+
if (method.name === 'ConfigureConventions') {
|
|
68
|
+
this.warn(`${place}: convention configuration (ConfigureConventions) is not interpreted; settings made there, such as a default string length or enum conversion, are not applied.`);
|
|
69
|
+
}
|
|
70
|
+
if (method.name !== 'OnModelCreating' ||
|
|
71
|
+
method.body === undefined ||
|
|
72
|
+
method.parameters.length === 0) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const parameter = method.parameters[0]?.name;
|
|
76
|
+
if (parameter === undefined) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const bindings = new Map([
|
|
80
|
+
[parameter, { kind: 'model' }],
|
|
81
|
+
]);
|
|
82
|
+
this.runStatements(method.body, bindings, place, context);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Reads the `Configure` method of an IEntityTypeConfiguration<T> class. */
|
|
86
|
+
runConfiguration(cls, entityName) {
|
|
87
|
+
if (this.applied.has(cls)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.applied.add(cls);
|
|
91
|
+
const config = this.entity(entityName);
|
|
92
|
+
const method = cls.methods.find((candidate) => candidate.name === 'Configure' && candidate.parameters.length === 1);
|
|
93
|
+
const parameter = method?.parameters[0]?.name;
|
|
94
|
+
if (config === undefined ||
|
|
95
|
+
method?.body === undefined ||
|
|
96
|
+
parameter === undefined) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const bindings = new Map([
|
|
100
|
+
[parameter, this.entityTarget(config)],
|
|
101
|
+
]);
|
|
102
|
+
this.runStatements(method.body, bindings, `${cls.name}.Configure`, cls);
|
|
103
|
+
}
|
|
104
|
+
/** Applies the configuration classes that no context applied explicitly (ApplyConfigurationsFromAssembly). */
|
|
105
|
+
applyAllConfigurations() {
|
|
106
|
+
for (const { cls, entity } of this.project.configurations) {
|
|
107
|
+
this.runConfiguration(cls, entity);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** The configuration classes that were never applied. */
|
|
111
|
+
unappliedConfigurations() {
|
|
112
|
+
return this.project.configurations
|
|
113
|
+
.map(({ cls }) => cls)
|
|
114
|
+
.filter((cls) => !this.applied.has(cls));
|
|
115
|
+
}
|
|
116
|
+
/** The navigation names the fluent API configures (HasOne / HasMany / WithOne / WithMany arguments). */
|
|
117
|
+
navigationNames() {
|
|
118
|
+
// Called once the fluent code has been read, so the set no longer changes.
|
|
119
|
+
if (this.navigationNameCache !== undefined) {
|
|
120
|
+
return this.navigationNameCache;
|
|
121
|
+
}
|
|
122
|
+
const names = new Set();
|
|
123
|
+
for (const config of this.entities.values()) {
|
|
124
|
+
for (const rel of config.relations) {
|
|
125
|
+
for (const name of [rel.ownerNav, rel.inverseNav]) {
|
|
126
|
+
if (name !== undefined) {
|
|
127
|
+
names.add(name);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
this.navigationNameCache = names;
|
|
133
|
+
return names;
|
|
134
|
+
}
|
|
135
|
+
entityTarget(config) {
|
|
136
|
+
return {
|
|
137
|
+
kind: 'entity',
|
|
138
|
+
entity: config.name,
|
|
139
|
+
config,
|
|
140
|
+
scope: config,
|
|
141
|
+
prefix: '',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// -------------------------------------------------------------------------
|
|
145
|
+
// Statements
|
|
146
|
+
// -------------------------------------------------------------------------
|
|
147
|
+
runStatements(body, bindings, place, owner) {
|
|
148
|
+
for (const statement of bodyStatements(body)) {
|
|
149
|
+
this.runStatement(statement, bindings, place, owner);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
runStatement(statement, bindings, place, owner) {
|
|
153
|
+
switch (statement.type) {
|
|
154
|
+
case 'expression_statement': {
|
|
155
|
+
const expression = statement.namedChild(0);
|
|
156
|
+
if (expression !== null) {
|
|
157
|
+
this.runExpression(expression, bindings, place, owner);
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
case 'invocation_expression':
|
|
162
|
+
this.runExpression(statement, bindings, place, owner);
|
|
163
|
+
return;
|
|
164
|
+
case 'local_declaration_statement': {
|
|
165
|
+
const declaration = statement.namedChildren.find((child) => child.type === 'variable_declaration');
|
|
166
|
+
for (const declarator of declaration?.namedChildren ?? []) {
|
|
167
|
+
if (declarator.type !== 'variable_declarator') {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const name = declarator.namedChild(0)?.text;
|
|
171
|
+
const clause = declarator.namedChildren.find((child) => child.type === 'equals_value_clause');
|
|
172
|
+
const initializer = clause?.namedChild(0) ?? null;
|
|
173
|
+
if (name === undefined || initializer === null) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const target = this.runExpression(initializer, bindings, place, owner);
|
|
177
|
+
if (target.kind !== 'none') {
|
|
178
|
+
bindings.set(name, target);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
case 'block':
|
|
184
|
+
this.runStatements(statement, bindings, place, owner);
|
|
185
|
+
return;
|
|
186
|
+
case 'if_statement': {
|
|
187
|
+
this.warn(`${place}: a conditional (if) around configuration code is not evaluated; the calls in all of its branches were read.`);
|
|
188
|
+
for (const field of ['consequence', 'alternative']) {
|
|
189
|
+
const branch = statement.childForFieldName(field);
|
|
190
|
+
if (branch !== null) {
|
|
191
|
+
this.runStatement(branch, bindings, place, owner);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
case 'using_statement':
|
|
197
|
+
case 'try_statement':
|
|
198
|
+
case 'lock_statement':
|
|
199
|
+
case 'checked_statement':
|
|
200
|
+
case 'catch_clause':
|
|
201
|
+
case 'finally_clause':
|
|
202
|
+
for (const child of statement.namedChildren) {
|
|
203
|
+
if (child.type === 'block' ||
|
|
204
|
+
child.type === 'catch_clause' ||
|
|
205
|
+
child.type === 'finally_clause' ||
|
|
206
|
+
child.type.endsWith('_statement')) {
|
|
207
|
+
this.runStatement(child, bindings, place, owner);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
case 'for_each_statement':
|
|
212
|
+
case 'for_statement':
|
|
213
|
+
case 'while_statement':
|
|
214
|
+
case 'do_statement':
|
|
215
|
+
this.readLoop(statement, place);
|
|
216
|
+
return;
|
|
217
|
+
case 'return_statement':
|
|
218
|
+
case 'comment':
|
|
219
|
+
case 'empty_statement':
|
|
220
|
+
return;
|
|
221
|
+
default:
|
|
222
|
+
this.unknownCall(statement.type.replace(/_statement$/, ''), place, 'statement kind');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
readLoop(statement, place) {
|
|
226
|
+
// The usual loop disables cascade delete for every foreign key.
|
|
227
|
+
const assignment = statement.text.match(/\.DeleteBehavior\s*=\s*(?:\w+\.)*DeleteBehavior\.(\w+)/);
|
|
228
|
+
if (assignment !== null && assignment[1] !== undefined) {
|
|
229
|
+
this.globalDeleteBehavior = assignment[1];
|
|
230
|
+
this.warn(`${place}: a loop assigns DeleteBehavior.${assignment[1]} to every foreign key; it was applied to all relationships.`);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
this.warn(`${place}: a loop over the model (${statement.text
|
|
234
|
+
.split('\n')[0]
|
|
235
|
+
?.trim()
|
|
236
|
+
.slice(0, 60)}...) is not interpreted; whatever it configures is not applied.`);
|
|
237
|
+
}
|
|
238
|
+
runExpression(expression, bindings, place, owner) {
|
|
239
|
+
if (expression.type === 'assignment_expression') {
|
|
240
|
+
return NONE;
|
|
241
|
+
}
|
|
242
|
+
const chain = flattenChain(expression);
|
|
243
|
+
if (chain === undefined) {
|
|
244
|
+
return NONE;
|
|
245
|
+
}
|
|
246
|
+
// A call to a helper method of the same class or an extension method.
|
|
247
|
+
const first = chain.calls[0];
|
|
248
|
+
if (first !== undefined && chain.root.type === 'identifier') {
|
|
249
|
+
const rootTarget = bindings.get(chain.root.text);
|
|
250
|
+
if (rootTarget === undefined) {
|
|
251
|
+
return this.callUserMethod(chain, undefined, bindings, place, owner);
|
|
252
|
+
}
|
|
253
|
+
let target = rootTarget;
|
|
254
|
+
for (const call of chain.calls) {
|
|
255
|
+
const helper = KNOWN_CALLS.has(call.name)
|
|
256
|
+
? undefined
|
|
257
|
+
: this.findExtension(call.name);
|
|
258
|
+
if (helper !== undefined) {
|
|
259
|
+
// Extension methods that configure a builder are followed into their body.
|
|
260
|
+
this.invoke(helper, target, call, bindings, place, owner);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
target = this.step(target, call, bindings, place, owner);
|
|
264
|
+
}
|
|
265
|
+
return target;
|
|
266
|
+
}
|
|
267
|
+
if (chain.root.type === 'this_expression' ||
|
|
268
|
+
chain.root.type === 'base_expression') {
|
|
269
|
+
return this.callUserMethod(chain, undefined, bindings, place, owner);
|
|
270
|
+
}
|
|
271
|
+
return NONE;
|
|
272
|
+
}
|
|
273
|
+
findExtension(name) {
|
|
274
|
+
for (const cls of this.project.classes.values()) {
|
|
275
|
+
if (!cls.modifiers.includes('static')) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const method = cls.methods.find((candidate) => candidate.name === name &&
|
|
279
|
+
candidate.node.text.includes('this ') &&
|
|
280
|
+
candidate.body !== undefined);
|
|
281
|
+
if (method !== undefined) {
|
|
282
|
+
return method;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
callUserMethod(chain, receiver, bindings, place, owner) {
|
|
288
|
+
const call = chain.calls[0];
|
|
289
|
+
if (call === undefined) {
|
|
290
|
+
return NONE;
|
|
291
|
+
}
|
|
292
|
+
if (call.name === 'OnModelCreating' || chain.root.text === 'base') {
|
|
293
|
+
return NONE;
|
|
294
|
+
}
|
|
295
|
+
const method = owner.methods.find((candidate) => candidate.name === call.name && candidate.body !== undefined) ?? this.findExtension(call.name);
|
|
296
|
+
if (method === undefined) {
|
|
297
|
+
return NONE;
|
|
298
|
+
}
|
|
299
|
+
this.invoke(method, receiver, call, bindings, place, owner);
|
|
300
|
+
return NONE;
|
|
301
|
+
}
|
|
302
|
+
invoke(method, receiver, call, bindings, place, owner) {
|
|
303
|
+
if (method.body === undefined || this.callDepth >= MAX_CALL_DEPTH) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const inner = new Map();
|
|
307
|
+
const isExtension = method.node.text.includes('this ');
|
|
308
|
+
const names = method.parameters.map((p) => p.name);
|
|
309
|
+
let index = 0;
|
|
310
|
+
if (isExtension && receiver !== undefined && names[0] !== undefined) {
|
|
311
|
+
inner.set(names[0], receiver);
|
|
312
|
+
index = 1;
|
|
313
|
+
}
|
|
314
|
+
for (const argument of call.args) {
|
|
315
|
+
const name = names[index];
|
|
316
|
+
index += 1;
|
|
317
|
+
if (name === undefined) {
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
if (argument.type === 'identifier') {
|
|
321
|
+
const bound = bindings.get(argument.text);
|
|
322
|
+
if (bound !== undefined) {
|
|
323
|
+
inner.set(name, bound);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
this.callDepth += 1;
|
|
328
|
+
try {
|
|
329
|
+
this.runStatements(method.body, inner, `${place} > ${method.name}`, owner);
|
|
330
|
+
}
|
|
331
|
+
finally {
|
|
332
|
+
this.callDepth -= 1;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// -------------------------------------------------------------------------
|
|
336
|
+
// Builder steps
|
|
337
|
+
// -------------------------------------------------------------------------
|
|
338
|
+
runLambda(lambda, target, bindings, place, owner) {
|
|
339
|
+
const inner = new Map(bindings);
|
|
340
|
+
if (lambda.parameter !== undefined) {
|
|
341
|
+
inner.set(lambda.parameter, target);
|
|
342
|
+
}
|
|
343
|
+
this.runStatements(lambda.body, inner, place, owner);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/** Builder method names that are never read as user-defined extension methods. */
|
|
347
|
+
const KNOWN_CALLS = new Set([
|
|
348
|
+
'Entity',
|
|
349
|
+
'Property',
|
|
350
|
+
'HasKey',
|
|
351
|
+
'HasNoKey',
|
|
352
|
+
'HasIndex',
|
|
353
|
+
'HasAlternateKey',
|
|
354
|
+
'Ignore',
|
|
355
|
+
'ToTable',
|
|
356
|
+
'ToView',
|
|
357
|
+
'HasOne',
|
|
358
|
+
'HasMany',
|
|
359
|
+
'OwnsOne',
|
|
360
|
+
'OwnsMany',
|
|
361
|
+
'ComplexProperty',
|
|
362
|
+
'HasDiscriminator',
|
|
363
|
+
'HasBaseType',
|
|
364
|
+
'HasComment',
|
|
365
|
+
'HasData',
|
|
366
|
+
'HasQueryFilter',
|
|
367
|
+
'Navigation',
|
|
368
|
+
'ToJson',
|
|
369
|
+
'WithOwner',
|
|
370
|
+
'ApplyConfiguration',
|
|
371
|
+
'ApplyConfigurationsFromAssembly',
|
|
372
|
+
'HasDefaultSchema',
|
|
373
|
+
'Owned',
|
|
374
|
+
]);
|
|
375
|
+
//# sourceMappingURL=efcoreFluent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"efcoreFluent.js","sourceRoot":"","sources":["../../src/parsers/efcoreFluent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import type { CsClass, CsEnum, CsValue, CsType } from './csharpSyntax.js';
|
|
2
|
+
/** Settings that data annotations and the fluent API give one property. Fluent calls overwrite annotations. */
|
|
3
|
+
export interface PropConfig {
|
|
4
|
+
column?: string;
|
|
5
|
+
columnType?: string;
|
|
6
|
+
maxLength?: number;
|
|
7
|
+
/** True or false when the property is explicitly required or optional. */
|
|
8
|
+
required?: boolean;
|
|
9
|
+
precision?: number;
|
|
10
|
+
scale?: number;
|
|
11
|
+
/** `HasDefaultValue(...)`. A `null` value means HasDefaultValue() with no argument. */
|
|
12
|
+
defaultValue?: CsValue;
|
|
13
|
+
defaultSql?: string;
|
|
14
|
+
/** How the value is generated: `identity` / `onAdd`, `computed` / `onAddOrUpdate`, or `never`. */
|
|
15
|
+
generated?: 'onAdd' | 'onAddOrUpdate' | 'never';
|
|
16
|
+
computedSql?: string;
|
|
17
|
+
computedStored?: boolean;
|
|
18
|
+
/** The storage type of `HasConversion<T>()`, for example `string`. */
|
|
19
|
+
conversion?: string;
|
|
20
|
+
/** True when a converter was given that cannot be evaluated statically. */
|
|
21
|
+
customConversion?: boolean;
|
|
22
|
+
/** The class of `HasConversion(new X())` / `HasConversion<X>()`, so an enum-to-string converter can be read. */
|
|
23
|
+
converterClass?: string;
|
|
24
|
+
isRowVersion?: boolean;
|
|
25
|
+
isConcurrencyToken?: boolean;
|
|
26
|
+
isUnicode?: boolean;
|
|
27
|
+
comment?: string;
|
|
28
|
+
ignored?: boolean;
|
|
29
|
+
/** Set by [Key]; the order is the position among several [Key] properties. */
|
|
30
|
+
isKey?: boolean;
|
|
31
|
+
/** True when the fluent API named the property (`Property(...)`). */
|
|
32
|
+
declared?: boolean;
|
|
33
|
+
/** The CLR type of a shadow property: `Property<int>("TenantId")`. */
|
|
34
|
+
shadowType?: string;
|
|
35
|
+
}
|
|
36
|
+
/** An index or unique constraint declared by [Index], HasIndex or HasAlternateKey. */
|
|
37
|
+
export interface ConfigIndex {
|
|
38
|
+
/** Property names (dotted for owned members). */
|
|
39
|
+
members: string[];
|
|
40
|
+
unique: boolean;
|
|
41
|
+
name?: string;
|
|
42
|
+
/** True when HasFilter / Filter makes it a partial index. */
|
|
43
|
+
hasFilter: boolean;
|
|
44
|
+
/** True when IncludeProperties adds covering columns. */
|
|
45
|
+
hasInclude: boolean;
|
|
46
|
+
/** Descending flags by member position; empty when all ascending. */
|
|
47
|
+
descending: boolean[];
|
|
48
|
+
/** Access method, from `HasMethod("gin")` (Npgsql). */
|
|
49
|
+
method?: string;
|
|
50
|
+
/** True for an alternate key rather than an index. */
|
|
51
|
+
isAlternateKey?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Members and settings of a type that is part of an entity (the entity itself, or an owned type). */
|
|
54
|
+
export interface Scope {
|
|
55
|
+
props: Map<string, PropConfig>;
|
|
56
|
+
ignored: Set<string>;
|
|
57
|
+
owned: Map<string, OwnedConfig>;
|
|
58
|
+
}
|
|
59
|
+
export interface OwnedConfig extends Scope {
|
|
60
|
+
/** The navigation property name on the owner. */
|
|
61
|
+
nav: string;
|
|
62
|
+
many: boolean;
|
|
63
|
+
/** True for `ToJson()`: the owned type is stored in one JSON column. */
|
|
64
|
+
toJson: boolean;
|
|
65
|
+
/** Set by OwnsOne / ComplexProperty with an explicit column prefix; unused by default. */
|
|
66
|
+
table?: string;
|
|
67
|
+
}
|
|
68
|
+
/** A relationship from HasOne / HasMany and what follows. */
|
|
69
|
+
export interface FluentRelation {
|
|
70
|
+
/** The entity whose builder the call was made on. */
|
|
71
|
+
owner: string;
|
|
72
|
+
/** The navigation on `owner`, or undefined for `HasOne<T>()`. */
|
|
73
|
+
ownerNav?: string;
|
|
74
|
+
ownerMany: boolean;
|
|
75
|
+
/** The type argument of `HasOne<T>()` / `HasMany<T>()`. */
|
|
76
|
+
target?: string;
|
|
77
|
+
/** The navigation on the other side (`WithMany(x => x.Posts)`). */
|
|
78
|
+
inverseNav?: string;
|
|
79
|
+
inverseMany: boolean;
|
|
80
|
+
/** True once a With* call was seen (a half-built relation is ignored). */
|
|
81
|
+
complete: boolean;
|
|
82
|
+
foreignKey?: string[];
|
|
83
|
+
/** The type argument of `HasForeignKey<T>(...)`: the dependent entity. */
|
|
84
|
+
foreignKeyEntity?: string;
|
|
85
|
+
principalKey?: string[];
|
|
86
|
+
onDelete?: string;
|
|
87
|
+
required?: boolean;
|
|
88
|
+
constraintName?: string;
|
|
89
|
+
/** Join entity settings of a many-to-many (`UsingEntity`). */
|
|
90
|
+
join?: JoinConfig;
|
|
91
|
+
}
|
|
92
|
+
/** What `UsingEntity(...)` says about the join table of a skip-navigation many-to-many. */
|
|
93
|
+
export interface JoinConfig {
|
|
94
|
+
/** The join entity type name when written as a string or a type argument. */
|
|
95
|
+
entityName?: string;
|
|
96
|
+
/** True when the join entity is a class in the input (explicit join model). */
|
|
97
|
+
entityClass?: string;
|
|
98
|
+
table?: string;
|
|
99
|
+
schema?: string;
|
|
100
|
+
/** Foreign key columns on the join table: toward the left (owner) and the right (inverse) entity. */
|
|
101
|
+
leftColumn?: string;
|
|
102
|
+
rightColumn?: string;
|
|
103
|
+
leftOnDelete?: string;
|
|
104
|
+
rightOnDelete?: string;
|
|
105
|
+
}
|
|
106
|
+
export interface DiscriminatorConfig {
|
|
107
|
+
column?: string;
|
|
108
|
+
/** The CLR type name of the discriminator, from `HasDiscriminator<T>()`. */
|
|
109
|
+
type?: string;
|
|
110
|
+
/** `HasValue<Derived>(value)` entries: derived entity (or '' for the base) to value. */
|
|
111
|
+
values: Map<string, CsValue>;
|
|
112
|
+
}
|
|
113
|
+
export interface EntityConfig extends Scope {
|
|
114
|
+
name: string;
|
|
115
|
+
table?: string;
|
|
116
|
+
schema?: string;
|
|
117
|
+
viewName?: string;
|
|
118
|
+
/** HasNoKey() or [Keyless]. */
|
|
119
|
+
keyless: boolean;
|
|
120
|
+
/** Primary key members from [Key], [PrimaryKey] or HasKey. */
|
|
121
|
+
key?: string[];
|
|
122
|
+
/** Name of the primary key constraint, from `HasKey(...).HasName("PK_x")`. */
|
|
123
|
+
keyName?: string;
|
|
124
|
+
indexes: ConfigIndex[];
|
|
125
|
+
relations: FluentRelation[];
|
|
126
|
+
discriminator?: DiscriminatorConfig;
|
|
127
|
+
/** `HasBaseType<T>()` or `HasBaseType((Type?)null)`: the explicit base entity, '' for none. */
|
|
128
|
+
baseType?: string;
|
|
129
|
+
mapping?: 'tph' | 'tpt' | 'tpc';
|
|
130
|
+
comment?: string;
|
|
131
|
+
/** Set when HasData / HasQueryFilter was seen, to warn about it once. */
|
|
132
|
+
hasData: boolean;
|
|
133
|
+
hasQueryFilter: boolean;
|
|
134
|
+
/** Table-level check constraints (`ToTable(t => t.HasCheckConstraint(...))`, [CheckConstraint]). */
|
|
135
|
+
checkConstraints: string[];
|
|
136
|
+
/** True when the class carries [NotMapped]. */
|
|
137
|
+
notMapped: boolean;
|
|
138
|
+
/** True for the class named by `UsingEntity<T>()`: its key defaults to the two foreign keys. */
|
|
139
|
+
joinEntity?: boolean;
|
|
140
|
+
}
|
|
141
|
+
/** What is known about the input as a whole. */
|
|
142
|
+
export interface Project {
|
|
143
|
+
classes: Map<string, CsClass>;
|
|
144
|
+
enums: Map<string, CsEnum>;
|
|
145
|
+
/** Classes that derive from DbContext (directly or through another context). */
|
|
146
|
+
contexts: CsClass[];
|
|
147
|
+
/** Classes that implement IEntityTypeConfiguration<T>, with the entity they configure. */
|
|
148
|
+
configurations: {
|
|
149
|
+
cls: CsClass;
|
|
150
|
+
entity: string;
|
|
151
|
+
}[];
|
|
152
|
+
/** DbSet property name by entity name. */
|
|
153
|
+
dbSets: Map<string, string>;
|
|
154
|
+
/** True when nullable reference types are in effect for the input as a whole. */
|
|
155
|
+
nullableReferences: boolean;
|
|
156
|
+
/** The `#nullable` directive of each file by path, which overrides the project-wide setting. */
|
|
157
|
+
nullableByPath: Map<string, 'enable' | 'disable' | undefined>;
|
|
158
|
+
/** Position of each class in the input (file order, then declaration order). */
|
|
159
|
+
classOrder: Map<string, number>;
|
|
160
|
+
warnings: string[];
|
|
161
|
+
}
|
|
162
|
+
/** A scalar column with the settings that decide its IR field. */
|
|
163
|
+
export interface ScalarMember {
|
|
164
|
+
kind: 'scalar';
|
|
165
|
+
/** Property name; dotted with the owned navigation for flattened members (`Address.Street`). */
|
|
166
|
+
path: string;
|
|
167
|
+
name: string;
|
|
168
|
+
type: CsType;
|
|
169
|
+
config: PropConfig;
|
|
170
|
+
declaredIn: string;
|
|
171
|
+
/** Column name prefix from owned navigations, e.g. `Address_`. */
|
|
172
|
+
prefix: string;
|
|
173
|
+
/** True when every column of an optional owned type must allow null. */
|
|
174
|
+
forceNullable: boolean;
|
|
175
|
+
/** The JSON column of a `ToJson()` owned type. */
|
|
176
|
+
isJson?: boolean;
|
|
177
|
+
/** The navigation named by [ForeignKey("Nav")] on this property. */
|
|
178
|
+
foreignKeyNav?: string;
|
|
179
|
+
}
|
|
180
|
+
export interface NavMember {
|
|
181
|
+
kind: 'nav';
|
|
182
|
+
name: string;
|
|
183
|
+
/** The target entity (class) name. */
|
|
184
|
+
target: string;
|
|
185
|
+
many: boolean;
|
|
186
|
+
/** True when written with `?` (or inside a nullable-oblivious context: unknown). */
|
|
187
|
+
nullable: boolean;
|
|
188
|
+
declaredIn: string;
|
|
189
|
+
/** The raw properties attributes: [ForeignKey], [InverseProperty], [Required]. */
|
|
190
|
+
foreignKeyAttr?: string;
|
|
191
|
+
inverseAttr?: string;
|
|
192
|
+
requiredAttr: boolean;
|
|
193
|
+
}
|
|
194
|
+
export type Member = ScalarMember | NavMember;
|
|
195
|
+
/** One entity with its mapped members, before relationships are resolved. */
|
|
196
|
+
export interface EntityInfo {
|
|
197
|
+
name: string;
|
|
198
|
+
cls: CsClass;
|
|
199
|
+
config: EntityConfig;
|
|
200
|
+
/** The entity whose table holds this one: itself, or the root of a table-per-hierarchy. */
|
|
201
|
+
root: string;
|
|
202
|
+
/** For a root: the derived entities stored in the same table. */
|
|
203
|
+
derived: string[];
|
|
204
|
+
/** The mapped members: this entity's own, those of non-entity base classes, and for a root the derived ones. */
|
|
205
|
+
members: Member[];
|
|
206
|
+
/** True when nullable reference types are in effect in the declaring file. */
|
|
207
|
+
nullableRefs: boolean;
|
|
208
|
+
order: number;
|
|
209
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"efcoreModel.js","sourceRoot":"","sources":["../../src/parsers/efcoreModel.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ConfigStore } from './efcoreFluent.js';
|
|
2
|
+
import type { EntityInfo, JoinConfig, NavMember, ScalarMember } from './efcoreModel.js';
|
|
3
|
+
/** A one-to-many or one-to-one relationship: the dependent entity holds the foreign key. */
|
|
4
|
+
export interface Link {
|
|
5
|
+
dependent: EntityInfo;
|
|
6
|
+
principal: EntityInfo;
|
|
7
|
+
/** The navigation on the dependent entity (a single reference), when it exists. */
|
|
8
|
+
dependentNav?: NavMember;
|
|
9
|
+
/** The navigation on the principal entity (a collection or a single reference), when it exists. */
|
|
10
|
+
principalNav?: NavMember;
|
|
11
|
+
/** Foreign key property names on the dependent. */
|
|
12
|
+
foreignKey: string[];
|
|
13
|
+
/** True when the foreign key properties are not in the class (EF creates shadow properties). */
|
|
14
|
+
isShadow: boolean;
|
|
15
|
+
/** Referenced property names on the principal; its primary key by default. */
|
|
16
|
+
principalKey: string[];
|
|
17
|
+
/** True for a one-to-one relationship. */
|
|
18
|
+
isOneToOne: boolean;
|
|
19
|
+
/** Required or optional, when the source decides it. */
|
|
20
|
+
required: boolean | undefined;
|
|
21
|
+
onDelete: string | undefined;
|
|
22
|
+
constraintName: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** A many-to-many relationship through skip navigations. */
|
|
25
|
+
export interface ManyToManyLink {
|
|
26
|
+
left: EntityInfo;
|
|
27
|
+
right: EntityInfo;
|
|
28
|
+
leftNav: NavMember | undefined;
|
|
29
|
+
rightNav: NavMember | undefined;
|
|
30
|
+
join: JoinConfig | undefined;
|
|
31
|
+
}
|
|
32
|
+
export interface Relationships {
|
|
33
|
+
links: Link[];
|
|
34
|
+
manyToMany: ManyToManyLink[];
|
|
35
|
+
}
|
|
36
|
+
/** Finds a scalar member of an entity by property name, ignoring case. */
|
|
37
|
+
export declare function findScalar(info: EntityInfo, name: string): ScalarMember | undefined;
|
|
38
|
+
/** The primary key property names of an entity: explicit, or `Id` / `<Type>Id` by convention. */
|
|
39
|
+
export declare function keyOf(info: EntityInfo): string[];
|
|
40
|
+
/** Whether the property can hold null, before the key and relationship rules adjust it. */
|
|
41
|
+
export declare function isNullableMember(member: ScalarMember, nullableRefs: boolean, enumNames: ReadonlySet<string>): boolean;
|
|
42
|
+
/** Resolves entity names that were merged into a hierarchy root to the root. */
|
|
43
|
+
type Resolver = (name: string) => EntityInfo | undefined;
|
|
44
|
+
/** Reads the relationships of the entities from the fluent API, [ForeignKey], [InverseProperty] and conventions. */
|
|
45
|
+
export declare function resolveRelationships(infos: readonly EntityInfo[], store: ConfigStore, resolve: Resolver, warn: (message: string) => void): Relationships;
|
|
46
|
+
export {};
|