@cedarjs/internal 5.0.3 → 5.0.4-next.167

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.
Files changed (143) hide show
  1. package/dist/ast.d.ts +1 -0
  2. package/dist/ast.d.ts.map +1 -1
  3. package/dist/ast.js +21 -0
  4. package/dist/build/api-graphql-transforms.d.ts +34 -0
  5. package/dist/build/api-graphql-transforms.d.ts.map +1 -0
  6. package/dist/build/api-graphql-transforms.js +119 -0
  7. package/dist/build/api.d.ts +2 -0
  8. package/dist/build/api.d.ts.map +1 -1
  9. package/dist/build/api.js +202 -39
  10. package/dist/build/auto-import.d.ts +10 -0
  11. package/dist/build/auto-import.d.ts.map +1 -0
  12. package/dist/build/auto-import.js +120 -0
  13. package/dist/build/directory-named-import.d.ts +2 -0
  14. package/dist/build/directory-named-import.d.ts.map +1 -0
  15. package/dist/build/directory-named-import.js +26 -0
  16. package/dist/build/esbuild-plugin-api-graphql.d.ts +6 -0
  17. package/dist/build/esbuild-plugin-api-graphql.d.ts.map +1 -0
  18. package/dist/build/esbuild-plugin-api-graphql.js +80 -0
  19. package/dist/build/esbuild-plugin-cedar-otel-wrapping.d.ts +13 -0
  20. package/dist/build/esbuild-plugin-cedar-otel-wrapping.d.ts.map +1 -0
  21. package/dist/build/esbuild-plugin-cedar-otel-wrapping.js +180 -0
  22. package/dist/build/esbuild-plugin-handler-als-wrapping.d.ts +4 -0
  23. package/dist/build/esbuild-plugin-handler-als-wrapping.d.ts.map +1 -0
  24. package/dist/build/{esbuild-plugin-cedar-context-wrapping.js → esbuild-plugin-handler-als-wrapping.js} +12 -12
  25. package/dist/build/esm-extensions.d.ts +33 -0
  26. package/dist/build/esm-extensions.d.ts.map +1 -0
  27. package/dist/build/esm-extensions.js +37 -0
  28. package/dist/build/import-dir.d.ts +22 -0
  29. package/dist/build/import-dir.d.ts.map +1 -0
  30. package/dist/build/import-dir.js +54 -0
  31. package/dist/build/job-path-injector.d.ts +15 -0
  32. package/dist/build/job-path-injector.d.ts.map +1 -0
  33. package/dist/build/job-path-injector.js +69 -0
  34. package/dist/build/src-alias.d.ts +14 -0
  35. package/dist/build/src-alias.d.ts.map +1 -0
  36. package/dist/build/src-alias.js +17 -0
  37. package/dist/build/tsconfig-paths.d.ts +2 -0
  38. package/dist/build/tsconfig-paths.d.ts.map +1 -0
  39. package/dist/build/tsconfig-paths.js +72 -0
  40. package/dist/generate/clientPreset.d.ts.map +1 -1
  41. package/dist/generate/clientPreset.js +10 -3
  42. package/dist/generate/templates/mirror-cell-fragment.d.ts.template +18 -0
  43. package/dist/generate/typeDefinitions.d.ts.map +1 -1
  44. package/dist/generate/typeDefinitions.js +15 -1
  45. package/dist/gql.d.ts +20 -0
  46. package/dist/gql.d.ts.map +1 -1
  47. package/dist/gql.js +24 -0
  48. package/package.json +48 -80
  49. package/dist/build/esbuild-plugin-cedar-context-wrapping.d.ts +0 -4
  50. package/dist/build/esbuild-plugin-cedar-context-wrapping.d.ts.map +0 -1
  51. package/dist/cjs/ast.d.ts +0 -26
  52. package/dist/cjs/ast.d.ts.map +0 -1
  53. package/dist/cjs/ast.js +0 -201
  54. package/dist/cjs/build/api.d.ts +0 -7
  55. package/dist/cjs/build/api.d.ts.map +0 -1
  56. package/dist/cjs/build/api.js +0 -251
  57. package/dist/cjs/build/esbuild-plugin-cedar-context-wrapping.d.ts +0 -4
  58. package/dist/cjs/build/esbuild-plugin-cedar-context-wrapping.d.ts.map +0 -1
  59. package/dist/cjs/build/esbuild-plugin-cedar-context-wrapping.js +0 -59
  60. package/dist/cjs/cliLogger.d.ts +0 -11
  61. package/dist/cjs/cliLogger.d.ts.map +0 -1
  62. package/dist/cjs/cliLogger.js +0 -36
  63. package/dist/cjs/dev.d.ts +0 -2
  64. package/dist/cjs/dev.d.ts.map +0 -1
  65. package/dist/cjs/dev.js +0 -41
  66. package/dist/cjs/files.d.ts +0 -56
  67. package/dist/cjs/files.d.ts.map +0 -1
  68. package/dist/cjs/files.js +0 -230
  69. package/dist/cjs/generate/clientPreset.d.ts +0 -17
  70. package/dist/cjs/generate/clientPreset.d.ts.map +0 -1
  71. package/dist/cjs/generate/clientPreset.js +0 -84
  72. package/dist/cjs/generate/generate.d.ts +0 -10
  73. package/dist/cjs/generate/generate.d.ts.map +0 -1
  74. package/dist/cjs/generate/generate.js +0 -97
  75. package/dist/cjs/generate/gqlormSchema.d.ts +0 -113
  76. package/dist/cjs/generate/gqlormSchema.d.ts.map +0 -1
  77. package/dist/cjs/generate/gqlormSchema.js +0 -1061
  78. package/dist/cjs/generate/graphqlCodeGen.d.ts +0 -16
  79. package/dist/cjs/generate/graphqlCodeGen.d.ts.map +0 -1
  80. package/dist/cjs/generate/graphqlCodeGen.js +0 -380
  81. package/dist/cjs/generate/graphqlSchema.d.ts +0 -8
  82. package/dist/cjs/generate/graphqlSchema.d.ts.map +0 -1
  83. package/dist/cjs/generate/graphqlSchema.js +0 -157
  84. package/dist/cjs/generate/plugins/rw-typescript-resolvers/index.d.ts +0 -7
  85. package/dist/cjs/generate/plugins/rw-typescript-resolvers/index.d.ts.map +0 -1
  86. package/dist/cjs/generate/plugins/rw-typescript-resolvers/index.js +0 -65
  87. package/dist/cjs/generate/plugins/rw-typescript-resolvers/visitor.d.ts +0 -10
  88. package/dist/cjs/generate/plugins/rw-typescript-resolvers/visitor.d.ts.map +0 -1
  89. package/dist/cjs/generate/plugins/rw-typescript-resolvers/visitor.js +0 -92
  90. package/dist/cjs/generate/possibleTypes.d.ts +0 -36
  91. package/dist/cjs/generate/possibleTypes.d.ts.map +0 -1
  92. package/dist/cjs/generate/possibleTypes.js +0 -106
  93. package/dist/cjs/generate/templates/all-currentUser.d.ts.template +0 -30
  94. package/dist/cjs/generate/templates/all-gqlorm.d.ts.template +0 -7
  95. package/dist/cjs/generate/templates/api-globImports.d.ts.template +0 -9
  96. package/dist/cjs/generate/templates/api-globalContext.d.ts.template +0 -7
  97. package/dist/cjs/generate/templates/api-scenarios.d.ts.template +0 -10
  98. package/dist/cjs/generate/templates/api-test-globals.d.ts.template +0 -5
  99. package/dist/cjs/generate/templates/mirror-cell.d.ts.template +0 -13
  100. package/dist/cjs/generate/templates/mirror-directoryNamedModule.d.ts.template +0 -5
  101. package/dist/cjs/generate/templates/web-routerRoutes.d.ts.template +0 -20
  102. package/dist/cjs/generate/templates/web-routesPages.d.ts.template +0 -13
  103. package/dist/cjs/generate/templates/web-test-globals.d.ts.template +0 -7
  104. package/dist/cjs/generate/templates.d.ts +0 -6
  105. package/dist/cjs/generate/templates.d.ts.map +0 -1
  106. package/dist/cjs/generate/templates.js +0 -68
  107. package/dist/cjs/generate/trustedDocuments.d.ts +0 -3
  108. package/dist/cjs/generate/trustedDocuments.d.ts.map +0 -1
  109. package/dist/cjs/generate/trustedDocuments.js +0 -95
  110. package/dist/cjs/generate/typeDefinitions.d.ts +0 -31
  111. package/dist/cjs/generate/typeDefinitions.d.ts.map +0 -1
  112. package/dist/cjs/generate/typeDefinitions.js +0 -372
  113. package/dist/cjs/generate/types.d.ts +0 -6
  114. package/dist/cjs/generate/types.d.ts.map +0 -1
  115. package/dist/cjs/generate/types.js +0 -16
  116. package/dist/cjs/generate/watch.d.ts +0 -3
  117. package/dist/cjs/generate/watch.d.ts.map +0 -1
  118. package/dist/cjs/generate/watch.js +0 -132
  119. package/dist/cjs/gql.d.ts +0 -14
  120. package/dist/cjs/gql.d.ts.map +0 -1
  121. package/dist/cjs/gql.js +0 -108
  122. package/dist/cjs/index.d.ts +0 -11
  123. package/dist/cjs/index.d.ts.map +0 -1
  124. package/dist/cjs/index.js +0 -49
  125. package/dist/cjs/jsx.d.ts +0 -16
  126. package/dist/cjs/jsx.d.ts.map +0 -1
  127. package/dist/cjs/jsx.js +0 -101
  128. package/dist/cjs/jsxAttributeValue.d.ts +0 -2
  129. package/dist/cjs/jsxAttributeValue.d.ts.map +0 -1
  130. package/dist/cjs/jsxAttributeValue.js +0 -129
  131. package/dist/cjs/package.json +0 -1
  132. package/dist/cjs/project.d.ts +0 -8
  133. package/dist/cjs/project.d.ts.map +0 -1
  134. package/dist/cjs/project.js +0 -82
  135. package/dist/cjs/routes.d.ts +0 -42
  136. package/dist/cjs/routes.d.ts.map +0 -1
  137. package/dist/cjs/routes.js +0 -111
  138. package/dist/cjs/ts2js.d.ts +0 -40
  139. package/dist/cjs/ts2js.d.ts.map +0 -1
  140. package/dist/cjs/ts2js.js +0 -159
  141. package/dist/cjs/validateSchema.d.ts +0 -14
  142. package/dist/cjs/validateSchema.d.ts.map +0 -1
  143. package/dist/cjs/validateSchema.js +0 -195
@@ -1,1061 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var gqlormSchema_exports = {};
30
- __export(gqlormSchema_exports, {
31
- buildBackendModelInfo: () => buildBackendModelInfo,
32
- buildFrontendModelInfo: () => buildFrontendModelInfo,
33
- buildModelSchema: () => buildModelSchema,
34
- generateGqlormArtifacts: () => generateGqlormArtifacts,
35
- generateGqlormBackendContent: () => generateGqlormBackendContent,
36
- generateWebGqlormModelsContent: () => generateWebGqlormModelsContent,
37
- getExistingSdlTypeNames: () => getExistingSdlTypeNames,
38
- mapDmmfTypeToGraphql: () => mapDmmfTypeToGraphql
39
- });
40
- module.exports = __toCommonJS(gqlormSchema_exports);
41
- var import_node_fs = __toESM(require("node:fs"), 1);
42
- var import_node_path = __toESM(require("node:path"), 1);
43
- var import_project_config = require("@cedarjs/project-config");
44
- var import_cedarPluralize = require("@cedarjs/utils/cedarPluralize");
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
- ];
60
- const DEFAULT_GQLORM_BACKEND_CONFIG = {
61
- membershipModel: "Membership",
62
- membershipModelCamel: "membership",
63
- membershipUserField: "userId",
64
- membershipOrganizationField: "organizationId",
65
- membershipModelExists: false
66
- };
67
- function hasDirective(doc, directive) {
68
- if (!doc) {
69
- return false;
70
- }
71
- return doc.split("\n").some((line) => line.trimStart().startsWith(`@gqlorm ${directive}`));
72
- }
73
- function isSensitiveField(fieldName) {
74
- const lower = fieldName.toLowerCase();
75
- return SENSITIVE_PATTERNS.some((pattern) => lower.includes(pattern));
76
- }
77
- function emitSensitivityWarning(modelName, fieldName) {
78
- console.warn(
79
- `[gqlorm] ${modelName}.${fieldName} was automatically hidden because its name appears sensitive. Add a directive to suppress this warning:
80
-
81
- /// @gqlorm hide \u2013 to confirm it should stay hidden
82
- /// @gqlorm show \u2013 to explicitly expose it
83
- `
84
- );
85
- }
86
- const DMMF_TYPE_TO_GRAPHQL = {
87
- String: "String",
88
- Int: "Int",
89
- Float: "Float",
90
- BigInt: "BigInt",
91
- Boolean: "Boolean",
92
- DateTime: "DateTime",
93
- Json: "JSON",
94
- Decimal: "String",
95
- Bytes: "String"
96
- };
97
- function mapDmmfTypeToGraphql(type, kind) {
98
- if (kind === "enum") {
99
- return "String";
100
- }
101
- return DMMF_TYPE_TO_GRAPHQL[type] ?? "String";
102
- }
103
- function graphqlTypeToTsType(graphqlType) {
104
- switch (graphqlType) {
105
- case "Int":
106
- case "Float":
107
- case "BigInt":
108
- return "number";
109
- case "Boolean":
110
- return "boolean";
111
- default:
112
- return "string";
113
- }
114
- }
115
- function graphqlTypeToTsInterfaceType(graphqlType, isRequired) {
116
- let tsType;
117
- switch (graphqlType) {
118
- case "Int":
119
- case "Float":
120
- case "BigInt":
121
- tsType = "number";
122
- break;
123
- case "Boolean":
124
- tsType = "boolean";
125
- break;
126
- case "DateTime":
127
- tsType = "Date";
128
- break;
129
- default:
130
- tsType = "string";
131
- }
132
- return isRequired ? tsType : `${tsType} | null`;
133
- }
134
- function dmmfTypeToFrontendTsType(type, kind, isRequired) {
135
- let tsType;
136
- if (kind === "enum") {
137
- tsType = "string";
138
- } else {
139
- switch (type) {
140
- case "String":
141
- tsType = "string";
142
- break;
143
- case "Int":
144
- case "Float":
145
- tsType = "number";
146
- break;
147
- case "BigInt":
148
- tsType = "bigint";
149
- break;
150
- case "Boolean":
151
- tsType = "boolean";
152
- break;
153
- case "DateTime":
154
- tsType = "string";
155
- break;
156
- case "Json":
157
- tsType = "unknown";
158
- break;
159
- case "Bytes":
160
- case "Decimal":
161
- tsType = "string";
162
- break;
163
- default:
164
- tsType = "unknown";
165
- }
166
- }
167
- if (isRequired) {
168
- return tsType;
169
- }
170
- return `${tsType} | null`;
171
- }
172
- function buildFrontendModelInfo(dmmf) {
173
- const models = [];
174
- for (const model of dmmf.datamodel.models) {
175
- if (INTERNAL_MODEL_NAMES.has(model.name)) {
176
- continue;
177
- }
178
- if (hasDirective(model.documentation, "hide")) {
179
- continue;
180
- }
181
- const fields = [];
182
- for (const field of model.fields) {
183
- if (field.kind !== "scalar" && field.kind !== "enum") {
184
- continue;
185
- }
186
- if (hasDirective(field.documentation, "hide")) {
187
- continue;
188
- }
189
- const isShown = hasDirective(field.documentation, "show");
190
- if (!isShown && isSensitiveField(field.name)) {
191
- continue;
192
- }
193
- fields.push({
194
- name: field.name,
195
- tsType: dmmfTypeToFrontendTsType(
196
- field.type,
197
- field.kind,
198
- field.isRequired
199
- )
200
- });
201
- }
202
- if (fields.length > 0) {
203
- models.push({
204
- modelName: model.name,
205
- camelName: model.name.charAt(0).toLowerCase() + model.name.slice(1),
206
- fields
207
- });
208
- }
209
- }
210
- return models;
211
- }
212
- function generateWebGqlormModelsContent(models) {
213
- if (models.length === 0) {
214
- return [
215
- "// Auto-generated by Cedar \u2014 do not edit",
216
- "// Regenerated on every codegen run. Source: api/db/schema.prisma",
217
- "",
218
- "declare module '@cedarjs/gqlorm/types/orm' {",
219
- " interface GqlormTypeMap {}",
220
- "}",
221
- ""
222
- ].join("\n");
223
- }
224
- const lines = [
225
- "// Auto-generated by Cedar \u2014 do not edit",
226
- "// Regenerated on every codegen run. Source: api/db/schema.prisma",
227
- "",
228
- "declare namespace GqlormScalar {"
229
- ];
230
- for (const model of models) {
231
- lines.push(` interface ${model.modelName} {`);
232
- for (const field of model.fields) {
233
- lines.push(` ${field.name}: ${field.tsType}`);
234
- }
235
- lines.push(" }");
236
- lines.push("");
237
- }
238
- lines.push("}");
239
- lines.push("");
240
- lines.push("declare module '@cedarjs/gqlorm/types/orm' {");
241
- lines.push(" interface GqlormTypeMap {");
242
- lines.push(" models: {");
243
- for (const model of models) {
244
- lines.push(` ${model.camelName}: GqlormScalar.${model.modelName}`);
245
- }
246
- lines.push(" }");
247
- lines.push(" }");
248
- lines.push("}");
249
- lines.push("");
250
- return lines.join("\n");
251
- }
252
- function buildModelSchema(dmmf) {
253
- const schema = {};
254
- for (const model of dmmf.datamodel.models) {
255
- if (INTERNAL_MODEL_NAMES.has(model.name)) {
256
- continue;
257
- }
258
- if (hasDirective(model.documentation, "hide")) {
259
- continue;
260
- }
261
- const visibleFields = [];
262
- for (const field of model.fields) {
263
- if (field.kind !== "scalar" && field.kind !== "enum") {
264
- continue;
265
- }
266
- if (hasDirective(field.documentation, "hide")) {
267
- continue;
268
- }
269
- if (hasDirective(field.documentation, "show")) {
270
- visibleFields.push(field.name);
271
- continue;
272
- }
273
- if (isSensitiveField(field.name)) {
274
- emitSensitivityWarning(model.name, field.name);
275
- continue;
276
- }
277
- visibleFields.push(field.name);
278
- }
279
- if (visibleFields.length > 0) {
280
- const camelCaseName = model.name.charAt(0).toLowerCase() + model.name.slice(1);
281
- schema[camelCaseName] = visibleFields;
282
- }
283
- }
284
- return schema;
285
- }
286
- function buildBackendModelInfo(dmmf) {
287
- const models = [];
288
- for (const model of dmmf.datamodel.models) {
289
- if (INTERNAL_MODEL_NAMES.has(model.name)) {
290
- continue;
291
- }
292
- if (hasDirective(model.documentation, "hide")) {
293
- continue;
294
- }
295
- const fields = [];
296
- for (const field of model.fields) {
297
- if (field.kind !== "scalar" && field.kind !== "enum") {
298
- continue;
299
- }
300
- if (hasDirective(field.documentation, "hide")) {
301
- continue;
302
- }
303
- const isShown = hasDirective(field.documentation, "show");
304
- if (!isShown && isSensitiveField(field.name)) {
305
- continue;
306
- }
307
- fields.push({
308
- name: field.name,
309
- graphqlType: mapDmmfTypeToGraphql(field.type, field.kind),
310
- isRequired: field.isRequired,
311
- isId: field.isId,
312
- hasDefaultValue: field.hasDefaultValue,
313
- isUpdatedAt: field.isUpdatedAt ?? false
314
- });
315
- }
316
- if (fields.length > 0) {
317
- const camelName = model.name.charAt(0).toLowerCase() + model.name.slice(1);
318
- const pluralName = (0, import_cedarPluralize.pluralize)(camelName);
319
- models.push({
320
- modelName: model.name,
321
- camelName,
322
- pluralName,
323
- fields,
324
- idField: fields.find((f) => f.isId)
325
- });
326
- }
327
- }
328
- return models;
329
- }
330
- const TYPE_DEF_REGEX = /\btype\s+([A-Z]\w*)\s*\{/g;
331
- const STRUCTURAL_TYPE_NAMES = /* @__PURE__ */ new Set(["Query", "Mutation", "Subscription"]);
332
- function getExistingSdlTypeNames(graphqlDir) {
333
- const typeNames = /* @__PURE__ */ new Set();
334
- if (!import_node_fs.default.existsSync(graphqlDir)) {
335
- return typeNames;
336
- }
337
- const sdlFiles = import_node_fs.default.readdirSync(graphqlDir).filter((file) => {
338
- return /\.sdl\.(ts|js)$/.test(file) && !file.startsWith("__gqlorm__");
339
- });
340
- for (const file of sdlFiles) {
341
- const content = import_node_fs.default.readFileSync(import_node_path.default.join(graphqlDir, file), "utf-8");
342
- let match;
343
- TYPE_DEF_REGEX.lastIndex = 0;
344
- while ((match = TYPE_DEF_REGEX.exec(content)) !== null) {
345
- const name = match[1];
346
- if (!STRUCTURAL_TYPE_NAMES.has(name)) {
347
- typeNames.add(name);
348
- }
349
- }
350
- }
351
- return typeNames;
352
- }
353
- function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CONFIG) {
354
- if (models.length === 0) {
355
- return "";
356
- }
357
- const anyModelNeedsOrgScoping = config.membershipModelExists && models.some(
358
- (m) => m.camelName !== config.membershipModelCamel && m.fields.some((f) => f.name === config.membershipOrganizationField)
359
- );
360
- const anyModelNeedsAuth = models.some((m) => {
361
- const hasUserField = m.fields.some(
362
- (f) => f.name === config.membershipUserField
363
- );
364
- const hasOrgField = m.fields.some(
365
- (f) => f.name === config.membershipOrganizationField
366
- );
367
- const isMembership = m.camelName === config.membershipModelCamel;
368
- return hasUserField || hasOrgField && config.membershipModelExists && !isMembership;
369
- });
370
- const lines = [
371
- "// This file is auto-generated by Cedar gqlorm codegen.",
372
- "// Do not edit \u2014 it will be overwritten on every codegen run.",
373
- "// To hide a model from gqlorm, add /// @gqlorm hide in schema.prisma.",
374
- "",
375
- "import gql from 'graphql-tag'",
376
- ...anyModelNeedsAuth ? [
377
- "import { AuthenticationError, ForbiddenError } from '@cedarjs/graphql-server'"
378
- ] : [],
379
- "",
380
- "// Minimal context type used in auth checks",
381
- "interface GqlormContext {",
382
- " currentUser: Record<string, unknown> | null | undefined",
383
- "}",
384
- "",
385
- "// Generated minimal interface \u2014 only visible models and fields, only the",
386
- "// operations used by this file. No @gqlorm hide models, no sensitive fields.",
387
- "// Scoped to avoid any dependency on the generated Prisma client path or",
388
- "// @prisma/client (which is an empty shim in Prisma v7).",
389
- "interface GqlormDb {"
390
- ];
391
- for (const model of models) {
392
- const selectType = model.fields.map((f) => `${f.name}: true`).join("; ");
393
- lines.push(` ${model.camelName}: {`);
394
- lines.push(" findMany(args: {");
395
- lines.push(" where?: Record<string, unknown>");
396
- lines.push(` select: Partial<{ ${selectType} }>`);
397
- lines.push(" }): Promise<");
398
- lines.push(" Array<{");
399
- for (const field of model.fields) {
400
- const tsType = graphqlTypeToTsInterfaceType(
401
- field.graphqlType,
402
- field.isRequired
403
- );
404
- lines.push(` ${field.name}: ${tsType}`);
405
- }
406
- lines.push(" }>");
407
- lines.push(" >");
408
- if (model.idField) {
409
- const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
410
- lines.push(" findUnique(args: {");
411
- lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
412
- lines.push(` select: { ${selectType} }`);
413
- lines.push(" }): Promise<{");
414
- for (const field of model.fields) {
415
- const tsType = graphqlTypeToTsInterfaceType(
416
- field.graphqlType,
417
- field.isRequired
418
- );
419
- lines.push(` ${field.name}: ${tsType}`);
420
- }
421
- lines.push(" } | null>");
422
- }
423
- if (anyModelNeedsOrgScoping && model.camelName === config.membershipModelCamel) {
424
- lines.push(" findFirst(args: {");
425
- lines.push(" where: Record<string, unknown>");
426
- lines.push(" }): Promise<Record<string, unknown> | null>");
427
- }
428
- lines.push(" create(args: {");
429
- lines.push(" data: Record<string, unknown>");
430
- lines.push(` select: { ${selectType} }`);
431
- lines.push(" }): Promise<{");
432
- for (const field of model.fields) {
433
- const tsType = graphqlTypeToTsInterfaceType(
434
- field.graphqlType,
435
- field.isRequired
436
- );
437
- lines.push(` ${field.name}: ${tsType}`);
438
- }
439
- lines.push(" }>");
440
- if (model.idField) {
441
- const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
442
- lines.push(" update(args: {");
443
- lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
444
- lines.push(" data: Record<string, unknown>");
445
- lines.push(` select: { ${selectType} }`);
446
- lines.push(" }): Promise<{");
447
- for (const field of model.fields) {
448
- const tsType = graphqlTypeToTsInterfaceType(
449
- field.graphqlType,
450
- field.isRequired
451
- );
452
- lines.push(` ${field.name}: ${tsType}`);
453
- }
454
- lines.push(" }>");
455
- lines.push(" delete(args: {");
456
- lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
457
- lines.push(` select: { ${selectType} }`);
458
- lines.push(" }): Promise<{");
459
- for (const field of model.fields) {
460
- const tsType = graphqlTypeToTsInterfaceType(
461
- field.graphqlType,
462
- field.isRequired
463
- );
464
- lines.push(` ${field.name}: ${tsType}`);
465
- }
466
- lines.push(" }>");
467
- }
468
- lines.push(" }");
469
- }
470
- const membershipAlreadyInModels = models.some(
471
- (m) => m.camelName === config.membershipModelCamel
472
- );
473
- if (anyModelNeedsOrgScoping && !membershipAlreadyInModels) {
474
- lines.push(` ${config.membershipModelCamel}: {`);
475
- lines.push(" findMany(args: {");
476
- lines.push(" where: Record<string, unknown>");
477
- lines.push(` select: { ${config.membershipOrganizationField}: true }`);
478
- lines.push(" }): Promise<");
479
- lines.push(
480
- ` Array<{ ${config.membershipOrganizationField}: unknown }>`
481
- );
482
- lines.push(" >");
483
- lines.push(" findFirst(args: {");
484
- lines.push(" where: Record<string, unknown>");
485
- lines.push(" }): Promise<Record<string, unknown> | null>");
486
- lines.push(" }");
487
- }
488
- lines.push("}");
489
- lines.push("");
490
- lines.push("export const schema = gql`");
491
- for (const model of models) {
492
- lines.push(` type ${model.modelName} {`);
493
- for (const field of model.fields) {
494
- const nullMark = field.isRequired ? "!" : "";
495
- lines.push(` ${field.name}: ${field.graphqlType}${nullMark}`);
496
- }
497
- lines.push(" }");
498
- lines.push("");
499
- if (!model.idField) {
500
- continue;
501
- }
502
- const writableFields = model.fields.filter(
503
- (field) => !field.isId && !field.isUpdatedAt && field.name !== config.membershipUserField
504
- );
505
- lines.push(` input Create${model.modelName}Input {`);
506
- for (const field of writableFields) {
507
- const isClientRequired = field.isRequired && !field.hasDefaultValue;
508
- const nullMark = isClientRequired ? "!" : "";
509
- lines.push(` ${field.name}: ${field.graphqlType}${nullMark}`);
510
- }
511
- lines.push(" }");
512
- lines.push("");
513
- lines.push(` input Update${model.modelName}Input {`);
514
- for (const field of writableFields) {
515
- lines.push(` ${field.name}: ${field.graphqlType}`);
516
- }
517
- lines.push(" }");
518
- lines.push("");
519
- }
520
- lines.push(" type Query {");
521
- for (const model of models) {
522
- const hasUserField = model.fields.some(
523
- (f) => f.name === config.membershipUserField
524
- );
525
- const hasOrgField = model.fields.some(
526
- (f) => f.name === config.membershipOrganizationField
527
- );
528
- const isMembershipModel = model.camelName === config.membershipModelCamel;
529
- const needsAuth = hasUserField || hasOrgField && config.membershipModelExists && !isMembershipModel;
530
- const authDirective = needsAuth ? "@requireAuth" : "@skipAuth";
531
- lines.push(
532
- ` ${model.pluralName}: [${model.modelName}!]! ${authDirective}`
533
- );
534
- if (model.idField) {
535
- const idNullMark = model.idField.isRequired ? "!" : "";
536
- lines.push(
537
- ` ${model.camelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}): ${model.modelName} ${authDirective}`
538
- );
539
- }
540
- }
541
- lines.push(" }");
542
- lines.push("");
543
- lines.push(" type Mutation {");
544
- for (const model of models) {
545
- if (model.idField) {
546
- const hasUserField = model.fields.some(
547
- (f) => f.name === config.membershipUserField
548
- );
549
- const hasOrgField = model.fields.some(
550
- (f) => f.name === config.membershipOrganizationField
551
- );
552
- const isMembershipModel = model.camelName === config.membershipModelCamel;
553
- const needsAuth = hasUserField || hasOrgField && config.membershipModelExists && !isMembershipModel;
554
- const authDirective = needsAuth ? "@requireAuth" : "@skipAuth";
555
- const idNullMark = model.idField.isRequired ? "!" : "";
556
- lines.push(
557
- ` create${model.modelName}(input: Create${model.modelName}Input!): ${model.modelName}! ${authDirective}`
558
- );
559
- lines.push(
560
- ` update${model.modelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}, input: Update${model.modelName}Input!): ${model.modelName}! ${authDirective}`
561
- );
562
- lines.push(
563
- ` delete${model.modelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}): ${model.modelName}! ${authDirective}`
564
- );
565
- }
566
- }
567
- lines.push(" }");
568
- lines.push("`");
569
- lines.push("");
570
- lines.push(
571
- "// db is passed in from graphql.ts by the Babel inject plugin, which imports it"
572
- );
573
- lines.push(
574
- "// from 'src/lib/db' in a context where that alias resolves correctly."
575
- );
576
- lines.push("export function createGqlormResolvers(db: GqlormDb) {");
577
- lines.push(" return {");
578
- lines.push(" Query: {");
579
- for (let i = 0; i < models.length; i++) {
580
- const model = models[i];
581
- const selectObj = model.fields.map((f) => `${f.name}: true`).join(", ");
582
- const hasUserField = model.fields.some(
583
- (f) => f.name === config.membershipUserField
584
- );
585
- const hasOrgField = model.fields.some(
586
- (f) => f.name === config.membershipOrganizationField
587
- );
588
- const isMembershipModel = model.camelName === config.membershipModelCamel;
589
- const useOrgScoping = hasOrgField && config.membershipModelExists && !isMembershipModel;
590
- lines.push(
591
- ` ${model.pluralName}: async (_root: unknown, _args: unknown, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
592
- );
593
- if (hasUserField || useOrgScoping) {
594
- lines.push(" if (!context.currentUser) {");
595
- lines.push(
596
- ` throw new AuthenticationError("You don't have permission to do that.")`
597
- );
598
- lines.push(" }");
599
- lines.push(" const currentUserId = context.currentUser['id']");
600
- lines.push(
601
- " if (currentUserId === undefined || currentUserId === null) {"
602
- );
603
- lines.push(
604
- ` throw new AuthenticationError("Could not determine the current user's ID.")`
605
- );
606
- lines.push(" }");
607
- lines.push(" const where: Record<string, unknown> = {}");
608
- if (hasUserField) {
609
- lines.push(" // Scope to the current user");
610
- lines.push(
611
- ` where['${config.membershipUserField}'] = currentUserId`
612
- );
613
- }
614
- if (useOrgScoping) {
615
- lines.push(" // Scope to the current user's organizations");
616
- lines.push(
617
- ` const memberships = await db.${config.membershipModelCamel}.findMany({`
618
- );
619
- lines.push(
620
- ` where: { ${config.membershipUserField}: currentUserId },`
621
- );
622
- lines.push(
623
- ` select: { ${config.membershipOrganizationField}: true },`
624
- );
625
- lines.push(" })");
626
- lines.push(
627
- ` const organizationIds = memberships.map((m) => m.${config.membershipOrganizationField})`
628
- );
629
- lines.push(
630
- ` where['${config.membershipOrganizationField}'] = { in: organizationIds }`
631
- );
632
- }
633
- lines.push(` return db.${model.camelName}.findMany({`);
634
- lines.push(" where,");
635
- lines.push(` select: { ${selectObj} },`);
636
- lines.push(" })");
637
- } else {
638
- lines.push(` return db.${model.camelName}.findMany({`);
639
- lines.push(` select: { ${selectObj} },`);
640
- lines.push(" })");
641
- }
642
- lines.push(" },");
643
- if (model.idField) {
644
- const idFieldName = model.idField.name;
645
- const tsType = graphqlTypeToTsType(model.idField.graphqlType);
646
- lines.push(
647
- ` ${model.camelName}: async (_root: unknown, { ${idFieldName} }: { ${idFieldName}: ${tsType} }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
648
- );
649
- if (hasUserField || useOrgScoping) {
650
- lines.push(" if (!context.currentUser) {");
651
- lines.push(
652
- ` throw new AuthenticationError("You don't have permission to do that.")`
653
- );
654
- lines.push(" }");
655
- lines.push(" const currentUserId = context.currentUser['id']");
656
- lines.push(
657
- " if (currentUserId === undefined || currentUserId === null) {"
658
- );
659
- lines.push(
660
- ` throw new AuthenticationError("Could not determine the current user's ID.")`
661
- );
662
- lines.push(" }");
663
- }
664
- lines.push("");
665
- lines.push(
666
- ` const record = await db.${model.camelName}.findUnique({`
667
- );
668
- lines.push(` where: { ${idFieldName} },`);
669
- lines.push(` select: { ${selectObj} },`);
670
- lines.push(" })");
671
- lines.push("");
672
- lines.push(" if (!record) {");
673
- lines.push(" return null");
674
- lines.push(" }");
675
- if (hasUserField) {
676
- lines.push("");
677
- lines.push(" // Verify the current user owns this record");
678
- lines.push(
679
- ` if (record.${config.membershipUserField} !== currentUserId) {`
680
- );
681
- lines.push(
682
- ` throw new ForbiddenError('Not authorized to access this resource')`
683
- );
684
- lines.push(" }");
685
- }
686
- if (useOrgScoping) {
687
- lines.push("");
688
- lines.push(
689
- " // Verify the current user belongs to the record's organization"
690
- );
691
- lines.push(
692
- ` const membership = await db.${config.membershipModelCamel}.findFirst({`
693
- );
694
- lines.push(" where: {");
695
- lines.push(` ${config.membershipUserField}: currentUserId,`);
696
- lines.push(
697
- ` ${config.membershipOrganizationField}: record.${config.membershipOrganizationField},`
698
- );
699
- lines.push(" },");
700
- lines.push(" })");
701
- lines.push(" if (!membership) {");
702
- lines.push(
703
- ` throw new ForbiddenError('Not authorized to access this resource')`
704
- );
705
- lines.push(" }");
706
- }
707
- lines.push("");
708
- lines.push(" return record");
709
- lines.push(" },");
710
- }
711
- if (i < models.length - 1) {
712
- lines.push("");
713
- }
714
- }
715
- lines.push(" },");
716
- lines.push(" Mutation: {");
717
- for (const model of models) {
718
- if (!model.idField) {
719
- continue;
720
- }
721
- const selectObj = model.fields.map((f) => `${f.name}: true`).join(", ");
722
- const hasUserField = model.fields.some(
723
- (f) => f.name === config.membershipUserField
724
- );
725
- const hasOrgField = model.fields.some(
726
- (f) => f.name === config.membershipOrganizationField
727
- );
728
- const isMembershipModel = model.camelName === config.membershipModelCamel;
729
- const useOrgScoping = hasOrgField && config.membershipModelExists && !isMembershipModel;
730
- const idFieldName = model.idField.name;
731
- const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
732
- lines.push(
733
- ` create${model.modelName}: async (_root: unknown, { input }: { input: Record<string, unknown> }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
734
- );
735
- if (hasUserField || useOrgScoping) {
736
- lines.push(" if (!context.currentUser) {");
737
- lines.push(
738
- ` throw new AuthenticationError("You don't have permission to do that.")`
739
- );
740
- lines.push(" }");
741
- lines.push(" const currentUserId = context.currentUser['id']");
742
- lines.push(
743
- " if (currentUserId === undefined || currentUserId === null) {"
744
- );
745
- lines.push(
746
- ` throw new AuthenticationError("Could not determine the current user's ID.")`
747
- );
748
- lines.push(" }");
749
- }
750
- lines.push(" const data: Record<string, unknown> = { ...input }");
751
- if (hasUserField) {
752
- lines.push(
753
- ` data['${config.membershipUserField}'] = currentUserId`
754
- );
755
- }
756
- if (useOrgScoping) {
757
- lines.push(
758
- ` const organizationId = data['${config.membershipOrganizationField}']`
759
- );
760
- lines.push(
761
- " if (organizationId === undefined || organizationId === null) {"
762
- );
763
- lines.push(
764
- ` throw new ForbiddenError('Organization membership is required for this operation')`
765
- );
766
- lines.push(" }");
767
- lines.push(
768
- ` const membership = await db.${config.membershipModelCamel}.findFirst({`
769
- );
770
- lines.push(" where: {");
771
- lines.push(` ${config.membershipUserField}: currentUserId,`);
772
- lines.push(
773
- ` ${config.membershipOrganizationField}: organizationId,`
774
- );
775
- lines.push(" },");
776
- lines.push(" })");
777
- lines.push(" if (!membership) {");
778
- lines.push(
779
- ` throw new ForbiddenError('Not authorized to access this resource')`
780
- );
781
- lines.push(" }");
782
- }
783
- lines.push(` return db.${model.camelName}.create({`);
784
- lines.push(" data,");
785
- lines.push(` select: { ${selectObj} },`);
786
- lines.push(" })");
787
- lines.push(" },");
788
- lines.push(
789
- ` update${model.modelName}: async (_root: unknown, { ${idFieldName}, input }: { ${idFieldName}: ${idTsType}; input: Record<string, unknown> }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
790
- );
791
- if (hasUserField || useOrgScoping) {
792
- lines.push(" if (!context.currentUser) {");
793
- lines.push(
794
- ` throw new AuthenticationError("You don't have permission to do that.")`
795
- );
796
- lines.push(" }");
797
- lines.push(" const currentUserId = context.currentUser['id']");
798
- lines.push(
799
- " if (currentUserId === undefined || currentUserId === null) {"
800
- );
801
- lines.push(
802
- ` throw new AuthenticationError("Could not determine the current user's ID.")`
803
- );
804
- lines.push(" }");
805
- lines.push(
806
- ` const existingRecord = await db.${model.camelName}.findUnique({`
807
- );
808
- lines.push(` where: { ${idFieldName} },`);
809
- lines.push(` select: { ${selectObj} },`);
810
- lines.push(" })");
811
- lines.push(" if (!existingRecord) {");
812
- lines.push(
813
- ` throw new ForbiddenError('Not authorized to access this resource')`
814
- );
815
- lines.push(" }");
816
- lines.push(" const data: Record<string, unknown> = { ...input }");
817
- if (hasUserField) {
818
- lines.push(
819
- ` if (existingRecord.${config.membershipUserField} !== currentUserId) {`
820
- );
821
- lines.push(
822
- ` throw new ForbiddenError('Not authorized to access this resource')`
823
- );
824
- lines.push(" }");
825
- lines.push(` delete data['${config.membershipUserField}']`);
826
- }
827
- if (useOrgScoping) {
828
- lines.push(
829
- ` const currentOrganizationId = existingRecord.${config.membershipOrganizationField}`
830
- );
831
- lines.push(
832
- ` const currentOrganizationMembership = await db.${config.membershipModelCamel}.findFirst({`
833
- );
834
- lines.push(" where: {");
835
- lines.push(` ${config.membershipUserField}: currentUserId,`);
836
- lines.push(
837
- ` ${config.membershipOrganizationField}: currentOrganizationId,`
838
- );
839
- lines.push(" },");
840
- lines.push(" })");
841
- lines.push(" if (!currentOrganizationMembership) {");
842
- lines.push(
843
- ` throw new ForbiddenError('Not authorized to access this resource')`
844
- );
845
- lines.push(" }");
846
- lines.push(
847
- ` const requestedOrganizationId = input['${config.membershipOrganizationField}'] ?? currentOrganizationId`
848
- );
849
- lines.push(
850
- ` const requestedOrganizationMembership = await db.${config.membershipModelCamel}.findFirst({`
851
- );
852
- lines.push(" where: {");
853
- lines.push(` ${config.membershipUserField}: currentUserId,`);
854
- lines.push(
855
- ` ${config.membershipOrganizationField}: requestedOrganizationId,`
856
- );
857
- lines.push(" },");
858
- lines.push(" })");
859
- lines.push(" if (!requestedOrganizationMembership) {");
860
- lines.push(
861
- ` throw new ForbiddenError('Not authorized to access this resource')`
862
- );
863
- lines.push(" }");
864
- }
865
- }
866
- if (!(hasUserField || useOrgScoping)) {
867
- lines.push(
868
- ` const existingRecord = await db.${model.camelName}.findUnique({`
869
- );
870
- lines.push(` where: { ${idFieldName} },`);
871
- lines.push(` select: { ${selectObj} },`);
872
- lines.push(" })");
873
- lines.push(" if (!existingRecord) {");
874
- lines.push(
875
- ` throw new ForbiddenError('Not authorized to access this resource')`
876
- );
877
- lines.push(" }");
878
- lines.push(" const data: Record<string, unknown> = { ...input }");
879
- }
880
- lines.push(` return db.${model.camelName}.update({`);
881
- lines.push(` where: { ${idFieldName} },`);
882
- lines.push(" data,");
883
- lines.push(` select: { ${selectObj} },`);
884
- lines.push(" })");
885
- lines.push(" },");
886
- lines.push(
887
- ` delete${model.modelName}: async (_root: unknown, { ${idFieldName} }: { ${idFieldName}: ${idTsType} }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
888
- );
889
- lines.push(
890
- ` const existingRecord = await db.${model.camelName}.findUnique({`
891
- );
892
- lines.push(` where: { ${idFieldName} },`);
893
- lines.push(` select: { ${selectObj} },`);
894
- lines.push(" })");
895
- lines.push(" if (!existingRecord) {");
896
- lines.push(
897
- ` throw new ForbiddenError('Not authorized to access this resource')`
898
- );
899
- lines.push(" }");
900
- if (hasUserField || useOrgScoping) {
901
- lines.push(" if (!context.currentUser) {");
902
- lines.push(
903
- ` throw new AuthenticationError("You don't have permission to do that.")`
904
- );
905
- lines.push(" }");
906
- lines.push(" const currentUserId = context.currentUser['id']");
907
- lines.push(
908
- " if (currentUserId === undefined || currentUserId === null) {"
909
- );
910
- lines.push(
911
- ` throw new AuthenticationError("Could not determine the current user's ID.")`
912
- );
913
- lines.push(" }");
914
- if (hasUserField) {
915
- lines.push(
916
- ` if (existingRecord.${config.membershipUserField} !== currentUserId) {`
917
- );
918
- lines.push(
919
- ` throw new ForbiddenError('Not authorized to access this resource')`
920
- );
921
- lines.push(" }");
922
- }
923
- if (useOrgScoping) {
924
- lines.push(
925
- ` const membership = await db.${config.membershipModelCamel}.findFirst({`
926
- );
927
- lines.push(" where: {");
928
- lines.push(` ${config.membershipUserField}: currentUserId,`);
929
- lines.push(
930
- ` ${config.membershipOrganizationField}: existingRecord.${config.membershipOrganizationField},`
931
- );
932
- lines.push(" },");
933
- lines.push(" })");
934
- lines.push(" if (!membership) {");
935
- lines.push(
936
- ` throw new ForbiddenError('Not authorized to access this resource')`
937
- );
938
- lines.push(" }");
939
- }
940
- }
941
- lines.push(` return db.${model.camelName}.delete({`);
942
- lines.push(` where: { ${idFieldName} },`);
943
- lines.push(` select: { ${selectObj} },`);
944
- lines.push(" })");
945
- lines.push(" },");
946
- lines.push("");
947
- }
948
- while (lines[lines.length - 1] === "") {
949
- lines.pop();
950
- }
951
- lines.push(" },");
952
- lines.push(" }");
953
- lines.push("}");
954
- lines.push("");
955
- return lines.join("\n");
956
- }
957
- async function generateGqlormArtifacts() {
958
- if (!(0, import_project_config.getConfig)().experimental?.gqlorm?.enabled) {
959
- const generatedBase = (0, import_project_config.getPaths)().generated.base;
960
- const staleFiles = [
961
- import_node_path.default.join(generatedBase, "gqlorm", "backend.ts"),
962
- import_node_path.default.join(generatedBase, "gqlorm-schema.json"),
963
- import_node_path.default.join(generatedBase, "types", "includes", "web-gqlorm-models.d.ts")
964
- ];
965
- for (const staleFile of staleFiles) {
966
- if (import_node_fs.default.existsSync(staleFile)) {
967
- import_node_fs.default.unlinkSync(staleFile);
968
- }
969
- }
970
- return { files: [], errors: [] };
971
- }
972
- const files = [];
973
- const errors = [];
974
- try {
975
- const { schemas } = await (0, import_project_config.getPrismaSchemas)();
976
- const mod = await import("@prisma/internals");
977
- const { getDMMF } = mod.default || mod;
978
- const dmmf = await getDMMF({ datamodel: schemas });
979
- const paths = (0, import_project_config.getPaths)();
980
- const generatedBase = paths.generated.base;
981
- const modelSchema = buildModelSchema(dmmf);
982
- const frontendModels = buildFrontendModelInfo(dmmf);
983
- const schemaOutputPath = import_node_path.default.join(generatedBase, "gqlorm-schema.json");
984
- const webTypesOutputPath = import_node_path.default.join(
985
- generatedBase,
986
- "types",
987
- "includes",
988
- "web-gqlorm-models.d.ts"
989
- );
990
- import_node_fs.default.mkdirSync(import_node_path.default.dirname(schemaOutputPath), { recursive: true });
991
- import_node_fs.default.writeFileSync(schemaOutputPath, JSON.stringify(modelSchema, null, 2));
992
- files.push(schemaOutputPath);
993
- import_node_fs.default.mkdirSync(import_node_path.default.dirname(webTypesOutputPath), { recursive: true });
994
- import_node_fs.default.writeFileSync(
995
- webTypesOutputPath,
996
- generateWebGqlormModelsContent(frontendModels)
997
- );
998
- files.push(webTypesOutputPath);
999
- const backendOutputDir = import_node_path.default.join(generatedBase, "gqlorm");
1000
- const backendOutputPath = import_node_path.default.join(backendOutputDir, "backend.ts");
1001
- const graphqlDir = paths.api.graphql;
1002
- const existingTypes = getExistingSdlTypeNames(graphqlDir);
1003
- const allModels = buildBackendModelInfo(dmmf);
1004
- const gqlormConfig = (0, import_project_config.getConfig)().experimental.gqlorm;
1005
- const membershipModel = gqlormConfig.membershipModel ?? "Membership";
1006
- const membershipModelCamel = membershipModel.charAt(0).toLowerCase() + membershipModel.slice(1);
1007
- const membershipUserField = gqlormConfig.membershipUserField ?? "userId";
1008
- const membershipOrganizationField = gqlormConfig.membershipOrganizationField ?? "organizationId";
1009
- const membershipModelExists = dmmf.datamodel.models.some(
1010
- (m) => m.name === membershipModel
1011
- );
1012
- const backendConfig = {
1013
- membershipModel,
1014
- membershipModelCamel,
1015
- membershipUserField,
1016
- membershipOrganizationField,
1017
- membershipModelExists
1018
- };
1019
- const gqlormModels = allModels.filter(
1020
- (m) => !existingTypes.has(m.modelName)
1021
- );
1022
- const anyModelHasOrgField = gqlormModels.some(
1023
- (m) => m.fields.some((f) => f.name === membershipOrganizationField)
1024
- );
1025
- if (anyModelHasOrgField && !membershipModelExists) {
1026
- console.warn(
1027
- `[gqlorm] One or more models have a \`${membershipOrganizationField}\` field, but the membership model "${membershipModel}" was not found in the schema. Organization-based access scoping will not be applied for these models. Add a \`${membershipModel}\` model to your schema.prisma or configure \`experimental.gqlorm.membershipModel\` in cedar.toml.`
1028
- );
1029
- }
1030
- if (gqlormModels.length > 0) {
1031
- const backendContent = generateGqlormBackendContent(
1032
- gqlormModels,
1033
- backendConfig
1034
- );
1035
- import_node_fs.default.mkdirSync(backendOutputDir, { recursive: true });
1036
- import_node_fs.default.writeFileSync(backendOutputPath, backendContent);
1037
- files.push(backendOutputPath);
1038
- } else {
1039
- if (import_node_fs.default.existsSync(backendOutputPath)) {
1040
- import_node_fs.default.unlinkSync(backendOutputPath);
1041
- }
1042
- }
1043
- } catch (error) {
1044
- errors.push({
1045
- message: "Failed to generate gqlorm schema artifacts",
1046
- error
1047
- });
1048
- }
1049
- return { files, errors };
1050
- }
1051
- // Annotate the CommonJS export names for ESM import in node:
1052
- 0 && (module.exports = {
1053
- buildBackendModelInfo,
1054
- buildFrontendModelInfo,
1055
- buildModelSchema,
1056
- generateGqlormArtifacts,
1057
- generateGqlormBackendContent,
1058
- generateWebGqlormModelsContent,
1059
- getExistingSdlTypeNames,
1060
- mapDmmfTypeToGraphql
1061
- });