@zenstackhq/sdk 3.5.5 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,1764 +1,1189 @@
1
- "use strict";
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __getProtoOf = Object.getPrototypeOf;
7
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
9
+ var __exportAll = (all, no_symbols) => {
10
+ let target = {};
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ return target;
12
17
  };
13
18
  var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
19
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
20
+ key = keys[i];
21
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
22
+ get: ((k) => from[k]).bind(null, key),
23
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
24
+ });
25
+ }
26
+ return to;
20
27
  };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
-
31
- // src/index.ts
32
- var src_exports = {};
33
- __export(src_exports, {
34
- ModelUtils: () => model_utils_exports,
35
- PrismaSchemaGenerator: () => PrismaSchemaGenerator,
36
- TsSchemaGenerator: () => TsSchemaGenerator
37
- });
38
- module.exports = __toCommonJS(src_exports);
39
-
40
- // src/model-utils.ts
41
- var model_utils_exports = {};
42
- __export(model_utils_exports, {
43
- DELEGATE_AUX_RELATION_PREFIX: () => DELEGATE_AUX_RELATION_PREFIX,
44
- getAttribute: () => getAttribute,
45
- getAuthDecl: () => getAuthDecl,
46
- getContainingModel: () => getContainingModel,
47
- getDelegateOriginModel: () => getDelegateOriginModel,
48
- getIdFields: () => getIdFields,
49
- getOwnedFields: () => getOwnedFields,
50
- hasAttribute: () => hasAttribute,
51
- isDelegateModel: () => isDelegateModel,
52
- isFromStdlib: () => isFromStdlib,
53
- isIdField: () => isIdField,
54
- isUniqueField: () => isUniqueField,
55
- resolved: () => resolved
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
29
+ value: mod,
30
+ enumerable: true
31
+ }) : target, mod));
32
+ //#endregion
33
+ let _zenstackhq_language_ast = require("@zenstackhq/language/ast");
34
+ let _zenstackhq_language_utils = require("@zenstackhq/language/utils");
35
+ let _zenstackhq_common_helpers = require("@zenstackhq/common-helpers");
36
+ let _zenstackhq_language = require("@zenstackhq/language");
37
+ let langium = require("langium");
38
+ let ts_pattern = require("ts-pattern");
39
+ let node_fs = require("node:fs");
40
+ node_fs = __toESM(node_fs, 1);
41
+ let node_path = require("node:path");
42
+ node_path = __toESM(node_path, 1);
43
+ let typescript = require("typescript");
44
+ typescript = __toESM(typescript, 1);
45
+ //#region src/model-utils.ts
46
+ var model_utils_exports = /* @__PURE__ */ __exportAll({
47
+ DELEGATE_AUX_RELATION_PREFIX: () => DELEGATE_AUX_RELATION_PREFIX,
48
+ getAttribute: () => getAttribute,
49
+ getAuthDecl: () => getAuthDecl,
50
+ getContainingModel: () => getContainingModel,
51
+ getDelegateOriginModel: () => getDelegateOriginModel,
52
+ getIdFields: () => getIdFields,
53
+ getOwnedFields: () => getOwnedFields,
54
+ hasAttribute: () => hasAttribute,
55
+ isDelegateModel: () => isDelegateModel$1,
56
+ isFromStdlib: () => isFromStdlib,
57
+ isIdField: () => isIdField,
58
+ isUniqueField: () => isUniqueField,
59
+ resolved: () => resolved
56
60
  });
57
- var import_ast = require("@zenstackhq/language/ast");
58
- var import_utils = require("@zenstackhq/language/utils");
59
61
  function isIdField(field, contextModel) {
60
- if (hasAttribute(field, "@id")) {
61
- return true;
62
- }
63
- const modelLevelIds = (0, import_utils.getModelIdFields)(contextModel);
64
- if (modelLevelIds.map((f) => f.name).includes(field.name)) {
65
- return true;
66
- }
67
- const allFields = (0, import_utils.getAllFields)(contextModel);
68
- if (allFields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) {
69
- return false;
70
- }
71
- const firstUniqueField = allFields.find((f) => hasAttribute(f, "@unique"));
72
- if (firstUniqueField) {
73
- return firstUniqueField.name === field.name;
74
- }
75
- const modelLevelUnique = (0, import_utils.getModelUniqueFields)(contextModel);
76
- if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
77
- return true;
78
- }
79
- return false;
62
+ if (hasAttribute(field, "@id")) return true;
63
+ const modelLevelIds = (0, _zenstackhq_language_utils.getModelIdFields)(contextModel);
64
+ if (modelLevelIds.map((f) => f.name).includes(field.name)) return true;
65
+ const allFields = (0, _zenstackhq_language_utils.getAllFields)(contextModel);
66
+ if (allFields.some((f) => hasAttribute(f, "@id")) || modelLevelIds.length > 0) return false;
67
+ const firstUniqueField = allFields.find((f) => hasAttribute(f, "@unique"));
68
+ if (firstUniqueField) return firstUniqueField.name === field.name;
69
+ if ((0, _zenstackhq_language_utils.getModelUniqueFields)(contextModel).map((f) => f.name).includes(field.name)) return true;
70
+ return false;
80
71
  }
81
- __name(isIdField, "isIdField");
82
72
  function hasAttribute(decl, name) {
83
- return !!getAttribute(decl, name);
73
+ return !!getAttribute(decl, name);
84
74
  }
85
- __name(hasAttribute, "hasAttribute");
86
75
  function getAttribute(decl, name) {
87
- return decl.attributes.find((attr) => attr.decl.$refText === name);
76
+ return decl.attributes.find((attr) => attr.decl.$refText === name);
88
77
  }
89
- __name(getAttribute, "getAttribute");
90
- function isDelegateModel(node) {
91
- return (0, import_ast.isDataModel)(node) && hasAttribute(node, "@@delegate");
78
+ function isDelegateModel$1(node) {
79
+ return (0, _zenstackhq_language_ast.isDataModel)(node) && hasAttribute(node, "@@delegate");
92
80
  }
93
- __name(isDelegateModel, "isDelegateModel");
81
+ /**
82
+ * Returns all fields that physically belong to a model's table: its directly declared
83
+ * fields plus fields from its mixins (recursively).
84
+ */
94
85
  function getOwnedFields(model) {
95
- const fields = [
96
- ...model.fields
97
- ];
98
- for (const mixin of model.mixins) {
99
- if (mixin.ref) {
100
- fields.push(...getOwnedFields(mixin.ref));
101
- }
102
- }
103
- return fields;
86
+ const fields = [...model.fields];
87
+ for (const mixin of model.mixins) if (mixin.ref) fields.push(...getOwnedFields(mixin.ref));
88
+ return fields;
104
89
  }
105
- __name(getOwnedFields, "getOwnedFields");
90
+ /**
91
+ * Returns the name of the delegate base model that "owns" the given field in the context of
92
+ * `contextModel`. This handles both direct fields of delegate models and mixin fields that
93
+ * belong to a mixin used by a delegate base model.
94
+ */
106
95
  function getDelegateOriginModel(field, contextModel) {
107
- let base = contextModel.baseModel?.ref;
108
- while (base) {
109
- if (isDelegateModel(base) && getOwnedFields(base).some((f) => f.name === field.name)) {
110
- return base.name;
111
- }
112
- base = base.baseModel?.ref;
113
- }
114
- return void 0;
96
+ let base = contextModel.baseModel?.ref;
97
+ while (base) {
98
+ if (isDelegateModel$1(base) && getOwnedFields(base).some((f) => f.name === field.name)) return base.name;
99
+ base = base.baseModel?.ref;
100
+ }
115
101
  }
116
- __name(getDelegateOriginModel, "getDelegateOriginModel");
117
102
  function isUniqueField(field) {
118
- if (hasAttribute(field, "@unique")) {
119
- return true;
120
- }
121
- const modelIds = getAttribute(field.$container, "@@unique");
122
- if (modelIds && modelIds.args.some((arg) => (0, import_ast.isLiteralExpr)(arg.value) && arg.value.value === field.name)) {
123
- return true;
124
- }
125
- return false;
103
+ if (hasAttribute(field, "@unique")) return true;
104
+ const modelIds = getAttribute(field.$container, "@@unique");
105
+ if (modelIds && modelIds.args.some((arg) => (0, _zenstackhq_language_ast.isLiteralExpr)(arg.value) && arg.value.value === field.name)) return true;
106
+ return false;
126
107
  }
127
- __name(isUniqueField, "isUniqueField");
128
108
  function isFromStdlib(node) {
129
- const model = getContainingModel(node);
130
- return !!model && !!model.$document && model.$document.uri.path.endsWith("stdlib.zmodel");
109
+ const model = getContainingModel(node);
110
+ return !!model && !!model.$document && model.$document.uri.path.endsWith("stdlib.zmodel");
131
111
  }
132
- __name(isFromStdlib, "isFromStdlib");
133
112
  function getContainingModel(node) {
134
- if (!node) {
135
- return null;
136
- }
137
- return (0, import_ast.isModel)(node) ? node : getContainingModel(node.$container);
113
+ if (!node) return null;
114
+ return (0, _zenstackhq_language_ast.isModel)(node) ? node : getContainingModel(node.$container);
138
115
  }
139
- __name(getContainingModel, "getContainingModel");
140
116
  function resolved(ref) {
141
- if (!ref.ref) {
142
- throw new Error(`Reference not resolved: ${ref.$refText}`);
143
- }
144
- return ref.ref;
117
+ if (!ref.ref) throw new Error(`Reference not resolved: ${ref.$refText}`);
118
+ return ref.ref;
145
119
  }
146
- __name(resolved, "resolved");
147
120
  function getAuthDecl(model) {
148
- let found = model.declarations.find((d) => ((0, import_ast.isDataModel)(d) || (0, import_ast.isTypeDef)(d)) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
149
- if (!found) {
150
- found = model.declarations.find((d) => ((0, import_ast.isDataModel)(d) || (0, import_ast.isTypeDef)(d)) && d.name === "User");
151
- }
152
- return found;
121
+ let found = model.declarations.find((d) => ((0, _zenstackhq_language_ast.isDataModel)(d) || (0, _zenstackhq_language_ast.isTypeDef)(d)) && d.attributes.some((attr) => attr.decl.$refText === "@@auth"));
122
+ if (!found) found = model.declarations.find((d) => ((0, _zenstackhq_language_ast.isDataModel)(d) || (0, _zenstackhq_language_ast.isTypeDef)(d)) && d.name === "User");
123
+ return found;
153
124
  }
154
- __name(getAuthDecl, "getAuthDecl");
155
125
  function getIdFields(dm) {
156
- return (0, import_utils.getAllFields)(dm).filter((f) => isIdField(f, dm)).map((f) => f.name);
126
+ return (0, _zenstackhq_language_utils.getAllFields)(dm).filter((f) => isIdField(f, dm)).map((f) => f.name);
157
127
  }
158
- __name(getIdFields, "getIdFields");
159
- var DELEGATE_AUX_RELATION_PREFIX = "delegate_aux";
160
-
161
- // src/prisma/prisma-schema-generator.ts
162
- var import_common_helpers = require("@zenstackhq/common-helpers");
163
- var import_language = require("@zenstackhq/language");
164
- var import_ast2 = require("@zenstackhq/language/ast");
165
- var import_utils2 = require("@zenstackhq/language/utils");
166
- var import_langium = require("langium");
167
- var import_ts_pattern = require("ts-pattern");
168
-
169
- // src/prisma/indent-string.ts
128
+ /**
129
+ * Prefix for auxiliary relation fields generated for delegated models
130
+ */
131
+ const DELEGATE_AUX_RELATION_PREFIX = "delegate_aux";
132
+ //#endregion
133
+ //#region src/prisma/indent-string.ts
134
+ /**
135
+ * Utility for indenting strings
136
+ */
170
137
  function indentString(string, count = 4) {
171
- const indent = " ";
172
- return string.replace(/^(?!\s*$)/gm, indent.repeat(count));
138
+ return string.replace(/^(?!\s*$)/gm, " ".repeat(count));
173
139
  }
174
- __name(indentString, "indentString");
175
-
176
- // src/prisma/prisma-builder.ts
140
+ //#endregion
141
+ //#region src/prisma/prisma-builder.ts
142
+ /**
143
+ * Prisma schema builder
144
+ */
177
145
  var PrismaModel = class {
178
- static {
179
- __name(this, "PrismaModel");
180
- }
181
- datasources = [];
182
- generators = [];
183
- models = [];
184
- enums = [];
185
- addDataSource(name, fields = []) {
186
- const ds = new DataSource(name, fields);
187
- this.datasources.push(ds);
188
- return ds;
189
- }
190
- addGenerator(name, fields) {
191
- const generator = new Generator(name, fields);
192
- this.generators.push(generator);
193
- return generator;
194
- }
195
- addModel(name) {
196
- const model = new Model(name, false);
197
- this.models.push(model);
198
- return model;
199
- }
200
- addView(name) {
201
- const model = new Model(name, true);
202
- this.models.push(model);
203
- return model;
204
- }
205
- addEnum(name) {
206
- const e = new Enum(name);
207
- this.enums.push(e);
208
- return e;
209
- }
210
- toString() {
211
- return [
212
- ...this.datasources,
213
- ...this.generators,
214
- ...this.enums,
215
- ...this.models
216
- ].map((d) => d.toString()).join("\n\n");
217
- }
146
+ datasources = [];
147
+ generators = [];
148
+ models = [];
149
+ enums = [];
150
+ addDataSource(name, fields = []) {
151
+ const ds = new DataSource$1(name, fields);
152
+ this.datasources.push(ds);
153
+ return ds;
154
+ }
155
+ addGenerator(name, fields) {
156
+ const generator = new Generator(name, fields);
157
+ this.generators.push(generator);
158
+ return generator;
159
+ }
160
+ addModel(name) {
161
+ const model = new Model$1(name, false);
162
+ this.models.push(model);
163
+ return model;
164
+ }
165
+ addView(name) {
166
+ const model = new Model$1(name, true);
167
+ this.models.push(model);
168
+ return model;
169
+ }
170
+ addEnum(name) {
171
+ const e = new Enum$2(name);
172
+ this.enums.push(e);
173
+ return e;
174
+ }
175
+ toString() {
176
+ return [
177
+ ...this.datasources,
178
+ ...this.generators,
179
+ ...this.enums,
180
+ ...this.models
181
+ ].map((d) => d.toString()).join("\n\n");
182
+ }
218
183
  };
219
- var DataSource = class {
220
- static {
221
- __name(this, "DataSource");
222
- }
223
- name;
224
- fields;
225
- constructor(name, fields = []) {
226
- this.name = name;
227
- this.fields = fields;
228
- }
229
- toString() {
230
- return `datasource ${this.name} {
231
- ` + this.fields.map((f) => indentString(`${f.name} = ${f.text}`)).join("\n") + `
232
- }`;
233
- }
184
+ var DataSource$1 = class {
185
+ constructor(name, fields = []) {
186
+ this.name = name;
187
+ this.fields = fields;
188
+ }
189
+ toString() {
190
+ return `datasource ${this.name} {\n` + this.fields.map((f) => indentString(`${f.name} = ${f.text}`)).join("\n") + `\n}`;
191
+ }
234
192
  };
235
193
  var Generator = class {
236
- static {
237
- __name(this, "Generator");
238
- }
239
- name;
240
- fields;
241
- constructor(name, fields) {
242
- this.name = name;
243
- this.fields = fields;
244
- }
245
- toString() {
246
- return `generator ${this.name} {
247
- ` + this.fields.map((f) => indentString(`${f.name} = ${f.text}`)).join("\n") + `
248
- }`;
249
- }
194
+ constructor(name, fields) {
195
+ this.name = name;
196
+ this.fields = fields;
197
+ }
198
+ toString() {
199
+ return `generator ${this.name} {\n` + this.fields.map((f) => indentString(`${f.name} = ${f.text}`)).join("\n") + `\n}`;
200
+ }
250
201
  };
251
202
  var DeclarationBase = class {
252
- static {
253
- __name(this, "DeclarationBase");
254
- }
255
- documentations;
256
- constructor(documentations = []) {
257
- this.documentations = documentations;
258
- }
259
- addComment(name) {
260
- this.documentations.push(name);
261
- return name;
262
- }
263
- toString() {
264
- return this.documentations.map((x) => `${x}
265
- `).join("");
266
- }
203
+ constructor(documentations = []) {
204
+ this.documentations = documentations;
205
+ }
206
+ addComment(name) {
207
+ this.documentations.push(name);
208
+ return name;
209
+ }
210
+ toString() {
211
+ return this.documentations.map((x) => `${x}\n`).join("");
212
+ }
267
213
  };
268
214
  var ContainerDeclaration = class extends DeclarationBase {
269
- static {
270
- __name(this, "ContainerDeclaration");
271
- }
272
- attributes;
273
- constructor(documentations = [], attributes = []) {
274
- super(documentations), this.attributes = attributes;
275
- }
215
+ constructor(documentations = [], attributes = []) {
216
+ super(documentations);
217
+ this.attributes = attributes;
218
+ }
276
219
  };
277
220
  var FieldDeclaration = class extends DeclarationBase {
278
- static {
279
- __name(this, "FieldDeclaration");
280
- }
281
- attributes;
282
- constructor(documentations = [], attributes = []) {
283
- super(documentations), this.attributes = attributes;
284
- }
221
+ constructor(documentations = [], attributes = []) {
222
+ super(documentations);
223
+ this.attributes = attributes;
224
+ }
285
225
  };
286
- var Model = class extends ContainerDeclaration {
287
- static {
288
- __name(this, "Model");
289
- }
290
- name;
291
- isView;
292
- fields = [];
293
- constructor(name, isView, documentations = []) {
294
- super(documentations), this.name = name, this.isView = isView;
295
- }
296
- addField(name, type, attributes = [], documentations = [], addToFront = false) {
297
- const field = new ModelField(name, type, attributes, documentations);
298
- if (addToFront) {
299
- this.fields.unshift(field);
300
- } else {
301
- this.fields.push(field);
302
- }
303
- return field;
304
- }
305
- addAttribute(name, args = []) {
306
- const attr = new ContainerAttribute(name, args);
307
- this.attributes.push(attr);
308
- return attr;
309
- }
310
- toString() {
311
- const result = [
312
- ...this.fields
313
- ];
314
- if (this.attributes.length > 0) {
315
- result.push("");
316
- }
317
- result.push(...this.attributes);
318
- return super.toString() + `${this.isView ? "view" : "model"} ${this.name} {
319
- ` + indentString(result.map((d) => d.toString()).join("\n")) + `
320
- }`;
321
- }
226
+ var Model$1 = class extends ContainerDeclaration {
227
+ fields = [];
228
+ constructor(name, isView, documentations = []) {
229
+ super(documentations);
230
+ this.name = name;
231
+ this.isView = isView;
232
+ }
233
+ addField(name, type, attributes = [], documentations = [], addToFront = false) {
234
+ const field = new ModelField(name, type, attributes, documentations);
235
+ if (addToFront) this.fields.unshift(field);
236
+ else this.fields.push(field);
237
+ return field;
238
+ }
239
+ addAttribute(name, args = []) {
240
+ const attr = new ContainerAttribute(name, args);
241
+ this.attributes.push(attr);
242
+ return attr;
243
+ }
244
+ toString() {
245
+ const result = [...this.fields];
246
+ if (this.attributes.length > 0) result.push("");
247
+ result.push(...this.attributes);
248
+ return super.toString() + `${this.isView ? "view" : "model"} ${this.name} {\n` + indentString(result.map((d) => d.toString()).join("\n")) + `\n}`;
249
+ }
322
250
  };
323
251
  var ModelFieldType = class {
324
- static {
325
- __name(this, "ModelFieldType");
326
- }
327
- type;
328
- array;
329
- optional;
330
- constructor(type, array, optional) {
331
- this.type = type;
332
- this.array = array;
333
- this.optional = optional;
334
- }
335
- toString() {
336
- return `${this.type}${this.array ? "[]" : ""}${this.optional ? "?" : ""}`;
337
- }
252
+ constructor(type, array, optional) {
253
+ this.type = type;
254
+ this.array = array;
255
+ this.optional = optional;
256
+ }
257
+ toString() {
258
+ return `${this.type}${this.array ? "[]" : ""}${this.optional ? "?" : ""}`;
259
+ }
338
260
  };
339
261
  var ModelField = class extends FieldDeclaration {
340
- static {
341
- __name(this, "ModelField");
342
- }
343
- name;
344
- type;
345
- constructor(name, type, attributes = [], documentations = []) {
346
- super(documentations, attributes), this.name = name, this.type = type;
347
- }
348
- addAttribute(name, args = []) {
349
- const attr = new FieldAttribute(name, args);
350
- this.attributes.push(attr);
351
- return attr;
352
- }
353
- toString() {
354
- return super.toString() + `${this.name} ${this.type}` + (this.attributes.length > 0 ? " " + this.attributes.map((a) => a.toString()).join(" ") : "");
355
- }
262
+ constructor(name, type, attributes = [], documentations = []) {
263
+ super(documentations, attributes);
264
+ this.name = name;
265
+ this.type = type;
266
+ }
267
+ addAttribute(name, args = []) {
268
+ const attr = new FieldAttribute(name, args);
269
+ this.attributes.push(attr);
270
+ return attr;
271
+ }
272
+ toString() {
273
+ return super.toString() + `${this.name} ${this.type}` + (this.attributes.length > 0 ? " " + this.attributes.map((a) => a.toString()).join(" ") : "");
274
+ }
356
275
  };
357
276
  var FieldAttribute = class {
358
- static {
359
- __name(this, "FieldAttribute");
360
- }
361
- name;
362
- args;
363
- constructor(name, args = []) {
364
- this.name = name;
365
- this.args = args;
366
- }
367
- toString() {
368
- return `${this.name}(` + this.args.map((a) => a.toString()).join(", ") + `)`;
369
- }
277
+ constructor(name, args = []) {
278
+ this.name = name;
279
+ this.args = args;
280
+ }
281
+ toString() {
282
+ return `${this.name}(` + this.args.map((a) => a.toString()).join(", ") + `)`;
283
+ }
370
284
  };
371
285
  var ContainerAttribute = class {
372
- static {
373
- __name(this, "ContainerAttribute");
374
- }
375
- name;
376
- args;
377
- constructor(name, args = []) {
378
- this.name = name;
379
- this.args = args;
380
- }
381
- toString() {
382
- return `${this.name}(` + this.args.map((a) => a.toString()).join(", ") + `)`;
383
- }
286
+ constructor(name, args = []) {
287
+ this.name = name;
288
+ this.args = args;
289
+ }
290
+ toString() {
291
+ return `${this.name}(` + this.args.map((a) => a.toString()).join(", ") + `)`;
292
+ }
384
293
  };
385
- var AttributeArg = class {
386
- static {
387
- __name(this, "AttributeArg");
388
- }
389
- name;
390
- value;
391
- constructor(name, value) {
392
- this.name = name;
393
- this.value = value;
394
- }
395
- toString() {
396
- return this.name ? `${this.name}: ${this.value}` : this.value.toString();
397
- }
294
+ var AttributeArg$2 = class {
295
+ constructor(name, value) {
296
+ this.name = name;
297
+ this.value = value;
298
+ }
299
+ toString() {
300
+ return this.name ? `${this.name}: ${this.value}` : this.value.toString();
301
+ }
398
302
  };
399
303
  var AttributeArgValue = class {
400
- static {
401
- __name(this, "AttributeArgValue");
402
- }
403
- type;
404
- value;
405
- constructor(type, value) {
406
- this.type = type;
407
- this.value = value;
408
- switch (type) {
409
- case "String":
410
- if (typeof value !== "string") throw new Error("Value must be string");
411
- break;
412
- case "Number":
413
- if (typeof value !== "number" && typeof value !== "string") throw new Error("Value must be number or string");
414
- break;
415
- case "Boolean":
416
- if (typeof value !== "boolean") throw new Error("Value must be boolean");
417
- break;
418
- case "Array":
419
- if (!Array.isArray(value)) throw new Error("Value must be array");
420
- break;
421
- case "FieldReference":
422
- if (typeof value !== "string" && !(value instanceof FieldReference)) throw new Error("Value must be string or FieldReference");
423
- break;
424
- case "FunctionCall":
425
- if (!(value instanceof FunctionCall)) throw new Error("Value must be FunctionCall");
426
- break;
427
- }
428
- }
429
- toString() {
430
- switch (this.type) {
431
- case "String":
432
- return JSON.stringify(this.value);
433
- case "Number":
434
- return this.value.toString();
435
- case "FieldReference": {
436
- if (typeof this.value === "string") {
437
- return this.value;
438
- } else {
439
- const fr = this.value;
440
- let r = fr.field;
441
- if (fr.args.length > 0) {
442
- r += "(" + fr.args.map((a) => a.toString()).join(",") + ")";
443
- }
444
- return r;
445
- }
446
- }
447
- case "FunctionCall":
448
- return this.value.toString();
449
- case "Boolean":
450
- return this.value ? "true" : "false";
451
- case "Array":
452
- return "[" + this.value.map((v) => v.toString()).join(", ") + "]";
453
- default:
454
- throw new Error(`Unknown attribute value type ${this.type}`);
455
- }
456
- }
304
+ constructor(type, value) {
305
+ this.type = type;
306
+ this.value = value;
307
+ switch (type) {
308
+ case "String":
309
+ if (typeof value !== "string") throw new Error("Value must be string");
310
+ break;
311
+ case "Number":
312
+ if (typeof value !== "number" && typeof value !== "string") throw new Error("Value must be number or string");
313
+ break;
314
+ case "Boolean":
315
+ if (typeof value !== "boolean") throw new Error("Value must be boolean");
316
+ break;
317
+ case "Array":
318
+ if (!Array.isArray(value)) throw new Error("Value must be array");
319
+ break;
320
+ case "FieldReference":
321
+ if (typeof value !== "string" && !(value instanceof FieldReference)) throw new Error("Value must be string or FieldReference");
322
+ break;
323
+ case "FunctionCall":
324
+ if (!(value instanceof FunctionCall)) throw new Error("Value must be FunctionCall");
325
+ break;
326
+ }
327
+ }
328
+ toString() {
329
+ switch (this.type) {
330
+ case "String": return JSON.stringify(this.value);
331
+ case "Number": return this.value.toString();
332
+ case "FieldReference": if (typeof this.value === "string") return this.value;
333
+ else {
334
+ const fr = this.value;
335
+ let r = fr.field;
336
+ if (fr.args.length > 0) r += "(" + fr.args.map((a) => a.toString()).join(",") + ")";
337
+ return r;
338
+ }
339
+ case "FunctionCall": return this.value.toString();
340
+ case "Boolean": return this.value ? "true" : "false";
341
+ case "Array": return "[" + this.value.map((v) => v.toString()).join(", ") + "]";
342
+ default: throw new Error(`Unknown attribute value type ${this.type}`);
343
+ }
344
+ }
457
345
  };
458
346
  var FieldReference = class {
459
- static {
460
- __name(this, "FieldReference");
461
- }
462
- field;
463
- args;
464
- constructor(field, args = []) {
465
- this.field = field;
466
- this.args = args;
467
- }
347
+ constructor(field, args = []) {
348
+ this.field = field;
349
+ this.args = args;
350
+ }
468
351
  };
469
352
  var FieldReferenceArg = class {
470
- static {
471
- __name(this, "FieldReferenceArg");
472
- }
473
- name;
474
- value;
475
- constructor(name, value) {
476
- this.name = name;
477
- this.value = value;
478
- }
479
- toString() {
480
- return `${this.name}: ${this.value}`;
481
- }
353
+ constructor(name, value) {
354
+ this.name = name;
355
+ this.value = value;
356
+ }
357
+ toString() {
358
+ return `${this.name}: ${this.value}`;
359
+ }
482
360
  };
483
361
  var FunctionCall = class {
484
- static {
485
- __name(this, "FunctionCall");
486
- }
487
- func;
488
- args;
489
- constructor(func, args = []) {
490
- this.func = func;
491
- this.args = args;
492
- }
493
- toString() {
494
- return `${this.func}(` + this.args.map((a) => a.toString()).join(", ") + ")";
495
- }
362
+ constructor(func, args = []) {
363
+ this.func = func;
364
+ this.args = args;
365
+ }
366
+ toString() {
367
+ return `${this.func}(` + this.args.map((a) => a.toString()).join(", ") + ")";
368
+ }
496
369
  };
497
370
  var FunctionCallArg = class {
498
- static {
499
- __name(this, "FunctionCallArg");
500
- }
501
- value;
502
- constructor(value) {
503
- this.value = value;
504
- }
505
- toString() {
506
- return this.value;
507
- }
371
+ constructor(value) {
372
+ this.value = value;
373
+ }
374
+ toString() {
375
+ return this.value;
376
+ }
508
377
  };
509
- var Enum = class extends ContainerDeclaration {
510
- static {
511
- __name(this, "Enum");
512
- }
513
- name;
514
- fields = [];
515
- constructor(name, documentations = []) {
516
- super(documentations), this.name = name;
517
- }
518
- addField(name, attributes = [], documentations = []) {
519
- const field = new EnumField(name, attributes, documentations);
520
- this.fields.push(field);
521
- return field;
522
- }
523
- addAttribute(name, args = []) {
524
- const attr = new ContainerAttribute(name, args);
525
- this.attributes.push(attr);
526
- return attr;
527
- }
528
- addComment(name) {
529
- this.documentations.push(name);
530
- return name;
531
- }
532
- toString() {
533
- return super.toString() + `enum ${this.name} {
534
- ` + indentString([
535
- ...this.fields,
536
- ...this.attributes
537
- ].map((d) => d.toString()).join("\n")) + "\n}";
538
- }
378
+ var Enum$2 = class extends ContainerDeclaration {
379
+ fields = [];
380
+ constructor(name, documentations = []) {
381
+ super(documentations);
382
+ this.name = name;
383
+ }
384
+ addField(name, attributes = [], documentations = []) {
385
+ const field = new EnumField$1(name, attributes, documentations);
386
+ this.fields.push(field);
387
+ return field;
388
+ }
389
+ addAttribute(name, args = []) {
390
+ const attr = new ContainerAttribute(name, args);
391
+ this.attributes.push(attr);
392
+ return attr;
393
+ }
394
+ addComment(name) {
395
+ this.documentations.push(name);
396
+ return name;
397
+ }
398
+ toString() {
399
+ return super.toString() + `enum ${this.name} {\n` + indentString([...this.fields, ...this.attributes].map((d) => d.toString()).join("\n")) + "\n}";
400
+ }
539
401
  };
540
- var EnumField = class extends DeclarationBase {
541
- static {
542
- __name(this, "EnumField");
543
- }
544
- name;
545
- attributes;
546
- constructor(name, attributes = [], documentations = []) {
547
- super(documentations), this.name = name, this.attributes = attributes;
548
- }
549
- addAttribute(name, args = []) {
550
- const attr = new FieldAttribute(name, args);
551
- this.attributes.push(attr);
552
- return attr;
553
- }
554
- toString() {
555
- return super.toString() + this.name + (this.attributes.length > 0 ? " " + this.attributes.map((a) => a.toString()).join(" ") : "");
556
- }
402
+ var EnumField$1 = class extends DeclarationBase {
403
+ constructor(name, attributes = [], documentations = []) {
404
+ super(documentations);
405
+ this.name = name;
406
+ this.attributes = attributes;
407
+ }
408
+ addAttribute(name, args = []) {
409
+ const attr = new FieldAttribute(name, args);
410
+ this.attributes.push(attr);
411
+ return attr;
412
+ }
413
+ toString() {
414
+ return super.toString() + this.name + (this.attributes.length > 0 ? " " + this.attributes.map((a) => a.toString()).join(" ") : "");
415
+ }
557
416
  };
558
-
559
- // src/prisma/prisma-schema-generator.ts
560
- var IDENTIFIER_NAME_MAX_LENGTH = 50 - DELEGATE_AUX_RELATION_PREFIX.length;
561
- var NON_PRISMA_DATASOURCE_FIELDS = [
562
- "defaultSchema"
563
- ];
417
+ //#endregion
418
+ //#region src/prisma/prisma-schema-generator.ts
419
+ const IDENTIFIER_NAME_MAX_LENGTH = 38;
420
+ const NON_PRISMA_DATASOURCE_FIELDS = ["defaultSchema"];
421
+ /**
422
+ * Generates Prisma schema file
423
+ */
564
424
  var PrismaSchemaGenerator = class {
565
- static {
566
- __name(this, "PrismaSchemaGenerator");
567
- }
568
- zmodel;
569
- PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
425
+ PRELUDE = `//////////////////////////////////////////////////////////////////////////////////////////////
570
426
  // DO NOT MODIFY THIS FILE //
571
427
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
572
428
  //////////////////////////////////////////////////////////////////////////////////////////////
573
429
 
574
430
  `;
575
- // a mapping from full names to shortened names
576
- shortNameMap = /* @__PURE__ */ new Map();
577
- constructor(zmodel) {
578
- this.zmodel = zmodel;
579
- }
580
- async generate() {
581
- const prisma = new PrismaModel();
582
- for (const decl of this.zmodel.declarations) {
583
- switch (decl.$type) {
584
- case import_ast2.DataSource:
585
- this.generateDataSource(prisma, decl);
586
- break;
587
- case import_ast2.Enum:
588
- this.generateEnum(prisma, decl);
589
- break;
590
- case import_ast2.DataModel:
591
- this.generateModel(prisma, decl);
592
- break;
593
- case import_ast2.GeneratorDecl:
594
- this.generateGenerator(prisma, decl);
595
- break;
596
- }
597
- }
598
- if (!this.zmodel.declarations.some(import_ast2.isGeneratorDecl)) {
599
- this.generateDefaultGenerator(prisma);
600
- }
601
- return this.PRELUDE + prisma.toString();
602
- }
603
- generateDataSource(prisma, dataSource) {
604
- const fields = dataSource.fields.filter((f) => !NON_PRISMA_DATASOURCE_FIELDS.includes(f.name)).map((f) => ({
605
- name: f.name,
606
- text: this.configExprToText(f.value)
607
- }));
608
- prisma.addDataSource(dataSource.name, fields);
609
- }
610
- configExprToText(expr) {
611
- if ((0, import_ast2.isLiteralExpr)(expr)) {
612
- return this.literalToText(expr);
613
- } else if ((0, import_ast2.isInvocationExpr)(expr)) {
614
- const fc = this.makeFunctionCall(expr);
615
- return fc.toString();
616
- } else {
617
- return this.configArrayToText(expr);
618
- }
619
- }
620
- configArrayToText(expr) {
621
- return "[" + expr.items.map((item) => {
622
- if ((0, import_ast2.isLiteralExpr)(item)) {
623
- return this.literalToText(item);
624
- } else {
625
- return item.name + (item.args.length > 0 ? "(" + item.args.map((arg) => this.configInvocationArgToText(arg)).join(", ") + ")" : "");
626
- }
627
- }).join(", ") + "]";
628
- }
629
- configInvocationArgToText(arg) {
630
- return `${arg.name}: ${this.literalToText(arg.value)}`;
631
- }
632
- literalToText(expr) {
633
- return JSON.stringify(expr.value);
634
- }
635
- generateGenerator(prisma, decl) {
636
- prisma.addGenerator(decl.name, decl.fields.map((f) => ({
637
- name: f.name,
638
- text: this.configExprToText(f.value)
639
- })));
640
- }
641
- generateDefaultGenerator(prisma) {
642
- const gen = prisma.addGenerator("client", [
643
- {
644
- name: "provider",
645
- text: '"prisma-client-js"'
646
- }
647
- ]);
648
- const previewFeatures = [];
649
- const dataSource = this.zmodel.declarations.find(import_ast2.isDataSource);
650
- if (dataSource?.fields.some((f) => f.name === "extensions")) {
651
- previewFeatures.push("postgresqlExtensions");
652
- }
653
- if (this.zmodel.declarations.some((d) => (0, import_ast2.isDataModel)(d) && d.isView)) {
654
- previewFeatures.push("views");
655
- }
656
- if (previewFeatures.length > 0) {
657
- gen.fields.push({
658
- name: "previewFeatures",
659
- text: JSON.stringify(previewFeatures)
660
- });
661
- }
662
- }
663
- generateModel(prisma, decl) {
664
- const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
665
- const allFields = (0, import_utils2.getAllFields)(decl, true);
666
- for (const field of allFields) {
667
- if (model_utils_exports.hasAttribute(field, "@computed")) {
668
- continue;
669
- }
670
- if (model_utils_exports.isIdField(field, decl) || !getDelegateOriginModel(field, decl)) {
671
- this.generateModelField(model, field, decl);
672
- }
673
- }
674
- const allAttributes = (0, import_utils2.getAllAttributes)(decl).filter((attr) => this.isPrismaAttribute(attr));
675
- for (const attr of allAttributes) {
676
- this.generateContainerAttribute(model, attr);
677
- }
678
- if (this.datasourceHasSchemasSetting(decl.$container) && !allAttributes.some((attr) => attr.decl.ref?.name === "@@schema")) {
679
- model.addAttribute("@@schema", [
680
- new AttributeArg(void 0, new AttributeArgValue("String", this.getDefaultPostgresSchemaName(decl.$container)))
681
- ]);
682
- }
683
- decl.comments.forEach((c) => model.addComment(c));
684
- this.generateDelegateRelationForBase(model, decl);
685
- this.generateDelegateRelationForConcrete(model, decl);
686
- }
687
- getDatasourceField(zmodel, fieldName) {
688
- const dataSource = zmodel.declarations.find(import_ast2.isDataSource);
689
- return dataSource?.fields.find((f) => f.name === fieldName);
690
- }
691
- datasourceHasSchemasSetting(zmodel) {
692
- return !!this.getDatasourceField(zmodel, "schemas");
693
- }
694
- getDefaultPostgresSchemaName(zmodel) {
695
- const defaultSchemaField = this.getDatasourceField(zmodel, "defaultSchema");
696
- return (0, import_utils2.getStringLiteral)(defaultSchemaField?.value) ?? "public";
697
- }
698
- isPrismaAttribute(attr) {
699
- if (!attr.decl.ref) {
700
- return false;
701
- }
702
- return attr.decl.ref.attributes.some((a) => a.decl.ref?.name === "@@@prisma");
703
- }
704
- getUnsupportedFieldType(fieldType) {
705
- if (fieldType.unsupported) {
706
- const value = (0, import_utils2.getStringLiteral)(fieldType.unsupported.value);
707
- if (value) {
708
- return `Unsupported("${value}")`;
709
- } else {
710
- return void 0;
711
- }
712
- } else {
713
- return void 0;
714
- }
715
- }
716
- generateModelField(model, field, contextModel, addToFront = false) {
717
- let fieldType;
718
- if (field.type.type) {
719
- fieldType = field.type.type;
720
- } else if (field.type.reference?.ref) {
721
- if ((0, import_ast2.isTypeDef)(field.type.reference.ref)) {
722
- fieldType = "Json";
723
- } else {
724
- fieldType = field.type.reference.ref.name;
725
- }
726
- } else {
727
- const unsupported = this.getUnsupportedFieldType(field.type);
728
- if (unsupported) {
729
- fieldType = unsupported;
730
- }
731
- }
732
- if (!fieldType) {
733
- throw new Error(`Field type is not resolved: ${field.$container.name}.${field.name}`);
734
- }
735
- const isArray = (
736
- // typed-JSON fields should be translated to scalar Json type
737
- (0, import_ast2.isTypeDef)(field.type.reference?.ref) ? false : field.type.array
738
- );
739
- const type = new ModelFieldType(fieldType, isArray, field.type.optional);
740
- const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithAuthInvocation(attr)).filter((attr) => (
741
- // when building physical schema, exclude `@default` for id fields inherited from delegate base
742
- !(model_utils_exports.isIdField(field, contextModel) && getDelegateOriginModel(field, contextModel) && attr.decl.$refText === "@default")
743
- )).map((attr) => this.makeFieldAttribute(attr));
744
- const docs = [
745
- ...field.comments
746
- ];
747
- const result = model.addField(field.name, type, attributes, docs, addToFront);
748
- return result;
749
- }
750
- isDefaultWithAuthInvocation(attr) {
751
- if (attr.decl.ref?.name !== "@default") {
752
- return false;
753
- }
754
- const expr = attr.args[0]?.value;
755
- if (!expr) {
756
- return false;
757
- }
758
- return import_langium.AstUtils.streamAst(expr).some(import_utils2.isAuthInvocation);
759
- }
760
- makeFieldAttribute(attr) {
761
- const attrName = attr.decl.ref.name;
762
- return new FieldAttribute(attrName, attr.args.map((arg) => this.makeAttributeArg(arg)));
763
- }
764
- makeAttributeArg(arg) {
765
- return new AttributeArg(arg.name, this.makeAttributeArgValue(arg.value));
766
- }
767
- makeAttributeArgValue(node) {
768
- if ((0, import_ast2.isLiteralExpr)(node)) {
769
- const argType = (0, import_ts_pattern.match)(node.$type).with(import_ast2.StringLiteral, () => "String").with(import_ast2.NumberLiteral, () => "Number").with(import_ast2.BooleanLiteral, () => "Boolean").exhaustive();
770
- return new AttributeArgValue(argType, node.value);
771
- } else if ((0, import_ast2.isArrayExpr)(node)) {
772
- return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
773
- } else if ((0, import_ast2.isReferenceExpr)(node)) {
774
- return new AttributeArgValue("FieldReference", new FieldReference(node.target.ref.name, node.args.map((arg) => new FieldReferenceArg(arg.name, this.exprToText(arg.value)))));
775
- } else if ((0, import_ast2.isInvocationExpr)(node)) {
776
- return new AttributeArgValue("FunctionCall", this.makeFunctionCall(node));
777
- } else {
778
- throw Error(`Unsupported attribute argument expression type: ${node.$type}`);
779
- }
780
- }
781
- exprToText(expr) {
782
- return new import_language.ZModelCodeGenerator({
783
- quote: "double"
784
- }).generate(expr);
785
- }
786
- makeFunctionCall(node) {
787
- return new FunctionCall(node.function.ref.name, node.args.map((arg) => {
788
- const val = (0, import_ts_pattern.match)(arg.value).when(import_ast2.isStringLiteral, (v) => `"${v.value}"`).when(import_ast2.isLiteralExpr, (v) => v.value.toString()).when(import_ast2.isNullExpr, () => "null").otherwise(() => {
789
- throw new Error("Function call argument must be literal or null");
790
- });
791
- return new FunctionCallArg(val);
792
- }));
793
- }
794
- generateContainerAttribute(container, attr) {
795
- const attrName = attr.decl.ref.name;
796
- container.attributes.push(new ContainerAttribute(attrName, attr.args.map((arg) => this.makeAttributeArg(arg))));
797
- }
798
- generateEnum(prisma, decl) {
799
- const _enum = prisma.addEnum(decl.name);
800
- for (const field of decl.fields) {
801
- this.generateEnumField(_enum, field);
802
- }
803
- const allAttributes = decl.attributes.filter((attr) => this.isPrismaAttribute(attr));
804
- for (const attr of allAttributes) {
805
- this.generateContainerAttribute(_enum, attr);
806
- }
807
- if (this.datasourceHasSchemasSetting(decl.$container) && !allAttributes.some((attr) => attr.decl.ref?.name === "@@schema")) {
808
- _enum.addAttribute("@@schema", [
809
- new AttributeArg(void 0, new AttributeArgValue("String", this.getDefaultPostgresSchemaName(decl.$container)))
810
- ]);
811
- }
812
- decl.comments.forEach((c) => _enum.addComment(c));
813
- }
814
- generateEnumField(_enum, field) {
815
- const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).map((attr) => this.makeFieldAttribute(attr));
816
- const docs = [
817
- ...field.comments
818
- ];
819
- _enum.addField(field.name, attributes, docs);
820
- }
821
- generateDelegateRelationForBase(model, decl) {
822
- if (!(0, import_utils2.isDelegateModel)(decl)) {
823
- return;
824
- }
825
- const concreteModels = this.getConcreteModels(decl);
826
- concreteModels.forEach((concrete) => {
827
- const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, import_common_helpers.lowerCaseFirst)(concrete.name)}`);
828
- model.addField(auxName, new ModelFieldType(concrete.name, false, true));
829
- });
830
- }
831
- generateDelegateRelationForConcrete(model, concreteDecl) {
832
- const base = concreteDecl.baseModel?.ref;
833
- if (!base) {
834
- return;
835
- }
836
- const idFields = getIdFields(base);
837
- const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, import_common_helpers.lowerCaseFirst)(base.name)}`);
838
- model.addField(relationField, base.name, [
839
- new FieldAttribute("@relation", [
840
- new AttributeArg("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
841
- new AttributeArg("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
842
- new AttributeArg("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
843
- new AttributeArg("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
844
- ])
845
- ]);
846
- }
847
- getConcreteModels(dataModel) {
848
- if (!(0, import_utils2.isDelegateModel)(dataModel)) {
849
- return [];
850
- }
851
- return dataModel.$container.declarations.filter((d) => (0, import_ast2.isDataModel)(d) && d !== dataModel && d.baseModel?.ref === dataModel);
852
- }
853
- truncate(name) {
854
- if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) {
855
- return name;
856
- }
857
- const existing = this.shortNameMap.get(name);
858
- if (existing) {
859
- return existing;
860
- }
861
- const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
862
- let index = 0;
863
- let shortName = `${baseName}_${index}`;
864
- while (true) {
865
- const conflict = Array.from(this.shortNameMap.values()).find((v) => v === shortName);
866
- if (!conflict) {
867
- this.shortNameMap.set(name, shortName);
868
- break;
869
- }
870
- index++;
871
- shortName = `${baseName}_${index}`;
872
- }
873
- return shortName;
874
- }
431
+ shortNameMap = /* @__PURE__ */ new Map();
432
+ constructor(zmodel) {
433
+ this.zmodel = zmodel;
434
+ }
435
+ async generate() {
436
+ const prisma = new PrismaModel();
437
+ for (const decl of this.zmodel.declarations) switch (decl.$type) {
438
+ case _zenstackhq_language_ast.DataSource:
439
+ this.generateDataSource(prisma, decl);
440
+ break;
441
+ case _zenstackhq_language_ast.Enum:
442
+ this.generateEnum(prisma, decl);
443
+ break;
444
+ case _zenstackhq_language_ast.DataModel:
445
+ this.generateModel(prisma, decl);
446
+ break;
447
+ case _zenstackhq_language_ast.GeneratorDecl:
448
+ this.generateGenerator(prisma, decl);
449
+ break;
450
+ }
451
+ if (!this.zmodel.declarations.some(_zenstackhq_language_ast.isGeneratorDecl)) this.generateDefaultGenerator(prisma);
452
+ return this.PRELUDE + prisma.toString();
453
+ }
454
+ generateDataSource(prisma, dataSource) {
455
+ const fields = dataSource.fields.filter((f) => !NON_PRISMA_DATASOURCE_FIELDS.includes(f.name)).map((f) => ({
456
+ name: f.name,
457
+ text: this.configExprToText(f.value)
458
+ }));
459
+ prisma.addDataSource(dataSource.name, fields);
460
+ }
461
+ configExprToText(expr) {
462
+ if ((0, _zenstackhq_language_ast.isLiteralExpr)(expr)) return this.literalToText(expr);
463
+ else if ((0, _zenstackhq_language_ast.isInvocationExpr)(expr)) return this.makeFunctionCall(expr).toString();
464
+ else return this.configArrayToText(expr);
465
+ }
466
+ configArrayToText(expr) {
467
+ return "[" + expr.items.map((item) => {
468
+ if ((0, _zenstackhq_language_ast.isLiteralExpr)(item)) return this.literalToText(item);
469
+ else return item.name + (item.args.length > 0 ? "(" + item.args.map((arg) => this.configInvocationArgToText(arg)).join(", ") + ")" : "");
470
+ }).join(", ") + "]";
471
+ }
472
+ configInvocationArgToText(arg) {
473
+ return `${arg.name}: ${this.literalToText(arg.value)}`;
474
+ }
475
+ literalToText(expr) {
476
+ return JSON.stringify(expr.value);
477
+ }
478
+ generateGenerator(prisma, decl) {
479
+ prisma.addGenerator(decl.name, decl.fields.map((f) => ({
480
+ name: f.name,
481
+ text: this.configExprToText(f.value)
482
+ })));
483
+ }
484
+ generateDefaultGenerator(prisma) {
485
+ const gen = prisma.addGenerator("client", [{
486
+ name: "provider",
487
+ text: "\"prisma-client-js\""
488
+ }]);
489
+ const previewFeatures = [];
490
+ if (this.zmodel.declarations.find(_zenstackhq_language_ast.isDataSource)?.fields.some((f) => f.name === "extensions")) previewFeatures.push("postgresqlExtensions");
491
+ if (this.zmodel.declarations.some((d) => (0, _zenstackhq_language_ast.isDataModel)(d) && d.isView)) previewFeatures.push("views");
492
+ if (previewFeatures.length > 0) gen.fields.push({
493
+ name: "previewFeatures",
494
+ text: JSON.stringify(previewFeatures)
495
+ });
496
+ }
497
+ generateModel(prisma, decl) {
498
+ const model = decl.isView ? prisma.addView(decl.name) : prisma.addModel(decl.name);
499
+ const allFields = (0, _zenstackhq_language_utils.getAllFields)(decl, true);
500
+ for (const field of allFields) {
501
+ if (hasAttribute(field, "@computed")) continue;
502
+ if (isIdField(field, decl) || !getDelegateOriginModel(field, decl)) this.generateModelField(model, field, decl);
503
+ }
504
+ const allAttributes = (0, _zenstackhq_language_utils.getAllAttributes)(decl).filter((attr) => this.isPrismaAttribute(attr));
505
+ for (const attr of allAttributes) this.generateContainerAttribute(model, attr);
506
+ if (this.datasourceHasSchemasSetting(decl.$container) && !allAttributes.some((attr) => attr.decl.ref?.name === "@@schema")) model.addAttribute("@@schema", [new AttributeArg$2(void 0, new AttributeArgValue("String", this.getDefaultPostgresSchemaName(decl.$container)))]);
507
+ decl.comments.forEach((c) => model.addComment(c));
508
+ this.generateDelegateRelationForBase(model, decl);
509
+ this.generateDelegateRelationForConcrete(model, decl);
510
+ }
511
+ getDatasourceField(zmodel, fieldName) {
512
+ return zmodel.declarations.find(_zenstackhq_language_ast.isDataSource)?.fields.find((f) => f.name === fieldName);
513
+ }
514
+ datasourceHasSchemasSetting(zmodel) {
515
+ return !!this.getDatasourceField(zmodel, "schemas");
516
+ }
517
+ getDefaultPostgresSchemaName(zmodel) {
518
+ return (0, _zenstackhq_language_utils.getStringLiteral)(this.getDatasourceField(zmodel, "defaultSchema")?.value) ?? "public";
519
+ }
520
+ isPrismaAttribute(attr) {
521
+ if (!attr.decl.ref) return false;
522
+ return attr.decl.ref.attributes.some((a) => a.decl.ref?.name === "@@@prisma");
523
+ }
524
+ getUnsupportedFieldType(fieldType) {
525
+ if (fieldType.unsupported) {
526
+ const value = (0, _zenstackhq_language_utils.getStringLiteral)(fieldType.unsupported.value);
527
+ if (value) return `Unsupported("${value}")`;
528
+ else return;
529
+ } else return;
530
+ }
531
+ generateModelField(model, field, contextModel, addToFront = false) {
532
+ let fieldType;
533
+ if (field.type.type) fieldType = field.type.type;
534
+ else if (field.type.reference?.ref) if ((0, _zenstackhq_language_ast.isTypeDef)(field.type.reference.ref)) fieldType = "Json";
535
+ else fieldType = field.type.reference.ref.name;
536
+ else {
537
+ const unsupported = this.getUnsupportedFieldType(field.type);
538
+ if (unsupported) fieldType = unsupported;
539
+ }
540
+ if (!fieldType) throw new Error(`Field type is not resolved: ${field.$container.name}.${field.name}`);
541
+ const isArray = (0, _zenstackhq_language_ast.isTypeDef)(field.type.reference?.ref) ? false : field.type.array;
542
+ const type = new ModelFieldType(fieldType, isArray, field.type.optional);
543
+ const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).filter((attr) => !this.isDefaultWithAuthInvocation(attr)).filter((attr) => !(isIdField(field, contextModel) && getDelegateOriginModel(field, contextModel) && attr.decl.$refText === "@default")).map((attr) => this.makeFieldAttribute(attr));
544
+ const docs = [...field.comments];
545
+ return model.addField(field.name, type, attributes, docs, addToFront);
546
+ }
547
+ isDefaultWithAuthInvocation(attr) {
548
+ if (attr.decl.ref?.name !== "@default") return false;
549
+ const expr = attr.args[0]?.value;
550
+ if (!expr) return false;
551
+ return langium.AstUtils.streamAst(expr).some(_zenstackhq_language_utils.isAuthInvocation);
552
+ }
553
+ makeFieldAttribute(attr) {
554
+ const attrName = attr.decl.ref.name;
555
+ return new FieldAttribute(attrName, attr.args.map((arg) => this.makeAttributeArg(arg)));
556
+ }
557
+ makeAttributeArg(arg) {
558
+ return new AttributeArg$2(arg.name, this.makeAttributeArgValue(arg.value));
559
+ }
560
+ makeAttributeArgValue(node) {
561
+ if ((0, _zenstackhq_language_ast.isLiteralExpr)(node)) return new AttributeArgValue((0, ts_pattern.match)(node.$type).with(_zenstackhq_language_ast.StringLiteral, () => "String").with(_zenstackhq_language_ast.NumberLiteral, () => "Number").with(_zenstackhq_language_ast.BooleanLiteral, () => "Boolean").exhaustive(), node.value);
562
+ else if ((0, _zenstackhq_language_ast.isArrayExpr)(node)) return new AttributeArgValue("Array", new Array(...node.items.map((item) => this.makeAttributeArgValue(item))));
563
+ else if ((0, _zenstackhq_language_ast.isReferenceExpr)(node)) return new AttributeArgValue("FieldReference", new FieldReference(node.target.ref.name, node.args.map((arg) => new FieldReferenceArg(arg.name, this.exprToText(arg.value)))));
564
+ else if ((0, _zenstackhq_language_ast.isInvocationExpr)(node)) return new AttributeArgValue("FunctionCall", this.makeFunctionCall(node));
565
+ else throw Error(`Unsupported attribute argument expression type: ${node.$type}`);
566
+ }
567
+ exprToText(expr) {
568
+ return new _zenstackhq_language.ZModelCodeGenerator({ quote: "double" }).generate(expr);
569
+ }
570
+ makeFunctionCall(node) {
571
+ return new FunctionCall(node.function.ref.name, node.args.map((arg) => {
572
+ return new FunctionCallArg((0, ts_pattern.match)(arg.value).when(_zenstackhq_language_ast.isStringLiteral, (v) => `"${v.value}"`).when(_zenstackhq_language_ast.isLiteralExpr, (v) => v.value.toString()).when(_zenstackhq_language_ast.isNullExpr, () => "null").otherwise(() => {
573
+ throw new Error("Function call argument must be literal or null");
574
+ }));
575
+ }));
576
+ }
577
+ generateContainerAttribute(container, attr) {
578
+ const attrName = attr.decl.ref.name;
579
+ container.attributes.push(new ContainerAttribute(attrName, attr.args.map((arg) => this.makeAttributeArg(arg))));
580
+ }
581
+ generateEnum(prisma, decl) {
582
+ const _enum = prisma.addEnum(decl.name);
583
+ for (const field of decl.fields) this.generateEnumField(_enum, field);
584
+ const allAttributes = decl.attributes.filter((attr) => this.isPrismaAttribute(attr));
585
+ for (const attr of allAttributes) this.generateContainerAttribute(_enum, attr);
586
+ if (this.datasourceHasSchemasSetting(decl.$container) && !allAttributes.some((attr) => attr.decl.ref?.name === "@@schema")) _enum.addAttribute("@@schema", [new AttributeArg$2(void 0, new AttributeArgValue("String", this.getDefaultPostgresSchemaName(decl.$container)))]);
587
+ decl.comments.forEach((c) => _enum.addComment(c));
588
+ }
589
+ generateEnumField(_enum, field) {
590
+ const attributes = field.attributes.filter((attr) => this.isPrismaAttribute(attr)).map((attr) => this.makeFieldAttribute(attr));
591
+ const docs = [...field.comments];
592
+ _enum.addField(field.name, attributes, docs);
593
+ }
594
+ generateDelegateRelationForBase(model, decl) {
595
+ if (!(0, _zenstackhq_language_utils.isDelegateModel)(decl)) return;
596
+ this.getConcreteModels(decl).forEach((concrete) => {
597
+ const auxName = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, _zenstackhq_common_helpers.lowerCaseFirst)(concrete.name)}`);
598
+ model.addField(auxName, new ModelFieldType(concrete.name, false, true));
599
+ });
600
+ }
601
+ generateDelegateRelationForConcrete(model, concreteDecl) {
602
+ const base = concreteDecl.baseModel?.ref;
603
+ if (!base) return;
604
+ const idFields = getIdFields(base);
605
+ const relationField = this.truncate(`${DELEGATE_AUX_RELATION_PREFIX}_${(0, _zenstackhq_common_helpers.lowerCaseFirst)(base.name)}`);
606
+ model.addField(relationField, base.name, [new FieldAttribute("@relation", [
607
+ new AttributeArg$2("fields", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
608
+ new AttributeArg$2("references", new AttributeArgValue("Array", idFields.map((idField) => new AttributeArgValue("FieldReference", new FieldReference(idField))))),
609
+ new AttributeArg$2("onDelete", new AttributeArgValue("FieldReference", new FieldReference("Cascade"))),
610
+ new AttributeArg$2("onUpdate", new AttributeArgValue("FieldReference", new FieldReference("Cascade")))
611
+ ])]);
612
+ }
613
+ getConcreteModels(dataModel) {
614
+ if (!(0, _zenstackhq_language_utils.isDelegateModel)(dataModel)) return [];
615
+ return dataModel.$container.declarations.filter((d) => (0, _zenstackhq_language_ast.isDataModel)(d) && d !== dataModel && d.baseModel?.ref === dataModel);
616
+ }
617
+ truncate(name) {
618
+ if (name.length <= IDENTIFIER_NAME_MAX_LENGTH) return name;
619
+ const existing = this.shortNameMap.get(name);
620
+ if (existing) return existing;
621
+ const baseName = name.slice(0, IDENTIFIER_NAME_MAX_LENGTH);
622
+ let index = 0;
623
+ let shortName = `${baseName}_${index}`;
624
+ while (true) {
625
+ if (!Array.from(this.shortNameMap.values()).find((v) => v === shortName)) {
626
+ this.shortNameMap.set(name, shortName);
627
+ break;
628
+ }
629
+ index++;
630
+ shortName = `${baseName}_${index}`;
631
+ }
632
+ return shortName;
633
+ }
875
634
  };
876
-
877
- // src/ts-schema-generator.ts
878
- var import_common_helpers2 = require("@zenstackhq/common-helpers");
879
- var import_ast3 = require("@zenstackhq/language/ast");
880
- var import_utils3 = require("@zenstackhq/language/utils");
881
- var import_node_fs = __toESM(require("fs"), 1);
882
- var import_node_path = __toESM(require("path"), 1);
883
- var import_ts_pattern2 = require("ts-pattern");
884
- var ts = __toESM(require("typescript"), 1);
635
+ //#endregion
636
+ //#region src/ts-schema-generator.ts
885
637
  var TsSchemaGenerator = class {
886
- static {
887
- __name(this, "TsSchemaGenerator");
888
- }
889
- usedExpressionUtils = false;
890
- usedAttributeApplication = false;
891
- usedFieldDefault = false;
892
- async generate(model, options) {
893
- import_node_fs.default.mkdirSync(options.outDir, {
894
- recursive: true
895
- });
896
- this.generateSchema(model, options);
897
- if (options.generateModelTypes !== false) {
898
- this.generateModelsAndTypeDefs(model, options);
899
- }
900
- if (options.generateInputTypes !== false) {
901
- this.generateInputTypes(model, options);
902
- }
903
- }
904
- generateSchema(model, options) {
905
- const targets = [];
906
- if (!options.liteOnly) {
907
- targets.push({
908
- lite: false,
909
- file: "schema.ts"
910
- });
911
- }
912
- if (options.lite || options.liteOnly) {
913
- targets.push({
914
- lite: true,
915
- file: "schema-lite.ts"
916
- });
917
- }
918
- for (const { lite, file } of targets) {
919
- this.usedExpressionUtils = false;
920
- this.usedAttributeApplication = false;
921
- this.usedFieldDefault = false;
922
- const statements = [];
923
- this.generateSchemaStatements(model, statements, lite);
924
- this.generateBannerComments(statements);
925
- const schemaOutputFile = import_node_path.default.join(options.outDir, file);
926
- const sourceFile = ts.createSourceFile(schemaOutputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
927
- const printer = ts.createPrinter();
928
- const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
929
- import_node_fs.default.writeFileSync(schemaOutputFile, result);
930
- }
931
- }
932
- generateSchemaStatements(model, statements, lite) {
933
- const schemaClass = this.createSchemaClass(model, lite);
934
- const schemaImportDecl = ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(void 0, void 0, ts.factory.createNamedImports([
935
- ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("SchemaDef")),
936
- ...this.usedAttributeApplication ? [
937
- ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("AttributeApplication"))
938
- ] : [],
939
- ...this.usedFieldDefault ? [
940
- ts.factory.createImportSpecifier(true, void 0, ts.factory.createIdentifier("FieldDefault"))
941
- ] : [],
942
- ...this.usedExpressionUtils ? [
943
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("ExpressionUtils"))
944
- ] : []
945
- ])), ts.factory.createStringLiteral("@zenstackhq/schema"));
946
- statements.push(schemaImportDecl);
947
- statements.push(schemaClass);
948
- const schemaDecl = ts.factory.createVariableStatement([
949
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
950
- ], ts.factory.createVariableDeclarationList([
951
- ts.factory.createVariableDeclaration("schema", void 0, void 0, ts.factory.createNewExpression(ts.factory.createIdentifier("SchemaType"), void 0, []))
952
- ], ts.NodeFlags.Const));
953
- statements.push(schemaDecl);
954
- }
955
- createExpressionUtilsCall(method, args) {
956
- this.usedExpressionUtils = true;
957
- return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("ExpressionUtils"), method), void 0, args || []);
958
- }
959
- createSchemaClass(model, lite) {
960
- const members = [
961
- // provider
962
- ts.factory.createPropertyDeclaration(void 0, "provider", void 0, void 0, this.createAsConst(this.createProviderObject(model))),
963
- // models
964
- ts.factory.createPropertyDeclaration(void 0, "models", void 0, void 0, this.createAsConst(this.createModelsObject(model, lite))),
965
- // typeDefs
966
- ...model.declarations.some(import_ast3.isTypeDef) ? [
967
- ts.factory.createPropertyDeclaration(void 0, "typeDefs", void 0, void 0, this.createAsConst(this.createTypeDefsObject(model, lite)))
968
- ] : []
969
- ];
970
- const enums = model.declarations.filter(import_ast3.isEnum);
971
- if (enums.length > 0) {
972
- members.push(ts.factory.createPropertyDeclaration(void 0, "enums", void 0, void 0, this.createAsConst(ts.factory.createObjectLiteralExpression(enums.map((e) => ts.factory.createPropertyAssignment(e.name, this.createEnumObject(e))), true))));
973
- }
974
- const authType = getAuthDecl(model);
975
- if (authType) {
976
- members.push(ts.factory.createPropertyDeclaration(void 0, "authType", void 0, void 0, this.createAsConst(this.createLiteralNode(authType.name))));
977
- }
978
- const procedures = model.declarations.filter(import_ast3.isProcedure);
979
- if (procedures.length > 0) {
980
- members.push(ts.factory.createPropertyDeclaration(void 0, "procedures", void 0, void 0, this.createAsConst(this.createProceduresObject(procedures))));
981
- }
982
- members.push(ts.factory.createPropertyDeclaration(void 0, "plugins", void 0, void 0, ts.factory.createObjectLiteralExpression([], true)));
983
- const schemaClass = ts.factory.createClassDeclaration([
984
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
985
- ], "SchemaType", void 0, [
986
- ts.factory.createHeritageClause(ts.SyntaxKind.ImplementsKeyword, [
987
- ts.factory.createExpressionWithTypeArguments(ts.factory.createIdentifier("SchemaDef"), void 0)
988
- ])
989
- ], members);
990
- return schemaClass;
991
- }
992
- createAsConst(expr) {
993
- return ts.factory.createAsExpression(expr, ts.factory.createTypeReferenceNode("const"));
994
- }
995
- createAttributesTypeAssertion(expr) {
996
- this.usedAttributeApplication = true;
997
- return ts.factory.createAsExpression(expr, ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, ts.factory.createArrayTypeNode(ts.factory.createTypeReferenceNode("AttributeApplication"))));
998
- }
999
- createDefaultTypeAssertion(expr) {
1000
- this.usedFieldDefault = true;
1001
- return ts.factory.createAsExpression(expr, ts.factory.createTypeReferenceNode("FieldDefault"));
1002
- }
1003
- createProviderObject(model) {
1004
- const dsProvider = this.getDataSourceProvider(model);
1005
- const defaultSchema = this.getDataSourceDefaultSchema(model);
1006
- return ts.factory.createObjectLiteralExpression([
1007
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(dsProvider)),
1008
- ...defaultSchema ? [
1009
- ts.factory.createPropertyAssignment("defaultSchema", ts.factory.createStringLiteral(defaultSchema))
1010
- ] : []
1011
- ], true);
1012
- }
1013
- createModelsObject(model, lite) {
1014
- return ts.factory.createObjectLiteralExpression(this.getAllDataModels(model).map((dm) => ts.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm, lite))), true);
1015
- }
1016
- getAllDataModels(model) {
1017
- return model.declarations.filter((d) => (0, import_ast3.isDataModel)(d) && !hasAttribute(d, "@@ignore"));
1018
- }
1019
- getAllTypeDefs(model) {
1020
- return model.declarations.filter((d) => (0, import_ast3.isTypeDef)(d) && !hasAttribute(d, "@@ignore"));
1021
- }
1022
- createTypeDefsObject(model, lite) {
1023
- return ts.factory.createObjectLiteralExpression(this.getAllTypeDefs(model).map((td) => ts.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td, lite))), true);
1024
- }
1025
- createDataModelObject(dm, lite) {
1026
- const allFields = (0, import_utils3.getAllFields)(dm);
1027
- const allAttributes = lite ? [] : (0, import_utils3.getAllAttributes)(dm).filter((attr) => {
1028
- if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) {
1029
- return false;
1030
- }
1031
- return true;
1032
- });
1033
- const subModels = this.getSubModels(dm);
1034
- const fields = [
1035
- // name
1036
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(dm.name)),
1037
- // baseModel
1038
- ...dm.baseModel ? [
1039
- ts.factory.createPropertyAssignment("baseModel", ts.factory.createStringLiteral(dm.baseModel.$refText))
1040
- ] : [],
1041
- // fields
1042
- ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm, lite))), true)),
1043
- // attributes
1044
- ...allAttributes.length > 0 ? [
1045
- ts.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true)))
1046
- ] : [],
1047
- // idFields
1048
- ts.factory.createPropertyAssignment("idFields", ts.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => ts.factory.createStringLiteral(idField)))),
1049
- // uniqueFields
1050
- ts.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
1051
- // isDelegate
1052
- ...isDelegateModel(dm) ? [
1053
- ts.factory.createPropertyAssignment("isDelegate", ts.factory.createTrue())
1054
- ] : [],
1055
- // subModels
1056
- ...subModels.length > 0 ? [
1057
- ts.factory.createPropertyAssignment("subModels", ts.factory.createArrayLiteralExpression(subModels.map((subModel) => ts.factory.createStringLiteral(subModel))))
1058
- ] : [],
1059
- ...dm.isView ? [
1060
- ts.factory.createPropertyAssignment("isView", ts.factory.createTrue())
1061
- ] : []
1062
- ];
1063
- const computedFields = dm.fields.filter((f) => hasAttribute(f, "@computed"));
1064
- if (computedFields.length > 0) {
1065
- fields.push(ts.factory.createPropertyAssignment("computedFields", this.createComputedFieldsObject(computedFields)));
1066
- }
1067
- return ts.factory.createObjectLiteralExpression(fields, true);
1068
- }
1069
- getSubModels(dm) {
1070
- return dm.$container.declarations.filter(import_ast3.isDataModel).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
1071
- }
1072
- createTypeDefObject(td, lite) {
1073
- const allFields = (0, import_utils3.getAllFields)(td);
1074
- const allAttributes = (0, import_utils3.getAllAttributes)(td);
1075
- const fields = [
1076
- // name
1077
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(td.name)),
1078
- // fields
1079
- ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(allFields.map((field) => ts.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0, lite))), true)),
1080
- // attributes
1081
- ...allAttributes.length > 0 ? [
1082
- ts.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(ts.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true)))
1083
- ] : []
1084
- ];
1085
- return ts.factory.createObjectLiteralExpression(fields, true);
1086
- }
1087
- createComputedFieldsObject(fields) {
1088
- return ts.factory.createObjectLiteralExpression(fields.map((field) => ts.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [
1089
- // parameter: `context: { modelAlias: string }`
1090
- ts.factory.createParameterDeclaration(void 0, void 0, "_context", void 0, ts.factory.createTypeLiteralNode([
1091
- ts.factory.createPropertySignature(void 0, "modelAlias", void 0, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
1092
- ]), void 0)
1093
- ], ts.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type)), ts.factory.createBlock([
1094
- ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), void 0, [
1095
- ts.factory.createStringLiteral("This is a stub for computed field")
1096
- ]))
1097
- ], true))), true);
1098
- }
1099
- createUpdatedAtObject(ignoreArg) {
1100
- return ts.factory.createObjectLiteralExpression([
1101
- ts.factory.createPropertyAssignment("ignore", ts.factory.createArrayLiteralExpression(ignoreArg.value.items.map((item) => ts.factory.createStringLiteral(item.target.$refText))))
1102
- ]);
1103
- }
1104
- mapFieldTypeToTSType(type) {
1105
- let result = (0, import_ts_pattern2.match)(type.type).with("String", () => "string").with("Boolean", () => "boolean").with("Int", () => "number").with("Float", () => "number").with("BigInt", () => "bigint").with("Decimal", () => "number").otherwise(() => "unknown");
1106
- if (type.array) {
1107
- result = `${result}[]`;
1108
- }
1109
- if (type.optional) {
1110
- result = `${result} | null`;
1111
- }
1112
- return result;
1113
- }
1114
- createDataFieldObject(field, contextModel, lite) {
1115
- const objectFields = [
1116
- // name
1117
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
1118
- // type
1119
- ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1120
- ];
1121
- if (contextModel && model_utils_exports.isIdField(field, contextModel)) {
1122
- objectFields.push(ts.factory.createPropertyAssignment("id", ts.factory.createTrue()));
1123
- }
1124
- if (isUniqueField(field)) {
1125
- objectFields.push(ts.factory.createPropertyAssignment("unique", ts.factory.createTrue()));
1126
- }
1127
- if (field.type.optional) {
1128
- objectFields.push(ts.factory.createPropertyAssignment("optional", ts.factory.createTrue()));
1129
- }
1130
- if (field.type.array) {
1131
- objectFields.push(ts.factory.createPropertyAssignment("array", ts.factory.createTrue()));
1132
- }
1133
- const updatedAtAttrib = getAttribute(field, "@updatedAt");
1134
- if (updatedAtAttrib) {
1135
- const ignoreArg = updatedAtAttrib.args.find((arg) => arg.$resolvedParam?.name === "ignore");
1136
- objectFields.push(ts.factory.createPropertyAssignment("updatedAt", ignoreArg ? this.createUpdatedAtObject(ignoreArg) : ts.factory.createTrue()));
1137
- }
1138
- if (hasAttribute(field, "@omit")) {
1139
- objectFields.push(ts.factory.createPropertyAssignment("omit", ts.factory.createTrue()));
1140
- }
1141
- if (contextModel && // id fields are duplicated in inherited models
1142
- !isIdField(field, contextModel)) {
1143
- const delegateOrigin = getDelegateOriginModel(field, contextModel);
1144
- if (delegateOrigin) {
1145
- objectFields.push(ts.factory.createPropertyAssignment("originModel", ts.factory.createStringLiteral(delegateOrigin)));
1146
- }
1147
- }
1148
- if (this.isDiscriminatorField(field)) {
1149
- objectFields.push(ts.factory.createPropertyAssignment("isDiscriminator", ts.factory.createTrue()));
1150
- }
1151
- if (!lite && field.attributes.length > 0) {
1152
- objectFields.push(ts.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(ts.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr))))));
1153
- }
1154
- const defaultValue = this.getFieldMappedDefault(field);
1155
- if (defaultValue !== void 0) {
1156
- let defaultExpr;
1157
- if (defaultValue === null) {
1158
- defaultExpr = this.createExpressionUtilsCall("_null");
1159
- } else if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
1160
- if ("call" in defaultValue) {
1161
- defaultExpr = this.createExpressionUtilsCall("call", [
1162
- ts.factory.createStringLiteral(defaultValue.call),
1163
- ...defaultValue.args.length > 0 ? [
1164
- ts.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.createExpressionUtilsCall("literal", [
1165
- this.createLiteralNode(arg)
1166
- ])))
1167
- ] : []
1168
- ]);
1169
- } else if ("authMember" in defaultValue) {
1170
- defaultExpr = this.createExpressionUtilsCall("member", [
1171
- this.createExpressionUtilsCall("call", [
1172
- ts.factory.createStringLiteral("auth")
1173
- ]),
1174
- ts.factory.createArrayLiteralExpression(defaultValue.authMember.map((m) => ts.factory.createStringLiteral(m)))
1175
- ]);
1176
- } else {
1177
- throw new Error(`Unsupported default value type for field ${field.name}`);
1178
- }
1179
- } else if (Array.isArray(defaultValue)) {
1180
- defaultExpr = ts.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)));
1181
- } else {
1182
- defaultExpr = this.createLiteralNode(defaultValue);
1183
- }
1184
- objectFields.push(ts.factory.createPropertyAssignment("default", this.createDefaultTypeAssertion(defaultExpr)));
1185
- }
1186
- if (hasAttribute(field, "@computed")) {
1187
- objectFields.push(ts.factory.createPropertyAssignment("computed", ts.factory.createTrue()));
1188
- }
1189
- if ((0, import_ast3.isDataModel)(field.type.reference?.ref)) {
1190
- objectFields.push(ts.factory.createPropertyAssignment("relation", this.createRelationObject(field)));
1191
- }
1192
- const fkFor = this.getForeignKeyFor(field);
1193
- if (fkFor && fkFor.length > 0) {
1194
- objectFields.push(ts.factory.createPropertyAssignment("foreignKeyFor", ts.factory.createAsExpression(ts.factory.createArrayLiteralExpression(fkFor.map((fk) => ts.factory.createStringLiteral(fk)), true), ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, ts.factory.createArrayTypeNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))))));
1195
- }
1196
- return ts.factory.createObjectLiteralExpression(objectFields, true);
1197
- }
1198
- isDiscriminatorField(field) {
1199
- const origin = field.$container;
1200
- return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam.name === "discriminator" && (0, import_utils3.isDataFieldReference)(arg.value) && arg.value.target.ref === field);
1201
- }
1202
- getDataSourceProvider(model) {
1203
- const dataSource = model.declarations.find(import_ast3.isDataSource);
1204
- (0, import_common_helpers2.invariant)(dataSource, "No data source found in the model");
1205
- const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
1206
- (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(providerExpr) && typeof providerExpr.value === "string", "Provider must be a string literal");
1207
- return providerExpr.value;
1208
- }
1209
- getDataSourceDefaultSchema(model) {
1210
- const dataSource = model.declarations.find(import_ast3.isDataSource);
1211
- (0, import_common_helpers2.invariant)(dataSource, "No data source found in the model");
1212
- const defaultSchemaExpr = dataSource.fields.find((f) => f.name === "defaultSchema")?.value;
1213
- if (!defaultSchemaExpr) {
1214
- return void 0;
1215
- }
1216
- (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(defaultSchemaExpr) && typeof defaultSchemaExpr.value === "string", "Default schema must be a string literal");
1217
- return defaultSchemaExpr.value;
1218
- }
1219
- getFieldMappedDefault(field) {
1220
- const defaultAttr = getAttribute(field, "@default");
1221
- if (!defaultAttr) {
1222
- return void 0;
1223
- }
1224
- const defaultValue = defaultAttr.args[0]?.value;
1225
- (0, import_common_helpers2.invariant)(defaultValue, "Expected a default value");
1226
- return this.getMappedValue(defaultValue, field.type);
1227
- }
1228
- getMappedValue(expr, fieldType) {
1229
- if ((0, import_ast3.isLiteralExpr)(expr)) {
1230
- const lit = expr.value;
1231
- return fieldType.type === "Boolean" ? lit : [
1232
- "Int",
1233
- "Float",
1234
- "Decimal",
1235
- "BigInt"
1236
- ].includes(fieldType.type) ? Number(lit) : lit;
1237
- } else if ((0, import_ast3.isArrayExpr)(expr)) {
1238
- return expr.items.map((item) => this.getMappedValue(item, fieldType));
1239
- } else if ((0, import_ast3.isReferenceExpr)(expr) && (0, import_ast3.isEnumField)(expr.target.ref)) {
1240
- return expr.target.ref.name;
1241
- } else if ((0, import_ast3.isInvocationExpr)(expr)) {
1242
- return {
1243
- call: expr.function.$refText,
1244
- args: expr.args.map((arg) => this.getLiteral(arg.value))
1245
- };
1246
- } else if (this.isAuthMemberAccess(expr)) {
1247
- return {
1248
- authMember: this.getMemberAccessChain(expr)
1249
- };
1250
- } else if ((0, import_ast3.isNullExpr)(expr)) {
1251
- return null;
1252
- } else {
1253
- throw new Error(`Unsupported expression type: ${expr.$type}`);
1254
- }
1255
- }
1256
- getMemberAccessChain(expr) {
1257
- if (!(0, import_ast3.isMemberAccessExpr)(expr.operand)) {
1258
- return [
1259
- expr.member.$refText
1260
- ];
1261
- } else {
1262
- return [
1263
- ...this.getMemberAccessChain(expr.operand),
1264
- expr.member.$refText
1265
- ];
1266
- }
1267
- }
1268
- isAuthMemberAccess(expr) {
1269
- if ((0, import_ast3.isMemberAccessExpr)(expr)) {
1270
- return this.isAuthInvocation(expr.operand) || this.isAuthMemberAccess(expr.operand);
1271
- } else {
1272
- return false;
1273
- }
1274
- }
1275
- isAuthInvocation(expr) {
1276
- return (0, import_ast3.isInvocationExpr)(expr) && expr.function.$refText === "auth" && model_utils_exports.isFromStdlib(expr.function.ref);
1277
- }
1278
- createRelationObject(field) {
1279
- const relationFields = [];
1280
- const oppositeRelation = this.getOppositeRelationField(field);
1281
- if (oppositeRelation) {
1282
- relationFields.push(ts.factory.createPropertyAssignment("opposite", ts.factory.createStringLiteral(oppositeRelation.name)));
1283
- }
1284
- const relationName = this.getRelationName(field);
1285
- if (relationName) {
1286
- relationFields.push(ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(relationName)));
1287
- }
1288
- const relation = getAttribute(field, "@relation");
1289
- const fkFields = [];
1290
- if (relation) {
1291
- for (const arg of relation.args) {
1292
- const param = arg.$resolvedParam.name;
1293
- if (param === "fields" || param === "references") {
1294
- const fieldNames = this.getReferenceNames(arg.value);
1295
- if (fieldNames) {
1296
- if (param === "fields") {
1297
- fkFields.push(...fieldNames);
1298
- }
1299
- relationFields.push(ts.factory.createPropertyAssignment(param, ts.factory.createArrayLiteralExpression(fieldNames.map((el) => ts.factory.createStringLiteral(el)))));
1300
- }
1301
- }
1302
- if (param === "onDelete" || param === "onUpdate") {
1303
- const action = arg.value.target.$refText;
1304
- relationFields.push(ts.factory.createPropertyAssignment(param, ts.factory.createStringLiteral(action)));
1305
- }
1306
- }
1307
- }
1308
- if (fkFields.length > 0) {
1309
- const allHaveDefault = fkFields.every((fieldName) => {
1310
- const fieldDef = field.$container.fields.find((f) => f.name === fieldName);
1311
- return fieldDef && hasAttribute(fieldDef, "@default");
1312
- });
1313
- if (allHaveDefault) {
1314
- relationFields.push(ts.factory.createPropertyAssignment("hasDefault", ts.factory.createTrue()));
1315
- }
1316
- }
1317
- return ts.factory.createObjectLiteralExpression(relationFields);
1318
- }
1319
- getReferenceNames(expr) {
1320
- return (0, import_ast3.isArrayExpr)(expr) && expr.items.map((item) => item.target.$refText);
1321
- }
1322
- getForeignKeyFor(field) {
1323
- const result = [];
1324
- for (const f of field.$container.fields) {
1325
- const relation = getAttribute(f, "@relation");
1326
- if (relation) {
1327
- for (const arg of relation.args) {
1328
- if (arg.name === "fields" && (0, import_ast3.isArrayExpr)(arg.value) && arg.value.items.some((el) => (0, import_ast3.isReferenceExpr)(el) && el.target.ref === field)) {
1329
- result.push(f.name);
1330
- }
1331
- }
1332
- }
1333
- }
1334
- return result;
1335
- }
1336
- getOppositeRelationField(field) {
1337
- if (!field.type.reference?.ref || !(0, import_ast3.isDataModel)(field.type.reference?.ref)) {
1338
- return void 0;
1339
- }
1340
- const sourceModel = field.$container;
1341
- const targetModel = field.type.reference.ref;
1342
- const relationName = this.getRelationName(field);
1343
- for (const otherField of targetModel.fields) {
1344
- if (otherField === field) {
1345
- continue;
1346
- }
1347
- if (otherField.type.reference?.ref === sourceModel) {
1348
- if (relationName) {
1349
- const otherRelationName = this.getRelationName(otherField);
1350
- if (otherRelationName === relationName) {
1351
- return otherField;
1352
- }
1353
- } else {
1354
- return otherField;
1355
- }
1356
- }
1357
- }
1358
- return void 0;
1359
- }
1360
- getRelationName(field) {
1361
- const relation = getAttribute(field, "@relation");
1362
- if (relation) {
1363
- const nameArg = relation.args.find((arg) => arg.$resolvedParam.name === "name");
1364
- if (nameArg) {
1365
- (0, import_common_helpers2.invariant)((0, import_ast3.isLiteralExpr)(nameArg.value), "name must be a literal");
1366
- return nameArg.value.value;
1367
- }
1368
- }
1369
- return void 0;
1370
- }
1371
- createUniqueFieldsObject(dm) {
1372
- const properties = [];
1373
- const allFields = (0, import_utils3.getAllFields)(dm);
1374
- for (const field of allFields) {
1375
- if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) {
1376
- properties.push(ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1377
- ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))
1378
- ])));
1379
- }
1380
- }
1381
- const allAttributes = (0, import_utils3.getAllAttributes)(dm);
1382
- const seenKeys = /* @__PURE__ */ new Set();
1383
- for (const attr of allAttributes) {
1384
- if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
1385
- const fieldsArg = (0, import_utils3.getAttributeArg)(attr, "fields");
1386
- if (!fieldsArg) {
1387
- continue;
1388
- }
1389
- const fieldNames = this.getReferenceNames(fieldsArg);
1390
- if (!fieldNames) {
1391
- continue;
1392
- }
1393
- if (fieldNames.length === 1) {
1394
- const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
1395
- properties.push(ts.factory.createPropertyAssignment(fieldNames[0], ts.factory.createObjectLiteralExpression([
1396
- ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1397
- ])));
1398
- } else {
1399
- const key = this.getCompoundUniqueKey(attr, fieldNames);
1400
- if (seenKeys.has(key)) {
1401
- continue;
1402
- }
1403
- seenKeys.add(key);
1404
- properties.push(ts.factory.createPropertyAssignment(key, ts.factory.createObjectLiteralExpression(fieldNames.map((field) => {
1405
- const fieldDef = allFields.find((f) => f.name === field);
1406
- return ts.factory.createPropertyAssignment(field, ts.factory.createObjectLiteralExpression([
1407
- ts.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))
1408
- ]));
1409
- }))));
1410
- }
1411
- }
1412
- }
1413
- return ts.factory.createObjectLiteralExpression(properties, true);
1414
- }
1415
- getCompoundUniqueKey(attr, fieldNames) {
1416
- const nameArg = attr.args.find((arg) => arg.$resolvedParam.name === "name");
1417
- if (nameArg && (0, import_ast3.isLiteralExpr)(nameArg.value)) {
1418
- return nameArg.value.value;
1419
- } else {
1420
- return fieldNames.join("_");
1421
- }
1422
- }
1423
- generateFieldTypeLiteral(field) {
1424
- (0, import_common_helpers2.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
1425
- return field.type.type ? ts.factory.createStringLiteral(field.type.type) : field.type.reference ? ts.factory.createStringLiteral(field.type.reference.$refText) : ts.factory.createStringLiteral("Unsupported");
1426
- }
1427
- createEnumObject(e) {
1428
- return ts.factory.createObjectLiteralExpression([
1429
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(e.name)),
1430
- ts.factory.createPropertyAssignment("values", ts.factory.createObjectLiteralExpression(e.fields.map((f) => ts.factory.createPropertyAssignment(f.name, ts.factory.createStringLiteral(f.name))), true)),
1431
- // only generate `fields` if there are attributes on the fields
1432
- ...e.fields.some((f) => f.attributes.length > 0) ? [
1433
- ts.factory.createPropertyAssignment("fields", ts.factory.createObjectLiteralExpression(e.fields.map((field) => ts.factory.createPropertyAssignment(field.name, ts.factory.createObjectLiteralExpression([
1434
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.name)),
1435
- ...field.attributes.length > 0 ? [
1436
- ts.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(ts.factory.createArrayLiteralExpression(field.attributes?.map((attr) => this.createAttributeObject(attr)) ?? [], true)))
1437
- ] : []
1438
- ], true))), true))
1439
- ] : [],
1440
- ...e.attributes.length > 0 ? [
1441
- ts.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(ts.factory.createArrayLiteralExpression(e.attributes.map((attr) => this.createAttributeObject(attr)), true)))
1442
- ] : []
1443
- ], true);
1444
- }
1445
- getLiteral(expr) {
1446
- if (!(0, import_ast3.isLiteralExpr)(expr)) {
1447
- throw new Error("Expected a literal expression");
1448
- }
1449
- switch (expr?.$type) {
1450
- case "StringLiteral":
1451
- case "BooleanLiteral":
1452
- return expr.value;
1453
- case "NumberLiteral":
1454
- return parseFloat(expr.value);
1455
- default:
1456
- throw new Error("Unsupported literal type");
1457
- }
1458
- }
1459
- createLiteralNode(arg) {
1460
- return arg === null ? ts.factory.createNull() : typeof arg === "string" ? ts.factory.createStringLiteral(arg) : typeof arg === "number" ? this.createNumberLiteral(arg) : arg === true ? ts.factory.createTrue() : arg === false ? ts.factory.createFalse() : void 0;
1461
- }
1462
- createNumberLiteral(arg) {
1463
- return arg < 0 ? ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, ts.factory.createNumericLiteral(-arg)) : ts.factory.createNumericLiteral(arg);
1464
- }
1465
- createProceduresObject(procedures) {
1466
- return ts.factory.createObjectLiteralExpression(procedures.map((proc) => ts.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
1467
- }
1468
- createProcedureObject(proc) {
1469
- const params = ts.factory.createObjectLiteralExpression(proc.params.map((param) => ts.factory.createPropertyAssignment(param.name, ts.factory.createObjectLiteralExpression([
1470
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(param.name)),
1471
- ...param.optional ? [
1472
- ts.factory.createPropertyAssignment("optional", ts.factory.createTrue())
1473
- ] : [],
1474
- ...param.type.array ? [
1475
- ts.factory.createPropertyAssignment("array", ts.factory.createTrue())
1476
- ] : [],
1477
- ts.factory.createPropertyAssignment("type", ts.factory.createStringLiteral(param.type.type ?? param.type.reference.$refText))
1478
- ]))), true);
1479
- return ts.factory.createObjectLiteralExpression([
1480
- ts.factory.createPropertyAssignment("params", params),
1481
- ts.factory.createPropertyAssignment("returnType", ts.factory.createStringLiteral(proc.returnType.type ?? proc.returnType.reference.$refText)),
1482
- ...proc.returnType.array ? [
1483
- ts.factory.createPropertyAssignment("returnArray", ts.factory.createTrue())
1484
- ] : [],
1485
- ...proc.mutation ? [
1486
- ts.factory.createPropertyAssignment("mutation", ts.factory.createTrue())
1487
- ] : []
1488
- ], true);
1489
- }
1490
- generateBannerComments(statements) {
1491
- const banner = `////////////////////////////////////////////////////////////////////////////////////////////
638
+ usedExpressionUtils = false;
639
+ usedAttributeApplication = false;
640
+ usedFieldDefault = false;
641
+ async generate(model, options) {
642
+ node_fs.default.mkdirSync(options.outDir, { recursive: true });
643
+ this.generateSchema(model, options);
644
+ if (options.generateModelTypes !== false) this.generateModelsAndTypeDefs(model, options);
645
+ if (options.generateInputTypes !== false) this.generateInputTypes(model, options);
646
+ }
647
+ generateSchema(model, options) {
648
+ const targets = [];
649
+ if (!options.liteOnly) targets.push({
650
+ lite: false,
651
+ file: "schema.ts"
652
+ });
653
+ if (options.lite || options.liteOnly) targets.push({
654
+ lite: true,
655
+ file: "schema-lite.ts"
656
+ });
657
+ for (const { lite, file } of targets) {
658
+ this.usedExpressionUtils = false;
659
+ this.usedAttributeApplication = false;
660
+ this.usedFieldDefault = false;
661
+ const statements = [];
662
+ this.generateSchemaStatements(model, statements, lite);
663
+ this.generateBannerComments(statements);
664
+ const schemaOutputFile = node_path.default.join(options.outDir, file);
665
+ const sourceFile = typescript.createSourceFile(schemaOutputFile, "", typescript.ScriptTarget.ESNext, false, typescript.ScriptKind.TS);
666
+ const result = typescript.createPrinter().printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(statements), sourceFile);
667
+ node_fs.default.writeFileSync(schemaOutputFile, result);
668
+ }
669
+ }
670
+ generateSchemaStatements(model, statements, lite) {
671
+ const schemaClass = this.createSchemaClass(model, lite);
672
+ const schemaImportDecl = typescript.factory.createImportDeclaration(void 0, typescript.factory.createImportClause(void 0, void 0, typescript.factory.createNamedImports([
673
+ typescript.factory.createImportSpecifier(true, void 0, typescript.factory.createIdentifier("SchemaDef")),
674
+ ...this.usedAttributeApplication ? [typescript.factory.createImportSpecifier(true, void 0, typescript.factory.createIdentifier("AttributeApplication"))] : [],
675
+ ...this.usedFieldDefault ? [typescript.factory.createImportSpecifier(true, void 0, typescript.factory.createIdentifier("FieldDefault"))] : [],
676
+ ...this.usedExpressionUtils ? [typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier("ExpressionUtils"))] : []
677
+ ])), typescript.factory.createStringLiteral("@zenstackhq/schema"));
678
+ statements.push(schemaImportDecl);
679
+ statements.push(schemaClass);
680
+ const schemaDecl = typescript.factory.createVariableStatement([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], typescript.factory.createVariableDeclarationList([typescript.factory.createVariableDeclaration("schema", void 0, void 0, typescript.factory.createNewExpression(typescript.factory.createIdentifier("SchemaType"), void 0, []))], typescript.NodeFlags.Const));
681
+ statements.push(schemaDecl);
682
+ }
683
+ createExpressionUtilsCall(method, args) {
684
+ this.usedExpressionUtils = true;
685
+ return typescript.factory.createCallExpression(typescript.factory.createPropertyAccessExpression(typescript.factory.createIdentifier("ExpressionUtils"), method), void 0, args || []);
686
+ }
687
+ createSchemaClass(model, lite) {
688
+ const members = [
689
+ typescript.factory.createPropertyDeclaration(void 0, "provider", void 0, void 0, this.createAsConst(this.createProviderObject(model))),
690
+ typescript.factory.createPropertyDeclaration(void 0, "models", void 0, void 0, this.createAsConst(this.createModelsObject(model, lite))),
691
+ ...model.declarations.some(_zenstackhq_language_ast.isTypeDef) ? [typescript.factory.createPropertyDeclaration(void 0, "typeDefs", void 0, void 0, this.createAsConst(this.createTypeDefsObject(model, lite)))] : []
692
+ ];
693
+ const enums = model.declarations.filter(_zenstackhq_language_ast.isEnum);
694
+ if (enums.length > 0) members.push(typescript.factory.createPropertyDeclaration(void 0, "enums", void 0, void 0, this.createAsConst(typescript.factory.createObjectLiteralExpression(enums.map((e) => typescript.factory.createPropertyAssignment(e.name, this.createEnumObject(e))), true))));
695
+ const authType = getAuthDecl(model);
696
+ if (authType) members.push(typescript.factory.createPropertyDeclaration(void 0, "authType", void 0, void 0, this.createAsConst(this.createLiteralNode(authType.name))));
697
+ const procedures = model.declarations.filter(_zenstackhq_language_ast.isProcedure);
698
+ if (procedures.length > 0) members.push(typescript.factory.createPropertyDeclaration(void 0, "procedures", void 0, void 0, this.createAsConst(this.createProceduresObject(procedures))));
699
+ members.push(typescript.factory.createPropertyDeclaration(void 0, "plugins", void 0, void 0, typescript.factory.createObjectLiteralExpression([], true)));
700
+ return typescript.factory.createClassDeclaration([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], "SchemaType", void 0, [typescript.factory.createHeritageClause(typescript.SyntaxKind.ImplementsKeyword, [typescript.factory.createExpressionWithTypeArguments(typescript.factory.createIdentifier("SchemaDef"), void 0)])], members);
701
+ }
702
+ createAsConst(expr) {
703
+ return typescript.factory.createAsExpression(expr, typescript.factory.createTypeReferenceNode("const"));
704
+ }
705
+ createAttributesTypeAssertion(expr) {
706
+ this.usedAttributeApplication = true;
707
+ return typescript.factory.createAsExpression(expr, typescript.factory.createTypeOperatorNode(typescript.SyntaxKind.ReadonlyKeyword, typescript.factory.createArrayTypeNode(typescript.factory.createTypeReferenceNode("AttributeApplication"))));
708
+ }
709
+ createDefaultTypeAssertion(expr) {
710
+ this.usedFieldDefault = true;
711
+ return typescript.factory.createAsExpression(expr, typescript.factory.createTypeReferenceNode("FieldDefault"));
712
+ }
713
+ createProviderObject(model) {
714
+ const dsProvider = this.getDataSourceProvider(model);
715
+ const defaultSchema = this.getDataSourceDefaultSchema(model);
716
+ return typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("type", typescript.factory.createStringLiteral(dsProvider)), ...defaultSchema ? [typescript.factory.createPropertyAssignment("defaultSchema", typescript.factory.createStringLiteral(defaultSchema))] : []], true);
717
+ }
718
+ createModelsObject(model, lite) {
719
+ return typescript.factory.createObjectLiteralExpression(this.getAllDataModels(model).map((dm) => typescript.factory.createPropertyAssignment(dm.name, this.createDataModelObject(dm, lite))), true);
720
+ }
721
+ getAllDataModels(model) {
722
+ return model.declarations.filter((d) => (0, _zenstackhq_language_ast.isDataModel)(d) && !hasAttribute(d, "@@ignore"));
723
+ }
724
+ getAllTypeDefs(model) {
725
+ return model.declarations.filter((d) => (0, _zenstackhq_language_ast.isTypeDef)(d) && !hasAttribute(d, "@@ignore"));
726
+ }
727
+ createTypeDefsObject(model, lite) {
728
+ return typescript.factory.createObjectLiteralExpression(this.getAllTypeDefs(model).map((td) => typescript.factory.createPropertyAssignment(td.name, this.createTypeDefObject(td, lite))), true);
729
+ }
730
+ createDataModelObject(dm, lite) {
731
+ const allFields = (0, _zenstackhq_language_utils.getAllFields)(dm);
732
+ const allAttributes = lite ? [] : (0, _zenstackhq_language_utils.getAllAttributes)(dm).filter((attr) => {
733
+ if (attr.decl.$refText === "@@delegate" && attr.$container !== dm) return false;
734
+ return true;
735
+ });
736
+ const subModels = this.getSubModels(dm);
737
+ const fields = [
738
+ typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(dm.name)),
739
+ ...dm.baseModel ? [typescript.factory.createPropertyAssignment("baseModel", typescript.factory.createStringLiteral(dm.baseModel.$refText))] : [],
740
+ typescript.factory.createPropertyAssignment("fields", typescript.factory.createObjectLiteralExpression(allFields.map((field) => typescript.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, dm, lite))), true)),
741
+ ...allAttributes.length > 0 ? [typescript.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(typescript.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true)))] : [],
742
+ typescript.factory.createPropertyAssignment("idFields", typescript.factory.createArrayLiteralExpression(getIdFields(dm).map((idField) => typescript.factory.createStringLiteral(idField)))),
743
+ typescript.factory.createPropertyAssignment("uniqueFields", this.createUniqueFieldsObject(dm)),
744
+ ...isDelegateModel$1(dm) ? [typescript.factory.createPropertyAssignment("isDelegate", typescript.factory.createTrue())] : [],
745
+ ...subModels.length > 0 ? [typescript.factory.createPropertyAssignment("subModels", typescript.factory.createArrayLiteralExpression(subModels.map((subModel) => typescript.factory.createStringLiteral(subModel))))] : [],
746
+ ...dm.isView ? [typescript.factory.createPropertyAssignment("isView", typescript.factory.createTrue())] : []
747
+ ];
748
+ const computedFields = allFields.filter((f) => hasAttribute(f, "@computed") && !getDelegateOriginModel(f, dm));
749
+ if (computedFields.length > 0) fields.push(typescript.factory.createPropertyAssignment("computedFields", this.createComputedFieldsObject(computedFields)));
750
+ return typescript.factory.createObjectLiteralExpression(fields, true);
751
+ }
752
+ getSubModels(dm) {
753
+ return dm.$container.declarations.filter(_zenstackhq_language_ast.isDataModel).filter((d) => d.baseModel?.ref === dm).map((d) => d.name);
754
+ }
755
+ createTypeDefObject(td, lite) {
756
+ const allFields = (0, _zenstackhq_language_utils.getAllFields)(td);
757
+ const allAttributes = (0, _zenstackhq_language_utils.getAllAttributes)(td);
758
+ const fields = [
759
+ typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(td.name)),
760
+ typescript.factory.createPropertyAssignment("fields", typescript.factory.createObjectLiteralExpression(allFields.map((field) => typescript.factory.createPropertyAssignment(field.name, this.createDataFieldObject(field, void 0, lite))), true)),
761
+ ...allAttributes.length > 0 ? [typescript.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(typescript.factory.createArrayLiteralExpression(allAttributes.map((attr) => this.createAttributeObject(attr)), true)))] : []
762
+ ];
763
+ return typescript.factory.createObjectLiteralExpression(fields, true);
764
+ }
765
+ createComputedFieldsObject(fields) {
766
+ return typescript.factory.createObjectLiteralExpression(fields.map((field) => typescript.factory.createMethodDeclaration(void 0, void 0, field.name, void 0, void 0, [typescript.factory.createParameterDeclaration(void 0, void 0, "_context", void 0, typescript.factory.createTypeLiteralNode([typescript.factory.createPropertySignature(void 0, "modelAlias", void 0, typescript.factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword))]), void 0)], typescript.factory.createTypeReferenceNode(this.mapFieldTypeToTSType(field.type)), typescript.factory.createBlock([typescript.factory.createThrowStatement(typescript.factory.createNewExpression(typescript.factory.createIdentifier("Error"), void 0, [typescript.factory.createStringLiteral("This is a stub for computed field")]))], true))), true);
767
+ }
768
+ createUpdatedAtObject(ignoreArg) {
769
+ return typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("ignore", typescript.factory.createArrayLiteralExpression(ignoreArg.value.items.map((item) => typescript.factory.createStringLiteral(item.target.$refText))))]);
770
+ }
771
+ mapFieldTypeToTSType(type) {
772
+ let result = (0, ts_pattern.match)(type.type).with("String", () => "string").with("Boolean", () => "boolean").with("Int", () => "number").with("Float", () => "number").with("BigInt", () => "bigint").with("Decimal", () => "number").otherwise(() => "unknown");
773
+ if (type.array) result = `${result}[]`;
774
+ if (type.optional) result = `${result} | null`;
775
+ return result;
776
+ }
777
+ createDataFieldObject(field, contextModel, lite) {
778
+ const objectFields = [typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(field.name)), typescript.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))];
779
+ if (contextModel && isIdField(field, contextModel)) objectFields.push(typescript.factory.createPropertyAssignment("id", typescript.factory.createTrue()));
780
+ if (isUniqueField(field)) objectFields.push(typescript.factory.createPropertyAssignment("unique", typescript.factory.createTrue()));
781
+ if (field.type.optional) objectFields.push(typescript.factory.createPropertyAssignment("optional", typescript.factory.createTrue()));
782
+ if (field.type.array) objectFields.push(typescript.factory.createPropertyAssignment("array", typescript.factory.createTrue()));
783
+ const updatedAtAttrib = getAttribute(field, "@updatedAt");
784
+ if (updatedAtAttrib) {
785
+ const ignoreArg = updatedAtAttrib.args.find((arg) => arg.$resolvedParam?.name === "ignore");
786
+ objectFields.push(typescript.factory.createPropertyAssignment("updatedAt", ignoreArg ? this.createUpdatedAtObject(ignoreArg) : typescript.factory.createTrue()));
787
+ }
788
+ if (hasAttribute(field, "@omit")) objectFields.push(typescript.factory.createPropertyAssignment("omit", typescript.factory.createTrue()));
789
+ if (contextModel && !isIdField(field, contextModel)) {
790
+ const delegateOrigin = getDelegateOriginModel(field, contextModel);
791
+ if (delegateOrigin) objectFields.push(typescript.factory.createPropertyAssignment("originModel", typescript.factory.createStringLiteral(delegateOrigin)));
792
+ }
793
+ if (this.isDiscriminatorField(field)) objectFields.push(typescript.factory.createPropertyAssignment("isDiscriminator", typescript.factory.createTrue()));
794
+ if (!lite && field.attributes.length > 0) objectFields.push(typescript.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(typescript.factory.createArrayLiteralExpression(field.attributes.map((attr) => this.createAttributeObject(attr))))));
795
+ const defaultValue = this.getFieldMappedDefault(field);
796
+ if (defaultValue !== void 0) {
797
+ let defaultExpr;
798
+ if (defaultValue === null) defaultExpr = this.createExpressionUtilsCall("_null");
799
+ else if (typeof defaultValue === "object" && !Array.isArray(defaultValue)) if ("call" in defaultValue) defaultExpr = this.createExpressionUtilsCall("call", [typescript.factory.createStringLiteral(defaultValue.call), ...defaultValue.args.length > 0 ? [typescript.factory.createArrayLiteralExpression(defaultValue.args.map((arg) => this.createExpressionUtilsCall("literal", [this.createLiteralNode(arg)])))] : []]);
800
+ else if ("authMember" in defaultValue) defaultExpr = this.createExpressionUtilsCall("member", [this.createExpressionUtilsCall("call", [typescript.factory.createStringLiteral("auth")]), typescript.factory.createArrayLiteralExpression(defaultValue.authMember.map((m) => typescript.factory.createStringLiteral(m)))]);
801
+ else throw new Error(`Unsupported default value type for field ${field.name}`);
802
+ else if (Array.isArray(defaultValue)) defaultExpr = typescript.factory.createArrayLiteralExpression(defaultValue.map((item) => this.createLiteralNode(item)));
803
+ else defaultExpr = this.createLiteralNode(defaultValue);
804
+ objectFields.push(typescript.factory.createPropertyAssignment("default", this.createDefaultTypeAssertion(defaultExpr)));
805
+ }
806
+ if (hasAttribute(field, "@computed")) objectFields.push(typescript.factory.createPropertyAssignment("computed", typescript.factory.createTrue()));
807
+ if ((0, _zenstackhq_language_ast.isDataModel)(field.type.reference?.ref)) objectFields.push(typescript.factory.createPropertyAssignment("relation", this.createRelationObject(field, contextModel)));
808
+ const fkFor = this.getForeignKeyFor(field, contextModel);
809
+ if (fkFor && fkFor.length > 0) objectFields.push(typescript.factory.createPropertyAssignment("foreignKeyFor", typescript.factory.createAsExpression(typescript.factory.createArrayLiteralExpression(fkFor.map((fk) => typescript.factory.createStringLiteral(fk)), true), typescript.factory.createTypeOperatorNode(typescript.SyntaxKind.ReadonlyKeyword, typescript.factory.createArrayTypeNode(typescript.factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword))))));
810
+ return typescript.factory.createObjectLiteralExpression(objectFields, true);
811
+ }
812
+ isDiscriminatorField(field) {
813
+ const origin = field.$container;
814
+ return getAttribute(origin, "@@delegate")?.args.some((arg) => arg.$resolvedParam?.name === "discriminator" && (0, _zenstackhq_language_utils.isDataFieldReference)(arg.value) && arg.value.target.ref === field);
815
+ }
816
+ getDataSourceProvider(model) {
817
+ const dataSource = model.declarations.find(_zenstackhq_language_ast.isDataSource);
818
+ (0, _zenstackhq_common_helpers.invariant)(dataSource, "No data source found in the model");
819
+ const providerExpr = dataSource.fields.find((f) => f.name === "provider")?.value;
820
+ (0, _zenstackhq_common_helpers.invariant)((0, _zenstackhq_language_ast.isLiteralExpr)(providerExpr) && typeof providerExpr.value === "string", "Provider must be a string literal");
821
+ return providerExpr.value;
822
+ }
823
+ getDataSourceDefaultSchema(model) {
824
+ const dataSource = model.declarations.find(_zenstackhq_language_ast.isDataSource);
825
+ (0, _zenstackhq_common_helpers.invariant)(dataSource, "No data source found in the model");
826
+ const defaultSchemaExpr = dataSource.fields.find((f) => f.name === "defaultSchema")?.value;
827
+ if (!defaultSchemaExpr) return;
828
+ (0, _zenstackhq_common_helpers.invariant)((0, _zenstackhq_language_ast.isLiteralExpr)(defaultSchemaExpr) && typeof defaultSchemaExpr.value === "string", "Default schema must be a string literal");
829
+ return defaultSchemaExpr.value;
830
+ }
831
+ getFieldMappedDefault(field) {
832
+ const defaultAttr = getAttribute(field, "@default");
833
+ if (!defaultAttr) return;
834
+ const defaultValue = defaultAttr.args[0]?.value;
835
+ (0, _zenstackhq_common_helpers.invariant)(defaultValue, "Expected a default value");
836
+ return this.getMappedValue(defaultValue, field.type);
837
+ }
838
+ getMappedValue(expr, fieldType) {
839
+ if ((0, _zenstackhq_language_ast.isLiteralExpr)(expr)) {
840
+ const lit = expr.value;
841
+ return fieldType.type === "Boolean" ? lit : [
842
+ "Int",
843
+ "Float",
844
+ "Decimal",
845
+ "BigInt"
846
+ ].includes(fieldType.type) ? Number(lit) : lit;
847
+ } else if ((0, _zenstackhq_language_ast.isArrayExpr)(expr)) return expr.items.map((item) => this.getMappedValue(item, fieldType));
848
+ else if ((0, _zenstackhq_language_ast.isReferenceExpr)(expr) && (0, _zenstackhq_language_ast.isEnumField)(expr.target.ref)) return expr.target.ref.name;
849
+ else if ((0, _zenstackhq_language_ast.isInvocationExpr)(expr)) return {
850
+ call: expr.function.$refText,
851
+ args: expr.args.map((arg) => this.getLiteral(arg.value))
852
+ };
853
+ else if (this.isAuthMemberAccess(expr)) return { authMember: this.getMemberAccessChain(expr) };
854
+ else if ((0, _zenstackhq_language_ast.isNullExpr)(expr)) return null;
855
+ else throw new Error(`Unsupported expression type: ${expr.$type}`);
856
+ }
857
+ getMemberAccessChain(expr) {
858
+ if (!(0, _zenstackhq_language_ast.isMemberAccessExpr)(expr.operand)) return [expr.member.$refText];
859
+ else return [...this.getMemberAccessChain(expr.operand), expr.member.$refText];
860
+ }
861
+ isAuthMemberAccess(expr) {
862
+ if ((0, _zenstackhq_language_ast.isMemberAccessExpr)(expr)) return this.isAuthInvocation(expr.operand) || this.isAuthMemberAccess(expr.operand);
863
+ else return false;
864
+ }
865
+ isAuthInvocation(expr) {
866
+ return (0, _zenstackhq_language_ast.isInvocationExpr)(expr) && expr.function.$refText === "auth" && isFromStdlib(expr.function.ref);
867
+ }
868
+ createRelationObject(field, contextModel) {
869
+ const relationFields = [];
870
+ const oppositeRelation = this.getOppositeRelationField(field, contextModel);
871
+ if (oppositeRelation) relationFields.push(typescript.factory.createPropertyAssignment("opposite", typescript.factory.createStringLiteral(oppositeRelation.name)));
872
+ const relationName = this.getRelationName(field);
873
+ if (relationName) relationFields.push(typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(relationName)));
874
+ const relation = getAttribute(field, "@relation");
875
+ const fkFields = [];
876
+ if (relation) for (const arg of relation.args) {
877
+ const param = arg.$resolvedParam?.name;
878
+ if (param === "fields" || param === "references") {
879
+ const fieldNames = this.getReferenceNames(arg.value);
880
+ if (fieldNames) {
881
+ if (param === "fields") fkFields.push(...fieldNames);
882
+ relationFields.push(typescript.factory.createPropertyAssignment(param, typescript.factory.createArrayLiteralExpression(fieldNames.map((el) => typescript.factory.createStringLiteral(el)))));
883
+ }
884
+ }
885
+ if (param === "onDelete" || param === "onUpdate") {
886
+ const action = arg.value.target.$refText;
887
+ relationFields.push(typescript.factory.createPropertyAssignment(param, typescript.factory.createStringLiteral(action)));
888
+ }
889
+ }
890
+ if (fkFields.length > 0) {
891
+ if (fkFields.every((fieldName) => {
892
+ const fieldDef = field.$container.fields.find((f) => f.name === fieldName);
893
+ return fieldDef && hasAttribute(fieldDef, "@default");
894
+ })) relationFields.push(typescript.factory.createPropertyAssignment("hasDefault", typescript.factory.createTrue()));
895
+ }
896
+ return typescript.factory.createObjectLiteralExpression(relationFields);
897
+ }
898
+ getReferenceNames(expr) {
899
+ return (0, _zenstackhq_language_ast.isArrayExpr)(expr) && expr.items.map((item) => item.target.$refText);
900
+ }
901
+ getForeignKeyFor(field, contextModel) {
902
+ if (!contextModel) return [];
903
+ const result = [];
904
+ for (const f of (0, _zenstackhq_language_utils.getAllFields)(contextModel)) {
905
+ const relation = getAttribute(f, "@relation");
906
+ if (relation) {
907
+ for (const arg of relation.args) if (arg.name === "fields" && (0, _zenstackhq_language_ast.isArrayExpr)(arg.value) && arg.value.items.some((el) => (0, _zenstackhq_language_ast.isReferenceExpr)(el) && el.target.ref === field)) result.push(f.name);
908
+ }
909
+ }
910
+ return result;
911
+ }
912
+ getOppositeRelationField(field, contextModel) {
913
+ if (!field.type.reference?.ref || !(0, _zenstackhq_language_ast.isDataModel)(field.type.reference?.ref) || !contextModel) return;
914
+ const sourceModel = (0, _zenstackhq_language_ast.isTypeDef)(field.$container) ? contextModel : field.$container;
915
+ const targetModel = field.type.reference.ref;
916
+ const relationName = this.getRelationName(field);
917
+ for (const otherField of (0, _zenstackhq_language_utils.getAllFields)(targetModel)) {
918
+ if (otherField === field) continue;
919
+ if (otherField.type.reference?.ref === sourceModel) if (relationName) {
920
+ if (this.getRelationName(otherField) === relationName) return otherField;
921
+ } else return otherField;
922
+ }
923
+ }
924
+ getRelationName(field) {
925
+ const relation = getAttribute(field, "@relation");
926
+ if (relation) {
927
+ const nameArg = relation.args.find((arg) => arg.$resolvedParam?.name === "name");
928
+ if (nameArg) {
929
+ (0, _zenstackhq_common_helpers.invariant)((0, _zenstackhq_language_ast.isLiteralExpr)(nameArg.value), "name must be a literal");
930
+ return nameArg.value.value;
931
+ }
932
+ }
933
+ }
934
+ createUniqueFieldsObject(dm) {
935
+ const properties = [];
936
+ const allFields = (0, _zenstackhq_language_utils.getAllFields)(dm);
937
+ for (const field of allFields) if (hasAttribute(field, "@id") || hasAttribute(field, "@unique")) properties.push(typescript.factory.createPropertyAssignment(field.name, typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(field))])));
938
+ const allAttributes = (0, _zenstackhq_language_utils.getAllAttributes)(dm);
939
+ const seenKeys = /* @__PURE__ */ new Set();
940
+ for (const attr of allAttributes) if (attr.decl.$refText === "@@id" || attr.decl.$refText === "@@unique") {
941
+ const fieldsArg = (0, _zenstackhq_language_utils.getAttributeArg)(attr, "fields");
942
+ if (!fieldsArg) continue;
943
+ const fieldNames = this.getReferenceNames(fieldsArg);
944
+ if (!fieldNames) continue;
945
+ if (fieldNames.length === 1) {
946
+ const fieldDef = allFields.find((f) => f.name === fieldNames[0]);
947
+ properties.push(typescript.factory.createPropertyAssignment(fieldNames[0], typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))])));
948
+ } else {
949
+ const key = this.getCompoundUniqueKey(attr, fieldNames);
950
+ if (seenKeys.has(key)) continue;
951
+ seenKeys.add(key);
952
+ properties.push(typescript.factory.createPropertyAssignment(key, typescript.factory.createObjectLiteralExpression(fieldNames.map((field) => {
953
+ const fieldDef = allFields.find((f) => f.name === field);
954
+ return typescript.factory.createPropertyAssignment(field, typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("type", this.generateFieldTypeLiteral(fieldDef))]));
955
+ }))));
956
+ }
957
+ }
958
+ return typescript.factory.createObjectLiteralExpression(properties, true);
959
+ }
960
+ getCompoundUniqueKey(attr, fieldNames) {
961
+ const nameArg = attr.args.find((arg) => arg.$resolvedParam?.name === "name");
962
+ if (nameArg && (0, _zenstackhq_language_ast.isLiteralExpr)(nameArg.value)) return nameArg.value.value;
963
+ else return fieldNames.join("_");
964
+ }
965
+ generateFieldTypeLiteral(field) {
966
+ (0, _zenstackhq_common_helpers.invariant)(field.type.type || field.type.reference || field.type.unsupported, "Field type must be a primitive, reference, or Unsupported");
967
+ return field.type.type ? typescript.factory.createStringLiteral(field.type.type) : field.type.reference ? typescript.factory.createStringLiteral(field.type.reference.$refText) : typescript.factory.createStringLiteral("Unsupported");
968
+ }
969
+ createEnumObject(e) {
970
+ return typescript.factory.createObjectLiteralExpression([
971
+ typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(e.name)),
972
+ typescript.factory.createPropertyAssignment("values", typescript.factory.createObjectLiteralExpression(e.fields.map((f) => typescript.factory.createPropertyAssignment(f.name, typescript.factory.createStringLiteral(f.name))), true)),
973
+ ...e.fields.some((f) => f.attributes.length > 0) ? [typescript.factory.createPropertyAssignment("fields", typescript.factory.createObjectLiteralExpression(e.fields.map((field) => typescript.factory.createPropertyAssignment(field.name, typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(field.name)), ...field.attributes.length > 0 ? [typescript.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(typescript.factory.createArrayLiteralExpression(field.attributes?.map((attr) => this.createAttributeObject(attr)) ?? [], true)))] : []], true))), true))] : [],
974
+ ...e.attributes.length > 0 ? [typescript.factory.createPropertyAssignment("attributes", this.createAttributesTypeAssertion(typescript.factory.createArrayLiteralExpression(e.attributes.map((attr) => this.createAttributeObject(attr)), true)))] : []
975
+ ], true);
976
+ }
977
+ getLiteral(expr) {
978
+ if (!(0, _zenstackhq_language_ast.isLiteralExpr)(expr)) throw new Error("Expected a literal expression");
979
+ switch (expr?.$type) {
980
+ case "StringLiteral":
981
+ case "BooleanLiteral": return expr.value;
982
+ case "NumberLiteral": return parseFloat(expr.value);
983
+ default: throw new Error("Unsupported literal type");
984
+ }
985
+ }
986
+ createLiteralNode(arg) {
987
+ return arg === null ? typescript.factory.createNull() : typeof arg === "string" ? typescript.factory.createStringLiteral(arg) : typeof arg === "number" ? this.createNumberLiteral(arg) : arg === true ? typescript.factory.createTrue() : arg === false ? typescript.factory.createFalse() : void 0;
988
+ }
989
+ createNumberLiteral(arg) {
990
+ return arg < 0 ? typescript.factory.createPrefixUnaryExpression(typescript.SyntaxKind.MinusToken, typescript.factory.createNumericLiteral(-arg)) : typescript.factory.createNumericLiteral(arg);
991
+ }
992
+ createProceduresObject(procedures) {
993
+ return typescript.factory.createObjectLiteralExpression(procedures.map((proc) => typescript.factory.createPropertyAssignment(proc.name, this.createProcedureObject(proc))), true);
994
+ }
995
+ createProcedureObject(proc) {
996
+ const params = typescript.factory.createObjectLiteralExpression(proc.params.map((param) => typescript.factory.createPropertyAssignment(param.name, typescript.factory.createObjectLiteralExpression([
997
+ typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(param.name)),
998
+ ...param.optional ? [typescript.factory.createPropertyAssignment("optional", typescript.factory.createTrue())] : [],
999
+ ...param.type.array ? [typescript.factory.createPropertyAssignment("array", typescript.factory.createTrue())] : [],
1000
+ typescript.factory.createPropertyAssignment("type", typescript.factory.createStringLiteral(param.type.type ?? param.type.reference.$refText))
1001
+ ]))), true);
1002
+ return typescript.factory.createObjectLiteralExpression([
1003
+ typescript.factory.createPropertyAssignment("params", params),
1004
+ typescript.factory.createPropertyAssignment("returnType", typescript.factory.createStringLiteral(proc.returnType.type ?? proc.returnType.reference.$refText)),
1005
+ ...proc.returnType.array ? [typescript.factory.createPropertyAssignment("returnArray", typescript.factory.createTrue())] : [],
1006
+ ...proc.mutation ? [typescript.factory.createPropertyAssignment("mutation", typescript.factory.createTrue())] : []
1007
+ ], true);
1008
+ }
1009
+ generateBannerComments(statements) {
1010
+ typescript.addSyntheticLeadingComment(statements[0], typescript.SyntaxKind.SingleLineCommentTrivia, `////////////////////////////////////////////////////////////////////////////////////////////
1492
1011
  // DO NOT MODIFY THIS FILE //
1493
1012
  // This file is automatically generated by ZenStack CLI and should not be manually updated. //
1494
1013
  //////////////////////////////////////////////////////////////////////////////////////////////
1495
1014
 
1496
1015
  /* eslint-disable */
1497
1016
 
1498
- `;
1499
- ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.SingleLineCommentTrivia, banner);
1500
- }
1501
- createAttributeObject(attr) {
1502
- return ts.factory.createObjectLiteralExpression([
1503
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(attr.decl.$refText)),
1504
- ...attr.args.length > 0 ? [
1505
- ts.factory.createPropertyAssignment("args", ts.factory.createArrayLiteralExpression(attr.args.map((arg) => this.createAttributeArg(arg))))
1506
- ] : []
1507
- ]);
1508
- }
1509
- createAttributeArg(arg) {
1510
- return ts.factory.createObjectLiteralExpression([
1511
- // name
1512
- ...arg.$resolvedParam?.name ? [
1513
- ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(arg.$resolvedParam.name))
1514
- ] : [],
1515
- // value
1516
- ts.factory.createPropertyAssignment("value", this.createExpression(arg.value))
1517
- ]);
1518
- }
1519
- createExpression(value) {
1520
- return (0, import_ts_pattern2.match)(value).when(import_ast3.isLiteralExpr, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(import_ast3.isInvocationExpr, (expr) => this.createCallExpression(expr)).when(import_ast3.isReferenceExpr, (expr) => this.createRefExpression(expr)).when(import_ast3.isArrayExpr, (expr) => this.createArrayExpression(expr)).when(import_ast3.isUnaryExpr, (expr) => this.createUnaryExpression(expr)).when(import_ast3.isBinaryExpr, (expr) => this.createBinaryExpression(expr)).when(import_ast3.isMemberAccessExpr, (expr) => this.createMemberExpression(expr)).when(import_ast3.isNullExpr, () => this.createNullExpression()).when(import_ast3.isThisExpr, () => this.createThisExpression()).otherwise(() => {
1521
- throw new Error(`Unsupported attribute arg value: ${value.$type}`);
1522
- });
1523
- }
1524
- createThisExpression() {
1525
- return this.createExpressionUtilsCall("_this");
1526
- }
1527
- createMemberExpression(expr) {
1528
- const members = [];
1529
- let current = expr;
1530
- while ((0, import_ast3.isMemberAccessExpr)(current)) {
1531
- members.unshift(current.member.$refText);
1532
- current = current.operand;
1533
- }
1534
- const receiver = current;
1535
- const args = [
1536
- this.createExpression(receiver),
1537
- ts.factory.createArrayLiteralExpression(members.map((m) => ts.factory.createStringLiteral(m)))
1538
- ];
1539
- return this.createExpressionUtilsCall("member", args);
1540
- }
1541
- createNullExpression() {
1542
- return this.createExpressionUtilsCall("_null");
1543
- }
1544
- createBinaryExpression(expr) {
1545
- const args = [
1546
- this.createExpression(expr.left),
1547
- this.createLiteralNode(expr.operator),
1548
- this.createExpression(expr.right)
1549
- ];
1550
- if (expr.binding) {
1551
- args.push(this.createLiteralNode(expr.binding.name));
1552
- }
1553
- return this.createExpressionUtilsCall("binary", args);
1554
- }
1555
- createUnaryExpression(expr) {
1556
- return this.createExpressionUtilsCall("unary", [
1557
- this.createLiteralNode(expr.operator),
1558
- this.createExpression(expr.operand)
1559
- ]);
1560
- }
1561
- createArrayExpression(expr) {
1562
- const arrayResolved = expr.$resolvedType?.decl;
1563
- const arrayType = typeof arrayResolved === "string" ? arrayResolved : arrayResolved?.name;
1564
- (0, import_common_helpers2.invariant)(arrayType, "Array type must be resolved to a string or declaration");
1565
- return this.createExpressionUtilsCall("array", [
1566
- this.createLiteralNode(arrayType),
1567
- ts.factory.createArrayLiteralExpression(expr.items.map((item) => this.createExpression(item)))
1568
- ]);
1569
- }
1570
- createRefExpression(expr) {
1571
- const target = expr.target.ref;
1572
- return (0, import_ts_pattern2.match)(target).when(import_ast3.isDataField, () => this.createExpressionUtilsCall("field", [
1573
- this.createLiteralNode(expr.target.$refText)
1574
- ])).when(import_ast3.isEnumField, () => this.createLiteralExpression("StringLiteral", expr.target.$refText)).when(import_ast3.isCollectionPredicateBinding, () => this.createExpressionUtilsCall("binding", [
1575
- this.createLiteralNode(expr.target.$refText)
1576
- ])).otherwise(() => {
1577
- throw Error(`Unsupported reference type: ${expr.target.$refText}`);
1578
- });
1579
- }
1580
- createCallExpression(expr) {
1581
- return this.createExpressionUtilsCall("call", [
1582
- ts.factory.createStringLiteral(expr.function.$refText),
1583
- ...expr.args.length > 0 ? [
1584
- ts.factory.createArrayLiteralExpression(expr.args.map((arg) => this.createExpression(arg.value)))
1585
- ] : []
1586
- ]);
1587
- }
1588
- createLiteralExpression(type, value) {
1589
- return (0, import_ts_pattern2.match)(type).with("BooleanLiteral", () => this.createExpressionUtilsCall("literal", [
1590
- this.createLiteralNode(value)
1591
- ])).with("NumberLiteral", () => this.createExpressionUtilsCall("literal", [
1592
- ts.factory.createIdentifier(value)
1593
- ])).with("StringLiteral", () => this.createExpressionUtilsCall("literal", [
1594
- this.createLiteralNode(value)
1595
- ])).otherwise(() => {
1596
- throw new Error(`Unsupported literal type: ${type}`);
1597
- });
1598
- }
1599
- generateModelsAndTypeDefs(model, options) {
1600
- const statements = [];
1601
- statements.push(this.generateSchemaImport(model, true, true, !!(options.lite || options.liteOnly), options.importWithFileExtension));
1602
- statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1603
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(`ModelResult as $ModelResult`)),
1604
- ...model.declarations.some(import_ast3.isTypeDef) ? [
1605
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))
1606
- ] : []
1607
- ])), ts.factory.createStringLiteral("@zenstackhq/orm")));
1608
- const dataModels = this.getAllDataModels(model);
1609
- for (const dm of dataModels) {
1610
- let modelType = ts.factory.createTypeAliasDeclaration([
1611
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1612
- ], dm.name, void 0, ts.factory.createTypeReferenceNode("$ModelResult", [
1613
- ts.factory.createTypeReferenceNode("$Schema"),
1614
- ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1615
- ]));
1616
- if (dm.comments.length > 0) {
1617
- modelType = this.generateDocs(modelType, dm);
1618
- }
1619
- statements.push(modelType);
1620
- }
1621
- const typeDefs = this.getAllTypeDefs(model);
1622
- for (const td of typeDefs) {
1623
- let typeDef = ts.factory.createTypeAliasDeclaration([
1624
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1625
- ], td.name, void 0, ts.factory.createTypeReferenceNode("$TypeDefResult", [
1626
- ts.factory.createTypeReferenceNode("$Schema"),
1627
- ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(td.name))
1628
- ]));
1629
- if (td.comments.length > 0) {
1630
- typeDef = this.generateDocs(typeDef, td);
1631
- }
1632
- statements.push(typeDef);
1633
- }
1634
- const enums = model.declarations.filter(import_ast3.isEnum);
1635
- for (const e of enums) {
1636
- let enumDecl = ts.factory.createVariableStatement([
1637
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1638
- ], ts.factory.createVariableDeclarationList([
1639
- ts.factory.createVariableDeclaration(e.name, void 0, void 0, ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier("$schema"), ts.factory.createIdentifier("enums")), ts.factory.createIdentifier(e.name)), ts.factory.createIdentifier("values")))
1640
- ], ts.NodeFlags.Const));
1641
- if (e.comments.length > 0) {
1642
- enumDecl = this.generateDocs(enumDecl, e);
1643
- }
1644
- statements.push(enumDecl);
1645
- let typeAlias = ts.factory.createTypeAliasDeclaration([
1646
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1647
- ], e.name, void 0, ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeQueryNode(ts.factory.createIdentifier(e.name)), ts.factory.createTypeOperatorNode(ts.SyntaxKind.KeyOfKeyword, ts.factory.createTypeQueryNode(ts.factory.createIdentifier(e.name)))));
1648
- if (e.comments.length > 0) {
1649
- typeAlias = this.generateDocs(typeAlias, e);
1650
- }
1651
- statements.push(typeAlias);
1652
- }
1653
- this.generateBannerComments(statements);
1654
- const outputFile = import_node_path.default.join(options.outDir, "models.ts");
1655
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1656
- const printer = ts.createPrinter();
1657
- const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1658
- import_node_fs.default.writeFileSync(outputFile, result);
1659
- }
1660
- generateSchemaImport(model, schemaObject, schemaType, useLite, importWithFileExtension) {
1661
- const importSpecifiers = [];
1662
- if (schemaObject) {
1663
- if (model.declarations.some(import_ast3.isEnum)) {
1664
- importSpecifiers.push(ts.factory.createImportSpecifier(false, ts.factory.createIdentifier("schema"), ts.factory.createIdentifier("$schema")));
1665
- }
1666
- }
1667
- if (schemaType) {
1668
- importSpecifiers.push(ts.factory.createImportSpecifier(true, ts.factory.createIdentifier("SchemaType"), ts.factory.createIdentifier("$Schema")));
1669
- }
1670
- let importFrom = useLite ? "./schema-lite" : "./schema";
1671
- if (importWithFileExtension) {
1672
- importFrom += importWithFileExtension.startsWith(".") ? importWithFileExtension : `.${importWithFileExtension}`;
1673
- }
1674
- return ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(importSpecifiers)), ts.factory.createStringLiteral(importFrom));
1675
- }
1676
- generateDocs(tsDecl, decl) {
1677
- return ts.addSyntheticLeadingComment(tsDecl, ts.SyntaxKind.MultiLineCommentTrivia, `*
1678
- * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}
1679
- `, true);
1680
- }
1681
- generateInputTypes(model, options) {
1682
- const dataModels = this.getAllDataModels(model);
1683
- const statements = [];
1684
- statements.push(this.generateSchemaImport(model, false, true, !!(options.lite || options.liteOnly), options.importWithFileExtension));
1685
- const inputTypes = [
1686
- "FindManyArgs",
1687
- "FindUniqueArgs",
1688
- "FindFirstArgs",
1689
- "ExistsArgs",
1690
- "CreateArgs",
1691
- "CreateManyArgs",
1692
- "CreateManyAndReturnArgs",
1693
- "UpdateArgs",
1694
- "UpdateManyArgs",
1695
- "UpdateManyAndReturnArgs",
1696
- "UpsertArgs",
1697
- "DeleteArgs",
1698
- "DeleteManyArgs",
1699
- "CountArgs",
1700
- "AggregateArgs",
1701
- "GroupByArgs",
1702
- "WhereInput",
1703
- "SelectInput",
1704
- "IncludeInput",
1705
- "OmitInput"
1706
- ];
1707
- const inputTypeNameFixes = {
1708
- SelectInput: "Select",
1709
- IncludeInput: "Include",
1710
- OmitInput: "Omit"
1711
- };
1712
- statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1713
- ...inputTypes.map((inputType) => ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(`${inputType} as $${inputType}`))),
1714
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("QueryOptions as $QueryOptions"))
1715
- ])), ts.factory.createStringLiteral("@zenstackhq/orm")));
1716
- statements.push(ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(true, void 0, ts.factory.createNamedImports([
1717
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SimplifiedPlainResult as $Result")),
1718
- ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))
1719
- ])), ts.factory.createStringLiteral("@zenstackhq/orm")));
1720
- for (const dm of dataModels) {
1721
- for (const inputType of inputTypes) {
1722
- const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1723
- statements.push(ts.factory.createTypeAliasDeclaration([
1724
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1725
- ], exportName, void 0, ts.factory.createTypeReferenceNode(`$${inputType}`, [
1726
- ts.factory.createTypeReferenceNode("$Schema"),
1727
- ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name))
1728
- ])));
1729
- }
1730
- statements.push(ts.factory.createTypeAliasDeclaration([
1731
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)
1732
- ], `${dm.name}GetPayload`, [
1733
- ts.factory.createTypeParameterDeclaration(void 0, "Args", ts.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1734
- ts.factory.createTypeReferenceNode("$Schema"),
1735
- ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1736
- ts.factory.createLiteralTypeNode(ts.factory.createTrue())
1737
- ])),
1738
- ts.factory.createTypeParameterDeclaration(void 0, "Options", ts.factory.createTypeReferenceNode("$QueryOptions", [
1739
- ts.factory.createTypeReferenceNode("$Schema")
1740
- ]), ts.factory.createTypeReferenceNode("$QueryOptions", [
1741
- ts.factory.createTypeReferenceNode("$Schema")
1742
- ]))
1743
- ], ts.factory.createTypeReferenceNode("$Result", [
1744
- ts.factory.createTypeReferenceNode("$Schema"),
1745
- ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(dm.name)),
1746
- ts.factory.createTypeReferenceNode("Args"),
1747
- ts.factory.createTypeReferenceNode("Options")
1748
- ])));
1749
- }
1750
- this.generateBannerComments(statements);
1751
- const outputFile = import_node_path.default.join(options.outDir, "input.ts");
1752
- const sourceFile = ts.createSourceFile(outputFile, "", ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
1753
- const printer = ts.createPrinter();
1754
- const result = printer.printList(ts.ListFormat.MultiLine, ts.factory.createNodeArray(statements), sourceFile);
1755
- import_node_fs.default.writeFileSync(outputFile, result);
1756
- }
1017
+ `);
1018
+ }
1019
+ createAttributeObject(attr) {
1020
+ return typescript.factory.createObjectLiteralExpression([typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(attr.decl.$refText)), ...attr.args.length > 0 ? [typescript.factory.createPropertyAssignment("args", typescript.factory.createArrayLiteralExpression(attr.args.map((arg) => this.createAttributeArg(arg))))] : []]);
1021
+ }
1022
+ createAttributeArg(arg) {
1023
+ return typescript.factory.createObjectLiteralExpression([...arg.$resolvedParam?.name ? [typescript.factory.createPropertyAssignment("name", typescript.factory.createStringLiteral(arg.$resolvedParam.name))] : [], typescript.factory.createPropertyAssignment("value", this.createExpression(arg.value))]);
1024
+ }
1025
+ createExpression(value) {
1026
+ return (0, ts_pattern.match)(value).when(_zenstackhq_language_ast.isLiteralExpr, (expr) => this.createLiteralExpression(expr.$type, expr.value)).when(_zenstackhq_language_ast.isInvocationExpr, (expr) => this.createCallExpression(expr)).when(_zenstackhq_language_ast.isReferenceExpr, (expr) => this.createRefExpression(expr)).when(_zenstackhq_language_ast.isArrayExpr, (expr) => this.createArrayExpression(expr)).when(_zenstackhq_language_ast.isUnaryExpr, (expr) => this.createUnaryExpression(expr)).when(_zenstackhq_language_ast.isBinaryExpr, (expr) => this.createBinaryExpression(expr)).when(_zenstackhq_language_ast.isMemberAccessExpr, (expr) => this.createMemberExpression(expr)).when(_zenstackhq_language_ast.isNullExpr, () => this.createNullExpression()).when(_zenstackhq_language_ast.isThisExpr, () => this.createThisExpression()).otherwise(() => {
1027
+ throw new Error(`Unsupported attribute arg value: ${value.$type}`);
1028
+ });
1029
+ }
1030
+ createThisExpression() {
1031
+ return this.createExpressionUtilsCall("_this");
1032
+ }
1033
+ createMemberExpression(expr) {
1034
+ const members = [];
1035
+ let current = expr;
1036
+ while ((0, _zenstackhq_language_ast.isMemberAccessExpr)(current)) {
1037
+ members.unshift(current.member.$refText);
1038
+ current = current.operand;
1039
+ }
1040
+ const receiver = current;
1041
+ const args = [this.createExpression(receiver), typescript.factory.createArrayLiteralExpression(members.map((m) => typescript.factory.createStringLiteral(m)))];
1042
+ return this.createExpressionUtilsCall("member", args);
1043
+ }
1044
+ createNullExpression() {
1045
+ return this.createExpressionUtilsCall("_null");
1046
+ }
1047
+ createBinaryExpression(expr) {
1048
+ const args = [
1049
+ this.createExpression(expr.left),
1050
+ this.createLiteralNode(expr.operator),
1051
+ this.createExpression(expr.right)
1052
+ ];
1053
+ if (expr.binding) args.push(this.createLiteralNode(expr.binding.name));
1054
+ return this.createExpressionUtilsCall("binary", args);
1055
+ }
1056
+ createUnaryExpression(expr) {
1057
+ return this.createExpressionUtilsCall("unary", [this.createLiteralNode(expr.operator), this.createExpression(expr.operand)]);
1058
+ }
1059
+ createArrayExpression(expr) {
1060
+ const arrayResolved = expr.$resolvedType?.decl;
1061
+ const arrayType = typeof arrayResolved === "string" ? arrayResolved : arrayResolved?.name;
1062
+ (0, _zenstackhq_common_helpers.invariant)(arrayType, "Array type must be resolved to a string or declaration");
1063
+ return this.createExpressionUtilsCall("array", [this.createLiteralNode(arrayType), typescript.factory.createArrayLiteralExpression(expr.items.map((item) => this.createExpression(item)))]);
1064
+ }
1065
+ createRefExpression(expr) {
1066
+ const target = expr.target.ref;
1067
+ return (0, ts_pattern.match)(target).when(_zenstackhq_language_ast.isDataField, () => this.createExpressionUtilsCall("field", [this.createLiteralNode(expr.target.$refText)])).when(_zenstackhq_language_ast.isEnumField, () => this.createLiteralExpression("StringLiteral", expr.target.$refText)).when(_zenstackhq_language_ast.isCollectionPredicateBinding, () => this.createExpressionUtilsCall("binding", [this.createLiteralNode(expr.target.$refText)])).otherwise(() => {
1068
+ throw Error(`Unsupported reference type: ${expr.target.$refText}`);
1069
+ });
1070
+ }
1071
+ createCallExpression(expr) {
1072
+ return this.createExpressionUtilsCall("call", [typescript.factory.createStringLiteral(expr.function.$refText), ...expr.args.length > 0 ? [typescript.factory.createArrayLiteralExpression(expr.args.map((arg) => this.createExpression(arg.value)))] : []]);
1073
+ }
1074
+ createLiteralExpression(type, value) {
1075
+ return (0, ts_pattern.match)(type).with("BooleanLiteral", () => this.createExpressionUtilsCall("literal", [this.createLiteralNode(value)])).with("NumberLiteral", () => this.createExpressionUtilsCall("literal", [typescript.factory.createIdentifier(value)])).with("StringLiteral", () => this.createExpressionUtilsCall("literal", [this.createLiteralNode(value)])).otherwise(() => {
1076
+ throw new Error(`Unsupported literal type: ${type}`);
1077
+ });
1078
+ }
1079
+ generateModelsAndTypeDefs(model, options) {
1080
+ const statements = [];
1081
+ statements.push(this.generateSchemaImport(model, true, true, !!(options.lite || options.liteOnly), options.importWithFileExtension));
1082
+ statements.push(typescript.factory.createImportDeclaration(void 0, typescript.factory.createImportClause(true, void 0, typescript.factory.createNamedImports([typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier(`ModelResult as $ModelResult`)), ...model.declarations.some(_zenstackhq_language_ast.isTypeDef) ? [typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier(`TypeDefResult as $TypeDefResult`))] : []])), typescript.factory.createStringLiteral("@zenstackhq/orm")));
1083
+ const dataModels = this.getAllDataModels(model);
1084
+ for (const dm of dataModels) {
1085
+ let modelType = typescript.factory.createTypeAliasDeclaration([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], dm.name, void 0, typescript.factory.createTypeReferenceNode("$ModelResult", [typescript.factory.createTypeReferenceNode("$Schema"), typescript.factory.createLiteralTypeNode(typescript.factory.createStringLiteral(dm.name))]));
1086
+ if (dm.comments.length > 0) modelType = this.generateDocs(modelType, dm);
1087
+ statements.push(modelType);
1088
+ }
1089
+ const typeDefs = this.getAllTypeDefs(model);
1090
+ for (const td of typeDefs) {
1091
+ let typeDef = typescript.factory.createTypeAliasDeclaration([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], td.name, void 0, typescript.factory.createTypeReferenceNode("$TypeDefResult", [typescript.factory.createTypeReferenceNode("$Schema"), typescript.factory.createLiteralTypeNode(typescript.factory.createStringLiteral(td.name))]));
1092
+ if (td.comments.length > 0) typeDef = this.generateDocs(typeDef, td);
1093
+ statements.push(typeDef);
1094
+ }
1095
+ const enums = model.declarations.filter(_zenstackhq_language_ast.isEnum);
1096
+ for (const e of enums) {
1097
+ let enumDecl = typescript.factory.createVariableStatement([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], typescript.factory.createVariableDeclarationList([typescript.factory.createVariableDeclaration(e.name, void 0, void 0, typescript.factory.createPropertyAccessExpression(typescript.factory.createPropertyAccessExpression(typescript.factory.createPropertyAccessExpression(typescript.factory.createIdentifier("$schema"), typescript.factory.createIdentifier("enums")), typescript.factory.createIdentifier(e.name)), typescript.factory.createIdentifier("values")))], typescript.NodeFlags.Const));
1098
+ if (e.comments.length > 0) enumDecl = this.generateDocs(enumDecl, e);
1099
+ statements.push(enumDecl);
1100
+ let typeAlias = typescript.factory.createTypeAliasDeclaration([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], e.name, void 0, typescript.factory.createIndexedAccessTypeNode(typescript.factory.createTypeQueryNode(typescript.factory.createIdentifier(e.name)), typescript.factory.createTypeOperatorNode(typescript.SyntaxKind.KeyOfKeyword, typescript.factory.createTypeQueryNode(typescript.factory.createIdentifier(e.name)))));
1101
+ if (e.comments.length > 0) typeAlias = this.generateDocs(typeAlias, e);
1102
+ statements.push(typeAlias);
1103
+ }
1104
+ this.generateBannerComments(statements);
1105
+ const outputFile = node_path.default.join(options.outDir, "models.ts");
1106
+ const sourceFile = typescript.createSourceFile(outputFile, "", typescript.ScriptTarget.ESNext, false, typescript.ScriptKind.TS);
1107
+ const result = typescript.createPrinter().printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(statements), sourceFile);
1108
+ node_fs.default.writeFileSync(outputFile, result);
1109
+ }
1110
+ generateSchemaImport(model, schemaObject, schemaType, useLite, importWithFileExtension) {
1111
+ const importSpecifiers = [];
1112
+ if (schemaObject) {
1113
+ if (model.declarations.some(_zenstackhq_language_ast.isEnum)) importSpecifiers.push(typescript.factory.createImportSpecifier(false, typescript.factory.createIdentifier("schema"), typescript.factory.createIdentifier("$schema")));
1114
+ }
1115
+ if (schemaType) importSpecifiers.push(typescript.factory.createImportSpecifier(true, typescript.factory.createIdentifier("SchemaType"), typescript.factory.createIdentifier("$Schema")));
1116
+ let importFrom = useLite ? "./schema-lite" : "./schema";
1117
+ if (importWithFileExtension) importFrom += importWithFileExtension.startsWith(".") ? importWithFileExtension : `.${importWithFileExtension}`;
1118
+ return typescript.factory.createImportDeclaration(void 0, typescript.factory.createImportClause(false, void 0, typescript.factory.createNamedImports(importSpecifiers)), typescript.factory.createStringLiteral(importFrom));
1119
+ }
1120
+ generateDocs(tsDecl, decl) {
1121
+ return typescript.addSyntheticLeadingComment(tsDecl, typescript.SyntaxKind.MultiLineCommentTrivia, `*\n * ${decl.comments.map((c) => c.replace(/^\s*\/*\s*/, "")).join("\n * ")}\n `, true);
1122
+ }
1123
+ generateInputTypes(model, options) {
1124
+ const dataModels = this.getAllDataModels(model);
1125
+ const statements = [];
1126
+ statements.push(this.generateSchemaImport(model, false, true, !!(options.lite || options.liteOnly), options.importWithFileExtension));
1127
+ const inputTypes = [
1128
+ "FindManyArgs",
1129
+ "FindUniqueArgs",
1130
+ "FindFirstArgs",
1131
+ "ExistsArgs",
1132
+ "CreateArgs",
1133
+ "CreateManyArgs",
1134
+ "CreateManyAndReturnArgs",
1135
+ "UpdateArgs",
1136
+ "UpdateManyArgs",
1137
+ "UpdateManyAndReturnArgs",
1138
+ "UpsertArgs",
1139
+ "DeleteArgs",
1140
+ "DeleteManyArgs",
1141
+ "CountArgs",
1142
+ "AggregateArgs",
1143
+ "GroupByArgs",
1144
+ "WhereInput",
1145
+ "SelectInput",
1146
+ "IncludeInput",
1147
+ "OmitInput"
1148
+ ];
1149
+ const inputTypeNameFixes = {
1150
+ SelectInput: "Select",
1151
+ IncludeInput: "Include",
1152
+ OmitInput: "Omit"
1153
+ };
1154
+ statements.push(typescript.factory.createImportDeclaration(void 0, typescript.factory.createImportClause(true, void 0, typescript.factory.createNamedImports([...inputTypes.map((inputType) => typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier(`${inputType} as $${inputType}`))), typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier("QueryOptions as $QueryOptions"))])), typescript.factory.createStringLiteral("@zenstackhq/orm")));
1155
+ statements.push(typescript.factory.createImportDeclaration(void 0, typescript.factory.createImportClause(true, void 0, typescript.factory.createNamedImports([typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier("SimplifiedPlainResult as $Result")), typescript.factory.createImportSpecifier(false, void 0, typescript.factory.createIdentifier("SelectIncludeOmit as $SelectIncludeOmit"))])), typescript.factory.createStringLiteral("@zenstackhq/orm")));
1156
+ for (const dm of dataModels) {
1157
+ for (const inputType of inputTypes) {
1158
+ const exportName = inputTypeNameFixes[inputType] ? `${dm.name}${inputTypeNameFixes[inputType]}` : `${dm.name}${inputType}`;
1159
+ statements.push(typescript.factory.createTypeAliasDeclaration([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], exportName, void 0, typescript.factory.createTypeReferenceNode(`$${inputType}`, [typescript.factory.createTypeReferenceNode("$Schema"), typescript.factory.createLiteralTypeNode(typescript.factory.createStringLiteral(dm.name))])));
1160
+ }
1161
+ statements.push(typescript.factory.createTypeAliasDeclaration([typescript.factory.createModifier(typescript.SyntaxKind.ExportKeyword)], `${dm.name}GetPayload`, [typescript.factory.createTypeParameterDeclaration(void 0, "Args", typescript.factory.createTypeReferenceNode("$SelectIncludeOmit", [
1162
+ typescript.factory.createTypeReferenceNode("$Schema"),
1163
+ typescript.factory.createLiteralTypeNode(typescript.factory.createStringLiteral(dm.name)),
1164
+ typescript.factory.createLiteralTypeNode(typescript.factory.createTrue())
1165
+ ])), typescript.factory.createTypeParameterDeclaration(void 0, "Options", typescript.factory.createTypeReferenceNode("$QueryOptions", [typescript.factory.createTypeReferenceNode("$Schema")]), typescript.factory.createTypeReferenceNode("$QueryOptions", [typescript.factory.createTypeReferenceNode("$Schema")]))], typescript.factory.createTypeReferenceNode("$Result", [
1166
+ typescript.factory.createTypeReferenceNode("$Schema"),
1167
+ typescript.factory.createLiteralTypeNode(typescript.factory.createStringLiteral(dm.name)),
1168
+ typescript.factory.createTypeReferenceNode("Args"),
1169
+ typescript.factory.createTypeReferenceNode("Options")
1170
+ ])));
1171
+ }
1172
+ this.generateBannerComments(statements);
1173
+ const outputFile = node_path.default.join(options.outDir, "input.ts");
1174
+ const sourceFile = typescript.createSourceFile(outputFile, "", typescript.ScriptTarget.ESNext, false, typescript.ScriptKind.TS);
1175
+ const result = typescript.createPrinter().printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(statements), sourceFile);
1176
+ node_fs.default.writeFileSync(outputFile, result);
1177
+ }
1757
1178
  };
1758
- // Annotate the CommonJS export names for ESM import in node:
1759
- 0 && (module.exports = {
1760
- ModelUtils,
1761
- PrismaSchemaGenerator,
1762
- TsSchemaGenerator
1179
+ //#endregion
1180
+ Object.defineProperty(exports, "ModelUtils", {
1181
+ enumerable: true,
1182
+ get: function() {
1183
+ return model_utils_exports;
1184
+ }
1763
1185
  });
1186
+ exports.PrismaSchemaGenerator = PrismaSchemaGenerator;
1187
+ exports.TsSchemaGenerator = TsSchemaGenerator;
1188
+
1764
1189
  //# sourceMappingURL=index.cjs.map