@deterministic-code/datasources-cli 0.1.12 → 0.1.14
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/dist/detect.js +21 -7
- package/dist/generate/CSharpRepositories.js +18 -14
- package/dist/generate/DeterministicProvider.js +23 -7
- package/dist/generate/RepositoryModel.js +10 -4
- package/dist/generate/RepositoryPlan.js +12 -5
- package/dist/generate/RustRepositories.js +42 -31
- package/dist/generate/TypeScriptRepositories.js +22 -18
- package/dist/generate/applyGenerate.js +9 -2
- package/dist/generate/applyMigrations.js +5 -13
- package/dist/generate/casing.js +28 -0
- package/dist/generate/migrateUp.js +2 -8
- package/dist/generate/sqlFlags.js +27 -0
- package/dist/migrateInit.js +4 -3
- package/dist/parse.js +102 -25
- package/dist/run.js +42 -67
- package/dist/setup.js +7 -9
- package/dist/version/applyVersion.js +11 -14
- package/dist/version/delta.js +0 -50
- package/dist/version/render.js +1 -11
- package/dist/wireRegister.js +29 -11
- package/dist/wireRustProviders.js +42 -0
- package/node_modules/@deterministic-code/csharp-generators/dist/import-generator.js +16 -12
- package/node_modules/@deterministic-code/csharp-generators/src/import-generator.test.ts +22 -11
- package/node_modules/@deterministic-code/csharp-generators/src/import-generator.ts +21 -13
- package/node_modules/@deterministic-code/datasources-code-generators/dist/nestedSelectTypes.js +2 -6
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/infer-reference-types.d.ts +2 -0
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/infer-reference-types.js +37 -0
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/reference-target.d.ts +2 -0
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/reference-target.js +6 -0
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/sql-schema.d.ts +1 -1
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/sql-schema.js +3 -6
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/version-apply.d.ts +1 -0
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/version-apply.js +38 -1
- package/node_modules/@deterministic-code/datasources-code-generators/dist/sql/common/version-migrations.js +25 -14
- package/node_modules/@deterministic-code/datasources-code-generators/package.json +4 -2
- package/node_modules/@deterministic-code/deterministic-generators-common/README.md +61 -1
- package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/dist/specification-parser.js +128 -1
- package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/specification-parser.ts +1 -0
- package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/version-snapshot.ts +154 -0
- package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/yaml-node.ts +2 -2
- package/node_modules/@deterministic-code/rust-generators/dist/import-generator.js +25 -15
- package/node_modules/@deterministic-code/rust-generators/src/import-generator.test.ts +11 -0
- package/node_modules/@deterministic-code/rust-generators/src/import-generator.ts +36 -18
- package/node_modules/@deterministic-code/typescript-generators/dist/generate-frontend-types.js +6 -1
- package/node_modules/@deterministic-code/typescript-generators/dist/generate-frontend-validators.js +6 -1
- package/node_modules/@deterministic-code/typescript-generators/dist/generate-routes.js +1 -1
- package/node_modules/@deterministic-code/typescript-generators/dist/generate-services.js +1 -1
- package/node_modules/@deterministic-code/typescript-generators/dist/import-generator.js +29 -21
- package/node_modules/@deterministic-code/typescript-generators/src/emit.ts +2 -5
- package/node_modules/@deterministic-code/typescript-generators/src/generate-frontend-types.ts +7 -1
- package/node_modules/@deterministic-code/typescript-generators/src/generate-frontend-validators.ts +7 -1
- package/node_modules/@deterministic-code/typescript-generators/src/generate-routes.ts +1 -1
- package/node_modules/@deterministic-code/typescript-generators/src/generate-services.ts +1 -1
- package/node_modules/@deterministic-code/typescript-generators/src/import-generator.test.ts +16 -0
- package/node_modules/@deterministic-code/typescript-generators/src/import-generator.ts +37 -22
- package/package.json +2 -2
|
@@ -67,7 +67,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
datasourceRel(entity: string): string {
|
|
70
|
-
return this.rel("types/generated/datasource", this.datasource(entity));
|
|
70
|
+
return this.rel(this.layered("types/generated/datasource"), this.datasource(entity));
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
datasourceQual(entity: string): string {
|
|
@@ -88,7 +88,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
88
88
|
|
|
89
89
|
datasourceValidatorRel(entity: string): string {
|
|
90
90
|
return this.rel(
|
|
91
|
-
"types/generated/datasource/validators",
|
|
91
|
+
this.layered("types/generated/datasource/validators"),
|
|
92
92
|
this.datasourceValidator(entity),
|
|
93
93
|
);
|
|
94
94
|
}
|
|
@@ -102,7 +102,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
viewRel(entity: string): string {
|
|
105
|
-
return this.rel("types/generated/views", this.view(entity));
|
|
105
|
+
return this.rel(this.layered("types/generated/views"), this.view(entity));
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
viewQual(entity: string): string {
|
|
@@ -119,7 +119,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
119
119
|
|
|
120
120
|
viewValidatorRel(entity: string): string {
|
|
121
121
|
return this.rel(
|
|
122
|
-
"types/generated/views/validators",
|
|
122
|
+
this.layered("types/generated/views/validators"),
|
|
123
123
|
this.viewValidator(entity),
|
|
124
124
|
);
|
|
125
125
|
}
|
|
@@ -133,7 +133,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
serviceRel(entity: string): string {
|
|
136
|
-
return this.rel("services/generated", this.service(entity));
|
|
136
|
+
return this.rel(this.layered("services/generated"), this.service(entity));
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
serviceCustom(name: string, module?: string): string {
|
|
@@ -143,8 +143,8 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
143
143
|
serviceCustomRel(entity: string): string {
|
|
144
144
|
const file = `${this.serviceStem(entity)}.rs`;
|
|
145
145
|
return this.organizeByFeature
|
|
146
|
-
?
|
|
147
|
-
:
|
|
146
|
+
? `${this.featuresDir(entity)}/custom/${file}`
|
|
147
|
+
: `${this.layered("services")}/custom/${file}`;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
serviceTest(entity: string): string {
|
|
@@ -152,20 +152,20 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
serviceTestRel(entity: string): string {
|
|
155
|
-
return this.rel("services/generated/__tests__", this.serviceTest(entity));
|
|
155
|
+
return this.rel(this.layered("services/generated/__tests__"), this.serviceTest(entity));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
serviceIntegrationTest(entity: string): string {
|
|
159
159
|
const file = this.rsFile(`${entity}_service_integration_tests`);
|
|
160
160
|
if (this.organizeByFeature) {
|
|
161
|
-
return
|
|
161
|
+
return `${this.featuresDir(entity)}/__tests__/${file}`;
|
|
162
162
|
}
|
|
163
163
|
return file;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
serviceIntegrationTestRel(entity: string): string {
|
|
167
167
|
return this.rel(
|
|
168
|
-
"services/generated/__tests__",
|
|
168
|
+
this.layered("services/generated/__tests__"),
|
|
169
169
|
this.serviceIntegrationTest(entity),
|
|
170
170
|
);
|
|
171
171
|
}
|
|
@@ -183,7 +183,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
routeRel(entity: string): string {
|
|
186
|
-
return this.rel("routes/generated", this.route(entity));
|
|
186
|
+
return this.rel(this.layered("routes/generated"), this.route(entity));
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
routeCustom(name: string, module?: string): string {
|
|
@@ -224,7 +224,9 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
appWiring(): string {
|
|
227
|
-
return this.organizeByFeature
|
|
227
|
+
return this.organizeByFeature
|
|
228
|
+
? `${this.casing.convertDirectories("features")}/app_wiring.rs`
|
|
229
|
+
: "app_wiring.rs";
|
|
228
230
|
}
|
|
229
231
|
|
|
230
232
|
validatorFn(
|
|
@@ -239,11 +241,12 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
239
241
|
: this.viewValidator(entity);
|
|
240
242
|
return `${this.spec("", file)}::${fn}`;
|
|
241
243
|
}
|
|
242
|
-
const ns =
|
|
244
|
+
const ns = this.layered(
|
|
243
245
|
kind === "datasource"
|
|
244
|
-
? "
|
|
245
|
-
: "
|
|
246
|
-
|
|
246
|
+
? "types/generated/datasource/validators"
|
|
247
|
+
: "types/generated/views/validators",
|
|
248
|
+
).replaceAll("/", "::");
|
|
249
|
+
return `crate::${ns}::${fn}`;
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
apiPath(entity: string): string {
|
|
@@ -271,8 +274,23 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
271
274
|
return `${this.casing.fileBase(stem)}.rs`;
|
|
272
275
|
}
|
|
273
276
|
|
|
277
|
+
private layered(path: string): string {
|
|
278
|
+
return path
|
|
279
|
+
.split("/")
|
|
280
|
+
.map((segment) =>
|
|
281
|
+
segment === "custom" || segment === "__tests__"
|
|
282
|
+
? segment
|
|
283
|
+
: this.casing.convertDirectories(segment),
|
|
284
|
+
)
|
|
285
|
+
.join("/");
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private featuresDir(entity: string): string {
|
|
289
|
+
return `${this.casing.convertDirectories("features")}/${this.casing.directory(entity)}`;
|
|
290
|
+
}
|
|
291
|
+
|
|
274
292
|
private featurePath(entity: string, file: string): string {
|
|
275
|
-
return
|
|
293
|
+
return `${this.featuresDir(entity)}/${file}`;
|
|
276
294
|
}
|
|
277
295
|
|
|
278
296
|
private serviceStem(entity: string): string {
|
|
@@ -306,7 +324,7 @@ export class RustImportGenerator implements IImportGenerator {
|
|
|
306
324
|
featureEntityFromClass(name) || "shared"
|
|
307
325
|
).replace(/-/g, "_");
|
|
308
326
|
const defaultStub = this.organizeByFeature
|
|
309
|
-
?
|
|
327
|
+
? `${this.featuresDir(entity)}/custom/${file}`
|
|
310
328
|
: `../custom/${file}`;
|
|
311
329
|
if (this.organizeByFeature) {
|
|
312
330
|
if (
|
package/node_modules/@deterministic-code/typescript-generators/dist/generate-frontend-types.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { verifyEntries } from "@deterministic-code/generators-common/reference-verifier";
|
|
2
|
+
import { createCasing } from "./common/default-casing.js";
|
|
2
3
|
import { Emit } from "./emit.js";
|
|
3
4
|
import { generateViewTypes } from "./emit-shaped-types.js";
|
|
4
5
|
import { referencesBackend } from "./inline-inherited.js";
|
|
6
|
+
const layered = (settings, path) => {
|
|
7
|
+
const casing = createCasing(settings);
|
|
8
|
+
return path.split("/").map((segment) => casing.convertDirectories(segment)).join("/");
|
|
9
|
+
};
|
|
5
10
|
const generate = async (ctx) => {
|
|
6
11
|
const referenceBackendType = referencesBackend(ctx.settings);
|
|
7
12
|
const views = new Emit(ctx.settings).imports.frontend("src/types");
|
|
8
13
|
const entries = await generateViewTypes(ctx, {
|
|
9
14
|
referenceBackendType,
|
|
10
15
|
basePath: views,
|
|
11
|
-
datasourceBasePath: referenceBackendType ? "types/generated/datasource" : views
|
|
16
|
+
datasourceBasePath: referenceBackendType ? layered(ctx.settings, "types/generated/datasource") : views
|
|
12
17
|
});
|
|
13
18
|
if (!referenceBackendType) verifyEntries(entries);
|
|
14
19
|
return entries;
|
package/node_modules/@deterministic-code/typescript-generators/dist/generate-frontend-validators.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { verifyEntries } from "@deterministic-code/generators-common/reference-verifier";
|
|
2
|
+
import { createCasing } from "./common/default-casing.js";
|
|
2
3
|
import { Emit } from "./emit.js";
|
|
4
|
+
const layered = (settings, path) => {
|
|
5
|
+
const casing = createCasing(settings);
|
|
6
|
+
return path.split("/").map((segment) => casing.convertDirectories(segment)).join("/");
|
|
7
|
+
};
|
|
3
8
|
import { generate as generateViewTypeValidators } from "./generate-view-type-validators.js";
|
|
4
9
|
import { referencesBackend } from "./inline-inherited.js";
|
|
5
10
|
import {
|
|
@@ -24,7 +29,7 @@ const generate = async (ctx) => {
|
|
|
24
29
|
schemaInheritTmpl
|
|
25
30
|
},
|
|
26
31
|
basePath: validators,
|
|
27
|
-
datasourceBasePath: referenceBackendType ? "types/generated/datasource/validators" : validators
|
|
32
|
+
datasourceBasePath: referenceBackendType ? layered(ctx.settings, "types/generated/datasource/validators") : validators
|
|
28
33
|
});
|
|
29
34
|
if (!referenceBackendType) verifyEntries(entries);
|
|
30
35
|
return entries;
|
|
@@ -44,7 +44,7 @@ class Generator extends Emit {
|
|
|
44
44
|
return entries;
|
|
45
45
|
}
|
|
46
46
|
customModuleKey(emitPath) {
|
|
47
|
-
return customRelKey(emitPath, "routes");
|
|
47
|
+
return customRelKey(emitPath, this.casing.convertDirectories("routes"));
|
|
48
48
|
}
|
|
49
49
|
entityRouter(candidate) {
|
|
50
50
|
const { simpleDoc, descriptionDoc } = this.settings;
|
|
@@ -129,7 +129,7 @@ class Generator extends Emit {
|
|
|
129
129
|
}
|
|
130
130
|
/** Map emit paths like `../custom/foo.ts` to Rel keys `services/custom/foo.ts`. */
|
|
131
131
|
customModuleKey(emitPath) {
|
|
132
|
-
return customRelKey(emitPath, "services");
|
|
132
|
+
return customRelKey(emitPath, this.casing.convertDirectories("services"));
|
|
133
133
|
}
|
|
134
134
|
custom(entry) {
|
|
135
135
|
const { simpleDoc, descriptionDoc } = this.settings;
|
|
@@ -27,7 +27,7 @@ class TypeScriptImportGenerator {
|
|
|
27
27
|
return this.underBase(path);
|
|
28
28
|
}
|
|
29
29
|
datasourceRel(entity) {
|
|
30
|
-
return this.rel("types/generated/datasource", this.datasource(entity));
|
|
30
|
+
return this.rel(this.layered("types/generated/datasource"), this.datasource(entity));
|
|
31
31
|
}
|
|
32
32
|
datasourceQual(entity) {
|
|
33
33
|
return this.casing.convertTypes(entity);
|
|
@@ -39,19 +39,19 @@ class TypeScriptImportGenerator {
|
|
|
39
39
|
}
|
|
40
40
|
datasourceValidatorRel(entity) {
|
|
41
41
|
return this.rel(
|
|
42
|
-
"types/generated/datasource/validators",
|
|
42
|
+
this.layered("types/generated/datasource/validators"),
|
|
43
43
|
this.datasourceValidator(entity)
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
datasourceTestRel(entity) {
|
|
47
47
|
return this.rel(
|
|
48
|
-
"types/generated/datasource",
|
|
48
|
+
this.layered("types/generated/datasource"),
|
|
49
49
|
this.test(this.datasource(entity), entity)
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
datasourceValidatorTestRel(entity) {
|
|
53
53
|
return this.rel(
|
|
54
|
-
"types/generated/datasource/validators",
|
|
54
|
+
this.layered("types/generated/datasource/validators"),
|
|
55
55
|
this.test(this.datasourceValidator(entity), entity)
|
|
56
56
|
);
|
|
57
57
|
}
|
|
@@ -59,7 +59,7 @@ class TypeScriptImportGenerator {
|
|
|
59
59
|
return this.underBase(this.viewLike(entity, ""));
|
|
60
60
|
}
|
|
61
61
|
viewRel(entity) {
|
|
62
|
-
return this.rel("types/generated/views", this.view(entity));
|
|
62
|
+
return this.rel(this.layered("types/generated/views"), this.view(entity));
|
|
63
63
|
}
|
|
64
64
|
viewQual(entity) {
|
|
65
65
|
return this.casing.convertTypes(entity);
|
|
@@ -69,16 +69,16 @@ class TypeScriptImportGenerator {
|
|
|
69
69
|
}
|
|
70
70
|
viewValidatorRel(entity) {
|
|
71
71
|
return this.rel(
|
|
72
|
-
"types/generated/views/validators",
|
|
72
|
+
this.layered("types/generated/views/validators"),
|
|
73
73
|
this.viewValidator(entity)
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
76
|
viewTestRel(entity) {
|
|
77
|
-
return this.rel("types/generated/views", this.test(this.view(entity), entity));
|
|
77
|
+
return this.rel(this.layered("types/generated/views"), this.test(this.view(entity), entity));
|
|
78
78
|
}
|
|
79
79
|
viewValidatorTestRel(entity) {
|
|
80
80
|
return this.rel(
|
|
81
|
-
"types/generated/views/validators",
|
|
81
|
+
this.layered("types/generated/views/validators"),
|
|
82
82
|
this.test(this.viewValidator(entity), entity)
|
|
83
83
|
);
|
|
84
84
|
}
|
|
@@ -91,29 +91,29 @@ class TypeScriptImportGenerator {
|
|
|
91
91
|
return this.underBase(path);
|
|
92
92
|
}
|
|
93
93
|
serviceRel(entity) {
|
|
94
|
-
return this.rel("services/generated", this.service(entity));
|
|
94
|
+
return this.rel(this.layered("services/generated"), this.service(entity));
|
|
95
95
|
}
|
|
96
96
|
serviceCustom(name, module) {
|
|
97
97
|
return this.resolveCustom(name, module, "services");
|
|
98
98
|
}
|
|
99
99
|
serviceCustomRel(entity) {
|
|
100
100
|
const file = `${this.serviceStem(entity)}.ts`;
|
|
101
|
-
return this.organizeByFeature ?
|
|
101
|
+
return this.organizeByFeature ? `${this.featuresDir(entity)}/custom/${file}` : `${this.layered("services")}/custom/${file}`;
|
|
102
102
|
}
|
|
103
103
|
serviceTest(entity) {
|
|
104
104
|
const file = `${this.serviceStem(entity)}.test.ts`;
|
|
105
|
-
const path = this.organizeByFeature ?
|
|
105
|
+
const path = this.organizeByFeature ? `${this.featuresDir(entity)}/__tests__/${file}` : file;
|
|
106
106
|
return this.underBase(path);
|
|
107
107
|
}
|
|
108
108
|
serviceTestRel(entity) {
|
|
109
|
-
return this.rel("services/generated/__tests__", this.serviceTest(entity));
|
|
109
|
+
return this.rel(this.layered("services/generated/__tests__"), this.serviceTest(entity));
|
|
110
110
|
}
|
|
111
111
|
serviceIntegrationTest(entity) {
|
|
112
112
|
return this.serviceTest(entity).replace(/\.test\.ts$/, ".integration.test.js");
|
|
113
113
|
}
|
|
114
114
|
serviceIntegrationTestRel(entity) {
|
|
115
115
|
return this.rel(
|
|
116
|
-
"services/generated/__tests__",
|
|
116
|
+
this.layered("services/generated/__tests__"),
|
|
117
117
|
this.serviceIntegrationTest(entity)
|
|
118
118
|
);
|
|
119
119
|
}
|
|
@@ -126,18 +126,18 @@ class TypeScriptImportGenerator {
|
|
|
126
126
|
return this.underBase(path);
|
|
127
127
|
}
|
|
128
128
|
routeRel(entity) {
|
|
129
|
-
return this.rel("routes/generated", this.route(entity));
|
|
129
|
+
return this.rel(this.layered("routes/generated"), this.route(entity));
|
|
130
130
|
}
|
|
131
131
|
routeCustom(name, module) {
|
|
132
132
|
return this.resolveCustom(name, module, "routes");
|
|
133
133
|
}
|
|
134
134
|
routeTest(entity) {
|
|
135
135
|
const file = `${this.casing.fileBase(entity)}.integration.test.ts`;
|
|
136
|
-
const path = this.organizeByFeature ?
|
|
136
|
+
const path = this.organizeByFeature ? `${this.featuresDir(entity)}/__tests__/${file}` : file;
|
|
137
137
|
return this.underBase(path);
|
|
138
138
|
}
|
|
139
139
|
routeTestRel(entity) {
|
|
140
|
-
return this.rel("routes/generated/__tests__", this.routeTest(entity));
|
|
140
|
+
return this.rel(this.layered("routes/generated/__tests__"), this.routeTest(entity));
|
|
141
141
|
}
|
|
142
142
|
enrichment(_targetTable) {
|
|
143
143
|
return "";
|
|
@@ -187,8 +187,8 @@ class TypeScriptImportGenerator {
|
|
|
187
187
|
/** Layered types/services/routes globs, or features when by-feature. Empty when flat. */
|
|
188
188
|
tsconfigIncludes() {
|
|
189
189
|
if (this.flat) return [];
|
|
190
|
-
if (this.organizeByFeature) return ["features/**/*.ts
|
|
191
|
-
return ["types
|
|
190
|
+
if (this.organizeByFeature) return [`${this.casing.convertDirectories("features")}/**/*.ts`];
|
|
191
|
+
return ["types", "services", "routes"].map((layer) => `${this.casing.convertDirectories(layer)}/**/*.ts`);
|
|
192
192
|
}
|
|
193
193
|
rel(prefix, file) {
|
|
194
194
|
if (this.organizeByFeature || this.flat) return file;
|
|
@@ -197,8 +197,16 @@ class TypeScriptImportGenerator {
|
|
|
197
197
|
tsFile(stem) {
|
|
198
198
|
return `${this.casing.fileBase(stem)}.ts`;
|
|
199
199
|
}
|
|
200
|
+
layered(path) {
|
|
201
|
+
return path.split("/").map(
|
|
202
|
+
(segment) => segment === "custom" || segment === "__tests__" ? segment : this.casing.convertDirectories(segment)
|
|
203
|
+
).join("/");
|
|
204
|
+
}
|
|
205
|
+
featuresDir(entity) {
|
|
206
|
+
return `${this.casing.convertDirectories("features")}/${this.casing.directory(entity)}`;
|
|
207
|
+
}
|
|
200
208
|
featurePath(entity, file) {
|
|
201
|
-
return
|
|
209
|
+
return `${this.featuresDir(entity)}/${file}`;
|
|
202
210
|
}
|
|
203
211
|
serviceStem(entity) {
|
|
204
212
|
return this.casing.fileBase(`${entity}_service`);
|
|
@@ -209,13 +217,13 @@ class TypeScriptImportGenerator {
|
|
|
209
217
|
}
|
|
210
218
|
viewLike(entity, featureExt) {
|
|
211
219
|
const file = `${this.casing.fileBase(entity)}${this.organizeByFeature ? featureExt : ""}.ts`;
|
|
212
|
-
return this.organizeByFeature ?
|
|
220
|
+
return this.organizeByFeature ? `${this.featuresDir(entity)}/${file}` : file;
|
|
213
221
|
}
|
|
214
222
|
resolveCustom(name, mod, layer) {
|
|
215
223
|
const kind = layer === "services" ? "service" : "route";
|
|
216
224
|
const stubFn = layer === "services" ? "generateCustomServiceStub" : "generateCustomRouteStub";
|
|
217
225
|
const file = layer === "services" ? this.tsFile(name) : `${this.casing.fileBase(`${name}_route`)}.ts`;
|
|
218
|
-
const defaultStub = this.organizeByFeature ?
|
|
226
|
+
const defaultStub = this.organizeByFeature ? `${this.featuresDir(name)}/custom/${file}` : `../custom/${file}`;
|
|
219
227
|
if (this.organizeByFeature) {
|
|
220
228
|
if (typeof mod !== "string" || !mod.startsWith(".") || mod.startsWith("./services/") || mod.startsWith("./routes/")) {
|
|
221
229
|
return defaultStub;
|
|
@@ -37,11 +37,8 @@ export const bag = (attrs: {
|
|
|
37
37
|
return out;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
/** Map `../….ts` emit paths to project-relative Rel keys
|
|
41
|
-
export const customRelKey = (
|
|
42
|
-
emitPath: string,
|
|
43
|
-
layer: "services" | "routes",
|
|
44
|
-
): string =>
|
|
40
|
+
/** Map `../….ts` emit paths to project-relative Rel keys using the cased layer directory. */
|
|
41
|
+
export const customRelKey = (emitPath: string, layer: string): string =>
|
|
45
42
|
emitPath.startsWith("../") ? `${layer}/${emitPath.slice(3)}` : emitPath;
|
|
46
43
|
|
|
47
44
|
/** Settings plus pack import generators created once; lanes use `this.imports`. */
|
package/node_modules/@deterministic-code/typescript-generators/src/generate-frontend-types.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { GenerateContext } from "@deterministic-code/generators-common/generate-context";
|
|
2
2
|
import type { GenerateEntry } from "@deterministic-code/generators-common/generate-entry";
|
|
3
3
|
import { verifyEntries } from "@deterministic-code/generators-common/reference-verifier";
|
|
4
|
+
import { createCasing } from "./common/default-casing.ts";
|
|
4
5
|
import { Emit } from "./emit.ts";
|
|
5
6
|
import { generateViewTypes } from "./emit-shaped-types.ts";
|
|
6
7
|
import { referencesBackend } from "./inline-inherited.ts";
|
|
7
8
|
|
|
9
|
+
const layered = (settings: Record<string, string>, path: string): string => {
|
|
10
|
+
const casing = createCasing(settings);
|
|
11
|
+
return path.split("/").map((segment) => casing.convertDirectories(segment)).join("/");
|
|
12
|
+
};
|
|
13
|
+
|
|
8
14
|
/** Self-checks when the lane is closed; backend-type refs need host `finalizeEntries`. */
|
|
9
15
|
export const generate = async (
|
|
10
16
|
ctx: GenerateContext,
|
|
@@ -15,7 +21,7 @@ export const generate = async (
|
|
|
15
21
|
referenceBackendType,
|
|
16
22
|
basePath: views,
|
|
17
23
|
datasourceBasePath: referenceBackendType
|
|
18
|
-
? "types/generated/datasource"
|
|
24
|
+
? layered(ctx.settings, "types/generated/datasource")
|
|
19
25
|
: views,
|
|
20
26
|
});
|
|
21
27
|
if (!referenceBackendType) verifyEntries(entries);
|
package/node_modules/@deterministic-code/typescript-generators/src/generate-frontend-validators.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { GenerateContext } from "@deterministic-code/generators-common/generate-context";
|
|
2
2
|
import type { GenerateEntry } from "@deterministic-code/generators-common/generate-entry";
|
|
3
3
|
import { verifyEntries } from "@deterministic-code/generators-common/reference-verifier";
|
|
4
|
+
import { createCasing } from "./common/default-casing.ts";
|
|
4
5
|
import { Emit } from "./emit.ts";
|
|
6
|
+
|
|
7
|
+
const layered = (settings: Record<string, string>, path: string): string => {
|
|
8
|
+
const casing = createCasing(settings);
|
|
9
|
+
return path.split("/").map((segment) => casing.convertDirectories(segment)).join("/");
|
|
10
|
+
};
|
|
5
11
|
import { generate as generateViewTypeValidators } from "./generate-view-type-validators.ts";
|
|
6
12
|
import { referencesBackend } from "./inline-inherited.ts";
|
|
7
13
|
import {
|
|
@@ -31,7 +37,7 @@ export const generate = async (
|
|
|
31
37
|
},
|
|
32
38
|
basePath: validators,
|
|
33
39
|
datasourceBasePath: referenceBackendType
|
|
34
|
-
? "types/generated/datasource/validators"
|
|
40
|
+
? layered(ctx.settings, "types/generated/datasource/validators")
|
|
35
41
|
: validators,
|
|
36
42
|
});
|
|
37
43
|
if (!referenceBackendType) verifyEntries(entries);
|
|
@@ -54,7 +54,7 @@ class Generator extends Emit {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
private customModuleKey(emitPath: string): string {
|
|
57
|
-
return customRelKey(emitPath, "routes");
|
|
57
|
+
return customRelKey(emitPath, this.casing.convertDirectories("routes"));
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
private entityRouter(candidate: RouteCandidate): GenerateEntry {
|
|
@@ -165,7 +165,7 @@ class Generator extends Emit {
|
|
|
165
165
|
|
|
166
166
|
/** Map emit paths like `../custom/foo.ts` to Rel keys `services/custom/foo.ts`. */
|
|
167
167
|
private customModuleKey(emitPath: string): string {
|
|
168
|
-
return customRelKey(emitPath, "services");
|
|
168
|
+
return customRelKey(emitPath, this.casing.convertDirectories("services"));
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
private custom(entry: CustomServiceEntry): GenerateEntry {
|
|
@@ -73,6 +73,22 @@ describe("TypeScriptImportGenerator layered (organize_by_feature unset)", () =>
|
|
|
73
73
|
"services/generated/__tests__/userService.integration.test.ts",
|
|
74
74
|
);
|
|
75
75
|
assert.equal(imports.serviceCustomRel("user"), "services/custom/userService.ts");
|
|
76
|
+
const pascalDirs = createImportGenerator(".", {
|
|
77
|
+
"languages.typescript.casing.directories": "Pascal",
|
|
78
|
+
});
|
|
79
|
+
assert.equal(
|
|
80
|
+
pascalDirs.datasourceRel("user"),
|
|
81
|
+
"Types/Generated/Datasource/user.ts",
|
|
82
|
+
);
|
|
83
|
+
assert.equal(
|
|
84
|
+
pascalDirs.serviceRel("user"),
|
|
85
|
+
"Services/Generated/userService.ts",
|
|
86
|
+
);
|
|
87
|
+
assert.deepEqual(pascalDirs.tsconfigIncludes(), [
|
|
88
|
+
"Types/**/*.ts",
|
|
89
|
+
"Services/**/*.ts",
|
|
90
|
+
"Routes/**/*.ts",
|
|
91
|
+
]);
|
|
76
92
|
assert.equal(imports.route("user"), "user.ts");
|
|
77
93
|
assert.equal(imports.routeRel("user"), "routes/generated/user.ts");
|
|
78
94
|
assert.equal(imports.routeTest("user"), "user.integration.test.ts");
|
|
@@ -39,7 +39,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
datasourceRel(entity: string): string {
|
|
42
|
-
return this.rel("types/generated/datasource", this.datasource(entity));
|
|
42
|
+
return this.rel(this.layered("types/generated/datasource"), this.datasource(entity));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
datasourceQual(entity: string): string {
|
|
@@ -58,21 +58,21 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
58
58
|
|
|
59
59
|
datasourceValidatorRel(entity: string): string {
|
|
60
60
|
return this.rel(
|
|
61
|
-
"types/generated/datasource/validators",
|
|
61
|
+
this.layered("types/generated/datasource/validators"),
|
|
62
62
|
this.datasourceValidator(entity),
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
datasourceTestRel(entity: string): string {
|
|
67
67
|
return this.rel(
|
|
68
|
-
"types/generated/datasource",
|
|
68
|
+
this.layered("types/generated/datasource"),
|
|
69
69
|
this.test(this.datasource(entity), entity),
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
datasourceValidatorTestRel(entity: string): string {
|
|
74
74
|
return this.rel(
|
|
75
|
-
"types/generated/datasource/validators",
|
|
75
|
+
this.layered("types/generated/datasource/validators"),
|
|
76
76
|
this.test(this.datasourceValidator(entity), entity),
|
|
77
77
|
);
|
|
78
78
|
}
|
|
@@ -82,7 +82,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
viewRel(entity: string): string {
|
|
85
|
-
return this.rel("types/generated/views", this.view(entity));
|
|
85
|
+
return this.rel(this.layered("types/generated/views"), this.view(entity));
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
viewQual(entity: string): string {
|
|
@@ -95,18 +95,18 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
95
95
|
|
|
96
96
|
viewValidatorRel(entity: string): string {
|
|
97
97
|
return this.rel(
|
|
98
|
-
"types/generated/views/validators",
|
|
98
|
+
this.layered("types/generated/views/validators"),
|
|
99
99
|
this.viewValidator(entity),
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
viewTestRel(entity: string): string {
|
|
104
|
-
return this.rel("types/generated/views", this.test(this.view(entity), entity));
|
|
104
|
+
return this.rel(this.layered("types/generated/views"), this.test(this.view(entity), entity));
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
viewValidatorTestRel(entity: string): string {
|
|
108
108
|
return this.rel(
|
|
109
|
-
"types/generated/views/validators",
|
|
109
|
+
this.layered("types/generated/views/validators"),
|
|
110
110
|
this.test(this.viewValidator(entity), entity),
|
|
111
111
|
);
|
|
112
112
|
}
|
|
@@ -126,7 +126,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
serviceRel(entity: string): string {
|
|
129
|
-
return this.rel("services/generated", this.service(entity));
|
|
129
|
+
return this.rel(this.layered("services/generated"), this.service(entity));
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
serviceCustom(name: string, module?: string): string {
|
|
@@ -136,20 +136,20 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
136
136
|
serviceCustomRel(entity: string): string {
|
|
137
137
|
const file = `${this.serviceStem(entity)}.ts`;
|
|
138
138
|
return this.organizeByFeature
|
|
139
|
-
?
|
|
140
|
-
:
|
|
139
|
+
? `${this.featuresDir(entity)}/custom/${file}`
|
|
140
|
+
: `${this.layered("services")}/custom/${file}`;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
serviceTest(entity: string): string {
|
|
144
144
|
const file = `${this.serviceStem(entity)}.test.ts`;
|
|
145
145
|
const path = this.organizeByFeature
|
|
146
|
-
?
|
|
146
|
+
? `${this.featuresDir(entity)}/__tests__/${file}`
|
|
147
147
|
: file;
|
|
148
148
|
return this.underBase(path);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
serviceTestRel(entity: string): string {
|
|
152
|
-
return this.rel("services/generated/__tests__", this.serviceTest(entity));
|
|
152
|
+
return this.rel(this.layered("services/generated/__tests__"), this.serviceTest(entity));
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
serviceIntegrationTest(entity: string): string {
|
|
@@ -158,7 +158,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
158
158
|
|
|
159
159
|
serviceIntegrationTestRel(entity: string): string {
|
|
160
160
|
return this.rel(
|
|
161
|
-
"services/generated/__tests__",
|
|
161
|
+
this.layered("services/generated/__tests__"),
|
|
162
162
|
this.serviceIntegrationTest(entity),
|
|
163
163
|
);
|
|
164
164
|
}
|
|
@@ -178,7 +178,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
routeRel(entity: string): string {
|
|
181
|
-
return this.rel("routes/generated", this.route(entity));
|
|
181
|
+
return this.rel(this.layered("routes/generated"), this.route(entity));
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
routeCustom(name: string, module?: string): string {
|
|
@@ -188,13 +188,13 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
188
188
|
routeTest(entity: string): string {
|
|
189
189
|
const file = `${this.casing.fileBase(entity)}.integration.test.ts`;
|
|
190
190
|
const path = this.organizeByFeature
|
|
191
|
-
?
|
|
191
|
+
? `${this.featuresDir(entity)}/__tests__/${file}`
|
|
192
192
|
: file;
|
|
193
193
|
return this.underBase(path);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
routeTestRel(entity: string): string {
|
|
197
|
-
return this.rel("routes/generated/__tests__", this.routeTest(entity));
|
|
197
|
+
return this.rel(this.layered("routes/generated/__tests__"), this.routeTest(entity));
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
enrichment(_targetTable: string): string {
|
|
@@ -262,8 +262,8 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
262
262
|
/** Layered types/services/routes globs, or features when by-feature. Empty when flat. */
|
|
263
263
|
tsconfigIncludes(): string[] {
|
|
264
264
|
if (this.flat) return [];
|
|
265
|
-
if (this.organizeByFeature) return ["features/**/*.ts
|
|
266
|
-
return ["types
|
|
265
|
+
if (this.organizeByFeature) return [`${this.casing.convertDirectories("features")}/**/*.ts`];
|
|
266
|
+
return ["types", "services", "routes"].map((layer) => `${this.casing.convertDirectories(layer)}/**/*.ts`);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
private rel(prefix: string, file: string): string {
|
|
@@ -275,8 +275,23 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
275
275
|
return `${this.casing.fileBase(stem)}.ts`;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
private layered(path: string): string {
|
|
279
|
+
return path
|
|
280
|
+
.split("/")
|
|
281
|
+
.map((segment) =>
|
|
282
|
+
segment === "custom" || segment === "__tests__"
|
|
283
|
+
? segment
|
|
284
|
+
: this.casing.convertDirectories(segment),
|
|
285
|
+
)
|
|
286
|
+
.join("/");
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private featuresDir(entity: string): string {
|
|
290
|
+
return `${this.casing.convertDirectories("features")}/${this.casing.directory(entity)}`;
|
|
291
|
+
}
|
|
292
|
+
|
|
278
293
|
private featurePath(entity: string, file: string): string {
|
|
279
|
-
return
|
|
294
|
+
return `${this.featuresDir(entity)}/${file}`;
|
|
280
295
|
}
|
|
281
296
|
|
|
282
297
|
private serviceStem(entity: string): string {
|
|
@@ -291,7 +306,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
291
306
|
private viewLike(entity: string, featureExt: string): string {
|
|
292
307
|
const file = `${this.casing.fileBase(entity)}${this.organizeByFeature ? featureExt : ""}.ts`;
|
|
293
308
|
return this.organizeByFeature
|
|
294
|
-
?
|
|
309
|
+
? `${this.featuresDir(entity)}/${file}`
|
|
295
310
|
: file;
|
|
296
311
|
}
|
|
297
312
|
|
|
@@ -310,7 +325,7 @@ export class TypeScriptImportGenerator implements IImportGenerator {
|
|
|
310
325
|
? this.tsFile(name)
|
|
311
326
|
: `${this.casing.fileBase(`${name}_route`)}.ts`;
|
|
312
327
|
const defaultStub = this.organizeByFeature
|
|
313
|
-
?
|
|
328
|
+
? `${this.featuresDir(name)}/custom/${file}`
|
|
314
329
|
: `../custom/${file}`;
|
|
315
330
|
if (this.organizeByFeature) {
|
|
316
331
|
if (
|