@cedarjs/internal 4.0.0-canary.13810 → 4.0.0-canary.13812
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/cjs/generate/generate.d.ts.map +1 -1
- package/dist/cjs/generate/generate.js +1 -1
- package/dist/cjs/generate/gqlormSchema.d.ts +11 -0
- package/dist/cjs/generate/gqlormSchema.d.ts.map +1 -1
- package/dist/cjs/generate/gqlormSchema.js +169 -16
- package/dist/cjs/generate/watch.js +17 -10
- package/dist/generate/generate.d.ts.map +1 -1
- package/dist/generate/generate.js +1 -1
- package/dist/generate/gqlormSchema.d.ts +11 -0
- package/dist/generate/gqlormSchema.d.ts.map +1 -1
- package/dist/generate/gqlormSchema.js +168 -17
- package/dist/generate/watch.js +15 -8
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/generate/generate.ts"],"names":[],"mappings":";AAWA,eAAO,MAAM,QAAQ;;;;;;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/generate/generate.ts"],"names":[],"mappings":";AAWA,eAAO,MAAM,QAAQ;;;;;;EA2CpB,CAAA;AAED,eAAO,MAAM,GAAG,qBAoCf,CAAA"}
|
|
@@ -36,7 +36,7 @@ const generate = async () => {
|
|
|
36
36
|
const { typeDefFiles, errors: generateTypeDefsErrors } = await (0, import_typeDefinitions.generateTypeDefs)();
|
|
37
37
|
const clientPresetFiles = [];
|
|
38
38
|
const { possibleTypesFiles, errors: generatePossibleTypesErrors } = await (0, import_possibleTypes.generatePossibleTypes)();
|
|
39
|
-
const { files: gqlormFiles, errors: gqlormErrors } =
|
|
39
|
+
const { files: gqlormFiles, errors: gqlormErrors } = await (0, import_gqlormSchema.generateGqlormArtifacts)();
|
|
40
40
|
if (config.graphql.trustedDocuments) {
|
|
41
41
|
const preset = await (0, import_clientPreset.generateClientPreset)();
|
|
42
42
|
clientPresetFiles.push(...preset.clientPresetFiles);
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type * as DMMF from '@prisma/dmmf';
|
|
2
2
|
type ModelSchema = Record<string, string[]>;
|
|
3
|
+
interface FrontendFieldInfo {
|
|
4
|
+
name: string;
|
|
5
|
+
tsType: string;
|
|
6
|
+
}
|
|
7
|
+
interface FrontendModelInfo {
|
|
8
|
+
modelName: string;
|
|
9
|
+
camelName: string;
|
|
10
|
+
fields: FrontendFieldInfo[];
|
|
11
|
+
}
|
|
3
12
|
export interface BackendFieldInfo {
|
|
4
13
|
name: string;
|
|
5
14
|
graphqlType: string;
|
|
@@ -20,6 +29,8 @@ export interface BackendModelInfo {
|
|
|
20
29
|
* fall back to String.
|
|
21
30
|
*/
|
|
22
31
|
export declare function mapDmmfTypeToGraphql(type: string, kind: string): string;
|
|
32
|
+
export declare function buildFrontendModelInfo(dmmf: DMMF.Document): FrontendModelInfo[];
|
|
33
|
+
export declare function generateWebGqlormModelsContent(models: FrontendModelInfo[]): string;
|
|
23
34
|
/**
|
|
24
35
|
* Build a ModelSchema from a Prisma DMMF document.
|
|
25
36
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;AA8BzC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAC1B,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACtC;AAqDD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAoGD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAClB,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,iBAAiB,EAAE,GAC1B,MAAM,CA2CR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,WAAW,CAkDjE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CA2D7E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EAAE,GACzB,MAAM,CA0IR;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAC,CAgFD"}
|
|
@@ -29,9 +29,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var gqlormSchema_exports = {};
|
|
30
30
|
__export(gqlormSchema_exports, {
|
|
31
31
|
buildBackendModelInfo: () => buildBackendModelInfo,
|
|
32
|
+
buildFrontendModelInfo: () => buildFrontendModelInfo,
|
|
32
33
|
buildModelSchema: () => buildModelSchema,
|
|
33
34
|
generateGqlormArtifacts: () => generateGqlormArtifacts,
|
|
34
35
|
generateGqlormBackendContent: () => generateGqlormBackendContent,
|
|
36
|
+
generateWebGqlormModelsContent: () => generateWebGqlormModelsContent,
|
|
35
37
|
getExistingSdlTypeNames: () => getExistingSdlTypeNames,
|
|
36
38
|
mapDmmfTypeToGraphql: () => mapDmmfTypeToGraphql
|
|
37
39
|
});
|
|
@@ -40,8 +42,21 @@ var import_node_fs = __toESM(require("node:fs"), 1);
|
|
|
40
42
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
41
43
|
var import_project_config = require("@cedarjs/project-config");
|
|
42
44
|
var import_cedarPluralize = require("@cedarjs/utils/cedarPluralize");
|
|
43
|
-
const INTERNAL_MODEL_NAMES = /* @__PURE__ */ new Set([
|
|
44
|
-
|
|
45
|
+
const INTERNAL_MODEL_NAMES = /* @__PURE__ */ new Set([
|
|
46
|
+
"RW_DataMigration",
|
|
47
|
+
"Cedar_DataMigration"
|
|
48
|
+
]);
|
|
49
|
+
const SENSITIVE_PATTERNS = [
|
|
50
|
+
"password",
|
|
51
|
+
"secret",
|
|
52
|
+
"token",
|
|
53
|
+
"hash",
|
|
54
|
+
"salt",
|
|
55
|
+
"apikey",
|
|
56
|
+
"secretkey",
|
|
57
|
+
"encryptionkey",
|
|
58
|
+
"privatekey"
|
|
59
|
+
];
|
|
45
60
|
function hasDirective(doc, directive) {
|
|
46
61
|
if (!doc) {
|
|
47
62
|
return false;
|
|
@@ -109,6 +124,124 @@ function graphqlTypeToTsInterfaceType(graphqlType, isRequired) {
|
|
|
109
124
|
}
|
|
110
125
|
return isRequired ? tsType : `${tsType} | null`;
|
|
111
126
|
}
|
|
127
|
+
function dmmfTypeToFrontendTsType(type, kind, isRequired) {
|
|
128
|
+
let tsType;
|
|
129
|
+
if (kind === "enum") {
|
|
130
|
+
tsType = "string";
|
|
131
|
+
} else {
|
|
132
|
+
switch (type) {
|
|
133
|
+
case "String":
|
|
134
|
+
tsType = "string";
|
|
135
|
+
break;
|
|
136
|
+
case "Int":
|
|
137
|
+
case "Float":
|
|
138
|
+
tsType = "number";
|
|
139
|
+
break;
|
|
140
|
+
case "BigInt":
|
|
141
|
+
tsType = "bigint";
|
|
142
|
+
break;
|
|
143
|
+
case "Boolean":
|
|
144
|
+
tsType = "boolean";
|
|
145
|
+
break;
|
|
146
|
+
case "DateTime":
|
|
147
|
+
tsType = "string";
|
|
148
|
+
break;
|
|
149
|
+
case "Json":
|
|
150
|
+
tsType = "unknown";
|
|
151
|
+
break;
|
|
152
|
+
case "Bytes":
|
|
153
|
+
case "Decimal":
|
|
154
|
+
tsType = "string";
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
tsType = "unknown";
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (isRequired) {
|
|
161
|
+
return tsType;
|
|
162
|
+
}
|
|
163
|
+
return `${tsType} | null`;
|
|
164
|
+
}
|
|
165
|
+
function buildFrontendModelInfo(dmmf) {
|
|
166
|
+
const models = [];
|
|
167
|
+
for (const model of dmmf.datamodel.models) {
|
|
168
|
+
if (INTERNAL_MODEL_NAMES.has(model.name)) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (hasDirective(model.documentation, "hide")) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const fields = [];
|
|
175
|
+
for (const field of model.fields) {
|
|
176
|
+
if (field.kind !== "scalar" && field.kind !== "enum") {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (hasDirective(field.documentation, "hide")) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const isShown = hasDirective(field.documentation, "show");
|
|
183
|
+
if (!isShown && isSensitiveField(field.name)) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
fields.push({
|
|
187
|
+
name: field.name,
|
|
188
|
+
tsType: dmmfTypeToFrontendTsType(
|
|
189
|
+
field.type,
|
|
190
|
+
field.kind,
|
|
191
|
+
field.isRequired
|
|
192
|
+
)
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (fields.length > 0) {
|
|
196
|
+
models.push({
|
|
197
|
+
modelName: model.name,
|
|
198
|
+
camelName: model.name.charAt(0).toLowerCase() + model.name.slice(1),
|
|
199
|
+
fields
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return models;
|
|
204
|
+
}
|
|
205
|
+
function generateWebGqlormModelsContent(models) {
|
|
206
|
+
if (models.length === 0) {
|
|
207
|
+
return [
|
|
208
|
+
"// Auto-generated by Cedar \u2014 do not edit",
|
|
209
|
+
"// Regenerated on every codegen run. Source: api/db/schema.prisma",
|
|
210
|
+
"",
|
|
211
|
+
"declare module '@cedarjs/gqlorm/types/orm' {",
|
|
212
|
+
" interface GqlormTypeMap {}",
|
|
213
|
+
"}",
|
|
214
|
+
""
|
|
215
|
+
].join("\n");
|
|
216
|
+
}
|
|
217
|
+
const lines = [
|
|
218
|
+
"// Auto-generated by Cedar \u2014 do not edit",
|
|
219
|
+
"// Regenerated on every codegen run. Source: api/db/schema.prisma",
|
|
220
|
+
"",
|
|
221
|
+
"declare namespace GqlormScalar {"
|
|
222
|
+
];
|
|
223
|
+
for (const model of models) {
|
|
224
|
+
lines.push(` interface ${model.modelName} {`);
|
|
225
|
+
for (const field of model.fields) {
|
|
226
|
+
lines.push(` ${field.name}: ${field.tsType}`);
|
|
227
|
+
}
|
|
228
|
+
lines.push(" }");
|
|
229
|
+
lines.push("");
|
|
230
|
+
}
|
|
231
|
+
lines.push("}");
|
|
232
|
+
lines.push("");
|
|
233
|
+
lines.push("declare module '@cedarjs/gqlorm/types/orm' {");
|
|
234
|
+
lines.push(" interface GqlormTypeMap {");
|
|
235
|
+
lines.push(" models: {");
|
|
236
|
+
for (const model of models) {
|
|
237
|
+
lines.push(` ${model.camelName}: GqlormScalar.${model.modelName}`);
|
|
238
|
+
}
|
|
239
|
+
lines.push(" }");
|
|
240
|
+
lines.push(" }");
|
|
241
|
+
lines.push("}");
|
|
242
|
+
lines.push("");
|
|
243
|
+
return lines.join("\n");
|
|
244
|
+
}
|
|
112
245
|
function buildModelSchema(dmmf) {
|
|
113
246
|
const schema = {};
|
|
114
247
|
for (const model of dmmf.datamodel.models) {
|
|
@@ -330,27 +463,45 @@ async function generateGqlormArtifacts() {
|
|
|
330
463
|
const mod = await import("@prisma/internals");
|
|
331
464
|
const { getDMMF } = mod.default || mod;
|
|
332
465
|
const dmmf = await getDMMF({ datamodel: schemas });
|
|
466
|
+
const paths = (0, import_project_config.getPaths)();
|
|
467
|
+
const generatedBase = paths.generated.base;
|
|
333
468
|
const modelSchema = buildModelSchema(dmmf);
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
469
|
+
const frontendModels = buildFrontendModelInfo(dmmf);
|
|
470
|
+
const schemaOutputPath = import_node_path.default.join(generatedBase, "gqlorm-schema.json");
|
|
471
|
+
const webTypesOutputPath = import_node_path.default.join(
|
|
472
|
+
generatedBase,
|
|
473
|
+
"types",
|
|
474
|
+
"includes",
|
|
475
|
+
"web-gqlorm-models.d.ts"
|
|
337
476
|
);
|
|
338
477
|
import_node_fs.default.mkdirSync(import_node_path.default.dirname(schemaOutputPath), { recursive: true });
|
|
339
478
|
import_node_fs.default.writeFileSync(schemaOutputPath, JSON.stringify(modelSchema, null, 2));
|
|
340
479
|
files.push(schemaOutputPath);
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
(m) => !existingTypes.has(m.modelName)
|
|
480
|
+
import_node_fs.default.mkdirSync(import_node_path.default.dirname(webTypesOutputPath), { recursive: true });
|
|
481
|
+
import_node_fs.default.writeFileSync(
|
|
482
|
+
webTypesOutputPath,
|
|
483
|
+
generateWebGqlormModelsContent(frontendModels)
|
|
346
484
|
);
|
|
347
|
-
|
|
485
|
+
files.push(webTypesOutputPath);
|
|
486
|
+
const backendOutputDir = import_node_path.default.join(generatedBase, "gqlorm");
|
|
348
487
|
const backendOutputPath = import_node_path.default.join(backendOutputDir, "backend.ts");
|
|
349
|
-
if (
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
488
|
+
if ((0, import_project_config.getConfig)().experimental?.gqlorm?.enabled) {
|
|
489
|
+
const graphqlDir = paths.api.graphql;
|
|
490
|
+
const existingTypes = getExistingSdlTypeNames(graphqlDir);
|
|
491
|
+
const allModels = buildBackendModelInfo(dmmf);
|
|
492
|
+
const gqlormModels = allModels.filter(
|
|
493
|
+
(m) => !existingTypes.has(m.modelName)
|
|
494
|
+
);
|
|
495
|
+
if (gqlormModels.length > 0) {
|
|
496
|
+
const backendContent = generateGqlormBackendContent(gqlormModels);
|
|
497
|
+
import_node_fs.default.mkdirSync(backendOutputDir, { recursive: true });
|
|
498
|
+
import_node_fs.default.writeFileSync(backendOutputPath, backendContent);
|
|
499
|
+
files.push(backendOutputPath);
|
|
500
|
+
} else {
|
|
501
|
+
if (import_node_fs.default.existsSync(backendOutputPath)) {
|
|
502
|
+
import_node_fs.default.unlinkSync(backendOutputPath);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
354
505
|
} else {
|
|
355
506
|
if (import_node_fs.default.existsSync(backendOutputPath)) {
|
|
356
507
|
import_node_fs.default.unlinkSync(backendOutputPath);
|
|
@@ -367,9 +518,11 @@ async function generateGqlormArtifacts() {
|
|
|
367
518
|
// Annotate the CommonJS export names for ESM import in node:
|
|
368
519
|
0 && (module.exports = {
|
|
369
520
|
buildBackendModelInfo,
|
|
521
|
+
buildFrontendModelInfo,
|
|
370
522
|
buildModelSchema,
|
|
371
523
|
generateGqlormArtifacts,
|
|
372
524
|
generateGqlormBackendContent,
|
|
525
|
+
generateWebGqlormModelsContent,
|
|
373
526
|
getExistingSdlTypeNames,
|
|
374
527
|
mapDmmfTypeToGraphql
|
|
375
528
|
});
|
|
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
mod
|
|
24
24
|
));
|
|
25
25
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
26
|
-
var
|
|
26
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
27
27
|
var import_ansis = __toESM(require("ansis"), 1);
|
|
28
28
|
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
29
29
|
var import_project_config = require("@cedarjs/project-config");
|
|
@@ -32,18 +32,22 @@ var import_files = require("../files.js");
|
|
|
32
32
|
var import_routes = require("../routes.js");
|
|
33
33
|
var import_clientPreset = require("./clientPreset.js");
|
|
34
34
|
var import_generate = require("./generate.js");
|
|
35
|
+
var import_gqlormSchema = require("./gqlormSchema.js");
|
|
35
36
|
var import_graphqlCodeGen = require("./graphqlCodeGen.js");
|
|
36
37
|
var import_graphqlSchema = require("./graphqlSchema.js");
|
|
37
38
|
var import_typeDefinitions = require("./typeDefinitions.js");
|
|
38
39
|
const rwjsPaths = (0, import_project_config.getPaths)();
|
|
39
|
-
const generatedDirName =
|
|
40
|
-
const watcher = import_chokidar.default.watch(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
const generatedDirName = import_node_path.default.basename(rwjsPaths.generated.base);
|
|
41
|
+
const watcher = import_chokidar.default.watch(
|
|
42
|
+
["(web|api)/src/**/*.{ts,js,jsx,tsx}", "api/db/**/*.prisma"],
|
|
43
|
+
{
|
|
44
|
+
persistent: true,
|
|
45
|
+
ignored: ["node_modules", generatedDirName],
|
|
46
|
+
ignoreInitial: true,
|
|
47
|
+
cwd: rwjsPaths.base,
|
|
48
|
+
awaitWriteFinish: true
|
|
49
|
+
}
|
|
50
|
+
);
|
|
47
51
|
const action = {
|
|
48
52
|
add: "Created",
|
|
49
53
|
unlink: "Deleted",
|
|
@@ -83,7 +87,7 @@ Created ${files.length} in ${Date.now() - start} ms`);
|
|
|
83
87
|
return;
|
|
84
88
|
}
|
|
85
89
|
const eventTigger = eventName;
|
|
86
|
-
const absPath =
|
|
90
|
+
const absPath = import_node_path.default.join(rwjsPaths.base, p);
|
|
87
91
|
const start = Date.now();
|
|
88
92
|
const finished = (type) => import_cliLogger.cliLogger.debug(
|
|
89
93
|
action[eventTigger],
|
|
@@ -118,6 +122,9 @@ Created ${files.length} in ${Date.now() - start} ms`);
|
|
|
118
122
|
await (0, import_graphqlSchema.generateGraphQLSchema)();
|
|
119
123
|
await (0, import_graphqlCodeGen.generateTypeDefGraphQLApi)();
|
|
120
124
|
finished("GraphQL Schema");
|
|
125
|
+
} else if (absPath.startsWith(import_node_path.default.join(rwjsPaths.base, "api/db/")) && absPath.endsWith(".prisma")) {
|
|
126
|
+
await (0, import_gqlormSchema.generateGqlormArtifacts)();
|
|
127
|
+
finished("Prisma Schema");
|
|
121
128
|
}
|
|
122
129
|
if (routesWarningMessage) {
|
|
123
130
|
console.warn(routesWarningMessage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/generate/generate.ts"],"names":[],"mappings":";AAWA,eAAO,MAAM,QAAQ;;;;;;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/generate/generate.ts"],"names":[],"mappings":";AAWA,eAAO,MAAM,QAAQ;;;;;;EA2CpB,CAAA;AAED,eAAO,MAAM,GAAG,qBAoCf,CAAA"}
|
|
@@ -12,7 +12,7 @@ const generate = async () => {
|
|
|
12
12
|
const { typeDefFiles, errors: generateTypeDefsErrors } = await generateTypeDefs();
|
|
13
13
|
const clientPresetFiles = [];
|
|
14
14
|
const { possibleTypesFiles, errors: generatePossibleTypesErrors } = await generatePossibleTypes();
|
|
15
|
-
const { files: gqlormFiles, errors: gqlormErrors } =
|
|
15
|
+
const { files: gqlormFiles, errors: gqlormErrors } = await generateGqlormArtifacts();
|
|
16
16
|
if (config.graphql.trustedDocuments) {
|
|
17
17
|
const preset = await generateClientPreset();
|
|
18
18
|
clientPresetFiles.push(...preset.clientPresetFiles);
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type * as DMMF from '@prisma/dmmf';
|
|
2
2
|
type ModelSchema = Record<string, string[]>;
|
|
3
|
+
interface FrontendFieldInfo {
|
|
4
|
+
name: string;
|
|
5
|
+
tsType: string;
|
|
6
|
+
}
|
|
7
|
+
interface FrontendModelInfo {
|
|
8
|
+
modelName: string;
|
|
9
|
+
camelName: string;
|
|
10
|
+
fields: FrontendFieldInfo[];
|
|
11
|
+
}
|
|
3
12
|
export interface BackendFieldInfo {
|
|
4
13
|
name: string;
|
|
5
14
|
graphqlType: string;
|
|
@@ -20,6 +29,8 @@ export interface BackendModelInfo {
|
|
|
20
29
|
* fall back to String.
|
|
21
30
|
*/
|
|
22
31
|
export declare function mapDmmfTypeToGraphql(type: string, kind: string): string;
|
|
32
|
+
export declare function buildFrontendModelInfo(dmmf: DMMF.Document): FrontendModelInfo[];
|
|
33
|
+
export declare function generateWebGqlormModelsContent(models: FrontendModelInfo[]): string;
|
|
23
34
|
/**
|
|
24
35
|
* Build a ModelSchema from a Prisma DMMF document.
|
|
25
36
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;AA8BzC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAC1B,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACtC;AAqDD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAoGD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAClB,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,iBAAiB,EAAE,GAC1B,MAAM,CA2CR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,WAAW,CAkDjE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CA2D7E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EAAE,GACzB,MAAM,CA0IR;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAC,CAgFD"}
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
|
|
3
|
+
import { getConfig, getPaths, getPrismaSchemas } from "@cedarjs/project-config";
|
|
4
4
|
import { pluralize } from "@cedarjs/utils/cedarPluralize";
|
|
5
|
-
const INTERNAL_MODEL_NAMES = /* @__PURE__ */ new Set([
|
|
6
|
-
|
|
5
|
+
const INTERNAL_MODEL_NAMES = /* @__PURE__ */ new Set([
|
|
6
|
+
"RW_DataMigration",
|
|
7
|
+
"Cedar_DataMigration"
|
|
8
|
+
]);
|
|
9
|
+
const SENSITIVE_PATTERNS = [
|
|
10
|
+
"password",
|
|
11
|
+
"secret",
|
|
12
|
+
"token",
|
|
13
|
+
"hash",
|
|
14
|
+
"salt",
|
|
15
|
+
"apikey",
|
|
16
|
+
"secretkey",
|
|
17
|
+
"encryptionkey",
|
|
18
|
+
"privatekey"
|
|
19
|
+
];
|
|
7
20
|
function hasDirective(doc, directive) {
|
|
8
21
|
if (!doc) {
|
|
9
22
|
return false;
|
|
@@ -71,6 +84,124 @@ function graphqlTypeToTsInterfaceType(graphqlType, isRequired) {
|
|
|
71
84
|
}
|
|
72
85
|
return isRequired ? tsType : `${tsType} | null`;
|
|
73
86
|
}
|
|
87
|
+
function dmmfTypeToFrontendTsType(type, kind, isRequired) {
|
|
88
|
+
let tsType;
|
|
89
|
+
if (kind === "enum") {
|
|
90
|
+
tsType = "string";
|
|
91
|
+
} else {
|
|
92
|
+
switch (type) {
|
|
93
|
+
case "String":
|
|
94
|
+
tsType = "string";
|
|
95
|
+
break;
|
|
96
|
+
case "Int":
|
|
97
|
+
case "Float":
|
|
98
|
+
tsType = "number";
|
|
99
|
+
break;
|
|
100
|
+
case "BigInt":
|
|
101
|
+
tsType = "bigint";
|
|
102
|
+
break;
|
|
103
|
+
case "Boolean":
|
|
104
|
+
tsType = "boolean";
|
|
105
|
+
break;
|
|
106
|
+
case "DateTime":
|
|
107
|
+
tsType = "string";
|
|
108
|
+
break;
|
|
109
|
+
case "Json":
|
|
110
|
+
tsType = "unknown";
|
|
111
|
+
break;
|
|
112
|
+
case "Bytes":
|
|
113
|
+
case "Decimal":
|
|
114
|
+
tsType = "string";
|
|
115
|
+
break;
|
|
116
|
+
default:
|
|
117
|
+
tsType = "unknown";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (isRequired) {
|
|
121
|
+
return tsType;
|
|
122
|
+
}
|
|
123
|
+
return `${tsType} | null`;
|
|
124
|
+
}
|
|
125
|
+
function buildFrontendModelInfo(dmmf) {
|
|
126
|
+
const models = [];
|
|
127
|
+
for (const model of dmmf.datamodel.models) {
|
|
128
|
+
if (INTERNAL_MODEL_NAMES.has(model.name)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (hasDirective(model.documentation, "hide")) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const fields = [];
|
|
135
|
+
for (const field of model.fields) {
|
|
136
|
+
if (field.kind !== "scalar" && field.kind !== "enum") {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (hasDirective(field.documentation, "hide")) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const isShown = hasDirective(field.documentation, "show");
|
|
143
|
+
if (!isShown && isSensitiveField(field.name)) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
fields.push({
|
|
147
|
+
name: field.name,
|
|
148
|
+
tsType: dmmfTypeToFrontendTsType(
|
|
149
|
+
field.type,
|
|
150
|
+
field.kind,
|
|
151
|
+
field.isRequired
|
|
152
|
+
)
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (fields.length > 0) {
|
|
156
|
+
models.push({
|
|
157
|
+
modelName: model.name,
|
|
158
|
+
camelName: model.name.charAt(0).toLowerCase() + model.name.slice(1),
|
|
159
|
+
fields
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return models;
|
|
164
|
+
}
|
|
165
|
+
function generateWebGqlormModelsContent(models) {
|
|
166
|
+
if (models.length === 0) {
|
|
167
|
+
return [
|
|
168
|
+
"// Auto-generated by Cedar \u2014 do not edit",
|
|
169
|
+
"// Regenerated on every codegen run. Source: api/db/schema.prisma",
|
|
170
|
+
"",
|
|
171
|
+
"declare module '@cedarjs/gqlorm/types/orm' {",
|
|
172
|
+
" interface GqlormTypeMap {}",
|
|
173
|
+
"}",
|
|
174
|
+
""
|
|
175
|
+
].join("\n");
|
|
176
|
+
}
|
|
177
|
+
const lines = [
|
|
178
|
+
"// Auto-generated by Cedar \u2014 do not edit",
|
|
179
|
+
"// Regenerated on every codegen run. Source: api/db/schema.prisma",
|
|
180
|
+
"",
|
|
181
|
+
"declare namespace GqlormScalar {"
|
|
182
|
+
];
|
|
183
|
+
for (const model of models) {
|
|
184
|
+
lines.push(` interface ${model.modelName} {`);
|
|
185
|
+
for (const field of model.fields) {
|
|
186
|
+
lines.push(` ${field.name}: ${field.tsType}`);
|
|
187
|
+
}
|
|
188
|
+
lines.push(" }");
|
|
189
|
+
lines.push("");
|
|
190
|
+
}
|
|
191
|
+
lines.push("}");
|
|
192
|
+
lines.push("");
|
|
193
|
+
lines.push("declare module '@cedarjs/gqlorm/types/orm' {");
|
|
194
|
+
lines.push(" interface GqlormTypeMap {");
|
|
195
|
+
lines.push(" models: {");
|
|
196
|
+
for (const model of models) {
|
|
197
|
+
lines.push(` ${model.camelName}: GqlormScalar.${model.modelName}`);
|
|
198
|
+
}
|
|
199
|
+
lines.push(" }");
|
|
200
|
+
lines.push(" }");
|
|
201
|
+
lines.push("}");
|
|
202
|
+
lines.push("");
|
|
203
|
+
return lines.join("\n");
|
|
204
|
+
}
|
|
74
205
|
function buildModelSchema(dmmf) {
|
|
75
206
|
const schema = {};
|
|
76
207
|
for (const model of dmmf.datamodel.models) {
|
|
@@ -292,27 +423,45 @@ async function generateGqlormArtifacts() {
|
|
|
292
423
|
const mod = await import("@prisma/internals");
|
|
293
424
|
const { getDMMF } = mod.default || mod;
|
|
294
425
|
const dmmf = await getDMMF({ datamodel: schemas });
|
|
426
|
+
const paths = getPaths();
|
|
427
|
+
const generatedBase = paths.generated.base;
|
|
295
428
|
const modelSchema = buildModelSchema(dmmf);
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
429
|
+
const frontendModels = buildFrontendModelInfo(dmmf);
|
|
430
|
+
const schemaOutputPath = path.join(generatedBase, "gqlorm-schema.json");
|
|
431
|
+
const webTypesOutputPath = path.join(
|
|
432
|
+
generatedBase,
|
|
433
|
+
"types",
|
|
434
|
+
"includes",
|
|
435
|
+
"web-gqlorm-models.d.ts"
|
|
299
436
|
);
|
|
300
437
|
fs.mkdirSync(path.dirname(schemaOutputPath), { recursive: true });
|
|
301
438
|
fs.writeFileSync(schemaOutputPath, JSON.stringify(modelSchema, null, 2));
|
|
302
439
|
files.push(schemaOutputPath);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
(m) => !existingTypes.has(m.modelName)
|
|
440
|
+
fs.mkdirSync(path.dirname(webTypesOutputPath), { recursive: true });
|
|
441
|
+
fs.writeFileSync(
|
|
442
|
+
webTypesOutputPath,
|
|
443
|
+
generateWebGqlormModelsContent(frontendModels)
|
|
308
444
|
);
|
|
309
|
-
|
|
445
|
+
files.push(webTypesOutputPath);
|
|
446
|
+
const backendOutputDir = path.join(generatedBase, "gqlorm");
|
|
310
447
|
const backendOutputPath = path.join(backendOutputDir, "backend.ts");
|
|
311
|
-
if (
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
448
|
+
if (getConfig().experimental?.gqlorm?.enabled) {
|
|
449
|
+
const graphqlDir = paths.api.graphql;
|
|
450
|
+
const existingTypes = getExistingSdlTypeNames(graphqlDir);
|
|
451
|
+
const allModels = buildBackendModelInfo(dmmf);
|
|
452
|
+
const gqlormModels = allModels.filter(
|
|
453
|
+
(m) => !existingTypes.has(m.modelName)
|
|
454
|
+
);
|
|
455
|
+
if (gqlormModels.length > 0) {
|
|
456
|
+
const backendContent = generateGqlormBackendContent(gqlormModels);
|
|
457
|
+
fs.mkdirSync(backendOutputDir, { recursive: true });
|
|
458
|
+
fs.writeFileSync(backendOutputPath, backendContent);
|
|
459
|
+
files.push(backendOutputPath);
|
|
460
|
+
} else {
|
|
461
|
+
if (fs.existsSync(backendOutputPath)) {
|
|
462
|
+
fs.unlinkSync(backendOutputPath);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
316
465
|
} else {
|
|
317
466
|
if (fs.existsSync(backendOutputPath)) {
|
|
318
467
|
fs.unlinkSync(backendOutputPath);
|
|
@@ -328,9 +477,11 @@ async function generateGqlormArtifacts() {
|
|
|
328
477
|
}
|
|
329
478
|
export {
|
|
330
479
|
buildBackendModelInfo,
|
|
480
|
+
buildFrontendModelInfo,
|
|
331
481
|
buildModelSchema,
|
|
332
482
|
generateGqlormArtifacts,
|
|
333
483
|
generateGqlormBackendContent,
|
|
484
|
+
generateWebGqlormModelsContent,
|
|
334
485
|
getExistingSdlTypeNames,
|
|
335
486
|
mapDmmfTypeToGraphql
|
|
336
487
|
};
|
package/dist/generate/watch.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import path from "path";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
import ansis from "ansis";
|
|
5
5
|
import chokidar from "chokidar";
|
|
6
6
|
import { getPaths } from "@cedarjs/project-config";
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { warningForDuplicateRoutes } from "../routes.js";
|
|
15
15
|
import { generateClientPreset } from "./clientPreset.js";
|
|
16
16
|
import { generate } from "./generate.js";
|
|
17
|
+
import { generateGqlormArtifacts } from "./gqlormSchema.js";
|
|
17
18
|
import {
|
|
18
19
|
generateTypeDefGraphQLApi,
|
|
19
20
|
generateTypeDefGraphQLWeb
|
|
@@ -29,13 +30,16 @@ import {
|
|
|
29
30
|
} from "./typeDefinitions.js";
|
|
30
31
|
const rwjsPaths = getPaths();
|
|
31
32
|
const generatedDirName = path.basename(rwjsPaths.generated.base);
|
|
32
|
-
const watcher = chokidar.watch(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
const watcher = chokidar.watch(
|
|
34
|
+
["(web|api)/src/**/*.{ts,js,jsx,tsx}", "api/db/**/*.prisma"],
|
|
35
|
+
{
|
|
36
|
+
persistent: true,
|
|
37
|
+
ignored: ["node_modules", generatedDirName],
|
|
38
|
+
ignoreInitial: true,
|
|
39
|
+
cwd: rwjsPaths.base,
|
|
40
|
+
awaitWriteFinish: true
|
|
41
|
+
}
|
|
42
|
+
);
|
|
39
43
|
const action = {
|
|
40
44
|
add: "Created",
|
|
41
45
|
unlink: "Deleted",
|
|
@@ -110,6 +114,9 @@ Created ${files.length} in ${Date.now() - start} ms`);
|
|
|
110
114
|
await generateGraphQLSchema();
|
|
111
115
|
await generateTypeDefGraphQLApi();
|
|
112
116
|
finished("GraphQL Schema");
|
|
117
|
+
} else if (absPath.startsWith(path.join(rwjsPaths.base, "api/db/")) && absPath.endsWith(".prisma")) {
|
|
118
|
+
await generateGqlormArtifacts();
|
|
119
|
+
finished("Prisma Schema");
|
|
113
120
|
}
|
|
114
121
|
if (routesWarningMessage) {
|
|
115
122
|
console.warn(routesWarningMessage);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/internal",
|
|
3
|
-
"version": "4.0.0-canary.
|
|
3
|
+
"version": "4.0.0-canary.13812+d9fd5099d9",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -159,13 +159,13 @@
|
|
|
159
159
|
"@babel/plugin-transform-react-jsx": "7.28.6",
|
|
160
160
|
"@babel/plugin-transform-typescript": "^7.26.8",
|
|
161
161
|
"@babel/traverse": "7.29.0",
|
|
162
|
-
"@cedarjs/babel-config": "4.0.0-canary.
|
|
163
|
-
"@cedarjs/cli-helpers": "4.0.0-canary.
|
|
164
|
-
"@cedarjs/graphql-server": "4.0.0-canary.
|
|
165
|
-
"@cedarjs/project-config": "4.0.0-canary.
|
|
166
|
-
"@cedarjs/router": "4.0.0-canary.
|
|
167
|
-
"@cedarjs/structure": "4.0.0-canary.
|
|
168
|
-
"@cedarjs/utils": "4.0.0-canary.
|
|
162
|
+
"@cedarjs/babel-config": "4.0.0-canary.13812",
|
|
163
|
+
"@cedarjs/cli-helpers": "4.0.0-canary.13812",
|
|
164
|
+
"@cedarjs/graphql-server": "4.0.0-canary.13812",
|
|
165
|
+
"@cedarjs/project-config": "4.0.0-canary.13812",
|
|
166
|
+
"@cedarjs/router": "4.0.0-canary.13812",
|
|
167
|
+
"@cedarjs/structure": "4.0.0-canary.13812",
|
|
168
|
+
"@cedarjs/utils": "4.0.0-canary.13812",
|
|
169
169
|
"@graphql-codegen/add": "6.0.0",
|
|
170
170
|
"@graphql-codegen/cli": "6.2.1",
|
|
171
171
|
"@graphql-codegen/client-preset": "5.2.4",
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
},
|
|
199
199
|
"devDependencies": {
|
|
200
200
|
"@arethetypeswrong/cli": "0.18.2",
|
|
201
|
-
"@cedarjs/framework-tools": "4.0.0-canary.
|
|
201
|
+
"@cedarjs/framework-tools": "4.0.0-canary.13812",
|
|
202
202
|
"concurrently": "9.2.1",
|
|
203
203
|
"graphql-tag": "2.12.6",
|
|
204
204
|
"publint": "0.3.18",
|
|
@@ -211,5 +211,5 @@
|
|
|
211
211
|
"publishConfig": {
|
|
212
212
|
"access": "public"
|
|
213
213
|
},
|
|
214
|
-
"gitHead": "
|
|
214
|
+
"gitHead": "d9fd5099d9b7219062f7334f43c31ae617f88d34"
|
|
215
215
|
}
|