@burnsred/entity 0.6.2 → 1.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 (82) hide show
  1. package/README.md +174 -1
  2. package/dist/cleaner/as-boolean.d.ts +7 -0
  3. package/dist/cleaner/as-boolean.js +10 -0
  4. package/dist/cleaner/as-boolean.js.map +1 -0
  5. package/dist/cleaner/as-date.d.ts +1 -0
  6. package/dist/cleaner/as-date.js +5 -0
  7. package/dist/cleaner/as-date.js.map +1 -0
  8. package/dist/cleaner/as-integer.d.ts +1 -0
  9. package/dist/cleaner/as-integer.js +5 -0
  10. package/dist/cleaner/as-integer.js.map +1 -0
  11. package/dist/cleaner/as-number.d.ts +1 -0
  12. package/dist/cleaner/as-number.js +5 -0
  13. package/dist/cleaner/as-number.js.map +1 -0
  14. package/dist/cleaner/as-string.d.ts +1 -0
  15. package/dist/cleaner/as-string.js +4 -0
  16. package/dist/cleaner/as-string.js.map +1 -0
  17. package/dist/cleaner/collapse-spaces.d.ts +4 -0
  18. package/dist/cleaner/collapse-spaces.js +7 -0
  19. package/dist/cleaner/collapse-spaces.js.map +1 -0
  20. package/dist/cleaner/index.d.ts +7 -0
  21. package/dist/cleaner/index.js +8 -0
  22. package/dist/cleaner/index.js.map +1 -0
  23. package/dist/cleaner/trim.d.ts +1 -0
  24. package/dist/cleaner/trim.js +4 -0
  25. package/dist/cleaner/trim.js.map +1 -0
  26. package/dist/entity/Entity.d.ts +20 -0
  27. package/dist/entity/Entity.js +63 -0
  28. package/dist/entity/Entity.js.map +1 -0
  29. package/dist/entity/index.d.ts +8 -0
  30. package/dist/entity/index.js +9 -0
  31. package/dist/entity/index.js.map +1 -0
  32. package/dist/field/BooleanField.d.ts +7 -0
  33. package/dist/field/BooleanField.js +8 -0
  34. package/dist/field/BooleanField.js.map +1 -0
  35. package/dist/field/CharField.d.ts +7 -0
  36. package/dist/field/CharField.js +8 -0
  37. package/dist/field/CharField.js.map +1 -0
  38. package/dist/field/DateField.d.ts +9 -0
  39. package/dist/field/DateField.js +19 -0
  40. package/dist/field/DateField.js.map +1 -0
  41. package/dist/field/DateTimeField.d.ts +9 -0
  42. package/dist/field/DateTimeField.js +14 -0
  43. package/dist/field/DateTimeField.js.map +1 -0
  44. package/dist/field/EntityField.d.ts +22 -0
  45. package/dist/field/EntityField.js +55 -0
  46. package/dist/field/EntityField.js.map +1 -0
  47. package/dist/field/Field.d.ts +42 -0
  48. package/dist/field/Field.js +97 -0
  49. package/dist/field/Field.js.map +1 -0
  50. package/dist/field/IdField.d.ts +15 -0
  51. package/dist/field/IdField.js +23 -0
  52. package/dist/field/IdField.js.map +1 -0
  53. package/dist/field/IntegerField.d.ts +6 -0
  54. package/dist/field/IntegerField.js +9 -0
  55. package/dist/field/IntegerField.js.map +1 -0
  56. package/dist/field/NumberField.d.ts +7 -0
  57. package/dist/field/NumberField.js +8 -0
  58. package/dist/field/NumberField.js.map +1 -0
  59. package/dist/field/TextField.d.ts +4 -0
  60. package/dist/field/TextField.js +5 -0
  61. package/dist/field/TextField.js.map +1 -0
  62. package/dist/field/index.d.ts +68 -0
  63. package/dist/field/index.js +12 -0
  64. package/dist/field/index.js.map +1 -0
  65. package/dist/index.d.ts +67 -0
  66. package/dist/index.js +5 -5
  67. package/dist/index.js.map +1 -0
  68. package/dist/validator/entity-valid.d.ts +9 -0
  69. package/dist/validator/entity-valid.js +12 -0
  70. package/dist/validator/entity-valid.js.map +1 -0
  71. package/dist/validator/index.d.ts +2 -0
  72. package/dist/validator/index.js +3 -0
  73. package/dist/validator/index.js.map +1 -0
  74. package/dist/validator/value-range.d.ts +8 -0
  75. package/dist/validator/value-range.js +24 -0
  76. package/dist/validator/value-range.js.map +1 -0
  77. package/package.json +21 -34
  78. package/CHANGELOG.md +0 -88
  79. package/LICENSE +0 -21
  80. package/dist/development.js +0 -1377
  81. package/dist/development.js.map +0 -1
  82. package/dist/production.min.js +0 -1
@@ -0,0 +1,42 @@
1
+ import type { ErrorSet, FieldCleaner, FieldErrorMap, FieldValidator, ValidatorResult } from '..';
2
+ import type { FieldConstructorParams, FieldType } from '.';
3
+ export declare class Field<T> implements FieldType<T> {
4
+ static defaultValue: unknown;
5
+ static defaultCleaners: FieldCleaner[];
6
+ static defaultValidators: FieldValidator[];
7
+ type: string;
8
+ name: string;
9
+ defaultValue: T;
10
+ blank: boolean;
11
+ readOnly: boolean;
12
+ cleaners: FieldCleaner[];
13
+ validators: FieldValidator[];
14
+ many: boolean;
15
+ choices: T[];
16
+ extra: object;
17
+ /**
18
+ * Base Entity Field class
19
+ *
20
+ * @param config
21
+ * @param config.type Type label for this field.
22
+ * @param config.blank Is this field allowed to be blank?
23
+ * @param config.cleaners Array of cleaner functions; used by `clean()`
24
+ * @param config.validators Array of validator functions; used by `validate()`
25
+ * @param config.many False if this field holds a scalar value; true if vector.
26
+ * @param config.choices Array of value choices
27
+ * @param config.defaultValue Default value for this field
28
+ */
29
+ constructor({ blank, cleaners, validators, many, readOnly, choices, defaultValue, ...extra }?: FieldConstructorParams<T>);
30
+ fromData(value: unknown): T;
31
+ toData(value: T): unknown;
32
+ default(): T | T[];
33
+ clean(value: T): T;
34
+ validate(value: T): ValidatorResult;
35
+ getErrors(errors: FieldErrorMap, key?: number | string): ErrorSet;
36
+ getValue(value: T, key?: string | number): T | T[keyof T];
37
+ getId(value?: T): string | undefined;
38
+ /**
39
+ * Dummy placeholder; only makes sense on an EntityField.
40
+ */
41
+ getField(_name: keyof T): FieldType<T[keyof T]>;
42
+ }
@@ -0,0 +1,97 @@
1
+ export class Field {
2
+ static defaultValue;
3
+ static defaultCleaners = [];
4
+ static defaultValidators = [];
5
+ type = '';
6
+ name;
7
+ defaultValue;
8
+ blank;
9
+ readOnly;
10
+ cleaners;
11
+ validators;
12
+ many;
13
+ choices;
14
+ extra; // grab bag of extra options
15
+ /**
16
+ * Base Entity Field class
17
+ *
18
+ * @param config
19
+ * @param config.type Type label for this field.
20
+ * @param config.blank Is this field allowed to be blank?
21
+ * @param config.cleaners Array of cleaner functions; used by `clean()`
22
+ * @param config.validators Array of validator functions; used by `validate()`
23
+ * @param config.many False if this field holds a scalar value; true if vector.
24
+ * @param config.choices Array of value choices
25
+ * @param config.defaultValue Default value for this field
26
+ */
27
+ constructor({ blank = false, cleaners, validators, many = false, readOnly = false, choices, defaultValue, ...extra } = {}) {
28
+ this.name = '';
29
+ this.blank = blank;
30
+ this.cleaners =
31
+ cleaners || this.constructor.defaultCleaners;
32
+ this.validators =
33
+ validators || this.constructor.defaultValidators;
34
+ this.many = many;
35
+ this.readOnly = readOnly;
36
+ this.choices = choices || [];
37
+ this.defaultValue =
38
+ defaultValue !== undefined
39
+ ? defaultValue
40
+ : this.constructor.defaultValue;
41
+ this.extra = extra;
42
+ }
43
+ fromData(value) {
44
+ return value;
45
+ }
46
+ toData(value) {
47
+ return this.readOnly ? undefined : value;
48
+ }
49
+ default() {
50
+ return this.many ? [] : this.defaultValue;
51
+ }
52
+ clean(value) {
53
+ return this.cleaners.reduce((val, cleaner) => cleaner(val), value);
54
+ }
55
+ validate(value) {
56
+ return this.validators
57
+ .map((validator) => validator.call(this, value))
58
+ .flat(1)
59
+ .filter(Boolean); // TS can't detect we've filtered the undefineds
60
+ }
61
+ getErrors(errors, key) {
62
+ switch (typeof key) {
63
+ case 'undefined':
64
+ return errors;
65
+ case 'number':
66
+ if (!this.many) {
67
+ throw new Error(`[Field: ${this.name}] Index lookup not supported on scalar field.`);
68
+ }
69
+ return errors[key];
70
+ case 'string':
71
+ throw new Error(`[Field: ${this.name}] Use of field lookup not supported.`);
72
+ }
73
+ }
74
+ getValue(value, key) {
75
+ switch (typeof key) {
76
+ case 'string':
77
+ throw Error(`Field ${this.name} [${this.type}] does not support field lookups: ${key}`);
78
+ case 'number':
79
+ if (!this.many) {
80
+ throw Error(`Field ${this.name} [${this.type}] does not support index lookups`);
81
+ }
82
+ return value[key];
83
+ case 'undefined':
84
+ return value;
85
+ }
86
+ }
87
+ getId(value) {
88
+ return value;
89
+ }
90
+ /**
91
+ * Dummy placeholder; only makes sense on an EntityField.
92
+ */
93
+ getField(_name) {
94
+ throw new Error(`Cannot get sub-field for type ${this.type}`);
95
+ }
96
+ }
97
+ //# sourceMappingURL=Field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Field.js","sourceRoot":"","sources":["../../src/field/Field.ts"],"names":[],"mappings":"AAUA,MAAM,OAAO,KAAK;IAChB,MAAM,CAAC,YAAY,CAAU;IAC7B,MAAM,CAAC,eAAe,GAAmB,EAAE,CAAC;IAC5C,MAAM,CAAC,iBAAiB,GAAqB,EAAE,CAAC;IAEhD,IAAI,GAAG,EAAE,CAAC;IACV,IAAI,CAAS;IACb,YAAY,CAAI;IAChB,KAAK,CAAU;IACf,QAAQ,CAAU;IAClB,QAAQ,CAAiB;IACzB,UAAU,CAAmB;IAC7B,IAAI,CAAU;IACd,OAAO,CAAM;IACb,KAAK,CAAS,CAAC,4BAA4B;IAE3C;;;;;;;;;;;OAWG;IACH,YAAY,EACV,KAAK,GAAG,KAAK,EACb,QAAQ,EACR,UAAU,EACV,IAAI,GAAG,KAAK,EACZ,QAAQ,GAAG,KAAK,EAChB,OAAO,EACP,YAAY,EACZ,GAAG,KAAK,KACqB,EAAE;QAC/B,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ;YACX,QAAQ,IAAK,IAAI,CAAC,WAA4B,CAAC,eAAe,CAAC;QACjE,IAAI,CAAC,UAAU;YACb,UAAU,IAAK,IAAI,CAAC,WAA4B,CAAC,iBAAiB,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QAE7B,IAAI,CAAC,YAAY;YACf,YAAY,KAAK,SAAS;gBACxB,CAAC,CAAC,YAAY;gBACd,CAAC,CAAG,IAAI,CAAC,WAA4B,CAAC,YAAkB,CAAC;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,QAAQ,CAAC,KAAc;QACrB,OAAO,KAAU,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,KAAQ;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,KAAQ;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAM,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED,QAAQ,CAAC,KAAQ;QACf,OAAO,IAAI,CAAC,UAAU;aACnB,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;aAC/C,IAAI,CAAC,CAAC,CAAC;aACP,MAAM,CAAC,OAAO,CAAoB,CAAC,CAAC,gDAAgD;IACzF,CAAC;IAED,SAAS,CAAC,MAAqB,EAAE,GAAqB;QACpD,QAAQ,OAAO,GAAG,EAAE;YAClB,KAAK,WAAW;gBACd,OAAO,MAAM,CAAC;YAChB,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBACd,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,CAAC,IAAI,+CAA+C,CACpE,CAAC;iBACH;gBACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YACrB,KAAK,QAAQ;gBACX,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,CAAC,IAAI,sCAAsC,CAC3D,CAAC;SACL;IACH,CAAC;IAED,QAAQ,CAAC,KAAQ,EAAE,GAAqB;QACtC,QAAQ,OAAO,GAAG,EAAE;YAClB,KAAK,QAAQ;gBACX,MAAM,KAAK,CACT,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,qCAAqC,GAAG,EAAE,CAC3E,CAAC;YACJ,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBACd,MAAM,KAAK,CACT,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,kCAAkC,CACnE,CAAC;iBACH;gBACD,OAAQ,KAAa,CAAC,GAAa,CAAC,CAAC;YACvC,KAAK,WAAW;gBACd,OAAO,KAAK,CAAC;SAChB;IACH,CAAC;IAED,KAAK,CAAC,KAAS;QACb,OAAO,KAAe,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAc;QACrB,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Field } from '.';
2
+ import { type FieldConstructorParams } from '.';
3
+ /**
4
+ * Specialised Field type for use as ID.
5
+ *
6
+ * Ensures `many` is not set.
7
+ * Defaults to `undefined`.
8
+ * Will cast loaded values to string if possible.
9
+ *
10
+ */
11
+ export declare class IdField extends Field<string | undefined> {
12
+ type: string;
13
+ constructor(config?: FieldConstructorParams<string | undefined>);
14
+ fromData(value: unknown): string | undefined;
15
+ }
@@ -0,0 +1,23 @@
1
+ import { Field } from '.';
2
+ /**
3
+ * Specialised Field type for use as ID.
4
+ *
5
+ * Ensures `many` is not set.
6
+ * Defaults to `undefined`.
7
+ * Will cast loaded values to string if possible.
8
+ *
9
+ */
10
+ export class IdField extends Field {
11
+ type = 'id';
12
+ constructor(config = {}) {
13
+ super(config);
14
+ if (this.many)
15
+ throw new Error('IdField must not have many set');
16
+ }
17
+ fromData(value) {
18
+ return value?.toString instanceof Function
19
+ ? value.toString()
20
+ : value;
21
+ }
22
+ }
23
+ //# sourceMappingURL=IdField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdField.js","sourceRoot":"","sources":["../../src/field/IdField.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC;AAG1B;;;;;;;GAOG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAyB;IACpD,IAAI,GAAG,IAAI,CAAC;IAEZ,YAAY,SAAqD,EAAE;QACjE,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACnE,CAAC;IAED,QAAQ,CAAC,KAAc;QACrB,OAAO,KAAK,EAAE,QAAQ,YAAY,QAAQ;YACxC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE;YAClB,CAAC,CAAE,KAAmB,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import { asInteger } from '../cleaner';
2
+ import { NumberField } from '.';
3
+ export declare class IntegerField extends NumberField {
4
+ static defaultCleaners: (typeof asInteger)[];
5
+ fromData(value: unknown): number;
6
+ }
@@ -0,0 +1,9 @@
1
+ import { asInteger } from '../cleaner';
2
+ import { NumberField } from '.';
3
+ export class IntegerField extends NumberField {
4
+ static defaultCleaners = [asInteger];
5
+ fromData(value) {
6
+ return asInteger(value);
7
+ }
8
+ }
9
+ //# sourceMappingURL=IntegerField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IntegerField.js","sourceRoot":"","sources":["../../src/field/IntegerField.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,CAAC;AAEhC,MAAM,OAAO,YAAa,SAAQ,WAAW;IAC3C,MAAM,CAAC,eAAe,GAAG,CAAC,SAAS,CAAC,CAAC;IAErC,QAAQ,CAAC,KAAc;QACrB,OAAO,SAAS,CAAC,KAAK,CAAW,CAAC;IACpC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { asNumber } from '../cleaner';
2
+ import { Field } from '.';
3
+ export declare class NumberField extends Field<number> {
4
+ static defaultValue: number;
5
+ static defaultCleaners: (typeof asNumber)[];
6
+ type: string;
7
+ }
@@ -0,0 +1,8 @@
1
+ import { asNumber } from '../cleaner';
2
+ import { Field } from '.';
3
+ export class NumberField extends Field {
4
+ static defaultValue = 0;
5
+ static defaultCleaners = [asNumber];
6
+ type = 'number';
7
+ }
8
+ //# sourceMappingURL=NumberField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberField.js","sourceRoot":"","sources":["../../src/field/NumberField.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC;AAE1B,MAAM,OAAO,WAAY,SAAQ,KAAa;IAC5C,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC;IACxB,MAAM,CAAC,eAAe,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEpC,IAAI,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { CharField } from '.';
2
+ export declare class TextField extends CharField {
3
+ type: string;
4
+ }
@@ -0,0 +1,5 @@
1
+ import { CharField } from '.';
2
+ export class TextField extends CharField {
3
+ type = 'text';
4
+ }
5
+ //# sourceMappingURL=TextField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextField.js","sourceRoot":"","sources":["../../src/field/TextField.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC;AAE9B,MAAM,OAAO,SAAU,SAAQ,SAAS;IACtC,IAAI,GAAG,MAAM,CAAC;CACf"}
@@ -0,0 +1,68 @@
1
+ export * from './Field';
2
+ export * from './EntityField';
3
+ export * from './BooleanField';
4
+ export * from './CharField';
5
+ export * from './DateField';
6
+ export * from './DateTimeField';
7
+ export * from './TextField';
8
+ export * from './NumberField';
9
+ export * from './IntegerField';
10
+ export * from './IdField';
11
+ import type { ErrorSet, FieldCleaner, FieldErrorMap, FieldValidator, ValidatorResult } from '..';
12
+ export type FieldConstructorParams<T> = Partial<Pick<FieldType<T>, 'type' | 'blank' | 'cleaners' | 'validators' | 'many' | 'readOnly' | 'choices'>> & {
13
+ defaultValue?: T;
14
+ };
15
+ export interface FieldType<T> {
16
+ name: string;
17
+ type: string;
18
+ blank: boolean;
19
+ many: boolean;
20
+ readOnly: boolean;
21
+ choices: T[];
22
+ cleaners: FieldCleaner[];
23
+ validators: FieldValidator[];
24
+ /**
25
+ * Convert a raw value.
26
+ * Used for data from API
27
+ */
28
+ fromData: (value: unknown) => T;
29
+ /**
30
+ * Restore a value to raw state
31
+ */
32
+ toData: (value: T) => unknown;
33
+ /**
34
+ * Get the default value for this field.
35
+ */
36
+ default: (options: object) => T | T[];
37
+ /**
38
+ * Apply cleaners to the value.
39
+ * Use for data from user input.
40
+ */
41
+ clean: (value: T) => T;
42
+ /**
43
+ * Validate the value, returning an array of errors.
44
+ */
45
+ validate: (value: T) => ValidatorResult;
46
+ /**
47
+ * Extract errors for this field only.
48
+ */
49
+ getErrors: (errors: FieldErrorMap, key?: number | string) => ErrorSet;
50
+ /**
51
+ * Retrieves the value
52
+ *
53
+ * For scalar values, this is just the value
54
+ * For vector and compound values, the second argument specifies the key/index.
55
+ */
56
+ getValue: (value: T, key?: string | number) => T | T[keyof T];
57
+ /**
58
+ * Extract the identifier for the value.
59
+ *
60
+ * For scalar values, this is just the value.
61
+ * For Entities, this is their ID field's value.
62
+ */
63
+ getId: (value?: T) => string | undefined;
64
+ /**
65
+ * Provide a Field for a specific element of a compound value.
66
+ */
67
+ getField: (name: keyof T) => FieldType<T[keyof T]>;
68
+ }
@@ -0,0 +1,12 @@
1
+ // NB: Field MUST be imported first!
2
+ export * from './Field';
3
+ export * from './EntityField';
4
+ export * from './BooleanField';
5
+ export * from './CharField';
6
+ export * from './DateField';
7
+ export * from './DateTimeField';
8
+ export * from './TextField';
9
+ export * from './NumberField';
10
+ export * from './IntegerField';
11
+ export * from './IdField';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/field/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,67 @@
1
+ export * from './field';
2
+ export * from './entity';
3
+ export * from './cleaner';
4
+ export * from './validator';
5
+ import type { EntityField, FieldConstructorParams, FieldType } from './field';
6
+ export type FieldError = {
7
+ code: string;
8
+ message: string;
9
+ };
10
+ /**
11
+ * Scalar fields have Array<FieldError>
12
+ * EntityFields have FieldErrorMap
13
+ * Vector fields have Array<as above>
14
+ */
15
+ export type ErrorSet = Array<FieldError> | Array<Array<FieldError>> | FieldErrorMap | Array<FieldErrorMap>;
16
+ export type FieldErrorMap = {
17
+ [key: string]: ErrorSet;
18
+ };
19
+ export type ValidatorResult = ErrorSet | undefined;
20
+ export type FieldCleaner = (value: unknown) => unknown;
21
+ export type FieldValidator = (value: unknown) => ValidatorResult;
22
+ export type EntityRecordCleaner<T> = (record: T) => T;
23
+ export type EntityRecordValidator<T> = (record: T, errors: FieldErrorMap) => FieldErrorMap;
24
+ export interface EntityType<T> {
25
+ /** Field to use to uniquely identify a record. */
26
+ idField: keyof T;
27
+ /** Map of fields */
28
+ fields: {
29
+ [F in keyof T]: FieldType<T[F]>;
30
+ };
31
+ /** Array of cleaner functions; used by `clean()` */
32
+ cleaners: EntityRecordCleaner<T>[];
33
+ /** Array of validator functions; used by `validate()` */
34
+ validators: EntityRecordValidator<T>[];
35
+ /**
36
+ * Construct an entity record from supplied data.
37
+ *
38
+ * Use for data from API.
39
+ */
40
+ fromData: (data: Record<string, unknown>) => T;
41
+ /**
42
+ * Extract plain data from a record.
43
+ */
44
+ toData: (record: T) => Record<string, unknown>;
45
+ /**
46
+ * Given an existing record, clean its values.
47
+ *
48
+ * Applies per-field cleaners first, then Entity level cleaners.
49
+ *
50
+ * Used for data from user input.
51
+ */
52
+ clean: (record: T) => T;
53
+ /**
54
+ * Apply all field and entitly defined validators and collect errors.
55
+ */
56
+ validate: (record: T) => FieldErrorMap;
57
+ /**
58
+ * Extract the identifier for the supplied record.
59
+ *
60
+ * This can also be useful for `key={}` properties.
61
+ */
62
+ getId: (record?: T) => string | undefined;
63
+ /**
64
+ * Helper to create an EntityField for this type of entity.
65
+ */
66
+ getEntityField: (options?: FieldConstructorParams<T>) => EntityField<T>;
67
+ }
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- if (process.env.NODE_ENV === 'production') {
2
- module.exports = require('./production.min'); // eslint-disable-line global-require, import/no-unresolved
3
- } else {
4
- module.exports = require('./development'); // eslint-disable-line global-require, import/no-unresolved
5
- }
1
+ export * from './field';
2
+ export * from './entity';
3
+ export * from './cleaner';
4
+ export * from './validator';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type EntityField } from '../field';
2
+ /**
3
+ * Ensure the associated Entity considers the value valid.
4
+ */
5
+ declare function entityValid<T>(this: EntityField<T>, value: unknown): {
6
+ code: string;
7
+ message: string;
8
+ }[] | undefined;
9
+ export default entityValid;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Ensure the associated Entity considers the value valid.
3
+ */
4
+ function entityValid(value) {
5
+ const errors = this.entity.validate(value);
6
+ // TODO: ensure this handles cases of highly recursive error structures.
7
+ if (Object.values(errors).some((err) => err && err.length)) {
8
+ return [{ code: 'entity-invalid', message: 'Entity is not valid.' }];
9
+ }
10
+ }
11
+ export default entityValid;
12
+ //# sourceMappingURL=entity-valid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-valid.js","sourceRoot":"","sources":["../../src/validator/entity-valid.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,SAAS,WAAW,CAA0B,KAAc;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAU,CAAC,CAAC;IAEhD,wEAAwE;IACxE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE;QAC1D,OAAO,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC;KACtE;AACH,CAAC;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as entityValid } from './entity-valid';
2
+ export { default as valueRange } from './value-range';
@@ -0,0 +1,3 @@
1
+ export { default as entityValid } from './entity-valid';
2
+ export { default as valueRange } from './value-range';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { FieldType } from '../field';
2
+ /**
3
+ * A validator factory to ensure a numeric value is within range.
4
+ */
5
+ export default function valueRange(min: number, max: number): (this: FieldType<unknown>, value: unknown) => {
6
+ code: string;
7
+ message: string;
8
+ }[] | undefined;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A validator factory to ensure a numeric value is within range.
3
+ */
4
+ export default function valueRange(min, max) {
5
+ return function (value) {
6
+ if (min !== undefined && value < min) {
7
+ return [
8
+ {
9
+ code: 'range-error',
10
+ message: `Value must be greater than ${min}`,
11
+ },
12
+ ];
13
+ }
14
+ if (max !== undefined && value > max) {
15
+ return [
16
+ {
17
+ code: 'range-error',
18
+ message: `Value must be less than ${max}`,
19
+ },
20
+ ];
21
+ }
22
+ };
23
+ }
24
+ //# sourceMappingURL=value-range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-range.js","sourceRoot":"","sources":["../../src/validator/value-range.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,GAAW,EAAE,GAAW;IACzD,OAAO,UAAoC,KAAc;QACvD,IAAI,GAAG,KAAK,SAAS,IAAK,KAAgB,GAAG,GAAG,EAAE;YAChD,OAAO;gBACL;oBACE,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,8BAA8B,GAAG,EAAE;iBAC7C;aACF,CAAC;SACH;QACD,IAAI,GAAG,KAAK,SAAS,IAAK,KAAgB,GAAG,GAAG,EAAE;YAChD,OAAO;gBACL;oBACE,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,2BAA2B,GAAG,EAAE;iBAC1C;aACF,CAAC;SACH;IACH,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,40 +1,27 @@
1
1
  {
2
- "author": "Thierry Wong and Burnsred",
3
- "description": "entity",
4
- "license": "MIT",
5
- "main": "dist/index.js",
6
- "module": "dist/index.js",
7
2
  "name": "@burnsred/entity",
8
- "private": false,
9
- "repository": "https://github.com/burnsred/burnsred-entity-library.git",
10
- "sideEffects": false,
11
- "version": "0.6.2",
12
- "publishConfig": {
13
- "access": "public"
14
- },
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
15
7
  "scripts": {
16
- "build": "rollup -c=../../configs/rollup.config.js",
17
- "destroy": "rimraf dist",
18
- "link-main:dist": "json -I -f package.json -e 'this.main=\"dist/index.js\"'",
19
- "link-main:src": "json -I -f package.json -e 'this.main=\"src/index.js\"'",
20
- "link-module:dist": "json -I -f package.json -e 'this.module=\"dist/index.js\"'",
21
- "link-module:src": "json -I -f package.json -e 'this.module=\"src/index.js\"'",
22
- "postbuild": "npm run link-main:dist && npm run link-module:dist",
23
- "postdestroy": "npm run link-main:src && npm run link-module:src",
24
- "prebuild": "npm run destroy"
25
- },
26
- "dependencies": {
27
- "idx": "2.5.5",
28
- "immutable": "4.0.0-rc.12",
29
- "query-string": "6.4.0"
30
- },
31
- "devDependencies": {
32
- "lodash": "4.17.11",
33
- "moment": "2.24.0"
8
+ "test": "vitest run",
9
+ "build": "tsc -b",
10
+ "clean": "rm -rf tsconfig.tsbuildinfo dist/",
11
+ "lint": "eslint src/",
12
+ "lint:fix": "eslint --fix src/",
13
+ "test:watch": "vitest",
14
+ "prepublishOnly": "npm run build",
15
+ "check": "tsc --NoEmit"
34
16
  },
35
- "peerDependencies": {
36
- "lodash": ">=4.12.0",
37
- "moment": ">=2.0.0"
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git@bitbucket.org-br:burnsred/burnsred-engage-ui.git"
38
20
  },
39
- "gitHead": "b5eddced9b62ae74a4de6c2be7c9206b11ce1c05"
21
+ "author": "BurnsRED",
22
+ "license": "UNLICENSED",
23
+ "type": "module",
24
+ "files": [
25
+ "dist/**"
26
+ ]
40
27
  }
package/CHANGELOG.md DELETED
@@ -1,88 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- ## [0.6.2](https://github.com/burnsred/burnsred-entity-library/compare/v0.5.2...v0.6.2) (2019-05-15)
7
-
8
-
9
- ### Bug Fixes
10
-
11
- * deploy ([28349bb](https://github.com/burnsred/burnsred-entity-library/commit/28349bb))
12
-
13
-
14
-
15
-
16
-
17
- ## [0.5.2](https://github.com/gnowth/entity/compare/v0.5.1...v0.5.2) (2019-05-14)
18
-
19
-
20
- ### Bug Fixes
21
-
22
- * change license to MIT ([#154](https://github.com/gnowth/entity/issues/154)) ([78d85be](https://github.com/gnowth/entity/commit/78d85be))
23
-
24
-
25
-
26
-
27
-
28
- ## [0.5.1](https://github.com/gnowth/entity/compare/v0.5.0...v0.5.1) (2019-03-20)
29
-
30
-
31
- ### Bug Fixes
32
-
33
- * build import and lodash replacement ([#139](https://github.com/gnowth/entity/issues/139)) ([0f937b7](https://github.com/gnowth/entity/commit/0f937b7))
34
-
35
-
36
-
37
-
38
-
39
- # [0.5.0](https://github.com/gnowth/entity/compare/v0.4.0...v0.5.0) (2019-03-19)
40
-
41
-
42
- ### Features
43
-
44
- * add mock get api ([#106](https://github.com/gnowth/entity/issues/106)) ([e27d63b](https://github.com/gnowth/entity/commit/e27d63b))
45
- * added mock to entity ([#112](https://github.com/gnowth/entity/issues/112)) ([358bdee](https://github.com/gnowth/entity/commit/358bdee))
46
- * added UIPortal ([#137](https://github.com/gnowth/entity/issues/137)) ([08105b8](https://github.com/gnowth/entity/commit/08105b8))
47
- * PopupShadow allows a dirtier value of parent Form ([#81](https://github.com/gnowth/entity/issues/81)) ([4813d6b](https://github.com/gnowth/entity/commit/4813d6b))
48
- * widgetcheckbox, with other fixes ([#129](https://github.com/gnowth/entity/issues/129)) ([3c7810a](https://github.com/gnowth/entity/commit/3c7810a))
49
-
50
-
51
- ### Performance Improvements
52
-
53
- * allow lodash plugin to optimise ([#132](https://github.com/gnowth/entity/issues/132)) ([3c04468](https://github.com/gnowth/entity/commit/3c04468))
54
-
55
-
56
-
57
-
58
-
59
- # [0.4.0](https://github.com/gnowth/entity/compare/v0.2.0...v0.4.0) (2019-01-27)
60
-
61
-
62
- ### Bug Fixes
63
-
64
- * github requiring ssh from circleci ([3d86a88](https://github.com/gnowth/entity/commit/3d86a88))
65
-
66
-
67
- ### Performance Improvements
68
-
69
- * split code in vender/route ([#45](https://github.com/gnowth/entity/issues/45)) ([96b2067](https://github.com/gnowth/entity/commit/96b2067))
70
-
71
-
72
-
73
-
74
-
75
- # [0.2.0](https://github.com/gnowth/entity/compare/v0.1.1...v0.2.0) (2018-11-16)
76
-
77
-
78
- ### Features
79
-
80
- * added widgetList, field getKey ([#21](https://github.com/gnowth/entity/issues/21)) ([3ffb626](https://github.com/gnowth/entity/commit/3ffb626))
81
-
82
-
83
-
84
-
85
-
86
- ## 0.1.1 (2018-11-11)
87
-
88
- **Note:** Version bump only for package @entity/core