functional-models 3.9.5 → 3.11.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 (84) hide show
  1. package/cjs/errors.cjs +38 -0
  2. package/cjs/errors.cjs.map +7 -0
  3. package/cjs/index.cjs +2426 -0
  4. package/cjs/index.cjs.map +7 -0
  5. package/cjs/lib.cjs +431 -0
  6. package/cjs/lib.cjs.map +7 -0
  7. package/cjs/models.cjs +571 -0
  8. package/cjs/models.cjs.map +7 -0
  9. package/cjs/orm/index.cjs +1765 -0
  10. package/cjs/orm/index.cjs.map +7 -0
  11. package/cjs/orm/internal-libs.cjs +136 -0
  12. package/cjs/orm/internal-libs.cjs.map +7 -0
  13. package/cjs/orm/libs.cjs +88 -0
  14. package/cjs/orm/libs.cjs.map +7 -0
  15. package/cjs/orm/models.cjs +1027 -0
  16. package/cjs/orm/models.cjs.map +7 -0
  17. package/cjs/orm/properties.cjs +989 -0
  18. package/cjs/orm/properties.cjs.map +7 -0
  19. package/cjs/orm/query.cjs +376 -0
  20. package/cjs/orm/query.cjs.map +7 -0
  21. package/cjs/orm/types.cjs +59 -0
  22. package/cjs/orm/types.cjs.map +7 -0
  23. package/cjs/orm/validation.cjs +301 -0
  24. package/cjs/orm/validation.cjs.map +7 -0
  25. package/cjs/properties.cjs +998 -0
  26. package/cjs/properties.cjs.map +7 -0
  27. package/cjs/serialization.cjs +75 -0
  28. package/cjs/serialization.cjs.map +7 -0
  29. package/cjs/types.cjs +65 -0
  30. package/cjs/types.cjs.map +7 -0
  31. package/cjs/utils.cjs +187 -0
  32. package/cjs/utils.cjs.map +7 -0
  33. package/cjs/validation.cjs +431 -0
  34. package/cjs/validation.cjs.map +7 -0
  35. package/errors.js +3 -4
  36. package/errors.js.map +1 -1
  37. package/index.d.ts +13 -13
  38. package/index.js +13 -52
  39. package/index.js.map +1 -1
  40. package/lib.d.ts +5 -5
  41. package/lib.js +45 -65
  42. package/lib.js.map +1 -1
  43. package/models.d.ts +1 -1
  44. package/models.js +22 -30
  45. package/models.js.map +1 -1
  46. package/orm/index.d.ts +9 -9
  47. package/orm/index.js +9 -48
  48. package/orm/index.js.map +1 -1
  49. package/orm/internal-libs.js +7 -11
  50. package/orm/internal-libs.js.map +1 -1
  51. package/orm/libs.d.ts +1 -1
  52. package/orm/libs.js +8 -16
  53. package/orm/libs.js.map +1 -1
  54. package/orm/models.d.ts +2 -2
  55. package/orm/models.js +20 -26
  56. package/orm/models.js.map +1 -1
  57. package/orm/properties.d.ts +28 -28
  58. package/orm/properties.js +28 -36
  59. package/orm/properties.js.map +1 -1
  60. package/orm/query.d.ts +1 -1
  61. package/orm/query.js +31 -52
  62. package/orm/query.js.map +1 -1
  63. package/orm/types.d.ts +2 -2
  64. package/orm/types.js +7 -10
  65. package/orm/types.js.map +1 -1
  66. package/orm/validation.d.ts +2 -2
  67. package/orm/validation.js +5 -13
  68. package/orm/validation.js.map +1 -1
  69. package/package.json +50 -65
  70. package/properties.d.ts +133 -133
  71. package/properties.js +66 -94
  72. package/properties.js.map +1 -1
  73. package/serialization.d.ts +1 -1
  74. package/serialization.js +3 -9
  75. package/serialization.js.map +1 -1
  76. package/types.d.ts +6 -1
  77. package/types.js +4 -6
  78. package/types.js.map +1 -1
  79. package/utils.d.ts +2 -1
  80. package/utils.js +8 -23
  81. package/utils.js.map +1 -1
  82. package/validation.d.ts +1 -1
  83. package/validation.js +19 -50
  84. package/validation.js.map +1 -1
@@ -0,0 +1,998 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/properties.ts
31
+ var properties_exports = {};
32
+ __export(properties_exports, {
33
+ AdvancedModelReferenceProperty: () => AdvancedModelReferenceProperty,
34
+ ArrayProperty: () => ArrayProperty,
35
+ BigTextProperty: () => BigTextProperty,
36
+ BooleanProperty: () => BooleanProperty,
37
+ ConstantValueProperty: () => ConstantValueProperty,
38
+ DateProperty: () => DateProperty,
39
+ DatetimeProperty: () => DatetimeProperty,
40
+ DenormalizedIntegerProperty: () => DenormalizedIntegerProperty,
41
+ DenormalizedNumberProperty: () => DenormalizedNumberProperty,
42
+ DenormalizedProperty: () => DenormalizedProperty,
43
+ DenormalizedTextProperty: () => DenormalizedTextProperty,
44
+ EmailProperty: () => EmailProperty,
45
+ IntegerProperty: () => IntegerProperty,
46
+ ModelReferenceProperty: () => ModelReferenceProperty,
47
+ NaturalIdProperty: () => NaturalIdProperty,
48
+ NumberProperty: () => NumberProperty,
49
+ ObjectProperty: () => ObjectProperty,
50
+ PrimaryKeyUuidProperty: () => PrimaryKeyUuidProperty,
51
+ Property: () => Property,
52
+ SingleTypeArrayProperty: () => SingleTypeArrayProperty,
53
+ TextProperty: () => TextProperty,
54
+ UuidProperty: () => UuidProperty,
55
+ YearProperty: () => YearProperty
56
+ });
57
+ module.exports = __toCommonJS(properties_exports);
58
+ var import_merge3 = __toESM(require("lodash/merge.js"), 1);
59
+ var import_get3 = __toESM(require("lodash/get.js"), 1);
60
+
61
+ // node_modules/uuid/dist-node/stringify.js
62
+ var byteToHex = [];
63
+ for (let i = 0; i < 256; ++i) {
64
+ byteToHex.push((i + 256).toString(16).slice(1));
65
+ }
66
+ function unsafeStringify(arr, offset = 0) {
67
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
68
+ }
69
+
70
+ // node_modules/uuid/dist-node/rng.js
71
+ var rnds8 = new Uint8Array(16);
72
+ function rng() {
73
+ return crypto.getRandomValues(rnds8);
74
+ }
75
+
76
+ // node_modules/uuid/dist-node/v4.js
77
+ function v4(options, buf, offset) {
78
+ if (!buf && !options && crypto.randomUUID) {
79
+ return crypto.randomUUID();
80
+ }
81
+ return _v4(options, buf, offset);
82
+ }
83
+ function _v4(options, buf, offset) {
84
+ options = options || {};
85
+ const rnds = options.random ?? options.rng?.() ?? rng();
86
+ if (rnds.length < 16) {
87
+ throw new Error("Random bytes length must be >= 16");
88
+ }
89
+ rnds[6] = rnds[6] & 15 | 64;
90
+ rnds[8] = rnds[8] & 63 | 128;
91
+ if (buf) {
92
+ offset = offset || 0;
93
+ if (offset < 0 || offset + 16 > buf.length) {
94
+ throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
95
+ }
96
+ for (let i = 0; i < 16; ++i) {
97
+ buf[offset + i] = rnds[i];
98
+ }
99
+ return buf;
100
+ }
101
+ return unsafeStringify(rnds);
102
+ }
103
+ var v4_default = v4;
104
+
105
+ // src/validation.ts
106
+ var import_isEmpty = __toESM(require("lodash/isEmpty.js"), 1);
107
+ var import_merge = __toESM(require("lodash/merge.js"), 1);
108
+ var import_flatMap = __toESM(require("lodash/flatMap.js"), 1);
109
+ var import_get = __toESM(require("lodash/get.js"), 1);
110
+
111
+ // src/utils.ts
112
+ var import_async_lock = __toESM(require("async-lock"), 1);
113
+ var import_get_random_values = __toESM(require("get-random-values"), 1);
114
+ var PluralEndings = /* @__PURE__ */ ((PluralEndings2) => {
115
+ PluralEndings2["ves"] = "fe";
116
+ PluralEndings2["ies"] = "y";
117
+ PluralEndings2["i"] = "us";
118
+ PluralEndings2["zes"] = "ze";
119
+ PluralEndings2["ses"] = "s";
120
+ PluralEndings2["es"] = "e";
121
+ PluralEndings2["s"] = "";
122
+ return PluralEndings2;
123
+ })(PluralEndings || {});
124
+ var _singularizingRe = new RegExp(
125
+ `(${Object.keys(PluralEndings).join("|")})$`,
126
+ "u"
127
+ );
128
+ var createHeadAndTail = (values, joiner) => {
129
+ const head = values[0];
130
+ const tail = values.slice(1).join(joiner);
131
+ return [head, tail];
132
+ };
133
+ var flowFindFirst = (funcs) => (input) => {
134
+ return funcs.reduce((acc, func) => {
135
+ if (acc) {
136
+ return acc;
137
+ }
138
+ return func(input);
139
+ }, void 0);
140
+ };
141
+ var memoizeSync = (method) => {
142
+ let value = void 0;
143
+ let called = false;
144
+ return (...args) => {
145
+ if (!called) {
146
+ called = true;
147
+ value = method(...args);
148
+ }
149
+ return value;
150
+ };
151
+ };
152
+ var memoizeAsync = (method) => {
153
+ const key = v4_default();
154
+ const lock = new import_async_lock.default();
155
+ let value = void 0;
156
+ let called = false;
157
+ return async (...args) => {
158
+ return lock.acquire(key, async () => {
159
+ if (!called) {
160
+ called = true;
161
+ value = await method(...args);
162
+ }
163
+ return value;
164
+ });
165
+ };
166
+ };
167
+
168
+ // src/validation.ts
169
+ var multiValidator = (validators) => {
170
+ const flow2 = flowFindFirst(
171
+ validators
172
+ );
173
+ return flow2;
174
+ };
175
+ var filterEmpty = (array) => {
176
+ return array.filter((x) => x);
177
+ };
178
+ var _trueOrError = (method, error) => (value) => {
179
+ if (method(value) === false) {
180
+ return error;
181
+ }
182
+ return void 0;
183
+ };
184
+ var _typeOrError = (type, errorMessage) => (value) => {
185
+ if (typeof value !== type) {
186
+ return errorMessage;
187
+ }
188
+ return void 0;
189
+ };
190
+ var isType = (type) => (value) => {
191
+ return _typeOrError(type, `Must be a ${type}`)(value);
192
+ };
193
+ var isNumber = isType("number");
194
+ var isInteger = _trueOrError(Number.isInteger, "Must be an integer");
195
+ var isObject = multiValidator([
196
+ isType("object"),
197
+ (x) => Array.isArray(x) ? "Must be an object, but got an array" : void 0
198
+ ]);
199
+ var isBoolean = isType("boolean");
200
+ var isString = isType("string");
201
+ var isArray = _trueOrError(
202
+ (v) => Array.isArray(v),
203
+ "Value is not an array"
204
+ );
205
+ var PRIMITIVE_TO_SPECIAL_TYPE_VALIDATOR = {
206
+ ["boolean" /* boolean */]: isBoolean,
207
+ ["string" /* string */]: isString,
208
+ ["integer" /* integer */]: isInteger,
209
+ ["number" /* number */]: isNumber,
210
+ ["object" /* object */]: isObject
211
+ };
212
+ var arrayType = (type) => (value) => {
213
+ const arrayError = isArray(value);
214
+ if (arrayError) {
215
+ return arrayError;
216
+ }
217
+ const validator = PRIMITIVE_TO_SPECIAL_TYPE_VALIDATOR[type] || isType(type);
218
+ return value.reduce(
219
+ (acc, v) => {
220
+ if (acc) {
221
+ return acc;
222
+ }
223
+ return validator(v);
224
+ },
225
+ void 0
226
+ );
227
+ };
228
+ var meetsRegex = (regex, flags, errorMessage = "Format was invalid") => (value) => {
229
+ const reg = new RegExp(regex, flags);
230
+ return _trueOrError((v) => reg.test(v), errorMessage)(value);
231
+ };
232
+ var choices = (choiceArray) => (value) => {
233
+ if (Array.isArray(value)) {
234
+ const bad = value.find((v) => !choiceArray.includes(v));
235
+ if (bad) {
236
+ return `${bad} is not a valid choice`;
237
+ }
238
+ } else {
239
+ if (!choiceArray.includes(value)) {
240
+ return `${value} is not a valid choice`;
241
+ }
242
+ }
243
+ return void 0;
244
+ };
245
+ var isDate = (value) => {
246
+ if (!value) {
247
+ return "Date value is empty";
248
+ }
249
+ if (!value.toISOString) {
250
+ return "Value is not a date";
251
+ }
252
+ return void 0;
253
+ };
254
+ var isRequired = (value) => {
255
+ if (value === true || value === false) {
256
+ return void 0;
257
+ }
258
+ if (isNumber(value) === void 0) {
259
+ return void 0;
260
+ }
261
+ const empty = (0, import_isEmpty.default)(value);
262
+ if (empty) {
263
+ if (isDate(value)) {
264
+ return "A value is required";
265
+ }
266
+ }
267
+ return void 0;
268
+ };
269
+ var maxNumber = (max) => (value) => {
270
+ const numberError = isNumber(value);
271
+ if (numberError) {
272
+ return numberError;
273
+ }
274
+ if (value && value > max) {
275
+ return `The maximum is ${max}`;
276
+ }
277
+ return void 0;
278
+ };
279
+ var minNumber = (min) => (value) => {
280
+ const numberError = isNumber(value);
281
+ if (numberError) {
282
+ return numberError;
283
+ }
284
+ if (value && value < min) {
285
+ return `The minimum is ${min}`;
286
+ }
287
+ return void 0;
288
+ };
289
+ var maxTextLength = (max) => (value) => {
290
+ const stringError = isString(value);
291
+ if (stringError) {
292
+ return stringError;
293
+ }
294
+ if (value && value.length > max) {
295
+ return `The maximum length is ${max}`;
296
+ }
297
+ return void 0;
298
+ };
299
+ var minTextLength = (min) => (value) => {
300
+ const stringError = isString(value);
301
+ if (stringError) {
302
+ return stringError;
303
+ }
304
+ if (value && value.length < min) {
305
+ return `The minimum length is ${min}`;
306
+ }
307
+ return void 0;
308
+ };
309
+ var aggregateValidator = (value, methodOrMethods) => {
310
+ const toDo = Array.isArray(methodOrMethods) ? methodOrMethods : [methodOrMethods];
311
+ const _aggregativeValidator = async (model, instanceData, propertyConfiguration) => {
312
+ const values = await Promise.all(
313
+ toDo.map((method) => {
314
+ return method(value, model, instanceData, propertyConfiguration);
315
+ })
316
+ );
317
+ return filterEmpty(values);
318
+ };
319
+ return _aggregativeValidator;
320
+ };
321
+ var emptyValidator = () => void 0;
322
+ var _boolChoice = (method) => (configValue) => {
323
+ const func = method(configValue);
324
+ const validatorWrapper = func;
325
+ return validatorWrapper;
326
+ };
327
+ var simpleFuncWrap = (validator) => () => {
328
+ return validator;
329
+ };
330
+ var includeOrDont = (method) => (configValue) => {
331
+ if (configValue === false) {
332
+ return emptyValidator;
333
+ }
334
+ const func = method();
335
+ const validatorWrapper = func;
336
+ return validatorWrapper;
337
+ };
338
+ var CONFIG_TO_VALIDATE_METHOD = () => ({
339
+ required: includeOrDont(simpleFuncWrap(isRequired)),
340
+ isInteger: _boolChoice(simpleFuncWrap(isInteger)),
341
+ isNumber: _boolChoice(simpleFuncWrap(isNumber)),
342
+ isString: _boolChoice(simpleFuncWrap(isString)),
343
+ isArray: _boolChoice(simpleFuncWrap(isArray)),
344
+ isBoolean: _boolChoice(simpleFuncWrap(isBoolean)),
345
+ choices: _boolChoice(choices)
346
+ });
347
+ var createPropertyValidator = (valueGetter, config) => {
348
+ const _propertyValidator = async (model, instanceData, propertyConfiguration) => {
349
+ return Promise.resolve().then(async () => {
350
+ const configToValidateMethod = CONFIG_TO_VALIDATE_METHOD();
351
+ if (!config) {
352
+ config = {};
353
+ }
354
+ const validators = [
355
+ ...Object.entries(config).map(([key, value2]) => {
356
+ const method = configToValidateMethod[key];
357
+ if (method) {
358
+ return method(value2);
359
+ }
360
+ return emptyValidator;
361
+ }),
362
+ ...config.validators ? config.validators : []
363
+ ].filter((x) => x);
364
+ const value = await valueGetter();
365
+ const isRequiredValue = config.required ? true : validators.includes(isRequired);
366
+ if (!value && !isRequiredValue) {
367
+ return [];
368
+ }
369
+ const validator = aggregateValidator(value, validators);
370
+ const errors = await validator(model, instanceData, propertyConfiguration);
371
+ return [...new Set((0, import_flatMap.default)(errors))];
372
+ });
373
+ };
374
+ return _propertyValidator;
375
+ };
376
+ var referenceTypeMatch = (referencedModel) => {
377
+ return (value) => {
378
+ const theType = typeof value;
379
+ switch (theType) {
380
+ case "string":
381
+ case "number":
382
+ case "undefined":
383
+ return void 0;
384
+ default:
385
+ break;
386
+ }
387
+ if (value === null) {
388
+ return void 0;
389
+ }
390
+ const model = typeof referencedModel === "function" ? referencedModel() : referencedModel;
391
+ const eModel = model.getName();
392
+ const aModel = value.getModel().getName();
393
+ if (eModel !== aModel) {
394
+ return `Model should be ${eModel} instead, received ${aModel}`;
395
+ }
396
+ return void 0;
397
+ };
398
+ };
399
+ var optionalValidator = (validator) => {
400
+ return (v) => {
401
+ if (v === void 0 || v === null) {
402
+ return void 0;
403
+ }
404
+ return validator(v);
405
+ };
406
+ };
407
+ var UUID_VALIDATOR = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
408
+ var isValidUuid = (uuid) => {
409
+ const stringError = isString(uuid);
410
+ if (stringError) {
411
+ return stringError;
412
+ }
413
+ return meetsRegex(UUID_VALIDATOR, "g", "Invalid UUID format")(uuid);
414
+ };
415
+
416
+ // src/lib.ts
417
+ var import_openapi_types = require("openapi-types");
418
+ var import_kebabCase = __toESM(require("lodash/kebabCase.js"), 1);
419
+ var import_flow = __toESM(require("lodash/flow.js"), 1);
420
+ var import_merge2 = __toESM(require("lodash/merge.js"), 1);
421
+ var import_get2 = __toESM(require("lodash/get.js"), 1);
422
+ var import_zod = require("zod");
423
+ var HttpMethods = import_openapi_types.OpenAPIV3.HttpMethods;
424
+ var NULL_METHOD = HttpMethods.HEAD;
425
+ var ID_KEY = ":id";
426
+ var getValueForReferencedModel = async (modelInstance, path) => {
427
+ const [head, tail] = createHeadAndTail(path.split("."), ".");
428
+ if (!tail) {
429
+ return modelInstance.getReferences()[head]();
430
+ }
431
+ const modelReference = await modelInstance.get[head]();
432
+ if (modelReference.toObj) {
433
+ const [nestedHead, nestedTail] = createHeadAndTail(tail.split("."), ".");
434
+ const value = await modelReference.get[nestedHead]();
435
+ if (nestedTail) {
436
+ return (0, import_get2.default)(value, nestedTail);
437
+ }
438
+ return value;
439
+ }
440
+ return (0, import_get2.default)(modelReference, tail);
441
+ };
442
+ var getValueForModelInstance = async (modelInstance, path) => {
443
+ const [head, tail] = createHeadAndTail(path.split("."), ".");
444
+ const value = await modelInstance.get[head]();
445
+ return tail ? (0, import_get2.default)(value, tail) : value;
446
+ };
447
+ var isReferencedProperty = (modelInstance, key) => {
448
+ return modelInstance.getReferences()[key];
449
+ };
450
+ var getCommonTextValidators = (config) => {
451
+ return [
452
+ getValidatorFromConfigElseEmpty(config?.maxLength, maxTextLength),
453
+ getValidatorFromConfigElseEmpty(config?.minLength, minTextLength)
454
+ ];
455
+ };
456
+ var getValidatorFromConfigElseEmpty = (input, validatorGetter) => {
457
+ if (input !== void 0) {
458
+ const validator = validatorGetter(input);
459
+ return validator;
460
+ }
461
+ return emptyValidator;
462
+ };
463
+ var getCommonNumberValidators = (config) => {
464
+ return [
465
+ getValidatorFromConfigElseEmpty(config?.minValue, minNumber),
466
+ getValidatorFromConfigElseEmpty(config?.maxValue, maxNumber)
467
+ ];
468
+ };
469
+ var mergeValidators = (config, ...validators) => {
470
+ return [...validators, ...config?.validators ? config.validators : []];
471
+ };
472
+ var isModelInstance = (obj) => {
473
+ return Boolean(obj && obj.getPrimaryKey);
474
+ };
475
+ var buildValidEndpoint = (...components) => {
476
+ const suffix = components.map((x) => {
477
+ if (x === ID_KEY) {
478
+ return x;
479
+ }
480
+ return (0, import_kebabCase.default)(x);
481
+ }).map((s) => s.toLowerCase()).join("/");
482
+ return `/${suffix}`;
483
+ };
484
+ var _generateRestInfo = (method, withId, ...additional) => (pluralName, namespace) => (existing) => {
485
+ if (existing) {
486
+ return {
487
+ // Default add security, then override it.
488
+ security: {},
489
+ ...existing
490
+ };
491
+ }
492
+ const endpoint = withId ? buildValidEndpoint(namespace, pluralName, ID_KEY) : buildValidEndpoint(namespace, pluralName, ...additional);
493
+ return {
494
+ method,
495
+ endpoint,
496
+ // We cannot auto create security.
497
+ security: {}
498
+ };
499
+ };
500
+ var _apiMethodToRestInfoGenerator = {
501
+ ["create" /* create */]: _generateRestInfo(HttpMethods.POST, false),
502
+ ["retrieve" /* retrieve */]: _generateRestInfo(HttpMethods.GET, true),
503
+ ["update" /* update */]: _generateRestInfo(HttpMethods.PUT, true),
504
+ ["delete" /* delete */]: _generateRestInfo(HttpMethods.DELETE, true),
505
+ ["search" /* search */]: _generateRestInfo(HttpMethods.POST, false, "search")
506
+ };
507
+ var createZodForProperty = (propertyType, config) => () => {
508
+ const myConfig = config || {};
509
+ const provided = myConfig.zod;
510
+ if (provided) {
511
+ return provided;
512
+ }
513
+ const _getZodForPropertyType = (pt) => {
514
+ if (myConfig.choices) {
515
+ return import_zod.z.enum(myConfig.choices);
516
+ }
517
+ switch (pt) {
518
+ case "UniqueId":
519
+ return import_zod.z.string();
520
+ case "Date":
521
+ case "Datetime":
522
+ return import_zod.z.union([import_zod.z.string(), import_zod.z.date()]);
523
+ case "Integer":
524
+ return import_zod.z.number().int();
525
+ case "Number":
526
+ return import_zod.z.number();
527
+ case "Boolean":
528
+ return import_zod.z.boolean();
529
+ case "Array":
530
+ return import_zod.z.array(import_zod.z.any());
531
+ case "Object":
532
+ return import_zod.z.object().loose();
533
+ case "Email":
534
+ return import_zod.z.email();
535
+ case "Text":
536
+ case "BigText":
537
+ return import_zod.z.string();
538
+ case "ModelReference":
539
+ return import_zod.z.union([import_zod.z.string(), import_zod.z.number()]);
540
+ default:
541
+ return import_zod.z.any();
542
+ }
543
+ };
544
+ const baseSchema = _getZodForPropertyType(propertyType);
545
+ const choices2 = config?.choices;
546
+ const schemaFromChoices = choices2 && Array.isArray(choices2) && choices2.length > 0 ? import_zod.z.union(choices2.map((c) => import_zod.z.literal(c))) : baseSchema;
547
+ const finalSchema = (0, import_flow.default)([
548
+ (s) => typeof myConfig.minValue === "number" ? s.min(myConfig.minValue) : s,
549
+ (s) => typeof myConfig.maxValue === "number" ? s.max(myConfig.maxValue) : s,
550
+ (s) => typeof myConfig.minLength === "number" ? s.min(myConfig.minLength) : s,
551
+ (s) => typeof myConfig.maxLength === "number" ? s.max(myConfig.maxLength) : s,
552
+ (s) => myConfig.defaultValue !== void 0 ? s.default(myConfig.defaultValue) : s,
553
+ (s) => myConfig.required ? s : s.optional(),
554
+ // Attach description for Zod consumers and OpenAPI generators.
555
+ (s) => {
556
+ if (myConfig.description) {
557
+ if (typeof s.openapi === "function") {
558
+ return s.openapi({ description: myConfig.description });
559
+ }
560
+ return s.meta ? s.meta({ description: myConfig.description }) : s.describe(myConfig.description);
561
+ }
562
+ return s;
563
+ }
564
+ ])(schemaFromChoices);
565
+ return finalSchema;
566
+ };
567
+
568
+ // src/properties.ts
569
+ var MAX_YEAR = 3e3;
570
+ var EMAIL_REGEX = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/u;
571
+ var Property = (propertyType, config = {}, additionalMetadata = {}) => {
572
+ if (!propertyType && !config?.typeOverride) {
573
+ throw new Error(`Property type must be provided.`);
574
+ }
575
+ if (config?.typeOverride) {
576
+ propertyType = config.typeOverride;
577
+ }
578
+ const getConstantValue = () => config?.value !== void 0 ? config.value : void 0;
579
+ const getDefaultValue = () => config?.defaultValue !== void 0 ? config.defaultValue : void 0;
580
+ const getChoices = () => config?.choices || [];
581
+ const lazyLoadMethod = config?.lazyLoadMethod || false;
582
+ const valueSelector = config?.valueSelector || ((x) => x);
583
+ if (typeof valueSelector !== "function") {
584
+ throw new Error(`valueSelector must be a function`);
585
+ }
586
+ const createGetter = (instanceValue, modelData, instance) => {
587
+ const constantValue = getConstantValue();
588
+ if (constantValue !== void 0) {
589
+ return () => constantValue;
590
+ }
591
+ const defaultValue = getDefaultValue();
592
+ if (defaultValue !== void 0 && (instanceValue === null || instanceValue === void 0)) {
593
+ return () => defaultValue;
594
+ }
595
+ const method = lazyLoadMethod ? lazyLoadMethod : config.lazyLoadMethodAtomic ? memoizeAsync(config.lazyLoadMethodAtomic) : typeof instanceValue === "function" ? instanceValue : () => instanceValue;
596
+ const valueGetter = memoizeSync(() => {
597
+ const result = method(
598
+ instanceValue,
599
+ modelData,
600
+ // @ts-ignore
601
+ instance
602
+ );
603
+ return valueSelector(result);
604
+ });
605
+ return valueGetter;
606
+ };
607
+ const getValidator = (valueGetter) => {
608
+ const validator = createPropertyValidator(valueGetter, config);
609
+ const _propertyValidatorWrapper = async (model, instanceData, propertyConfiguration) => {
610
+ return validator(model, instanceData, propertyConfiguration);
611
+ };
612
+ return _propertyValidatorWrapper;
613
+ };
614
+ const getZod = () => {
615
+ const provided = config?.zod;
616
+ if (provided) {
617
+ return provided;
618
+ }
619
+ return createZodForProperty(propertyType, config)();
620
+ };
621
+ const propertyInstance = {
622
+ ...additionalMetadata,
623
+ getConfig: () => config || {},
624
+ getChoices,
625
+ getDefaultValue,
626
+ getConstantValue,
627
+ getPropertyType: () => propertyType,
628
+ createGetter,
629
+ getZod,
630
+ getValidator
631
+ };
632
+ return propertyInstance;
633
+ };
634
+ var isDate2 = (value) => {
635
+ if (value === null) {
636
+ return false;
637
+ }
638
+ return typeof value === "object" && value.toISOString;
639
+ };
640
+ var DateProperty = (config = {}, additionalMetadata = {}) => Property(
641
+ "Date" /* Date */,
642
+ (0, import_merge3.default)(
643
+ {
644
+ lazyLoadMethod: (value) => {
645
+ if (isDate2(value)) {
646
+ if (config.formatFunction) {
647
+ return config.formatFunction(value, config.format);
648
+ }
649
+ return value.toISOString().split("T")[0];
650
+ }
651
+ if (!value && config?.autoNow) {
652
+ const date = /* @__PURE__ */ new Date();
653
+ if (config.formatFunction) {
654
+ return config.formatFunction(date, config.format);
655
+ }
656
+ return date.toISOString().split("T")[0];
657
+ }
658
+ return value;
659
+ }
660
+ },
661
+ config
662
+ ),
663
+ additionalMetadata
664
+ );
665
+ var DatetimeProperty = (config = {}, additionalMetadata = {}) => Property(
666
+ "Datetime" /* Datetime */,
667
+ (0, import_merge3.default)(
668
+ {
669
+ lazyLoadMethod: (value) => {
670
+ if (isDate2(value)) {
671
+ if (config.formatFunction) {
672
+ return config.formatFunction(value, config.format);
673
+ }
674
+ return value.toISOString();
675
+ }
676
+ if (!value && config?.autoNow) {
677
+ const date = /* @__PURE__ */ new Date();
678
+ if (config.formatFunction) {
679
+ return config.formatFunction(date, config.format);
680
+ }
681
+ return date.toISOString();
682
+ }
683
+ return value;
684
+ }
685
+ },
686
+ config
687
+ ),
688
+ additionalMetadata
689
+ );
690
+ var ArrayProperty = (config = {}, additionalMetadata = {}) => Property(
691
+ "Array" /* Array */,
692
+ {
693
+ defaultValue: [],
694
+ ...config,
695
+ isArray: true
696
+ },
697
+ additionalMetadata
698
+ );
699
+ var SingleTypeArrayProperty = (valueType, config = {}, additionalMetadata = {}) => Property(
700
+ "Array" /* Array */,
701
+ {
702
+ defaultValue: [],
703
+ ...config,
704
+ isArray: true,
705
+ validators: mergeValidators(
706
+ config,
707
+ // @ts-ignore
708
+ arrayType(valueType)
709
+ )
710
+ },
711
+ additionalMetadata
712
+ );
713
+ var ObjectProperty = (config = {}, additionalMetadata = {}) => Property(
714
+ "Object" /* Object */,
715
+ (0, import_merge3.default)(config, {
716
+ validators: mergeValidators(config, isType("object"))
717
+ }),
718
+ additionalMetadata
719
+ );
720
+ var TextProperty = (config = {}, additionalMetadata = {}) => Property(
721
+ "Text" /* Text */,
722
+ (0, import_merge3.default)(config, {
723
+ isString: true,
724
+ // @ts-ignore
725
+ validators: mergeValidators(config, ...getCommonTextValidators(config))
726
+ }),
727
+ additionalMetadata
728
+ );
729
+ var BigTextProperty = (config = {}, additionalMetadata = {}) => Property(
730
+ "BigText" /* BigText */,
731
+ (0, import_merge3.default)(config, {
732
+ isString: true,
733
+ validators: mergeValidators(
734
+ config,
735
+ ...getCommonTextValidators(config)
736
+ )
737
+ }),
738
+ additionalMetadata
739
+ );
740
+ var IntegerProperty = (config = {}, additionalMetadata = {}) => Property(
741
+ "Integer" /* Integer */,
742
+ (0, import_merge3.default)(config, {
743
+ isInteger: true,
744
+ validators: mergeValidators(
745
+ config,
746
+ ...getCommonNumberValidators(config)
747
+ )
748
+ }),
749
+ additionalMetadata
750
+ );
751
+ var YearProperty = (config = {}, additionalMetadata = {}) => Property(
752
+ "Integer" /* Integer */,
753
+ (0, import_merge3.default)(config, {
754
+ isInteger: true,
755
+ validators: mergeValidators(
756
+ config,
757
+ ...getCommonNumberValidators(config),
758
+ minNumber(0),
759
+ maxNumber(MAX_YEAR)
760
+ )
761
+ }),
762
+ additionalMetadata
763
+ );
764
+ var NumberProperty = (config = {}, additionalMetadata = {}) => Property(
765
+ "Number" /* Number */,
766
+ (0, import_merge3.default)(config, {
767
+ isNumber: true,
768
+ validators: mergeValidators(config, ...getCommonNumberValidators(config))
769
+ }),
770
+ additionalMetadata
771
+ );
772
+ var ConstantValueProperty = (valueType, value, config = {}, additionalMetadata = {}) => Property(
773
+ valueType,
774
+ (0, import_merge3.default)(config, {
775
+ value
776
+ }),
777
+ additionalMetadata
778
+ );
779
+ var EmailProperty = (config = {}, additionalMetadata = {}) => TextProperty(
780
+ (0, import_merge3.default)(config, {
781
+ type: "Email" /* Email */,
782
+ validators: mergeValidators(config, meetsRegex(EMAIL_REGEX))
783
+ }),
784
+ additionalMetadata
785
+ );
786
+ var BooleanProperty = (config = {}, additionalMetadata = {}) => Property(
787
+ "Boolean" /* Boolean */,
788
+ (0, import_merge3.default)(config, {
789
+ isBoolean: true
790
+ }),
791
+ additionalMetadata
792
+ );
793
+ var PrimaryKeyUuidProperty = (config = {}, additionalMetadata = {}) => Property(
794
+ "UniqueId" /* UniqueId */,
795
+ (0, import_merge3.default)(config, {
796
+ required: true,
797
+ isString: true,
798
+ validators: mergeValidators(config, isValidUuid),
799
+ lazyLoadMethod: (value) => {
800
+ if (!value) {
801
+ return v4_default();
802
+ }
803
+ return value;
804
+ }
805
+ }),
806
+ additionalMetadata
807
+ );
808
+ var UuidProperty = (config = {}, additionalMetadata = {}) => Property(
809
+ "UniqueId" /* UniqueId */,
810
+ (0, import_merge3.default)(config, {
811
+ isString: true,
812
+ validators: mergeValidators(
813
+ config,
814
+ config.required ? isValidUuid : optionalValidator(isValidUuid)
815
+ ),
816
+ lazyLoadMethod: (value) => {
817
+ if (!value) {
818
+ if (config.autoNow) {
819
+ return v4_default();
820
+ }
821
+ }
822
+ return value;
823
+ }
824
+ }),
825
+ additionalMetadata
826
+ );
827
+ var ModelReferenceProperty = (model, config = {}, additionalMetadata = {}) => AdvancedModelReferenceProperty(model, config, additionalMetadata);
828
+ var AdvancedModelReferenceProperty = (model, config = {}, additionalMetadata = {}) => {
829
+ if (!model) {
830
+ throw new Error("Must include the referenced model");
831
+ }
832
+ const _getModel = () => {
833
+ if (typeof model === "function") {
834
+ return model();
835
+ }
836
+ return model;
837
+ };
838
+ const validator = referenceTypeMatch(model);
839
+ const validators = mergeValidators(config, validator);
840
+ const _getId = (instanceValues) => () => {
841
+ if (!instanceValues) {
842
+ return void 0;
843
+ }
844
+ if (typeof instanceValues === "number") {
845
+ return instanceValues;
846
+ }
847
+ if (typeof instanceValues === "string") {
848
+ return instanceValues;
849
+ }
850
+ if (instanceValues.getPrimaryKey) {
851
+ return instanceValues.getPrimaryKey();
852
+ }
853
+ const theModel = _getModel();
854
+ const primaryKey = theModel.getModelDefinition().primaryKeyName;
855
+ return instanceValues[primaryKey];
856
+ };
857
+ const lazyLoadMethodAtomic = async (instanceValues) => {
858
+ const valueIsModelInstance = isModelInstance(instanceValues);
859
+ const _getInstanceReturn = (objToUse) => {
860
+ const objIsModelInstance = isModelInstance(objToUse);
861
+ const instance = objIsModelInstance ? objToUse : (
862
+ // @ts-ignore
863
+ _getModel().create(objToUse)
864
+ );
865
+ return (0, import_merge3.default)({}, instance, {
866
+ toObj: memoizeAsync(_getId(instanceValues))
867
+ });
868
+ };
869
+ if (valueIsModelInstance) {
870
+ return _getInstanceReturn(instanceValues);
871
+ }
872
+ const theModel = _getModel();
873
+ const primaryKey = theModel.getModelDefinition().primaryKeyName;
874
+ if ((0, import_get3.default)(instanceValues, primaryKey)) {
875
+ return _getInstanceReturn(instanceValues);
876
+ }
877
+ if (config?.fetcher) {
878
+ const id = await _getId(instanceValues)();
879
+ const model2 = _getModel();
880
+ if (id !== null && id !== void 0) {
881
+ const obj = await config.fetcher(model2, id);
882
+ return _getInstanceReturn(obj);
883
+ }
884
+ return null;
885
+ }
886
+ return _getId(instanceValues)();
887
+ };
888
+ const p = (0, import_merge3.default)(
889
+ Property(
890
+ "ModelReference" /* ModelReference */,
891
+ (0, import_merge3.default)({}, config, {
892
+ validators,
893
+ lazyLoadMethodAtomic
894
+ }),
895
+ additionalMetadata
896
+ ),
897
+ {
898
+ getReferencedId: (instanceValues) => _getId(instanceValues)(),
899
+ getReferencedModel: _getModel
900
+ }
901
+ );
902
+ return p;
903
+ };
904
+ var DenormalizedProperty = (propertyType, calculate, config = {}, additionalMetadata = {}) => {
905
+ const property = Property(
906
+ propertyType,
907
+ (0, import_merge3.default)(config, {
908
+ isDenormalized: true,
909
+ lazyLoadMethodAtomic: async (value, modelData, modelInstance) => {
910
+ if (value !== void 0) {
911
+ return value;
912
+ }
913
+ return calculate(modelData, modelInstance);
914
+ }
915
+ }),
916
+ additionalMetadata
917
+ );
918
+ return (0, import_merge3.default)(property, {
919
+ calculate
920
+ });
921
+ };
922
+ var DenormalizedTextProperty = (calculate, config = {}, additionalMetadata = {}) => DenormalizedProperty(
923
+ "Text" /* Text */,
924
+ calculate,
925
+ (0, import_merge3.default)(config, {
926
+ isString: true,
927
+ validators: mergeValidators(
928
+ config,
929
+ ...getCommonTextValidators(config)
930
+ )
931
+ }),
932
+ additionalMetadata
933
+ );
934
+ var DenormalizedNumberProperty = (calculate, config = {}, additionalMetadata = {}) => DenormalizedProperty(
935
+ "Number" /* Number */,
936
+ calculate,
937
+ (0, import_merge3.default)(config, {
938
+ isNumber: true,
939
+ validators: mergeValidators(config, ...getCommonNumberValidators(config))
940
+ }),
941
+ additionalMetadata
942
+ );
943
+ var DenormalizedIntegerProperty = (calculate, config = {}, additionalMetadata = {}) => DenormalizedProperty(
944
+ "Integer" /* Integer */,
945
+ calculate,
946
+ (0, import_merge3.default)(config, {
947
+ isInteger: true,
948
+ validators: mergeValidators(config, ...getCommonNumberValidators(config))
949
+ }),
950
+ additionalMetadata
951
+ );
952
+ var NaturalIdProperty = (propertyKeys, joiner, config = {}, additionalMetadata = {}) => Property(
953
+ "Text" /* Text */,
954
+ (0, import_merge3.default)(config, {
955
+ isString: true,
956
+ validators: mergeValidators(config, ...getCommonTextValidators(config)),
957
+ lazyLoadMethodAtomic: async (value, model, modelInstance) => {
958
+ const data = await propertyKeys.reduce(async (accP, key) => {
959
+ const acc = await accP;
960
+ const [head] = createHeadAndTail(key.split("."), ".");
961
+ const value2 = await (isReferencedProperty(modelInstance, head) ? getValueForReferencedModel(modelInstance, key) : getValueForModelInstance(modelInstance, key));
962
+ return acc.concat(value2);
963
+ }, Promise.resolve([]));
964
+ if (data.some((value2) => value2 === void 0)) {
965
+ return void 0;
966
+ }
967
+ return data.join(joiner);
968
+ }
969
+ }),
970
+ additionalMetadata
971
+ );
972
+ // Annotate the CommonJS export names for ESM import in node:
973
+ 0 && (module.exports = {
974
+ AdvancedModelReferenceProperty,
975
+ ArrayProperty,
976
+ BigTextProperty,
977
+ BooleanProperty,
978
+ ConstantValueProperty,
979
+ DateProperty,
980
+ DatetimeProperty,
981
+ DenormalizedIntegerProperty,
982
+ DenormalizedNumberProperty,
983
+ DenormalizedProperty,
984
+ DenormalizedTextProperty,
985
+ EmailProperty,
986
+ IntegerProperty,
987
+ ModelReferenceProperty,
988
+ NaturalIdProperty,
989
+ NumberProperty,
990
+ ObjectProperty,
991
+ PrimaryKeyUuidProperty,
992
+ Property,
993
+ SingleTypeArrayProperty,
994
+ TextProperty,
995
+ UuidProperty,
996
+ YearProperty
997
+ });
998
+ //# sourceMappingURL=properties.cjs.map