@zenstackhq/better-auth 3.5.6 → 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,721 +1,554 @@
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 });
12
- };
13
9
  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;
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
20
18
  };
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
- zenstackAdapter: () => zenstackAdapter
35
- });
36
- module.exports = __toCommonJS(src_exports);
37
-
38
- // src/adapter.ts
39
- var import_error = require("@better-auth/core/error");
40
- var import_adapters = require("better-auth/adapters");
41
-
42
- // src/schema-generator.ts
43
- var import_common_helpers = require("@zenstackhq/common-helpers");
44
- var import_language = require("@zenstackhq/language");
45
- var import_ast = require("@zenstackhq/language/ast");
46
- var import_utils = require("@zenstackhq/language/utils");
47
- var import_node_fs = __toESM(require("fs"), 1);
48
- var import_ts_pattern = require("ts-pattern");
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _better_auth_core_error = require("@better-auth/core/error");
25
+ let better_auth_adapters = require("better-auth/adapters");
26
+ let _zenstackhq_common_helpers = require("@zenstackhq/common-helpers");
27
+ let _zenstackhq_language = require("@zenstackhq/language");
28
+ let _zenstackhq_language_ast = require("@zenstackhq/language/ast");
29
+ let _zenstackhq_language_utils = require("@zenstackhq/language/utils");
30
+ require("better-auth");
31
+ let node_fs = require("node:fs");
32
+ node_fs = __toESM(node_fs, 1);
33
+ let ts_pattern = require("ts-pattern");
34
+ //#region src/schema-generator.ts
49
35
  async function generateSchema(file, tables, config, options) {
50
- let filePath = file;
51
- if (!filePath) {
52
- if (import_node_fs.default.existsSync("./schema.zmodel")) {
53
- filePath = "./schema.zmodel";
54
- } else {
55
- filePath = "./zenstack/schema.zmodel";
56
- }
57
- }
58
- const schemaExists = import_node_fs.default.existsSync(filePath);
59
- const schema = await updateSchema(filePath, tables, config, options);
60
- return {
61
- code: schema ?? "",
62
- path: filePath,
63
- overwrite: schemaExists && !!schema
64
- };
36
+ let filePath = file;
37
+ if (!filePath) if (node_fs.default.existsSync("./schema.zmodel")) filePath = "./schema.zmodel";
38
+ else filePath = "./zenstack/schema.zmodel";
39
+ const schemaExists = node_fs.default.existsSync(filePath);
40
+ const schema = await updateSchema(filePath, tables, config, options);
41
+ return {
42
+ code: schema ?? "",
43
+ path: filePath,
44
+ overwrite: schemaExists && !!schema
45
+ };
65
46
  }
66
- __name(generateSchema, "generateSchema");
67
47
  async function updateSchema(schemaPath, tables, config, options) {
68
- let zmodel;
69
- if (import_node_fs.default.existsSync(schemaPath)) {
70
- const loadResult = await (0, import_language.loadDocument)(schemaPath);
71
- if (!loadResult.success) {
72
- throw new Error(`Failed to load existing schema at ${schemaPath}: ${loadResult.errors.join(", ")}`);
73
- }
74
- zmodel = loadResult.model;
75
- } else {
76
- zmodel = initializeZmodel(config);
77
- }
78
- const toManyRelations = /* @__PURE__ */ new Map();
79
- for (const [tableName, table] of Object.entries(tables)) {
80
- const fields = tables[tableName]?.fields;
81
- for (const field in fields) {
82
- const attr = fields[field];
83
- if (attr.references) {
84
- const referencedOriginalModel = attr.references.model;
85
- const referencedCustomModel = tables[referencedOriginalModel]?.modelName || referencedOriginalModel;
86
- const referencedModelNameCap = (0, import_common_helpers.upperCaseFirst)(referencedCustomModel);
87
- if (!toManyRelations.has(referencedModelNameCap)) {
88
- toManyRelations.set(referencedModelNameCap, /* @__PURE__ */ new Set());
89
- }
90
- const currentCustomModel = table.modelName ?? tableName;
91
- const currentModelNameCap = (0, import_common_helpers.upperCaseFirst)(currentCustomModel);
92
- toManyRelations.get(referencedModelNameCap).add(currentModelNameCap);
93
- }
94
- }
95
- }
96
- let changed = false;
97
- for (const [name, table] of Object.entries(tables)) {
98
- const c = addOrUpdateModel(name, table, zmodel, tables, toManyRelations, !!options.advanced?.database?.useNumberId);
99
- changed = changed || c;
100
- }
101
- if (!changed) {
102
- return void 0;
103
- }
104
- const generator = new import_language.ZModelCodeGenerator();
105
- let content = generator.generate(zmodel);
106
- try {
107
- content = await (0, import_language.formatDocument)(content);
108
- } catch {
109
- }
110
- return content;
48
+ let zmodel;
49
+ if (node_fs.default.existsSync(schemaPath)) {
50
+ const loadResult = await (0, _zenstackhq_language.loadDocument)(schemaPath);
51
+ if (!loadResult.success) throw new Error(`Failed to load existing schema at ${schemaPath}: ${loadResult.errors.join(", ")}`);
52
+ zmodel = loadResult.model;
53
+ } else zmodel = initializeZmodel(config);
54
+ const toManyRelations = /* @__PURE__ */ new Map();
55
+ for (const [tableName, table] of Object.entries(tables)) {
56
+ const fields = tables[tableName]?.fields;
57
+ for (const field in fields) {
58
+ const attr = fields[field];
59
+ if (attr.references) {
60
+ const referencedOriginalModel = attr.references.model;
61
+ const referencedModelNameCap = (0, _zenstackhq_common_helpers.upperCaseFirst)(tables[referencedOriginalModel]?.modelName || referencedOriginalModel);
62
+ if (!toManyRelations.has(referencedModelNameCap)) toManyRelations.set(referencedModelNameCap, /* @__PURE__ */ new Set());
63
+ const currentModelNameCap = (0, _zenstackhq_common_helpers.upperCaseFirst)(table.modelName ?? tableName);
64
+ toManyRelations.get(referencedModelNameCap).add(currentModelNameCap);
65
+ }
66
+ }
67
+ }
68
+ let changed = false;
69
+ for (const [name, table] of Object.entries(tables)) {
70
+ const c = addOrUpdateModel(name, table, zmodel, tables, toManyRelations, !!options.advanced?.database?.useNumberId);
71
+ changed = changed || c;
72
+ }
73
+ if (!changed) return;
74
+ let content = new _zenstackhq_language.ZModelCodeGenerator().generate(zmodel);
75
+ try {
76
+ content = await (0, _zenstackhq_language.formatDocument)(content);
77
+ } catch {}
78
+ return content;
111
79
  }
112
- __name(updateSchema, "updateSchema");
113
80
  function addDefaultNow(df) {
114
- const nowArg = {
115
- $type: "AttributeArg"
116
- };
117
- const nowExpr = {
118
- $type: "InvocationExpr",
119
- function: {
120
- $refText: "now"
121
- },
122
- args: [],
123
- $container: nowArg
124
- };
125
- nowArg.value = nowExpr;
126
- addFieldAttribute(df, "@default", [
127
- nowArg
128
- ]);
81
+ const nowArg = { $type: "AttributeArg" };
82
+ nowArg.value = {
83
+ $type: "InvocationExpr",
84
+ function: { $refText: "now" },
85
+ args: [],
86
+ $container: nowArg
87
+ };
88
+ addFieldAttribute(df, "@default", [nowArg]);
129
89
  }
130
- __name(addDefaultNow, "addDefaultNow");
131
90
  function createDataModel(modelName, zmodel, numericId) {
132
- const dataModel = {
133
- $type: "DataModel",
134
- name: modelName,
135
- fields: [],
136
- attributes: [],
137
- mixins: [],
138
- comments: [],
139
- isView: false,
140
- $container: zmodel
141
- };
142
- let idField;
143
- if (numericId) {
144
- idField = addModelField(dataModel, "id", "Int", false, false);
145
- } else {
146
- idField = addModelField(dataModel, "id", "String", false, false);
147
- }
148
- addFieldAttribute(idField, "@id");
149
- return dataModel;
91
+ const dataModel = {
92
+ $type: "DataModel",
93
+ name: modelName,
94
+ fields: [],
95
+ attributes: [],
96
+ mixins: [],
97
+ comments: [],
98
+ isView: false,
99
+ $container: zmodel
100
+ };
101
+ let idField;
102
+ if (numericId) idField = addModelField(dataModel, "id", "Int", false, false);
103
+ else idField = addModelField(dataModel, "id", "String", false, false);
104
+ addFieldAttribute(idField, "@id");
105
+ return dataModel;
150
106
  }
151
- __name(createDataModel, "createDataModel");
152
107
  function addModelField(dataModel, fieldName, fieldType, array, optional) {
153
- const field = {
154
- $type: "DataField",
155
- name: fieldName,
156
- attributes: [],
157
- comments: [],
158
- $container: dataModel
159
- };
160
- field.type = {
161
- $type: "DataFieldType",
162
- type: fieldType,
163
- array,
164
- optional,
165
- $container: field
166
- };
167
- dataModel.fields.push(field);
168
- return field;
108
+ const field = {
109
+ $type: "DataField",
110
+ name: fieldName,
111
+ attributes: [],
112
+ comments: [],
113
+ $container: dataModel
114
+ };
115
+ field.type = {
116
+ $type: "DataFieldType",
117
+ type: fieldType,
118
+ array,
119
+ optional,
120
+ $container: field
121
+ };
122
+ dataModel.fields.push(field);
123
+ return field;
169
124
  }
170
- __name(addModelField, "addModelField");
171
125
  function initializeZmodel(config) {
172
- const zmodel = {
173
- $type: "Model",
174
- declarations: [],
175
- imports: []
176
- };
177
- const ds = {
178
- $type: "DataSource",
179
- name: "db",
180
- fields: [],
181
- $container: zmodel
182
- };
183
- zmodel.declarations.push(ds);
184
- const providerField = {
185
- $type: "ConfigField",
186
- name: "provider",
187
- $container: ds
188
- };
189
- providerField.value = {
190
- $type: "StringLiteral",
191
- value: config.provider,
192
- $container: providerField
193
- };
194
- const urlField = {
195
- $type: "ConfigField",
196
- name: "url",
197
- $container: ds
198
- };
199
- const envCall = {
200
- $type: "InvocationExpr",
201
- function: {
202
- $refText: "env"
203
- },
204
- args: [],
205
- $container: urlField
206
- };
207
- const dbUrlArg = {
208
- $type: "Argument"
209
- };
210
- dbUrlArg.value = {
211
- $type: "StringLiteral",
212
- value: "DATABASE_URL",
213
- $container: dbUrlArg
214
- };
215
- envCall.args = [
216
- dbUrlArg
217
- ];
218
- urlField.value = config.provider === "sqlite" ? {
219
- $type: "StringLiteral",
220
- value: "file:./dev.db",
221
- $container: urlField
222
- } : envCall;
223
- ds.fields.push(providerField);
224
- ds.fields.push(urlField);
225
- return zmodel;
126
+ const zmodel = {
127
+ $type: "Model",
128
+ declarations: [],
129
+ imports: []
130
+ };
131
+ const ds = {
132
+ $type: "DataSource",
133
+ name: "db",
134
+ fields: [],
135
+ $container: zmodel
136
+ };
137
+ zmodel.declarations.push(ds);
138
+ const providerField = {
139
+ $type: "ConfigField",
140
+ name: "provider",
141
+ $container: ds
142
+ };
143
+ providerField.value = {
144
+ $type: "StringLiteral",
145
+ value: config.provider,
146
+ $container: providerField
147
+ };
148
+ const urlField = {
149
+ $type: "ConfigField",
150
+ name: "url",
151
+ $container: ds
152
+ };
153
+ const envCall = {
154
+ $type: "InvocationExpr",
155
+ function: { $refText: "env" },
156
+ args: [],
157
+ $container: urlField
158
+ };
159
+ const dbUrlArg = { $type: "Argument" };
160
+ dbUrlArg.value = {
161
+ $type: "StringLiteral",
162
+ value: "DATABASE_URL",
163
+ $container: dbUrlArg
164
+ };
165
+ envCall.args = [dbUrlArg];
166
+ urlField.value = config.provider === "sqlite" ? {
167
+ $type: "StringLiteral",
168
+ value: "file:./dev.db",
169
+ $container: urlField
170
+ } : envCall;
171
+ ds.fields.push(providerField);
172
+ ds.fields.push(urlField);
173
+ return zmodel;
226
174
  }
227
- __name(initializeZmodel, "initializeZmodel");
228
175
  function getMappedFieldType({ bigint, type }) {
229
- return (0, import_ts_pattern.match)(type).with("string", () => ({
230
- type: "String"
231
- })).with("number", () => bigint ? {
232
- type: "BigInt"
233
- } : {
234
- type: "Int"
235
- }).with("boolean", () => ({
236
- type: "Boolean"
237
- })).with("date", () => ({
238
- type: "DateTime"
239
- })).with("json", () => ({
240
- type: "Json"
241
- })).with("string[]", () => ({
242
- type: "String",
243
- array: true
244
- })).with("number[]", () => ({
245
- type: "Int",
246
- array: true
247
- })).when((v) => Array.isArray(v) && v.every((e) => typeof e === "string"), () => {
248
- return {
249
- type: "String"
250
- };
251
- }).otherwise(() => {
252
- throw new Error(`Unsupported field type: ${type}`);
253
- });
176
+ return (0, ts_pattern.match)(type).with("string", () => ({ type: "String" })).with("number", () => bigint ? { type: "BigInt" } : { type: "Int" }).with("boolean", () => ({ type: "Boolean" })).with("date", () => ({ type: "DateTime" })).with("json", () => ({ type: "Json" })).with("string[]", () => ({
177
+ type: "String",
178
+ array: true
179
+ })).with("number[]", () => ({
180
+ type: "Int",
181
+ array: true
182
+ })).when((v) => Array.isArray(v) && v.every((e) => typeof e === "string"), () => {
183
+ return { type: "String" };
184
+ }).otherwise(() => {
185
+ throw new Error(`Unsupported field type: ${type}`);
186
+ });
254
187
  }
255
- __name(getMappedFieldType, "getMappedFieldType");
256
188
  function addOrUpdateModel(tableName, table, zmodel, tables, toManyRelations, numericId) {
257
- let changed = false;
258
- const customModelName = tables[tableName]?.modelName ?? tableName;
259
- const modelName = (0, import_common_helpers.upperCaseFirst)(customModelName);
260
- let dataModel = zmodel.declarations.find((d) => (0, import_ast.isDataModel)(d) && d.name === modelName);
261
- if (!dataModel) {
262
- changed = true;
263
- dataModel = createDataModel(modelName, zmodel, numericId);
264
- zmodel.declarations.push(dataModel);
265
- }
266
- if (modelName !== tableName && !(0, import_utils.hasAttribute)(dataModel, "@@map")) {
267
- addModelAttribute(dataModel, "@@map", [
268
- createStringAttributeArg(tableName)
269
- ]);
270
- }
271
- for (const [fName, field] of Object.entries(table.fields)) {
272
- const fieldName = field.fieldName ?? fName;
273
- if (dataModel.fields.some((f) => f.name === fieldName)) {
274
- continue;
275
- }
276
- changed = true;
277
- if (!field.references) {
278
- const { array, type } = getMappedFieldType(field);
279
- const df = {
280
- $type: "DataField",
281
- name: fieldName,
282
- attributes: [],
283
- comments: [],
284
- $container: dataModel
285
- };
286
- df.type = {
287
- $type: "DataFieldType",
288
- type,
289
- array: !!array,
290
- optional: !field.required,
291
- $container: df
292
- };
293
- dataModel.fields.push(df);
294
- if (fieldName === "id") {
295
- addFieldAttribute(df, "@id");
296
- }
297
- if (field.unique) {
298
- addFieldAttribute(df, "@unique");
299
- }
300
- if (field.defaultValue !== void 0) {
301
- if (fieldName === "createdAt") {
302
- addDefaultNow(df);
303
- } else if (typeof field.defaultValue === "boolean") {
304
- addFieldAttribute(df, "@default", [
305
- createBooleanAttributeArg(field.defaultValue)
306
- ]);
307
- } else if (typeof field.defaultValue === "string") {
308
- addFieldAttribute(df, "@default", [
309
- createStringAttributeArg(field.defaultValue)
310
- ]);
311
- } else if (typeof field.defaultValue === "number") {
312
- addFieldAttribute(df, "@default", [
313
- createNumberAttributeArg(field.defaultValue)
314
- ]);
315
- } else if (typeof field.defaultValue === "function") {
316
- const defaultVal = field.defaultValue();
317
- if (defaultVal instanceof Date) {
318
- addDefaultNow(df);
319
- } else {
320
- console.warn(`Warning: Unsupported default function for field ${fieldName} in model ${table.modelName}. Please adjust manually.`);
321
- }
322
- }
323
- }
324
- if (fieldName === "updatedAt" && field.onUpdate) {
325
- addFieldAttribute(df, "@updatedAt");
326
- } else if (field.onUpdate) {
327
- console.warn(`Warning: 'onUpdate' is only supported on 'updatedAt' fields. Please adjust manually for field ${fieldName} in model ${table.modelName}.`);
328
- }
329
- } else {
330
- addModelField(dataModel, fieldName, numericId ? "Int" : "String", false, !field.required);
331
- const referencedOriginalModelName = field.references.model;
332
- const referencedCustomModelName = tables[referencedOriginalModelName]?.modelName || referencedOriginalModelName;
333
- const relationField = {
334
- $type: "DataField",
335
- name: (0, import_common_helpers.lowerCaseFirst)(referencedCustomModelName),
336
- attributes: [],
337
- comments: [],
338
- $container: dataModel
339
- };
340
- relationField.type = {
341
- $type: "DataFieldType",
342
- reference: {
343
- $refText: (0, import_common_helpers.upperCaseFirst)(referencedCustomModelName)
344
- },
345
- array: field.type.endsWith("[]"),
346
- optional: !field.required,
347
- $container: relationField
348
- };
349
- let action = "Cascade";
350
- if (field.references.onDelete === "no action") action = "NoAction";
351
- else if (field.references.onDelete === "set null") action = "SetNull";
352
- else if (field.references.onDelete === "set default") action = "SetDefault";
353
- else if (field.references.onDelete === "restrict") action = "Restrict";
354
- const relationAttr = {
355
- $type: "DataFieldAttribute",
356
- decl: {
357
- $refText: "@relation"
358
- },
359
- args: [],
360
- $container: relationField
361
- };
362
- const fieldsArg = {
363
- $type: "AttributeArg",
364
- name: "fields",
365
- $container: relationAttr
366
- };
367
- const fieldsExpr = {
368
- $type: "ArrayExpr",
369
- items: [],
370
- $container: fieldsArg
371
- };
372
- const fkRefExpr = {
373
- $type: "ReferenceExpr",
374
- args: [],
375
- $container: fieldsExpr,
376
- target: {
377
- $refText: fieldName
378
- }
379
- };
380
- fieldsExpr.items.push(fkRefExpr);
381
- fieldsArg.value = fieldsExpr;
382
- const referencesArg = {
383
- $type: "AttributeArg",
384
- name: "references",
385
- $container: relationAttr
386
- };
387
- const referencesExpr = {
388
- $type: "ArrayExpr",
389
- items: [],
390
- $container: referencesArg
391
- };
392
- const pkRefExpr = {
393
- $type: "ReferenceExpr",
394
- args: [],
395
- $container: referencesExpr,
396
- target: {
397
- $refText: field.references.field
398
- }
399
- };
400
- referencesExpr.items.push(pkRefExpr);
401
- referencesArg.value = referencesExpr;
402
- const onDeleteArg = {
403
- $type: "AttributeArg",
404
- name: "onDelete",
405
- $container: relationAttr
406
- };
407
- const onDeleteValueExpr = {
408
- $type: "ReferenceExpr",
409
- target: {
410
- $refText: action
411
- },
412
- args: [],
413
- $container: onDeleteArg
414
- };
415
- onDeleteArg.value = onDeleteValueExpr;
416
- relationAttr.args.push(...[
417
- fieldsArg,
418
- referencesArg,
419
- onDeleteArg
420
- ]);
421
- relationField.attributes.push(relationAttr);
422
- dataModel.fields.push(relationField);
423
- }
424
- }
425
- if (toManyRelations.has(modelName)) {
426
- const relations = toManyRelations.get(modelName);
427
- for (const relatedModel of relations) {
428
- const relationName = `${(0, import_common_helpers.lowerCaseFirst)(relatedModel)}s`;
429
- if (!dataModel.fields.some((f) => f.name === relationName)) {
430
- const relationField = {
431
- $type: "DataField",
432
- name: relationName,
433
- attributes: [],
434
- comments: [],
435
- $container: dataModel
436
- };
437
- const relationType = {
438
- $type: "DataFieldType",
439
- reference: {
440
- $refText: relatedModel
441
- },
442
- array: true,
443
- optional: false,
444
- $container: relationField
445
- };
446
- relationField.type = relationType;
447
- dataModel.fields.push(relationField);
448
- }
449
- }
450
- }
451
- return changed;
189
+ let changed = false;
190
+ const modelName = (0, _zenstackhq_common_helpers.upperCaseFirst)(tables[tableName]?.modelName ?? tableName);
191
+ let dataModel = zmodel.declarations.find((d) => (0, _zenstackhq_language_ast.isDataModel)(d) && d.name === modelName);
192
+ if (!dataModel) {
193
+ changed = true;
194
+ dataModel = createDataModel(modelName, zmodel, numericId);
195
+ zmodel.declarations.push(dataModel);
196
+ }
197
+ if (modelName !== tableName && !(0, _zenstackhq_language_utils.hasAttribute)(dataModel, "@@map")) addModelAttribute(dataModel, "@@map", [createStringAttributeArg(tableName)]);
198
+ for (const [fName, field] of Object.entries(table.fields)) {
199
+ const fieldName = field.fieldName ?? fName;
200
+ if (dataModel.fields.some((f) => f.name === fieldName)) continue;
201
+ changed = true;
202
+ if (!field.references) {
203
+ const { array, type } = getMappedFieldType(field);
204
+ const df = {
205
+ $type: "DataField",
206
+ name: fieldName,
207
+ attributes: [],
208
+ comments: [],
209
+ $container: dataModel
210
+ };
211
+ df.type = {
212
+ $type: "DataFieldType",
213
+ type,
214
+ array: !!array,
215
+ optional: !field.required,
216
+ $container: df
217
+ };
218
+ dataModel.fields.push(df);
219
+ if (fieldName === "id") addFieldAttribute(df, "@id");
220
+ if (field.unique) addFieldAttribute(df, "@unique");
221
+ if (field.defaultValue !== void 0) {
222
+ if (fieldName === "createdAt") addDefaultNow(df);
223
+ else if (typeof field.defaultValue === "boolean") addFieldAttribute(df, "@default", [createBooleanAttributeArg(field.defaultValue)]);
224
+ else if (typeof field.defaultValue === "string") addFieldAttribute(df, "@default", [createStringAttributeArg(field.defaultValue)]);
225
+ else if (typeof field.defaultValue === "number") addFieldAttribute(df, "@default", [createNumberAttributeArg(field.defaultValue)]);
226
+ else if (typeof field.defaultValue === "function") if (field.defaultValue() instanceof Date) addDefaultNow(df);
227
+ else console.warn(`Warning: Unsupported default function for field ${fieldName} in model ${table.modelName}. Please adjust manually.`);
228
+ }
229
+ if (fieldName === "updatedAt" && field.onUpdate) addFieldAttribute(df, "@updatedAt");
230
+ else if (field.onUpdate) console.warn(`Warning: 'onUpdate' is only supported on 'updatedAt' fields. Please adjust manually for field ${fieldName} in model ${table.modelName}.`);
231
+ } else {
232
+ addModelField(dataModel, fieldName, numericId ? "Int" : "String", false, !field.required);
233
+ const referencedOriginalModelName = field.references.model;
234
+ const referencedCustomModelName = tables[referencedOriginalModelName]?.modelName || referencedOriginalModelName;
235
+ const relationField = {
236
+ $type: "DataField",
237
+ name: (0, _zenstackhq_common_helpers.lowerCaseFirst)(referencedCustomModelName),
238
+ attributes: [],
239
+ comments: [],
240
+ $container: dataModel
241
+ };
242
+ relationField.type = {
243
+ $type: "DataFieldType",
244
+ reference: { $refText: (0, _zenstackhq_common_helpers.upperCaseFirst)(referencedCustomModelName) },
245
+ array: field.type.endsWith("[]"),
246
+ optional: !field.required,
247
+ $container: relationField
248
+ };
249
+ let action = "Cascade";
250
+ if (field.references.onDelete === "no action") action = "NoAction";
251
+ else if (field.references.onDelete === "set null") action = "SetNull";
252
+ else if (field.references.onDelete === "set default") action = "SetDefault";
253
+ else if (field.references.onDelete === "restrict") action = "Restrict";
254
+ const relationAttr = {
255
+ $type: "DataFieldAttribute",
256
+ decl: { $refText: "@relation" },
257
+ args: [],
258
+ $container: relationField
259
+ };
260
+ const fieldsArg = {
261
+ $type: "AttributeArg",
262
+ name: "fields",
263
+ $container: relationAttr
264
+ };
265
+ const fieldsExpr = {
266
+ $type: "ArrayExpr",
267
+ items: [],
268
+ $container: fieldsArg
269
+ };
270
+ const fkRefExpr = {
271
+ $type: "ReferenceExpr",
272
+ args: [],
273
+ $container: fieldsExpr,
274
+ target: { $refText: fieldName }
275
+ };
276
+ fieldsExpr.items.push(fkRefExpr);
277
+ fieldsArg.value = fieldsExpr;
278
+ const referencesArg = {
279
+ $type: "AttributeArg",
280
+ name: "references",
281
+ $container: relationAttr
282
+ };
283
+ const referencesExpr = {
284
+ $type: "ArrayExpr",
285
+ items: [],
286
+ $container: referencesArg
287
+ };
288
+ const pkRefExpr = {
289
+ $type: "ReferenceExpr",
290
+ args: [],
291
+ $container: referencesExpr,
292
+ target: { $refText: field.references.field }
293
+ };
294
+ referencesExpr.items.push(pkRefExpr);
295
+ referencesArg.value = referencesExpr;
296
+ const onDeleteArg = {
297
+ $type: "AttributeArg",
298
+ name: "onDelete",
299
+ $container: relationAttr
300
+ };
301
+ onDeleteArg.value = {
302
+ $type: "ReferenceExpr",
303
+ target: { $refText: action },
304
+ args: [],
305
+ $container: onDeleteArg
306
+ };
307
+ relationAttr.args.push(...[
308
+ fieldsArg,
309
+ referencesArg,
310
+ onDeleteArg
311
+ ]);
312
+ relationField.attributes.push(relationAttr);
313
+ dataModel.fields.push(relationField);
314
+ }
315
+ }
316
+ if (toManyRelations.has(modelName)) {
317
+ const relations = toManyRelations.get(modelName);
318
+ for (const relatedModel of relations) {
319
+ const relationName = `${(0, _zenstackhq_common_helpers.lowerCaseFirst)(relatedModel)}s`;
320
+ if (!dataModel.fields.some((f) => f.name === relationName)) {
321
+ const relationField = {
322
+ $type: "DataField",
323
+ name: relationName,
324
+ attributes: [],
325
+ comments: [],
326
+ $container: dataModel
327
+ };
328
+ relationField.type = {
329
+ $type: "DataFieldType",
330
+ reference: { $refText: relatedModel },
331
+ array: true,
332
+ optional: false,
333
+ $container: relationField
334
+ };
335
+ dataModel.fields.push(relationField);
336
+ }
337
+ }
338
+ }
339
+ return changed;
452
340
  }
453
- __name(addOrUpdateModel, "addOrUpdateModel");
454
341
  function addModelAttribute(dataModel, name, args = []) {
455
- const attr = {
456
- $type: "DataModelAttribute",
457
- decl: {
458
- $refText: name
459
- },
460
- $container: dataModel,
461
- args: []
462
- };
463
- const finalArgs = args.map((arg) => ({
464
- ...arg,
465
- $container: attr
466
- }));
467
- attr.args.push(...finalArgs);
468
- dataModel.attributes.push(attr);
342
+ const attr = {
343
+ $type: "DataModelAttribute",
344
+ decl: { $refText: name },
345
+ $container: dataModel,
346
+ args: []
347
+ };
348
+ const finalArgs = args.map((arg) => ({
349
+ ...arg,
350
+ $container: attr
351
+ }));
352
+ attr.args.push(...finalArgs);
353
+ dataModel.attributes.push(attr);
469
354
  }
470
- __name(addModelAttribute, "addModelAttribute");
471
355
  function addFieldAttribute(dataField, name, args = []) {
472
- const attr = {
473
- $type: "DataFieldAttribute",
474
- decl: {
475
- $refText: name
476
- },
477
- $container: dataField,
478
- args: []
479
- };
480
- const finalArgs = args.map((arg) => ({
481
- ...arg,
482
- $container: attr
483
- }));
484
- attr.args.push(...finalArgs);
485
- dataField.attributes.push(attr);
356
+ const attr = {
357
+ $type: "DataFieldAttribute",
358
+ decl: { $refText: name },
359
+ $container: dataField,
360
+ args: []
361
+ };
362
+ const finalArgs = args.map((arg) => ({
363
+ ...arg,
364
+ $container: attr
365
+ }));
366
+ attr.args.push(...finalArgs);
367
+ dataField.attributes.push(attr);
486
368
  }
487
- __name(addFieldAttribute, "addFieldAttribute");
488
369
  function createBooleanAttributeArg(value) {
489
- const arg = {
490
- $type: "AttributeArg"
491
- };
492
- const expr = {
493
- $type: "BooleanLiteral",
494
- value,
495
- $container: arg
496
- };
497
- arg.value = expr;
498
- return arg;
370
+ const arg = { $type: "AttributeArg" };
371
+ arg.value = {
372
+ $type: "BooleanLiteral",
373
+ value,
374
+ $container: arg
375
+ };
376
+ return arg;
499
377
  }
500
- __name(createBooleanAttributeArg, "createBooleanAttributeArg");
501
378
  function createNumberAttributeArg(value) {
502
- const arg = {
503
- $type: "AttributeArg"
504
- };
505
- const expr = {
506
- $type: "NumberLiteral",
507
- value: value.toString(),
508
- $container: arg
509
- };
510
- arg.value = expr;
511
- return arg;
379
+ const arg = { $type: "AttributeArg" };
380
+ arg.value = {
381
+ $type: "NumberLiteral",
382
+ value: value.toString(),
383
+ $container: arg
384
+ };
385
+ return arg;
512
386
  }
513
- __name(createNumberAttributeArg, "createNumberAttributeArg");
514
387
  function createStringAttributeArg(value) {
515
- const arg = {
516
- $type: "AttributeArg"
517
- };
518
- const expr = {
519
- $type: "StringLiteral",
520
- value,
521
- $container: arg
522
- };
523
- arg.value = expr;
524
- return arg;
388
+ const arg = { $type: "AttributeArg" };
389
+ arg.value = {
390
+ $type: "StringLiteral",
391
+ value,
392
+ $container: arg
393
+ };
394
+ return arg;
525
395
  }
526
- __name(createStringAttributeArg, "createStringAttributeArg");
396
+ //#endregion
397
+ //#region src/adapter.ts
398
+ /**
399
+ * Create a Better-Auth adapter for ZenStack ORM.
400
+ * @param db ZenStack ORM client instance
401
+ * @param config adapter configuration options
402
+ */
403
+ const zenstackAdapter = (db, config) => {
404
+ let lazyOptions = null;
405
+ const createCustomAdapter = (db) => ({ getFieldName, options }) => {
406
+ const convertSelect = (select, model) => {
407
+ if (!select || !model) return void 0;
408
+ return select.reduce((prev, cur) => {
409
+ return {
410
+ ...prev,
411
+ [getFieldName({
412
+ model,
413
+ field: cur
414
+ })]: true
415
+ };
416
+ }, {});
417
+ };
418
+ function operatorToORMOperator(operator) {
419
+ switch (operator) {
420
+ case "starts_with": return "startsWith";
421
+ case "ends_with": return "endsWith";
422
+ case "ne": return "not";
423
+ case "not_in": return "notIn";
424
+ default: return operator;
425
+ }
426
+ }
427
+ const convertWhereClause = (model, where) => {
428
+ if (!where || !where.length) return {};
429
+ if (where.length === 1) {
430
+ const w = where[0];
431
+ if (!w) throw new _better_auth_core_error.BetterAuthError("Invalid where clause");
432
+ return { [getFieldName({
433
+ model,
434
+ field: w.field
435
+ })]: w.operator === "eq" || !w.operator ? w.value : { [operatorToORMOperator(w.operator)]: w.value } };
436
+ }
437
+ const and = where.filter((w) => w.connector === "AND" || !w.connector);
438
+ const or = where.filter((w) => w.connector === "OR");
439
+ const andClause = and.map((w) => {
440
+ return { [getFieldName({
441
+ model,
442
+ field: w.field
443
+ })]: w.operator === "eq" || !w.operator ? w.value : { [operatorToORMOperator(w.operator)]: w.value } };
444
+ });
445
+ const orClause = or.map((w) => {
446
+ return { [getFieldName({
447
+ model,
448
+ field: w.field
449
+ })]: w.operator === "eq" || !w.operator ? w.value : { [operatorToORMOperator(w.operator)]: w.value } };
450
+ });
451
+ return {
452
+ ...andClause.length ? { AND: andClause } : {},
453
+ ...orClause.length ? { OR: orClause } : {}
454
+ };
455
+ };
456
+ function requireModelDb(db, model) {
457
+ const modelDb = db[model];
458
+ if (!modelDb) throw new _better_auth_core_error.BetterAuthError(`Model ${model} does not exist in the database. If you haven't generated the ZenStack schema, you need to run 'npx zen generate'`);
459
+ return modelDb;
460
+ }
461
+ return {
462
+ async create({ model, data: values, select }) {
463
+ return await requireModelDb(db, model).create({
464
+ data: values,
465
+ select: convertSelect(select, model)
466
+ });
467
+ },
468
+ async findOne({ model, where, select }) {
469
+ const modelDb = requireModelDb(db, model);
470
+ const whereClause = convertWhereClause(model, where);
471
+ return await modelDb.findFirst({
472
+ where: whereClause,
473
+ select: convertSelect(select, model)
474
+ });
475
+ },
476
+ async findMany({ model, where, limit, offset, sortBy }) {
477
+ const modelDb = requireModelDb(db, model);
478
+ const whereClause = convertWhereClause(model, where);
479
+ return await modelDb.findMany({
480
+ where: whereClause,
481
+ take: limit || 100,
482
+ skip: offset || 0,
483
+ ...sortBy?.field ? { orderBy: { [getFieldName({
484
+ model,
485
+ field: sortBy.field
486
+ })]: sortBy.direction === "desc" ? "desc" : "asc" } } : {}
487
+ });
488
+ },
489
+ async count({ model, where }) {
490
+ const modelDb = requireModelDb(db, model);
491
+ const whereClause = convertWhereClause(model, where);
492
+ return await modelDb.count({ where: whereClause });
493
+ },
494
+ async update({ model, where, update }) {
495
+ const modelDb = requireModelDb(db, model);
496
+ const whereClause = convertWhereClause(model, where);
497
+ return await modelDb.update({
498
+ where: whereClause,
499
+ data: update
500
+ });
501
+ },
502
+ async updateMany({ model, where, update }) {
503
+ const modelDb = requireModelDb(db, model);
504
+ const whereClause = convertWhereClause(model, where);
505
+ const result = await modelDb.updateMany({
506
+ where: whereClause,
507
+ data: update
508
+ });
509
+ return result ? result.count : 0;
510
+ },
511
+ async delete({ model, where }) {
512
+ const modelDb = requireModelDb(db, model);
513
+ const whereClause = convertWhereClause(model, where);
514
+ try {
515
+ await modelDb.delete({ where: whereClause });
516
+ } catch {}
517
+ },
518
+ async deleteMany({ model, where }) {
519
+ const modelDb = requireModelDb(db, model);
520
+ const whereClause = convertWhereClause(model, where);
521
+ const result = await modelDb.deleteMany({ where: whereClause });
522
+ return result ? result.count : 0;
523
+ },
524
+ options: config,
525
+ createSchema: async ({ file, tables }) => {
526
+ return generateSchema(file, tables, config, options);
527
+ }
528
+ };
529
+ };
530
+ const adapterOptions = {
531
+ config: {
532
+ adapterId: "zenstack",
533
+ adapterName: "ZenStack Adapter",
534
+ usePlural: config.usePlural ?? false,
535
+ debugLogs: config.debugLogs ?? false,
536
+ transaction: (cb) => db.$transaction((tx) => {
537
+ return cb((0, better_auth_adapters.createAdapterFactory)({
538
+ config: adapterOptions.config,
539
+ adapter: createCustomAdapter(tx)
540
+ })(lazyOptions));
541
+ })
542
+ },
543
+ adapter: createCustomAdapter(db)
544
+ };
545
+ const adapter = (0, better_auth_adapters.createAdapterFactory)(adapterOptions);
546
+ return (options) => {
547
+ lazyOptions = options;
548
+ return adapter(options);
549
+ };
550
+ };
551
+ //#endregion
552
+ exports.zenstackAdapter = zenstackAdapter;
527
553
 
528
- // src/adapter.ts
529
- var zenstackAdapter = /* @__PURE__ */ __name((db, config) => {
530
- let lazyOptions = null;
531
- const createCustomAdapter = /* @__PURE__ */ __name((db2) => ({ getFieldName, options }) => {
532
- const convertSelect = /* @__PURE__ */ __name((select, model) => {
533
- if (!select || !model) return void 0;
534
- return select.reduce((prev, cur) => {
535
- return {
536
- ...prev,
537
- [getFieldName({
538
- model,
539
- field: cur
540
- })]: true
541
- };
542
- }, {});
543
- }, "convertSelect");
544
- function operatorToORMOperator(operator) {
545
- switch (operator) {
546
- case "starts_with":
547
- return "startsWith";
548
- case "ends_with":
549
- return "endsWith";
550
- case "ne":
551
- return "not";
552
- case "not_in":
553
- return "notIn";
554
- default:
555
- return operator;
556
- }
557
- }
558
- __name(operatorToORMOperator, "operatorToORMOperator");
559
- const convertWhereClause = /* @__PURE__ */ __name((model, where) => {
560
- if (!where || !where.length) return {};
561
- if (where.length === 1) {
562
- const w = where[0];
563
- if (!w) {
564
- throw new import_error.BetterAuthError("Invalid where clause");
565
- }
566
- return {
567
- [getFieldName({
568
- model,
569
- field: w.field
570
- })]: w.operator === "eq" || !w.operator ? w.value : {
571
- [operatorToORMOperator(w.operator)]: w.value
572
- }
573
- };
574
- }
575
- const and = where.filter((w) => w.connector === "AND" || !w.connector);
576
- const or = where.filter((w) => w.connector === "OR");
577
- const andClause = and.map((w) => {
578
- return {
579
- [getFieldName({
580
- model,
581
- field: w.field
582
- })]: w.operator === "eq" || !w.operator ? w.value : {
583
- [operatorToORMOperator(w.operator)]: w.value
584
- }
585
- };
586
- });
587
- const orClause = or.map((w) => {
588
- return {
589
- [getFieldName({
590
- model,
591
- field: w.field
592
- })]: w.operator === "eq" || !w.operator ? w.value : {
593
- [operatorToORMOperator(w.operator)]: w.value
594
- }
595
- };
596
- });
597
- return {
598
- ...andClause.length ? {
599
- AND: andClause
600
- } : {},
601
- ...orClause.length ? {
602
- OR: orClause
603
- } : {}
604
- };
605
- }, "convertWhereClause");
606
- function requireModelDb(db3, model) {
607
- const modelDb = db3[model];
608
- if (!modelDb) {
609
- throw new import_error.BetterAuthError(`Model ${model} does not exist in the database. If you haven't generated the ZenStack schema, you need to run 'npx zen generate'`);
610
- }
611
- return modelDb;
612
- }
613
- __name(requireModelDb, "requireModelDb");
614
- return {
615
- async create({ model, data: values, select }) {
616
- const modelDb = requireModelDb(db2, model);
617
- return await modelDb.create({
618
- data: values,
619
- select: convertSelect(select, model)
620
- });
621
- },
622
- async findOne({ model, where, select }) {
623
- const modelDb = requireModelDb(db2, model);
624
- const whereClause = convertWhereClause(model, where);
625
- return await modelDb.findFirst({
626
- where: whereClause,
627
- select: convertSelect(select, model)
628
- });
629
- },
630
- async findMany({ model, where, limit, offset, sortBy }) {
631
- const modelDb = requireModelDb(db2, model);
632
- const whereClause = convertWhereClause(model, where);
633
- return await modelDb.findMany({
634
- where: whereClause,
635
- take: limit || 100,
636
- skip: offset || 0,
637
- ...sortBy?.field ? {
638
- orderBy: {
639
- [getFieldName({
640
- model,
641
- field: sortBy.field
642
- })]: sortBy.direction === "desc" ? "desc" : "asc"
643
- }
644
- } : {}
645
- });
646
- },
647
- async count({ model, where }) {
648
- const modelDb = requireModelDb(db2, model);
649
- const whereClause = convertWhereClause(model, where);
650
- return await modelDb.count({
651
- where: whereClause
652
- });
653
- },
654
- async update({ model, where, update }) {
655
- const modelDb = requireModelDb(db2, model);
656
- const whereClause = convertWhereClause(model, where);
657
- return await modelDb.update({
658
- where: whereClause,
659
- data: update
660
- });
661
- },
662
- async updateMany({ model, where, update }) {
663
- const modelDb = requireModelDb(db2, model);
664
- const whereClause = convertWhereClause(model, where);
665
- const result = await modelDb.updateMany({
666
- where: whereClause,
667
- data: update
668
- });
669
- return result ? result.count : 0;
670
- },
671
- async delete({ model, where }) {
672
- const modelDb = requireModelDb(db2, model);
673
- const whereClause = convertWhereClause(model, where);
674
- try {
675
- await modelDb.delete({
676
- where: whereClause
677
- });
678
- } catch {
679
- }
680
- },
681
- async deleteMany({ model, where }) {
682
- const modelDb = requireModelDb(db2, model);
683
- const whereClause = convertWhereClause(model, where);
684
- const result = await modelDb.deleteMany({
685
- where: whereClause
686
- });
687
- return result ? result.count : 0;
688
- },
689
- options: config,
690
- createSchema: /* @__PURE__ */ __name(async ({ file, tables }) => {
691
- return generateSchema(file, tables, config, options);
692
- }, "createSchema")
693
- };
694
- }, "createCustomAdapter");
695
- const adapterOptions = {
696
- config: {
697
- adapterId: "zenstack",
698
- adapterName: "ZenStack Adapter",
699
- usePlural: config.usePlural ?? false,
700
- debugLogs: config.debugLogs ?? false,
701
- transaction: /* @__PURE__ */ __name((cb) => db.$transaction((tx) => {
702
- const adapter2 = (0, import_adapters.createAdapterFactory)({
703
- config: adapterOptions.config,
704
- adapter: createCustomAdapter(tx)
705
- })(lazyOptions);
706
- return cb(adapter2);
707
- }), "transaction")
708
- },
709
- adapter: createCustomAdapter(db)
710
- };
711
- const adapter = (0, import_adapters.createAdapterFactory)(adapterOptions);
712
- return (options) => {
713
- lazyOptions = options;
714
- return adapter(options);
715
- };
716
- }, "zenstackAdapter");
717
- // Annotate the CommonJS export names for ESM import in node:
718
- 0 && (module.exports = {
719
- zenstackAdapter
720
- });
721
554
  //# sourceMappingURL=index.cjs.map