@tailor-platform/sdk 1.11.0 → 1.12.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/application-DM4zTgXU.mjs +4 -0
  3. package/dist/{application-BKBo5tGD.mjs → application-DnWZVbDO.mjs} +164 -26
  4. package/dist/application-DnWZVbDO.mjs.map +1 -0
  5. package/dist/cli/index.mjs +13 -19
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/cli/lib.d.mts +149 -17
  8. package/dist/cli/lib.mjs +132 -4
  9. package/dist/cli/lib.mjs.map +1 -1
  10. package/dist/configure/index.d.mts +4 -3
  11. package/dist/configure/index.mjs +16 -757
  12. package/dist/configure/index.mjs.map +1 -1
  13. package/dist/env-4RO7szrH.d.mts +66 -0
  14. package/dist/{index-D8zIUsWi.d.mts → index-BBr_q3vB.d.mts} +20 -11
  15. package/dist/{index-DcOTucF6.d.mts → index-Bid18Opo.d.mts} +473 -84
  16. package/dist/{jiti-ygK9KoRA.mjs → jiti-DuCiUfMj.mjs} +2 -2
  17. package/dist/{jiti-ygK9KoRA.mjs.map → jiti-DuCiUfMj.mjs.map} +1 -1
  18. package/dist/{job-l-pIR9IY.mjs → job-zGAXCidt.mjs} +1 -1
  19. package/dist/{job-l-pIR9IY.mjs.map → job-zGAXCidt.mjs.map} +1 -1
  20. package/dist/kysely/index.d.mts +25 -0
  21. package/dist/kysely/index.mjs +27 -0
  22. package/dist/kysely/index.mjs.map +1 -0
  23. package/dist/plugin/index.d.mts +105 -0
  24. package/dist/plugin/index.mjs +45 -0
  25. package/dist/plugin/index.mjs.map +1 -0
  26. package/dist/schema-BmKdDzr1.mjs +784 -0
  27. package/dist/schema-BmKdDzr1.mjs.map +1 -0
  28. package/dist/{src-CG8kJBI9.mjs → src-QNTCsO6J.mjs} +2 -2
  29. package/dist/{src-CG8kJBI9.mjs.map → src-QNTCsO6J.mjs.map} +1 -1
  30. package/dist/types-r-ZratAg.mjs +13 -0
  31. package/dist/types-r-ZratAg.mjs.map +1 -0
  32. package/dist/{update-D0muqqOP.mjs → update-B_W-UQnS.mjs} +1626 -390
  33. package/dist/update-B_W-UQnS.mjs.map +1 -0
  34. package/dist/utils/test/index.d.mts +2 -2
  35. package/dist/utils/test/index.mjs +1 -1
  36. package/docs/cli/tailordb.md +0 -12
  37. package/docs/generator/builtin.md +2 -2
  38. package/docs/plugin/custom.md +389 -0
  39. package/docs/plugin/index.md +112 -0
  40. package/docs/services/workflow.md +28 -0
  41. package/package.json +16 -23
  42. package/dist/application-BKBo5tGD.mjs.map +0 -1
  43. package/dist/application-a12-7TT3.mjs +0 -4
  44. package/dist/update-D0muqqOP.mjs.map +0 -1
  45. /package/dist/{chunk-CIV_ash9.mjs → chunk-C3Kl5s5P.mjs} +0 -0
@@ -0,0 +1,784 @@
1
+ import { cloneDeep } from "es-toolkit";
2
+
3
+ //#region src/configure/types/field.ts
4
+ /**
5
+ * Normalize allowed values into EnumValue objects with descriptions.
6
+ * @param values - Allowed values as strings or EnumValue objects
7
+ * @returns Normalized allowed values
8
+ */
9
+ function mapAllowedValues(values) {
10
+ return values.map((value) => {
11
+ if (typeof value === "string") return {
12
+ value,
13
+ description: ""
14
+ };
15
+ return {
16
+ ...value,
17
+ description: value.description ?? ""
18
+ };
19
+ });
20
+ }
21
+
22
+ //#endregion
23
+ //#region src/configure/types/type.ts
24
+ const regex$1 = {
25
+ uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
26
+ date: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/,
27
+ time: /^(?<hour>\d{2}):(?<minute>\d{2})$/,
28
+ datetime: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(.(?<millisec>\d{3}))?Z$/
29
+ };
30
+ /**
31
+ * Creates a new TailorField instance.
32
+ * @param type - Field type
33
+ * @param options - Field options
34
+ * @param fields - Nested fields for object-like types
35
+ * @param values - Allowed values for enum-like fields
36
+ * @returns A new TailorField
37
+ */
38
+ function createTailorField(type, options, fields, values) {
39
+ const _metadata = { required: true };
40
+ if (options) {
41
+ const hasRequired = Object.prototype.hasOwnProperty.call(options, "required");
42
+ const hasOptional = Object.prototype.hasOwnProperty.call(options, "optional");
43
+ if (hasRequired) {
44
+ const isRequired = options.required === true;
45
+ _metadata.required = isRequired;
46
+ if (isRequired) _metadata.requiredExplicit = true;
47
+ } else if (hasOptional) {
48
+ _metadata.required = !(options.optional === true);
49
+ if (options.optional === false) _metadata.requiredExplicit = true;
50
+ }
51
+ if (options.array === true) _metadata.array = true;
52
+ }
53
+ if (values) _metadata.allowedValues = mapAllowedValues(values);
54
+ /**
55
+ * Validate a single value (not an array element)
56
+ * Used internally for array element validation
57
+ * @param args - Value, context data, and user
58
+ * @returns Array of validation issues
59
+ */
60
+ function validateValue(args) {
61
+ const { value, data, user, pathArray } = args;
62
+ const issues = [];
63
+ switch (type) {
64
+ case "string":
65
+ if (typeof value !== "string") issues.push({
66
+ message: `Expected a string: received ${String(value)}`,
67
+ path: pathArray.length > 0 ? pathArray : void 0
68
+ });
69
+ break;
70
+ case "integer":
71
+ if (typeof value !== "number" || !Number.isInteger(value)) issues.push({
72
+ message: `Expected an integer: received ${String(value)}`,
73
+ path: pathArray.length > 0 ? pathArray : void 0
74
+ });
75
+ break;
76
+ case "float":
77
+ if (typeof value !== "number" || !Number.isFinite(value)) issues.push({
78
+ message: `Expected a number: received ${String(value)}`,
79
+ path: pathArray.length > 0 ? pathArray : void 0
80
+ });
81
+ break;
82
+ case "boolean":
83
+ if (typeof value !== "boolean") issues.push({
84
+ message: `Expected a boolean: received ${String(value)}`,
85
+ path: pathArray.length > 0 ? pathArray : void 0
86
+ });
87
+ break;
88
+ case "uuid":
89
+ if (typeof value !== "string" || !regex$1.uuid.test(value)) issues.push({
90
+ message: `Expected a valid UUID: received ${String(value)}`,
91
+ path: pathArray.length > 0 ? pathArray : void 0
92
+ });
93
+ break;
94
+ case "date":
95
+ if (typeof value !== "string" || !regex$1.date.test(value)) issues.push({
96
+ message: `Expected to match "yyyy-MM-dd" format: received ${String(value)}`,
97
+ path: pathArray.length > 0 ? pathArray : void 0
98
+ });
99
+ break;
100
+ case "datetime":
101
+ if (typeof value !== "string" || !regex$1.datetime.test(value)) issues.push({
102
+ message: `Expected to match ISO format: received ${String(value)}`,
103
+ path: pathArray.length > 0 ? pathArray : void 0
104
+ });
105
+ break;
106
+ case "time":
107
+ if (typeof value !== "string" || !regex$1.time.test(value)) issues.push({
108
+ message: `Expected to match "HH:mm" format: received ${String(value)}`,
109
+ path: pathArray.length > 0 ? pathArray : void 0
110
+ });
111
+ break;
112
+ case "enum":
113
+ if (field._metadata.allowedValues) {
114
+ const allowedValues = field._metadata.allowedValues.map((v) => v.value);
115
+ if (typeof value !== "string" || !allowedValues.includes(value)) issues.push({
116
+ message: `Must be one of [${allowedValues.join(", ")}]: received ${String(value)}`,
117
+ path: pathArray.length > 0 ? pathArray : void 0
118
+ });
119
+ }
120
+ break;
121
+ case "nested":
122
+ if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Date) issues.push({
123
+ message: `Expected an object: received ${String(value)}`,
124
+ path: pathArray.length > 0 ? pathArray : void 0
125
+ });
126
+ else if (field.fields && Object.keys(field.fields).length > 0) for (const [fieldName, nestedField] of Object.entries(field.fields)) {
127
+ const fieldValue = value?.[fieldName];
128
+ const result = nestedField._parseInternal({
129
+ value: fieldValue,
130
+ data,
131
+ user,
132
+ pathArray: pathArray.concat(fieldName)
133
+ });
134
+ if (result.issues) issues.push(...result.issues);
135
+ }
136
+ break;
137
+ }
138
+ const validateFns = field._metadata.validate;
139
+ if (validateFns && validateFns.length > 0) for (const validateInput of validateFns) {
140
+ const { fn, message } = typeof validateInput === "function" ? {
141
+ fn: validateInput,
142
+ message: "Validation failed"
143
+ } : {
144
+ fn: validateInput[0],
145
+ message: validateInput[1]
146
+ };
147
+ if (!fn({
148
+ value,
149
+ data,
150
+ user
151
+ })) issues.push({
152
+ message,
153
+ path: pathArray.length > 0 ? pathArray : void 0
154
+ });
155
+ }
156
+ return issues;
157
+ }
158
+ /**
159
+ * Internal parse method that tracks field path for nested validation
160
+ * @param args - Parse arguments
161
+ * @returns Parse result with value or issues
162
+ */
163
+ function parseInternal(args) {
164
+ const { value, data, user, pathArray } = args;
165
+ const issues = [];
166
+ const isNullOrUndefined = value === null || value === void 0;
167
+ if (field._metadata.required && isNullOrUndefined) {
168
+ issues.push({
169
+ message: "Required field is missing",
170
+ path: pathArray.length > 0 ? pathArray : void 0
171
+ });
172
+ return { issues };
173
+ }
174
+ if (!field._metadata.required && isNullOrUndefined) return { value: value ?? null };
175
+ if (field._metadata.array) {
176
+ if (!Array.isArray(value)) {
177
+ issues.push({
178
+ message: "Expected an array",
179
+ path: pathArray.length > 0 ? pathArray : void 0
180
+ });
181
+ return { issues };
182
+ }
183
+ for (let i = 0; i < value.length; i++) {
184
+ const elementValue = value[i];
185
+ const elementIssues = validateValue({
186
+ value: elementValue,
187
+ data,
188
+ user,
189
+ pathArray: pathArray.concat(`[${i}]`)
190
+ });
191
+ if (elementIssues.length > 0) issues.push(...elementIssues);
192
+ }
193
+ if (issues.length > 0) return { issues };
194
+ return { value };
195
+ }
196
+ const valueIssues = validateValue({
197
+ value,
198
+ data,
199
+ user,
200
+ pathArray
201
+ });
202
+ issues.push(...valueIssues);
203
+ if (issues.length > 0) return { issues };
204
+ return { value };
205
+ }
206
+ const field = {
207
+ type,
208
+ fields: fields ?? {},
209
+ _defined: void 0,
210
+ _output: void 0,
211
+ _metadata,
212
+ get metadata() {
213
+ return { ...this._metadata };
214
+ },
215
+ description(description) {
216
+ this._metadata.description = description;
217
+ return this;
218
+ },
219
+ typeName(typeName) {
220
+ this._metadata.typeName = typeName;
221
+ return this;
222
+ },
223
+ validate(...validateInputs) {
224
+ this._metadata.validate = validateInputs;
225
+ return this;
226
+ },
227
+ parse(args) {
228
+ return parseInternal({
229
+ value: args.value,
230
+ data: args.data,
231
+ user: args.user,
232
+ pathArray: []
233
+ });
234
+ },
235
+ _parseInternal: parseInternal
236
+ };
237
+ return field;
238
+ }
239
+ function uuid$1(options) {
240
+ return createTailorField("uuid", options);
241
+ }
242
+ function string$1(options) {
243
+ return createTailorField("string", options);
244
+ }
245
+ function bool$1(options) {
246
+ return createTailorField("boolean", options);
247
+ }
248
+ function int$1(options) {
249
+ return createTailorField("integer", options);
250
+ }
251
+ function float$1(options) {
252
+ return createTailorField("float", options);
253
+ }
254
+ function date$1(options) {
255
+ return createTailorField("date", options);
256
+ }
257
+ function datetime$1(options) {
258
+ return createTailorField("datetime", options);
259
+ }
260
+ function time$1(options) {
261
+ return createTailorField("time", options);
262
+ }
263
+ function _enum$1(values, options) {
264
+ return createTailorField("enum", options, void 0, values);
265
+ }
266
+ function object$1(fields, options) {
267
+ return createTailorField("nested", options, fields);
268
+ }
269
+ const t = {
270
+ uuid: uuid$1,
271
+ string: string$1,
272
+ bool: bool$1,
273
+ int: int$1,
274
+ float: float$1,
275
+ date: date$1,
276
+ datetime: datetime$1,
277
+ time: time$1,
278
+ enum: _enum$1,
279
+ object: object$1
280
+ };
281
+
282
+ //#endregion
283
+ //#region src/configure/services/tailordb/permission.ts
284
+ /**
285
+ * Grants full record-level access without any conditions.
286
+ *
287
+ * Unsafe and intended only for local development, prototyping, or tests.
288
+ * Do not use this in production environments, as it effectively disables
289
+ * authorization checks.
290
+ */
291
+ const unsafeAllowAllTypePermission = {
292
+ create: [{
293
+ conditions: [],
294
+ permit: true
295
+ }],
296
+ read: [{
297
+ conditions: [],
298
+ permit: true
299
+ }],
300
+ update: [{
301
+ conditions: [],
302
+ permit: true
303
+ }],
304
+ delete: [{
305
+ conditions: [],
306
+ permit: true
307
+ }]
308
+ };
309
+ /**
310
+ * Grants full GraphQL access (all actions) without any conditions.
311
+ *
312
+ * Unsafe and intended only for local development, prototyping, or tests.
313
+ * Do not use this in production environments, as it effectively disables
314
+ * authorization checks.
315
+ */
316
+ const unsafeAllowAllGqlPermission = [{
317
+ conditions: [],
318
+ actions: "all",
319
+ permit: true
320
+ }];
321
+
322
+ //#endregion
323
+ //#region src/configure/services/tailordb/schema.ts
324
+ function isRelationSelfConfig(config) {
325
+ return config.toward.type === "self";
326
+ }
327
+ const regex = {
328
+ uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
329
+ date: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/,
330
+ time: /^(?<hour>\d{2}):(?<minute>\d{2})$/,
331
+ datetime: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(.(?<millisec>\d{3}))?Z$/
332
+ };
333
+ /**
334
+ * Creates a new TailorDBField instance.
335
+ * @param type - Field type
336
+ * @param options - Field options
337
+ * @param fields - Nested fields for object-like types
338
+ * @param values - Allowed values for enum-like fields
339
+ * @returns A new TailorDBField
340
+ */
341
+ function createTailorDBField(type, options, fields, values) {
342
+ const _metadata = { required: true };
343
+ let _rawRelation;
344
+ if (options) {
345
+ if (options.optional === true) _metadata.required = false;
346
+ if (options.array === true) _metadata.array = true;
347
+ }
348
+ if (values) _metadata.allowedValues = mapAllowedValues(values);
349
+ /**
350
+ * Validate a single value (not an array element)
351
+ * Used internally for array element validation
352
+ * @param args - Value, context data, and user
353
+ * @returns Array of validation issues
354
+ */
355
+ function validateValue(args) {
356
+ const { value, data, user, pathArray } = args;
357
+ const issues = [];
358
+ switch (type) {
359
+ case "string":
360
+ if (typeof value !== "string") issues.push({
361
+ message: `Expected a string: received ${String(value)}`,
362
+ path: pathArray.length > 0 ? pathArray : void 0
363
+ });
364
+ break;
365
+ case "integer":
366
+ if (typeof value !== "number" || !Number.isInteger(value)) issues.push({
367
+ message: `Expected an integer: received ${String(value)}`,
368
+ path: pathArray.length > 0 ? pathArray : void 0
369
+ });
370
+ break;
371
+ case "float":
372
+ if (typeof value !== "number" || !Number.isFinite(value)) issues.push({
373
+ message: `Expected a number: received ${String(value)}`,
374
+ path: pathArray.length > 0 ? pathArray : void 0
375
+ });
376
+ break;
377
+ case "boolean":
378
+ if (typeof value !== "boolean") issues.push({
379
+ message: `Expected a boolean: received ${String(value)}`,
380
+ path: pathArray.length > 0 ? pathArray : void 0
381
+ });
382
+ break;
383
+ case "uuid":
384
+ if (typeof value !== "string" || !regex.uuid.test(value)) issues.push({
385
+ message: `Expected a valid UUID: received ${String(value)}`,
386
+ path: pathArray.length > 0 ? pathArray : void 0
387
+ });
388
+ break;
389
+ case "date":
390
+ if (typeof value !== "string" || !regex.date.test(value)) issues.push({
391
+ message: `Expected to match "yyyy-MM-dd" format: received ${String(value)}`,
392
+ path: pathArray.length > 0 ? pathArray : void 0
393
+ });
394
+ break;
395
+ case "datetime":
396
+ if (typeof value !== "string" || !regex.datetime.test(value)) issues.push({
397
+ message: `Expected to match ISO format: received ${String(value)}`,
398
+ path: pathArray.length > 0 ? pathArray : void 0
399
+ });
400
+ break;
401
+ case "time":
402
+ if (typeof value !== "string" || !regex.time.test(value)) issues.push({
403
+ message: `Expected to match "HH:mm" format: received ${String(value)}`,
404
+ path: pathArray.length > 0 ? pathArray : void 0
405
+ });
406
+ break;
407
+ case "enum":
408
+ if (field._metadata.allowedValues) {
409
+ const allowedValues = field._metadata.allowedValues.map((v) => v.value);
410
+ if (typeof value !== "string" || !allowedValues.includes(value)) issues.push({
411
+ message: `Must be one of [${allowedValues.join(", ")}]: received ${String(value)}`,
412
+ path: pathArray.length > 0 ? pathArray : void 0
413
+ });
414
+ }
415
+ break;
416
+ case "nested":
417
+ if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Date) issues.push({
418
+ message: `Expected an object: received ${String(value)}`,
419
+ path: pathArray.length > 0 ? pathArray : void 0
420
+ });
421
+ else if (field.fields && Object.keys(field.fields).length > 0) for (const [fieldName, nestedField] of Object.entries(field.fields)) {
422
+ const fieldValue = value?.[fieldName];
423
+ const result = nestedField._parseInternal({
424
+ value: fieldValue,
425
+ data,
426
+ user,
427
+ pathArray: pathArray.concat(fieldName)
428
+ });
429
+ if (result.issues) issues.push(...result.issues);
430
+ }
431
+ break;
432
+ }
433
+ const validateFns = field._metadata.validate;
434
+ if (validateFns && validateFns.length > 0) for (const validateInput of validateFns) {
435
+ const { fn, message } = typeof validateInput === "function" ? {
436
+ fn: validateInput,
437
+ message: "Validation failed"
438
+ } : {
439
+ fn: validateInput[0],
440
+ message: validateInput[1]
441
+ };
442
+ if (!fn({
443
+ value,
444
+ data,
445
+ user
446
+ })) issues.push({
447
+ message,
448
+ path: pathArray.length > 0 ? pathArray : void 0
449
+ });
450
+ }
451
+ return issues;
452
+ }
453
+ /**
454
+ * Internal parse method that tracks field path for nested validation
455
+ * @param args - Parse arguments
456
+ * @returns Parse result with value or issues
457
+ */
458
+ function parseInternal(args) {
459
+ const { value, data, user, pathArray } = args;
460
+ const issues = [];
461
+ const isNullOrUndefined = value === null || value === void 0;
462
+ if (field._metadata.required && isNullOrUndefined) {
463
+ issues.push({
464
+ message: "Required field is missing",
465
+ path: pathArray.length > 0 ? pathArray : void 0
466
+ });
467
+ return { issues };
468
+ }
469
+ if (!field._metadata.required && isNullOrUndefined) return { value: value ?? null };
470
+ if (field._metadata.array) {
471
+ if (!Array.isArray(value)) {
472
+ issues.push({
473
+ message: "Expected an array",
474
+ path: pathArray.length > 0 ? pathArray : void 0
475
+ });
476
+ return { issues };
477
+ }
478
+ for (let i = 0; i < value.length; i++) {
479
+ const elementValue = value[i];
480
+ const elementIssues = validateValue({
481
+ value: elementValue,
482
+ data,
483
+ user,
484
+ pathArray: pathArray.concat(`[${i}]`)
485
+ });
486
+ if (elementIssues.length > 0) issues.push(...elementIssues);
487
+ }
488
+ if (issues.length > 0) return { issues };
489
+ return { value };
490
+ }
491
+ const valueIssues = validateValue({
492
+ value,
493
+ data,
494
+ user,
495
+ pathArray
496
+ });
497
+ issues.push(...valueIssues);
498
+ if (issues.length > 0) return { issues };
499
+ return { value };
500
+ }
501
+ function cloneWith(metadataUpdates) {
502
+ const cloned = field.clone();
503
+ Object.assign(cloned._metadata, metadataUpdates);
504
+ return cloned;
505
+ }
506
+ const field = {
507
+ type,
508
+ fields: fields ?? {},
509
+ _defined: void 0,
510
+ _output: void 0,
511
+ _metadata,
512
+ get metadata() {
513
+ return { ...this._metadata };
514
+ },
515
+ get rawRelation() {
516
+ return _rawRelation ? {
517
+ ..._rawRelation,
518
+ toward: { ..._rawRelation.toward }
519
+ } : void 0;
520
+ },
521
+ description(description) {
522
+ return cloneWith({ description });
523
+ },
524
+ typeName(typeName) {
525
+ return cloneWith({ typeName });
526
+ },
527
+ validate(...validateInputs) {
528
+ return cloneWith({ validate: validateInputs });
529
+ },
530
+ parse(args) {
531
+ return parseInternal({
532
+ value: args.value,
533
+ data: args.data,
534
+ user: args.user,
535
+ pathArray: []
536
+ });
537
+ },
538
+ _parseInternal: parseInternal,
539
+ relation(config) {
540
+ const cloned = field.clone();
541
+ const targetType = isRelationSelfConfig(config) ? "self" : config.toward.type.name;
542
+ cloned._setRawRelation({
543
+ type: config.type,
544
+ toward: {
545
+ type: targetType,
546
+ as: config.toward.as,
547
+ key: config.toward.key
548
+ },
549
+ backward: config.backward
550
+ });
551
+ return cloned;
552
+ },
553
+ index() {
554
+ return cloneWith({ index: true });
555
+ },
556
+ unique() {
557
+ return cloneWith({
558
+ unique: true,
559
+ index: true
560
+ });
561
+ },
562
+ vector() {
563
+ return cloneWith({ vector: true });
564
+ },
565
+ hooks(hooks) {
566
+ return cloneWith({ hooks });
567
+ },
568
+ serial(config) {
569
+ return cloneWith({ serial: config });
570
+ },
571
+ clone(cloneOptions) {
572
+ let clonedFields = fields;
573
+ if (fields) {
574
+ const cloned = {};
575
+ for (const [key, field$1] of Object.entries(fields)) cloned[key] = field$1.clone();
576
+ clonedFields = cloned;
577
+ }
578
+ const clonedField = createTailorDBField(type, options, clonedFields, values);
579
+ Object.assign(clonedField._metadata, cloneDeep(this._metadata));
580
+ if (cloneOptions) {
581
+ if (cloneOptions.optional !== void 0) clonedField._metadata.required = !cloneOptions.optional;
582
+ if (cloneOptions.array !== void 0) clonedField._metadata.array = cloneOptions.array;
583
+ }
584
+ if (_rawRelation) {
585
+ const clonedRawRelation = cloneDeep(_rawRelation);
586
+ clonedField._setRawRelation(clonedRawRelation);
587
+ }
588
+ return clonedField;
589
+ },
590
+ _setRawRelation(relation) {
591
+ _rawRelation = relation;
592
+ }
593
+ };
594
+ return field;
595
+ }
596
+ const createField = createTailorDBField;
597
+ function uuid(options) {
598
+ return createField("uuid", options);
599
+ }
600
+ function string(options) {
601
+ return createField("string", options);
602
+ }
603
+ function bool(options) {
604
+ return createField("boolean", options);
605
+ }
606
+ function int(options) {
607
+ return createField("integer", options);
608
+ }
609
+ function float(options) {
610
+ return createField("float", options);
611
+ }
612
+ function date(options) {
613
+ return createField("date", options);
614
+ }
615
+ function datetime(options) {
616
+ return createField("datetime", options);
617
+ }
618
+ function time(options) {
619
+ return createField("time", options);
620
+ }
621
+ function _enum(values, options) {
622
+ return createField("enum", options, void 0, values);
623
+ }
624
+ function object(fields, options) {
625
+ return createField("nested", options, fields);
626
+ }
627
+ /**
628
+ * Creates a new TailorDBType instance.
629
+ * @param name - Type name
630
+ * @param fields - Field definitions
631
+ * @param options - Type options
632
+ * @param options.pluralForm - Optional plural form
633
+ * @param options.description - Optional description
634
+ * @returns A new TailorDBType
635
+ */
636
+ function createTailorDBType(name, fields, options) {
637
+ let _description = options.description;
638
+ let _settings = {};
639
+ let _indexes = [];
640
+ const _permissions = {};
641
+ let _files = {};
642
+ const _plugins = [];
643
+ if (options.pluralForm) {
644
+ if (name === options.pluralForm) throw new Error(`The name and the plural form must be different. name=${name}`);
645
+ _settings.pluralForm = options.pluralForm;
646
+ }
647
+ return {
648
+ name,
649
+ fields: { ...fields },
650
+ _output: null,
651
+ _description,
652
+ get metadata() {
653
+ const indexes = {};
654
+ if (_indexes && _indexes.length > 0) _indexes.forEach((index) => {
655
+ const fieldNames = index.fields.map((field) => String(field));
656
+ const key = index.name || `idx_${fieldNames.join("_")}`;
657
+ indexes[key] = {
658
+ fields: fieldNames,
659
+ unique: index.unique
660
+ };
661
+ });
662
+ return {
663
+ name: this.name,
664
+ description: _description,
665
+ settings: _settings,
666
+ permissions: _permissions,
667
+ files: _files,
668
+ ...Object.keys(indexes).length > 0 && { indexes }
669
+ };
670
+ },
671
+ hooks(hooks) {
672
+ Object.entries(hooks).forEach(([fieldName, fieldHooks]) => {
673
+ this.fields[fieldName] = this.fields[fieldName].hooks(fieldHooks);
674
+ });
675
+ return this;
676
+ },
677
+ validate(validators) {
678
+ Object.entries(validators).forEach(([fieldName, fieldValidators]) => {
679
+ const field = this.fields[fieldName];
680
+ const validators$1 = fieldValidators;
681
+ const isValidateConfig = (v) => {
682
+ return Array.isArray(v) && v.length === 2 && typeof v[1] === "string";
683
+ };
684
+ let updatedField;
685
+ if (Array.isArray(validators$1)) if (isValidateConfig(validators$1)) updatedField = field.validate(validators$1);
686
+ else updatedField = field.validate(...validators$1);
687
+ else updatedField = field.validate(validators$1);
688
+ this.fields[fieldName] = updatedField;
689
+ });
690
+ return this;
691
+ },
692
+ features(features) {
693
+ _settings = {
694
+ ..._settings,
695
+ ...features
696
+ };
697
+ return this;
698
+ },
699
+ indexes(...indexes) {
700
+ _indexes = indexes;
701
+ return this;
702
+ },
703
+ files(files) {
704
+ _files = files;
705
+ return this;
706
+ },
707
+ permission(permission) {
708
+ const ret = this;
709
+ _permissions.record = permission;
710
+ return ret;
711
+ },
712
+ gqlPermission(permission) {
713
+ const ret = this;
714
+ _permissions.gql = permission;
715
+ return ret;
716
+ },
717
+ description(description) {
718
+ _description = description;
719
+ this._description = description;
720
+ return this;
721
+ },
722
+ pickFields(keys, options$1) {
723
+ const result = {};
724
+ for (const key of keys) if (options$1) result[key] = this.fields[key].clone(options$1);
725
+ else result[key] = this.fields[key];
726
+ return result;
727
+ },
728
+ omitFields(keys) {
729
+ const keysSet = new Set(keys);
730
+ const result = {};
731
+ for (const key in this.fields) if (Object.hasOwn(this.fields, key) && !keysSet.has(key)) result[key] = this.fields[key];
732
+ return result;
733
+ },
734
+ get plugins() {
735
+ return _plugins;
736
+ },
737
+ plugin(config) {
738
+ for (const [pluginId, pluginConfig] of Object.entries(config)) _plugins.push({
739
+ pluginId,
740
+ config: pluginConfig
741
+ });
742
+ return this;
743
+ }
744
+ };
745
+ }
746
+ const idField = uuid();
747
+ function dbType(name, fieldsOrDescription, fields) {
748
+ const typeName = Array.isArray(name) ? name[0] : name;
749
+ const pluralForm = Array.isArray(name) ? name[1] : void 0;
750
+ let description;
751
+ let fieldDef;
752
+ if (typeof fieldsOrDescription === "string") {
753
+ description = fieldsOrDescription;
754
+ fieldDef = fields;
755
+ } else fieldDef = fieldsOrDescription;
756
+ return createTailorDBType(typeName, {
757
+ id: idField,
758
+ ...fieldDef
759
+ }, {
760
+ pluralForm,
761
+ description
762
+ });
763
+ }
764
+ const db = {
765
+ type: dbType,
766
+ uuid,
767
+ string,
768
+ bool,
769
+ int,
770
+ float,
771
+ date,
772
+ datetime,
773
+ time,
774
+ enum: _enum,
775
+ object,
776
+ fields: { timestamps: () => ({
777
+ createdAt: datetime().hooks({ create: () => /* @__PURE__ */ new Date() }).description("Record creation timestamp"),
778
+ updatedAt: datetime({ optional: true }).hooks({ update: () => /* @__PURE__ */ new Date() }).description("Record last update timestamp")
779
+ }) }
780
+ };
781
+
782
+ //#endregion
783
+ export { t as i, unsafeAllowAllGqlPermission as n, unsafeAllowAllTypePermission as r, db as t };
784
+ //# sourceMappingURL=schema-BmKdDzr1.mjs.map