@sprucelabs/schema 29.4.60 → 30.0.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 (117) hide show
  1. package/build/.spruce/schemas/fields/fieldClassMap.d.ts +2 -2
  2. package/build/.spruce/schemas/fields/fieldClassMap.js +3 -3
  3. package/build/AbstractEntity.js +1 -0
  4. package/build/AbstractSchemaTest.js +1 -0
  5. package/build/DynamicSchemaEntityImplementation.js +4 -3
  6. package/build/StaticSchemaEntityImpl.js +23 -13
  7. package/build/errors/SpruceError.js +3 -4
  8. package/build/errors/ValidateErrorMessageFormatter.js +11 -8
  9. package/build/esm/.spruce/schemas/fields/fieldClassMap.d.ts +2 -2
  10. package/build/esm/.spruce/schemas/fields/fieldClassMap.js +3 -3
  11. package/build/esm/StaticSchemaEntityImpl.js +6 -2
  12. package/build/esm/errors/ValidateErrorMessageFormatter.js +5 -1
  13. package/build/esm/fields/AddressField.d.ts +1 -1
  14. package/build/esm/fields/AddressField.js +3 -4
  15. package/build/esm/fields/BooleanField.d.ts +1 -1
  16. package/build/esm/fields/BooleanField.js +3 -4
  17. package/build/esm/fields/DateField.d.ts +1 -1
  18. package/build/esm/fields/DateField.js +3 -4
  19. package/build/esm/fields/DateTimeField.d.ts +1 -1
  20. package/build/esm/fields/DateTimeField.js +3 -4
  21. package/build/esm/fields/DirectoryField.d.ts +1 -1
  22. package/build/esm/fields/DirectoryField.js +9 -7
  23. package/build/esm/fields/DurationField.d.ts +1 -1
  24. package/build/esm/fields/DurationField.js +5 -5
  25. package/build/esm/fields/EmailField.d.ts +1 -1
  26. package/build/esm/fields/EmailField.js +3 -4
  27. package/build/esm/fields/FileField.d.ts +1 -1
  28. package/build/esm/fields/FileField.js +3 -4
  29. package/build/esm/fields/IdField.d.ts +1 -1
  30. package/build/esm/fields/IdField.js +3 -4
  31. package/build/esm/fields/ImageField.d.ts +1 -1
  32. package/build/esm/fields/ImageField.js +3 -4
  33. package/build/esm/fields/NumberField.d.ts +1 -1
  34. package/build/esm/fields/NumberField.js +3 -4
  35. package/build/esm/fields/PhoneField.d.ts +1 -1
  36. package/build/esm/fields/PhoneField.js +3 -4
  37. package/build/esm/fields/RawField.d.ts +1 -1
  38. package/build/esm/fields/RawField.js +3 -4
  39. package/build/esm/fields/SchemaField.d.ts +1 -1
  40. package/build/esm/fields/SchemaField.js +23 -13
  41. package/build/esm/fields/SchemaField.types.d.ts +2 -2
  42. package/build/esm/fields/SelectField.d.ts +1 -1
  43. package/build/esm/fields/SelectField.js +3 -4
  44. package/build/esm/fields/TextField.d.ts +1 -1
  45. package/build/esm/fields/TextField.js +7 -5
  46. package/build/esm/fields/field.static.types.d.ts +2 -4
  47. package/build/esm/schemas.static.types.d.ts +3 -10
  48. package/build/esm/tests/validationErrorAssert.utility.d.ts +2 -2
  49. package/build/esm/types/utilities.types.d.ts +4 -4
  50. package/build/esm/utilities/KeyMapper.js +0 -3
  51. package/build/esm/utilities/cloneDeep.js +2 -1
  52. package/build/esm/utilities/formatPhoneNumber.js +4 -2
  53. package/build/esm/utilities/mapFieldErrorsToParameterErrors.js +3 -1
  54. package/build/esm/utilities/registerFieldType.js +1 -3
  55. package/build/esm/utilities/validateSchemaValues.js +1 -3
  56. package/build/fields/AbstractField.js +7 -2
  57. package/build/fields/AddressField.d.ts +1 -1
  58. package/build/fields/AddressField.js +1 -3
  59. package/build/fields/BooleanField.d.ts +1 -1
  60. package/build/fields/BooleanField.js +1 -3
  61. package/build/fields/DateField.d.ts +1 -1
  62. package/build/fields/DateField.js +1 -3
  63. package/build/fields/DateTimeField.d.ts +1 -1
  64. package/build/fields/DateTimeField.js +2 -5
  65. package/build/fields/DirectoryField.d.ts +1 -1
  66. package/build/fields/DirectoryField.js +8 -7
  67. package/build/fields/DurationField.d.ts +1 -1
  68. package/build/fields/DurationField.js +4 -6
  69. package/build/fields/EmailField.d.ts +1 -1
  70. package/build/fields/EmailField.js +1 -3
  71. package/build/fields/FileField.d.ts +1 -1
  72. package/build/fields/FileField.js +3 -6
  73. package/build/fields/IdField.d.ts +1 -1
  74. package/build/fields/IdField.js +1 -3
  75. package/build/fields/ImageField.d.ts +1 -1
  76. package/build/fields/ImageField.js +3 -7
  77. package/build/fields/NumberField.d.ts +1 -1
  78. package/build/fields/NumberField.js +1 -3
  79. package/build/fields/PhoneField.d.ts +1 -1
  80. package/build/fields/PhoneField.js +1 -3
  81. package/build/fields/RawField.d.ts +1 -1
  82. package/build/fields/RawField.js +1 -3
  83. package/build/fields/SchemaField.d.ts +1 -1
  84. package/build/fields/SchemaField.js +28 -16
  85. package/build/fields/SchemaField.types.d.ts +2 -2
  86. package/build/fields/SelectField.d.ts +1 -1
  87. package/build/fields/SelectField.js +1 -3
  88. package/build/fields/TextField.d.ts +1 -1
  89. package/build/fields/TextField.js +6 -6
  90. package/build/fields/field.static.types.d.ts +2 -4
  91. package/build/schemas.static.types.d.ts +3 -10
  92. package/build/singletons/SchemaRegistry.js +4 -6
  93. package/build/tests/AbstractDateFieldTest.js +2 -0
  94. package/build/tests/validationErrorAssert.utility.d.ts +2 -2
  95. package/build/tests/validationErrorAssert.utility.js +2 -3
  96. package/build/types/utilities.types.d.ts +4 -4
  97. package/build/utilities/KeyMapper.js +3 -7
  98. package/build/utilities/areSchemasTheSame.js +2 -3
  99. package/build/utilities/assertOptions.js +1 -1
  100. package/build/utilities/cloneDeep.js +3 -3
  101. package/build/utilities/cloneDeepPreservingInstances.js +1 -2
  102. package/build/utilities/defaultSchemaValues.js +4 -1
  103. package/build/utilities/dropFields.js +3 -1
  104. package/build/utilities/dropPrivateFields.js +3 -1
  105. package/build/utilities/formatPhoneNumber.js +6 -5
  106. package/build/utilities/getFields.js +1 -2
  107. package/build/utilities/isSchemaValid.js +1 -1
  108. package/build/utilities/makeFieldsOptional.js +4 -1
  109. package/build/utilities/mapFieldErrorsToParameterErrors.js +15 -4
  110. package/build/utilities/normalizeFieldValue.js +13 -16
  111. package/build/utilities/normalizePartialSchemaValues.js +4 -1
  112. package/build/utilities/normalizeSchemaValues.js +5 -13
  113. package/build/utilities/registerFieldType.js +15 -6
  114. package/build/utilities/selectChoicesToHash.js +1 -2
  115. package/build/utilities/validateSchema.js +1 -2
  116. package/build/utilities/validateSchemaValues.js +2 -15
  117. package/package.json +11 -11
@@ -3,7 +3,7 @@ import AbstractField from './AbstractField';
3
3
  import { ImageFieldDefinition } from './ImageField.types';
4
4
  export default class ImageField extends AbstractField<ImageFieldDefinition> {
5
5
  static generateTemplateDetails(options: FieldTemplateDetailOptions<ImageFieldDefinition>): FieldTemplateDetails;
6
- static get description(): string;
6
+ static readonly description = "Images of various sizes!";
7
7
  validate(value: any): import("..").FieldError[];
8
8
  private getRequiredSizes;
9
9
  }
@@ -1,15 +1,12 @@
1
1
  import AbstractField from './AbstractField.js';
2
2
  import { requiredImageSizes } from './ImageField.types.js';
3
- export default class ImageField extends AbstractField {
3
+ class ImageField extends AbstractField {
4
4
  static generateTemplateDetails(options) {
5
5
  const { definition, importAs } = options;
6
6
  return {
7
7
  valueType: `${importAs}.ImageFieldValue${definition.isArray ? '[]' : ''}`,
8
8
  };
9
9
  }
10
- static get description() {
11
- return 'Images of various sizes!';
12
- }
13
10
  validate(value) {
14
11
  var _a;
15
12
  const errors = super.validate(value);
@@ -42,3 +39,5 @@ export default class ImageField extends AbstractField {
42
39
  return sizes;
43
40
  }
44
41
  }
42
+ ImageField.description = 'Images of various sizes!';
43
+ export default ImageField;
@@ -3,7 +3,7 @@ import { FieldTemplateDetailOptions, FieldTemplateDetails } from '../types/templ
3
3
  import AbstractField from './AbstractField';
4
4
  import { NumberFieldDefinition } from './NumberField.types';
5
5
  export default class NumberField extends AbstractField<NumberFieldDefinition> {
6
- static get description(): string;
6
+ static readonly description = "Handles all types of numbers with min/max and clamp support";
7
7
  static generateTemplateDetails(options: FieldTemplateDetailOptions<NumberFieldDefinition>): FieldTemplateDetails;
8
8
  toValueType(value: any): number;
9
9
  private buildNaNError;
@@ -1,9 +1,6 @@
1
1
  import SpruceError from '../errors/SpruceError.js';
2
2
  import AbstractField from './AbstractField.js';
3
- export default class NumberField extends AbstractField {
4
- static get description() {
5
- return 'Handles all types of numbers with min/max and clamp support';
6
- }
3
+ class NumberField extends AbstractField {
7
4
  static generateTemplateDetails(options) {
8
5
  return {
9
6
  valueType: `number${options.definition.isArray ? '[]' : ''}`,
@@ -45,3 +42,5 @@ export default class NumberField extends AbstractField {
45
42
  return typeof value === 'undefined' || value === null || !isNaN(value);
46
43
  }
47
44
  }
45
+ NumberField.description = 'Handles all types of numbers with min/max and clamp support';
46
+ export default NumberField;
@@ -3,7 +3,7 @@ import AbstractField from './AbstractField';
3
3
  import { ValidateOptions } from './field.static.types';
4
4
  import { PhoneFieldDefinition } from './PhoneField.types';
5
5
  export default class PhoneField extends AbstractField<PhoneFieldDefinition> {
6
- static get description(): string;
6
+ static readonly description = "Takes anything close to a phone number and formats it. Also great at validating numbers.";
7
7
  static generateTemplateDetails(options: FieldTemplateDetailOptions<PhoneFieldDefinition>): FieldTemplateDetails;
8
8
  toValueType(value: any): string;
9
9
  validate(value: any, options?: ValidateOptions<PhoneFieldDefinition>): import("..").FieldError[];
@@ -1,9 +1,6 @@
1
1
  import formatPhoneNumber, { isValidNumber, } from '../utilities/formatPhoneNumber.js';
2
2
  import AbstractField from './AbstractField.js';
3
- export default class PhoneField extends AbstractField {
4
- static get description() {
5
- return 'Takes anything close to a phone number and formats it. Also great at validating numbers.';
6
- }
3
+ class PhoneField extends AbstractField {
7
4
  static generateTemplateDetails(options) {
8
5
  return {
9
6
  valueType: `string${options.definition.isArray ? '[]' : ''}`,
@@ -34,3 +31,5 @@ export default class PhoneField extends AbstractField {
34
31
  return errors;
35
32
  }
36
33
  }
34
+ PhoneField.description = 'Takes anything close to a phone number and formats it. Also great at validating numbers.';
35
+ export default PhoneField;
@@ -2,6 +2,6 @@ import { FieldTemplateDetailOptions, FieldTemplateDetails } from '../types/templ
2
2
  import AbstractField from './AbstractField';
3
3
  import { RawFieldDefinition } from './RawField.types';
4
4
  export default class RawField extends AbstractField<RawFieldDefinition> {
5
- static get description(): string;
5
+ static readonly description = "Set an interface directly.";
6
6
  static generateTemplateDetails(options: FieldTemplateDetailOptions<RawFieldDefinition>): FieldTemplateDetails;
7
7
  }
@@ -1,11 +1,10 @@
1
1
  import AbstractField from './AbstractField.js';
2
- export default class RawField extends AbstractField {
3
- static get description() {
4
- return 'Set an interface directly.';
5
- }
2
+ class RawField extends AbstractField {
6
3
  static generateTemplateDetails(options) {
7
4
  return {
8
5
  valueType: `(${options.definition.options.valueType})${options.definition.isArray ? '[]' : ''}`,
9
6
  };
10
7
  }
11
8
  }
9
+ RawField.description = 'Set an interface directly.';
10
+ export default RawField;
@@ -5,7 +5,7 @@ import AbstractField from './AbstractField';
5
5
  import { ValidateOptions, ToValueTypeOptions, FieldDefinitionValueType } from './field.static.types';
6
6
  import { SchemaFieldFieldDefinition } from './SchemaField.types';
7
7
  export default class SchemaField<F extends SchemaFieldFieldDefinition = SchemaFieldFieldDefinition> extends AbstractField<F> {
8
- static get description(): string;
8
+ static readonly description = "A way to map relationships.";
9
9
  static mapFieldDefinitionToSchemasOrIdsWithVersion(field: SchemaFieldFieldDefinition): (SchemaIdWithVersion | Schema)[];
10
10
  static mapFieldDefinitionToSchemaIdsWithVersion(field: SchemaFieldFieldDefinition): SchemaIdWithVersion[];
11
11
  static generateTypeDetails(): {
@@ -8,10 +8,7 @@ import isIdWithVersion from '../utilities/isIdWithVersion.js';
8
8
  import normalizeSchemaToIdWithVersion from '../utilities/normalizeSchemaToIdWithVersion.js';
9
9
  import validateSchema from '../utilities/validateSchema.js';
10
10
  import AbstractField from './AbstractField.js';
11
- export default class SchemaField extends AbstractField {
12
- static get description() {
13
- return 'A way to map relationships.';
14
- }
11
+ class SchemaField extends AbstractField {
15
12
  static mapFieldDefinitionToSchemasOrIdsWithVersion(field) {
16
13
  const { options } = field;
17
14
  const schemasOrIds = [
@@ -70,7 +67,7 @@ export default class SchemaField extends AbstractField {
70
67
  if (!item.namespace) {
71
68
  throwInvalidReferenceError(item);
72
69
  }
73
- return item.namespace.toLowerCase() === namespace.toLowerCase();
70
+ return (item.namespace.toLowerCase() === namespace.toLowerCase());
74
71
  });
75
72
  }
76
73
  let matchedTemplateItem;
@@ -97,7 +94,8 @@ export default class SchemaField extends AbstractField {
97
94
  valueType = `${globalNamespace}.${matchedTemplateItem.namespace}${version ? `.${version}` : ''}${renderAs === TemplateRenderAs.Type
98
95
  ? `.${matchedTemplateItem.namePascal + typeSuffix}`
99
96
  : `.${matchedTemplateItem.namePascal}Schema`}`;
100
- if (renderAs === TemplateRenderAs.Type && idsWithVersion.length > 1) {
97
+ if (renderAs === TemplateRenderAs.Type &&
98
+ idsWithVersion.length > 1) {
101
99
  valueType = `{ schemaId: '${id}'${version ? `, version: '${version}'` : ''}, values: ${valueType} }`;
102
100
  }
103
101
  }
@@ -119,11 +117,14 @@ export default class SchemaField extends AbstractField {
119
117
  valueType =
120
118
  unions.length === 1
121
119
  ? unions[0].valueType
122
- : '[' + unions.map((item) => item.valueType).join(', ') + ']';
120
+ : '[' +
121
+ unions.map((item) => item.valueType).join(', ') +
122
+ ']';
123
123
  }
124
124
  else {
125
125
  valueType = unions.map((item) => item.valueType).join(' | ');
126
- valueType = `${(definition.isArray || renderAs === TemplateRenderAs.SchemaType) &&
126
+ valueType = `${(definition.isArray ||
127
+ renderAs === TemplateRenderAs.SchemaType) &&
127
128
  unions.length > 1
128
129
  ? `(${valueType})`
129
130
  : `${valueType}`}${(definition.isArray && renderAs === TemplateRenderAs.Type) ||
@@ -204,7 +205,8 @@ export default class SchemaField extends AbstractField {
204
205
  name: this.name,
205
206
  label: this.label,
206
207
  code: 'INVALID_PARAMETER',
207
- friendlyMessage: 'You need to add `values` to the value of ' + this.name,
208
+ friendlyMessage: 'You need to add `values` to the value of ' +
209
+ this.name,
208
210
  });
209
211
  }
210
212
  else if (!schemaId) {
@@ -212,17 +214,21 @@ export default class SchemaField extends AbstractField {
212
214
  name: this.name,
213
215
  label: this.label,
214
216
  code: 'INVALID_PARAMETER',
215
- friendlyMessage: 'You need to add `schemaId` to the value of ' + this.name,
217
+ friendlyMessage: 'You need to add `schemaId` to the value of ' +
218
+ this.name,
216
219
  });
217
220
  }
218
221
  else {
219
- const matchSchema = schemas.find((schema) => schema.id === schemaId && schema.version === version);
222
+ const matchSchema = schemas.find((schema) => schema.id === schemaId &&
223
+ schema.version === version);
220
224
  if (!matchSchema) {
221
225
  errors.push({
222
226
  name: this.name,
223
227
  label: this.label,
224
228
  code: 'INVALID_PARAMETER',
225
- friendlyMessage: `Could not find a schema by id '${schemaId}'${version ? ` and version '${version}'` : ' with no version'}.`,
229
+ friendlyMessage: `Could not find a schema by id '${schemaId}'${version
230
+ ? ` and version '${version}'`
231
+ : ' with no version'}.`,
226
232
  });
227
233
  }
228
234
  else {
@@ -267,7 +273,9 @@ export default class SchemaField extends AbstractField {
267
273
  }
268
274
  const { createEntityInstances, schemasById: schemasById = {} } = options || {};
269
275
  // try and pull the schema definition from the options and by id
270
- const destinationSchemas = SchemaField.mapFieldDefinitionToSchemas(this.definition, { schemasById });
276
+ const destinationSchemas = SchemaField.mapFieldDefinitionToSchemas(this.definition, {
277
+ schemasById,
278
+ });
271
279
  const isUnion = destinationSchemas.length > 1;
272
280
  let instance;
273
281
  if (value instanceof AbstractEntity) {
@@ -320,6 +328,8 @@ export default class SchemaField extends AbstractField {
320
328
  return instance.getValues(getValueOptions);
321
329
  }
322
330
  }
331
+ SchemaField.description = 'A way to map relationships.';
332
+ export default SchemaField;
323
333
  function throwInvalidReferenceError(item) {
324
334
  throw new SpruceError({
325
335
  code: 'INVALID_SCHEMA_REFERENCE',
@@ -15,14 +15,14 @@ export interface SchemaFieldOptions {
15
15
  /** Dropped in after the type. Used to generate generics, like <T> */
16
16
  typeSuffix?: string;
17
17
  }
18
- export type SchemaFieldUnion<S extends Array<Schema>, CreateEntityInstances extends boolean = false> = {
18
+ export type SchemaFieldUnion<S extends Schema[], CreateEntityInstances extends boolean = false> = {
19
19
  [K in keyof S]: S[K] extends Schema ? CreateEntityInstances extends true ? StaticSchemaEntity<S[K]> : {
20
20
  schemaId: S[K]['id'];
21
21
  version?: S[K]['version'];
22
22
  values: SchemaValues<S[K]>;
23
23
  } : any;
24
24
  };
25
- export type SchemaFieldValueTypeMapper<F extends SchemaFieldFieldDefinition, CreateEntityInstances extends boolean = false, ShouldIncludeNullAndUndefinedFields extends boolean = false> = F['options']['schemas'] extends Array<Schema> ? IsArrayNoUnpack<SchemaFieldUnion<F['options']['schemas'], CreateEntityInstances>[number], F['isArray']> : F['options']['schema'] extends Schema ? CreateEntityInstances extends true ? IsArray<StaticSchemaEntity<F['options']['schema']>, F['isArray']> : IsArray<SchemaValues<F['options']['schema'], false, true, ShouldIncludeNullAndUndefinedFields>, F['isArray']> : any;
25
+ export type SchemaFieldValueTypeMapper<F extends SchemaFieldFieldDefinition, CreateEntityInstances extends boolean = false, ShouldIncludeNullAndUndefinedFields extends boolean = false> = F['options']['schemas'] extends Schema[] ? IsArrayNoUnpack<SchemaFieldUnion<F['options']['schemas'], CreateEntityInstances>[number], F['isArray']> : F['options']['schema'] extends Schema ? CreateEntityInstances extends true ? IsArray<StaticSchemaEntity<F['options']['schema']>, F['isArray']> : IsArray<SchemaValues<F['options']['schema'], false, true, ShouldIncludeNullAndUndefinedFields>, F['isArray']> : any;
26
26
  export type SchemaFieldFieldDefinition = FieldDefinition<Record<string, any>, Record<string, any>, SchemaFieldValueUnion[], SchemaFieldValueUnion[]> & {
27
27
  /** * .Schema go team! */
28
28
  type: 'schema';
@@ -3,7 +3,7 @@ import { FieldTemplateDetailOptions, FieldTemplateDetails } from '../types/templ
3
3
  import AbstractField from './AbstractField';
4
4
  import { SelectFieldDefinition, SelectChoice } from './SelectField.types';
5
5
  export default class SelectField<T extends SelectFieldDefinition = SelectFieldDefinition> extends AbstractField<T> {
6
- static get description(): string;
6
+ static readonly description = "Stored as string, lets user select between available options.";
7
7
  constructor(name: string, definition: T);
8
8
  static generateTypeDetails(): {
9
9
  valueTypeMapper: string;
@@ -1,9 +1,6 @@
1
1
  import { selectChoicesToHash } from '../utilities/selectChoicesToHash.js';
2
2
  import AbstractField from './AbstractField.js';
3
- export default class SelectField extends AbstractField {
4
- static get description() {
5
- return 'Stored as string, lets user select between available options.';
6
- }
3
+ class SelectField extends AbstractField {
7
4
  constructor(name, definition) {
8
5
  super(name, definition);
9
6
  if (!definition.options || !definition.options.choices) {
@@ -41,3 +38,5 @@ export default class SelectField extends AbstractField {
41
38
  return this.definition.options.choices;
42
39
  }
43
40
  }
41
+ SelectField.description = 'Stored as string, lets user select between available options.';
42
+ export default SelectField;
@@ -4,7 +4,7 @@ import AbstractField from './AbstractField';
4
4
  import { ToValueTypeOptions, ValidateOptions } from './field.static.types';
5
5
  import { TextFieldDefinition } from './TextField.types';
6
6
  export default class TextField extends AbstractField<TextFieldDefinition> {
7
- static get description(): string;
7
+ static readonly description = "A text field. Converts non-strings into strings by calling toString(). Size set by options.";
8
8
  static generateTemplateDetails(options: FieldTemplateDetailOptions<TextFieldDefinition>): FieldTemplateDetails;
9
9
  validate(value: any, options: ValidateOptions<TextFieldDefinition>): FieldError[];
10
10
  toValueType<C extends boolean>(value: any, options?: ToValueTypeOptions<TextFieldDefinition, C>): string;
@@ -1,9 +1,6 @@
1
1
  import SpruceError from '../errors/SpruceError.js';
2
2
  import AbstractField from './AbstractField.js';
3
- export default class TextField extends AbstractField {
4
- static get description() {
5
- return 'A text field. Converts non-strings into strings by calling toString(). Size set by options.';
6
- }
3
+ class TextField extends AbstractField {
7
4
  static generateTemplateDetails(options) {
8
5
  const { definition } = options;
9
6
  return {
@@ -59,6 +56,11 @@ export default class TextField extends AbstractField {
59
56
  convertToString(value) {
60
57
  return typeof value === 'string'
61
58
  ? value
62
- : typeof value === 'number' && value && value.toString && value.toString();
59
+ : typeof value === 'number' &&
60
+ value &&
61
+ value.toString &&
62
+ value.toString();
63
63
  }
64
64
  }
65
+ TextField.description = 'A text field. Converts non-strings into strings by calling toString(). Size set by options.';
66
+ export default TextField;
@@ -2,10 +2,8 @@ import { FieldDefinitions, FieldMap, FieldValueTypeGeneratorMap } from "./../.sp
2
2
  import { FieldError } from '../errors/options.types';
3
3
  import { Schema, SchemaFieldsByName, SchemaValues, StaticSchemaEntity } from '../schemas.static.types';
4
4
  import { Unpack, IsArray, IsRequired } from '../types/utilities.types';
5
- export interface SchemasById {
6
- [id: string]: Schema[];
7
- }
8
- export type SchemaFieldUnion<S extends Array<Schema>, CreateEntityInstances extends boolean = false> = {
5
+ export type SchemasById = Record<string, Schema[]>;
6
+ export type SchemaFieldUnion<S extends Schema[], CreateEntityInstances extends boolean = false> = {
9
7
  [K in keyof S]: S[K] extends Schema ? CreateEntityInstances extends true ? StaticSchemaEntity<S[K]> : {
10
8
  schemaId: S[K]['id'];
11
9
  version?: S[K]['version'];
@@ -39,9 +39,7 @@ export interface DynamicSchemaEntityByName<ISchema extends Schema, OurField exte
39
39
  validate(options?: DynamicSchemaValidateOptions): void;
40
40
  isValid(options?: DynamicSchemaValidateOptions): boolean;
41
41
  }
42
- export interface SchemaFieldsByName {
43
- [fieldName: string]: FieldDefinitions;
44
- }
42
+ export type SchemaFieldsByName = Record<string, FieldDefinitions>;
45
43
  export interface Schema {
46
44
  id: string;
47
45
  name?: string;
@@ -70,18 +68,13 @@ export type SchemaAllValues<S extends Schema, CreateEntityInstances extends bool
70
68
  export type StaticSchemaAllValues<S extends Schema, CreateEntityInstances extends boolean = false> = {
71
69
  [K in SchemaFieldNames<S>]-?: SchemaFieldValueType<S, K, CreateEntityInstances>;
72
70
  };
73
- export type DynamicSchemaAllValues<S extends Schema, CreateEntityInstances extends boolean = false> = {
74
- [dynamicKey: string]: S['dynamicFieldSignature'] extends FieldDefinitions ? FieldDefinitionValueType<S['dynamicFieldSignature'], CreateEntityInstances> : never;
75
- };
71
+ export type DynamicSchemaAllValues<S extends Schema, CreateEntityInstances extends boolean = false> = Record<string, S['dynamicFieldSignature'] extends FieldDefinitions ? FieldDefinitionValueType<S['dynamicFieldSignature'], CreateEntityInstances> : never>;
76
72
  export type SchemaPartialValues<S extends Schema, CreateEntityInstances extends boolean = false> = IsDynamicSchema<S> extends true ? DynamicSchemaPartialValues<S, CreateEntityInstances> : StaticSchemaPartialValues<S, CreateEntityInstances>;
77
73
  export type StaticSchemaPartialValues<T extends Schema, CreateEntityInstances extends boolean = false> = {
78
74
  [K in SchemaFieldNames<T>]?: SchemaFieldValueType<T, K, CreateEntityInstances> | undefined | null;
79
75
  };
80
- export type DynamicSchemaPartialValues<S extends Schema, CreateEntityInstances extends boolean = false> = Partial<{
81
- [dynamicField: string]: S['dynamicFieldSignature'] extends FieldDefinitions ? FieldDefinitionValueType<S['dynamicFieldSignature'], CreateEntityInstances> | undefined | null : never;
82
- }>;
76
+ export type DynamicSchemaPartialValues<S extends Schema, CreateEntityInstances extends boolean = false> = Partial<Record<string, S['dynamicFieldSignature'] extends FieldDefinitions ? FieldDefinitionValueType<S['dynamicFieldSignature'], CreateEntityInstances> | undefined | null : never>>;
83
77
  export type SchemaStaticValues<T extends Schema, CreateEntityInstances extends boolean = false, K extends SchemaOptionalFieldNames<T> = SchemaOptionalFieldNames<T>, V extends SchemaAllValues<T, CreateEntityInstances> = SchemaAllValues<T, CreateEntityInstances>> = Omit<V, K> & Partial<Pick<V, K>>;
84
- export type SchemaValues_OLD<S extends Schema, CreateEntityInstances extends boolean = false> = IsDynamicSchema<S> extends true ? DynamicSchemaAllValues<S> : SchemaStaticValues<S, CreateEntityInstances>;
85
78
  export type IsDynamicSchema<S extends Schema> = S['dynamicFieldSignature'] extends FieldDefinitions ? true : false;
86
79
  export type SchemaDefaultValues<S extends Schema, CreateEntityInstances extends boolean = false, K extends SchemaFieldNamesWithDefaultValue<S> = SchemaFieldNamesWithDefaultValue<S>, V extends SchemaAllValues<S, CreateEntityInstances> = SchemaAllValues<S, CreateEntityInstances>> = {
87
80
  [F in K]: NonNullable<V[F]>;
@@ -1,8 +1,8 @@
1
- type ValidationErrorAssertOptions = {
1
+ interface ValidationErrorAssertOptions {
2
2
  missing?: string[];
3
3
  invalid?: string[];
4
4
  unexpected?: string[];
5
- };
5
+ }
6
6
  export type ValidationErrorAssertOptionsKey = keyof ValidationErrorAssertOptions;
7
7
  declare const validationErrorAssert: {
8
8
  assertError(error: any, options: ValidationErrorAssertOptions): void;
@@ -1,6 +1,6 @@
1
1
  import { Schema, SchemaRequiredFieldNames } from '../schemas.static.types';
2
- export type Unpack<A> = A extends Array<infer E> ? E : A;
3
- export type IsArray<T, isArray> = isArray extends true ? Unpack<T>[] : Unpack<T>;
4
- export type IsArrayNoUnpack<T, isArray> = isArray extends true ? T[] : T;
5
- export type IsRequired<T, isRequired> = isRequired extends true ? T : T | undefined | null;
2
+ export type Unpack<A> = A extends (infer E)[] ? E : A;
3
+ export type IsArray<T, IsArray> = IsArray extends true ? Unpack<T>[] : Unpack<T>;
4
+ export type IsArrayNoUnpack<T, IsArray> = IsArray extends true ? T[] : T;
5
+ export type IsRequired<T, IsRequired> = IsRequired extends true ? T : T | undefined | null;
6
6
  export type AreAnyFieldsRequired<S extends Schema | undefined> = S extends Schema ? SchemaRequiredFieldNames<S> extends [] ? false : true : false;
@@ -25,7 +25,6 @@ export default class KeyMapper {
25
25
  }
26
26
  mapFieldNameFrom(name) {
27
27
  for (const key in this.map) {
28
- // eslint-disable-next-line no-prototype-builtins
29
28
  if (this.map.hasOwnProperty(key)) {
30
29
  if (this.map[key] === name) {
31
30
  return key;
@@ -39,7 +38,6 @@ export default class KeyMapper {
39
38
  const foundFields = [];
40
39
  let target = {};
41
40
  for (const key in map) {
42
- // eslint-disable-next-line no-prototype-builtins
43
41
  if (values.hasOwnProperty(key)) {
44
42
  target[map[key]] = values[key];
45
43
  foundFields.push(key);
@@ -56,7 +54,6 @@ export default class KeyMapper {
56
54
  let target = {};
57
55
  for (const targetKey in map) {
58
56
  const sourceKey = map[targetKey];
59
- // eslint-disable-next-line no-prototype-builtins
60
57
  if (values.hasOwnProperty(sourceKey)) {
61
58
  target[targetKey] = values[sourceKey];
62
59
  foundFields.push(sourceKey);
@@ -24,7 +24,8 @@ export default function cloneDeep(obj, transformer) {
24
24
  if (type == 'Array' || type == 'Object') {
25
25
  result = Array.isArray(o) ? [] : {};
26
26
  for (let key in o) {
27
- result[key] = (_a = transformer === null || transformer === void 0 ? void 0 : transformer(o[key], key)) !== null && _a !== void 0 ? _a : cloneDeep(o[key], transformer);
27
+ result[key] =
28
+ (_a = transformer === null || transformer === void 0 ? void 0 : transformer(o[key], key)) !== null && _a !== void 0 ? _a : cloneDeep(o[key], transformer);
28
29
  }
29
30
  }
30
31
  // primitives and non-supported objects (e.g. functions) land here
@@ -32,7 +32,7 @@ export function isValidNumber(number) {
32
32
  }
33
33
  function getCode(number) {
34
34
  let code = `1`; // Default to North American country code
35
- const cleaned = number.replace(/\D/g, '');
35
+ const cleaned = number.replace(/(?!^\+)[^\d]/g, '');
36
36
  // Explicitly check for '+' sign to distinguish international codes
37
37
  if (cleaned.startsWith('+90') ||
38
38
  (cleaned.startsWith('90') && cleaned.length > 10)) {
@@ -59,7 +59,9 @@ export default function formatPhoneNumber(val, shouldFailSilently = true) {
59
59
  return val;
60
60
  }
61
61
  }
62
- return formatted;
62
+ // remove trailing spaces
63
+ const cleaned = formatted.replace(/\s+$/, '');
64
+ return cleaned;
63
65
  }
64
66
  export function isDummyNumber(phone) {
65
67
  const cleanedValue = phone.replace(/\D/g, '');
@@ -30,7 +30,9 @@ function pullParamaterIssues(errors, prefix = '') {
30
30
  const invalidParameters = [];
31
31
  const unexpectedParamaters = [];
32
32
  errors.forEach((fieldError) => {
33
- const fieldName = prefix ? `${prefix}.${fieldError.name}` : fieldError.name;
33
+ const fieldName = prefix
34
+ ? `${prefix}.${fieldError.name}`
35
+ : fieldError.name;
34
36
  if (fieldError.errors) {
35
37
  const { missingParameters: m, invalidParameters: i, unexpectedParamaters: u, } = pullParamaterIssues(fieldError.errors, fieldName);
36
38
  missingParameters.push(...m);
@@ -1,7 +1,5 @@
1
1
  import SpruceError from '../errors/SpruceError.js';
2
- export function validateFieldRegistration(registration
3
- // eslint-disable-next-line no-undef
4
- ) {
2
+ export function validateFieldRegistration(registration) {
5
3
  const errors = [];
6
4
  const builtRegistration = {
7
5
  package: '***missing***',
@@ -12,9 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  import set from 'just-safe-set';
13
13
  import { validateSchema } from '../index.js';
14
14
  import EntityFactory from '../factories/SchemaEntityFactory.js';
15
- export default function validateSchemaValues(schema, values, options
16
- // eslint-disable-next-line no-undef
17
- ) {
15
+ export default function validateSchemaValues(schema, values, options) {
18
16
  const opts = __rest(options !== null && options !== void 0 ? options : {}, []);
19
17
  validateSchema(schema);
20
18
  const mapped = Object.keys(values).reduce((mapped, key) => {
@@ -6,6 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const SpruceError_1 = __importDefault(require("../errors/SpruceError"));
7
7
  const isUndefinedOrNull_1 = __importDefault(require("../utilities/isUndefinedOrNull"));
8
8
  class AbstractField {
9
+ /** The definition for this field */
10
+ definition;
11
+ /** Shortcut to this field */
12
+ type;
13
+ /** The name of this field (camel case) */
14
+ name;
9
15
  constructor(name, definition) {
10
16
  this.definition = definition;
11
17
  this.name = name;
@@ -65,8 +71,7 @@ public static generateTemplateDetails(
65
71
  return this.definition.hint;
66
72
  }
67
73
  get minArrayLength() {
68
- var _a;
69
- return (_a = this.definition.minArrayLength) !== null && _a !== void 0 ? _a : 1;
74
+ return this.definition.minArrayLength ?? 1;
70
75
  }
71
76
  validate(value, _) {
72
77
  const errors = [];
@@ -2,6 +2,6 @@ import { FieldTemplateDetailOptions, FieldTemplateDetails } from '../types/templ
2
2
  import AbstractField from './AbstractField';
3
3
  import { AddressFieldDefinition } from './AddressField.types';
4
4
  export default class AddressField extends AbstractField<AddressFieldDefinition> {
5
- static get description(): string;
5
+ static readonly description = "An address with geocoding ability *coming soon*";
6
6
  static generateTemplateDetails(options: FieldTemplateDetailOptions<AddressFieldDefinition>): FieldTemplateDetails;
7
7
  }
@@ -5,9 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const AbstractField_1 = __importDefault(require("./AbstractField"));
7
7
  class AddressField extends AbstractField_1.default {
8
- static get description() {
9
- return 'An address with geocoding ability *coming soon*';
10
- }
8
+ static description = 'An address with geocoding ability *coming soon*';
11
9
  static generateTemplateDetails(options) {
12
10
  return {
13
11
  valueType: `${options.importAs}.AddressFieldValue${options.definition.isArray ? '[]' : ''}`,
@@ -2,7 +2,7 @@ import { FieldTemplateDetailOptions, FieldTemplateDetails } from '../types/templ
2
2
  import AbstractField from './AbstractField';
3
3
  import { BooleanFieldDefinition } from './BooleanField.types';
4
4
  export default class BooleanField extends AbstractField<BooleanFieldDefinition> {
5
- static get description(): string;
5
+ static readonly description = "A true/false. Converts false string to false, all other strings to true.";
6
6
  static generateTemplateDetails(options: FieldTemplateDetailOptions<BooleanFieldDefinition>): FieldTemplateDetails;
7
7
  /** * Turn everything into a string */
8
8
  toValueType(value: any): boolean;
@@ -5,9 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const AbstractField_1 = __importDefault(require("./AbstractField"));
7
7
  class BooleanField extends AbstractField_1.default {
8
- static get description() {
9
- return 'A true/false. Converts false string to false, all other strings to true.';
10
- }
8
+ static description = 'A true/false. Converts false string to false, all other strings to true.';
11
9
  static generateTemplateDetails(options) {
12
10
  return {
13
11
  valueType: `boolean${options.definition.isArray ? '[]' : ''}`,
@@ -4,7 +4,7 @@ import AbstractField from './AbstractField';
4
4
  import { DateFieldDefinition } from './DateField.types';
5
5
  import { ValidateOptions } from './field.static.types';
6
6
  export default class DateField extends AbstractField<DateFieldDefinition> {
7
- static get description(): string;
7
+ static readonly description = "Date and time support.";
8
8
  static generateTemplateDetails(options: FieldTemplateDetailOptions<DateFieldDefinition>): FieldTemplateDetails;
9
9
  validate(value: any, options?: ValidateOptions<DateFieldDefinition>): FieldError[];
10
10
  toValueType(value: any): any;
@@ -8,9 +8,7 @@ const getStartOfDay_1 = __importDefault(require("../utilities/getStartOfDay"));
8
8
  const isUndefinedOrNull_1 = __importDefault(require("../utilities/isUndefinedOrNull"));
9
9
  const AbstractField_1 = __importDefault(require("./AbstractField"));
10
10
  class DateField extends AbstractField_1.default {
11
- static get description() {
12
- return 'Date and time support.';
13
- }
11
+ static description = 'Date and time support.';
14
12
  static generateTemplateDetails(options) {
15
13
  return {
16
14
  valueType: `${options.importAs}.DateFieldValue${options.definition.isArray ? '[]' : ''}`,
@@ -4,7 +4,7 @@ import AbstractField from './AbstractField';
4
4
  import { DateTimeFieldDefinition } from './DateTimeField.types';
5
5
  import { ValidateOptions } from './field.static.types';
6
6
  export default class DateTimeField extends AbstractField<DateTimeFieldDefinition> {
7
- static get description(): string;
7
+ static readonly description = "Date and time support.";
8
8
  static generateTemplateDetails(options: FieldTemplateDetailOptions<DateTimeFieldDefinition>): FieldTemplateDetails;
9
9
  validate(value: any, options?: ValidateOptions<DateTimeFieldDefinition>): FieldError[];
10
10
  toValueType(value: any): any;
@@ -6,9 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const AbstractField_1 = __importDefault(require("./AbstractField"));
7
7
  const DateField_1 = require("./DateField");
8
8
  class DateTimeField extends AbstractField_1.default {
9
- static get description() {
10
- return 'Date and time support.';
11
- }
9
+ static description = 'Date and time support.';
12
10
  static generateTemplateDetails(options) {
13
11
  return {
14
12
  valueType: `${options.importAs}.DateTimeFieldValue${options.definition.isArray ? '[]' : ''}`,
@@ -26,12 +24,11 @@ class DateTimeField extends AbstractField_1.default {
26
24
  });
27
25
  }
28
26
  toValueType(value) {
29
- var _a;
30
27
  let normalized = value;
31
28
  if (normalized instanceof Date) {
32
29
  normalized = normalized.getTime();
33
30
  }
34
- if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.dateTimeFormat) === 'iso_8601') {
31
+ if (this.options?.dateTimeFormat === 'iso_8601') {
35
32
  return new Date(value).toISOString();
36
33
  }
37
34
  if (typeof normalized === 'string') {
@@ -3,7 +3,7 @@ import AbstractField from './AbstractField';
3
3
  import { DirectoryFieldDefinition, DirectoryFieldValue } from './DirectoryField.types';
4
4
  import { ToValueTypeOptions } from './field.static.types';
5
5
  export default class DirectoryField extends AbstractField<DirectoryFieldDefinition> {
6
- static get description(): string;
6
+ static readonly description = "A way to select entire directories once!";
7
7
  static generateTemplateDetails(options: FieldTemplateDetailOptions<DirectoryFieldDefinition>): FieldTemplateDetails;
8
8
  toValueType<C extends boolean>(value: any, options?: ToValueTypeOptions<DirectoryFieldDefinition, C>): DirectoryFieldValue;
9
9
  }