@quatrain/core 1.2.5 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Core.d.ts.map +1 -1
- package/dist/Core.js.map +1 -1
- package/dist/common/ResourcesErrors.d.ts.map +1 -1
- package/dist/common/ResourcesErrors.js.map +1 -1
- package/dist/components/AbstractObject.d.ts.map +1 -1
- package/dist/components/AbstractObject.js.map +1 -1
- package/dist/components/BaseObject.d.ts.map +1 -1
- package/dist/components/BaseObject.js.map +1 -1
- package/dist/components/DataObject.d.ts.map +1 -1
- package/dist/components/DataObject.js.map +1 -1
- package/dist/components/Entity.d.ts.map +1 -1
- package/dist/components/Entity.js.map +1 -1
- package/dist/components/ObjectUri.d.ts.map +1 -1
- package/dist/components/ObjectUri.js.map +1 -1
- package/dist/components/User.d.ts.map +1 -1
- package/dist/components/User.js.map +1 -1
- package/dist/properties/ArrayProperty.d.ts.map +1 -1
- package/dist/properties/ArrayProperty.js.map +1 -1
- package/dist/properties/BaseProperty.d.ts.map +1 -1
- package/dist/properties/BaseProperty.js.map +1 -1
- package/dist/properties/BooleanProperty.d.ts.map +1 -1
- package/dist/properties/BooleanProperty.js.map +1 -1
- package/dist/properties/CollectionProperty.d.ts.map +1 -1
- package/dist/properties/CollectionProperty.js.map +1 -1
- package/dist/properties/DateTimeProperty.d.ts.map +1 -1
- package/dist/properties/DateTimeProperty.js.map +1 -1
- package/dist/properties/EnumProperty.d.ts.map +1 -1
- package/dist/properties/EnumProperty.js.map +1 -1
- package/dist/properties/FileProperty.d.ts.map +1 -1
- package/dist/properties/FileProperty.js.map +1 -1
- package/dist/properties/HashProperty.d.ts.map +1 -1
- package/dist/properties/HashProperty.js +3 -0
- package/dist/properties/HashProperty.js.map +1 -1
- package/dist/properties/MapProperty.d.ts.map +1 -1
- package/dist/properties/MapProperty.js.map +1 -1
- package/dist/properties/NumberProperty.d.ts.map +1 -1
- package/dist/properties/NumberProperty.js.map +1 -1
- package/dist/properties/ObjectProperty.d.ts.map +1 -1
- package/dist/properties/ObjectProperty.js.map +1 -1
- package/dist/properties/Property.d.ts.map +1 -1
- package/dist/properties/Property.js.map +1 -1
- package/dist/properties/StringProperty.d.ts.map +1 -1
- package/dist/properties/StringProperty.js.map +1 -1
- package/package.json +2 -2
- package/src/Core.ts +96 -0
- package/src/common/ResourcesErrors.ts +12 -0
- package/src/components/AbstractObject.ts +33 -3
- package/src/components/BaseObject.ts +37 -0
- package/src/components/DataObject.ts +45 -0
- package/src/components/Entity.ts +12 -0
- package/src/components/ObjectUri.ts +11 -0
- package/src/components/User.ts +12 -0
- package/src/properties/ArrayProperty.ts +48 -0
- package/src/properties/BaseProperty.ts +60 -0
- package/src/properties/BooleanProperty.ts +26 -0
- package/src/properties/CollectionProperty.ts +35 -0
- package/src/properties/DateTimeProperty.ts +35 -0
- package/src/properties/EnumProperty.ts +34 -0
- package/src/properties/FileProperty.ts +17 -0
- package/src/properties/HashProperty.ts +63 -0
- package/src/properties/MapProperty.ts +31 -0
- package/src/properties/NumberProperty.ts +55 -0
- package/src/properties/ObjectProperty.ts +46 -0
- package/src/properties/Property.ts +24 -0
- package/src/properties/StringProperty.ts +54 -0
|
@@ -7,6 +7,21 @@ export type EventTypes =
|
|
|
7
7
|
| typeof BaseProperty.EVENT_ONCHANGE
|
|
8
8
|
| typeof BaseProperty.EVENT_ONDELETE
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Configuration dictionary for instantiating a BaseProperty.
|
|
12
|
+
* Defines the behavior, constraints, and default state of a property within a Quatrain DataObject.
|
|
13
|
+
*
|
|
14
|
+
* | Parameter | Type | Description | Default |
|
|
15
|
+
* | :--- | :--- | :--- | :--- |
|
|
16
|
+
* | `name` | string | The canonical name of the property. | **Required** |
|
|
17
|
+
* | `id` | string | The internal identifier (defaults to lowercase `name`). | `name.toLowerCase()` |
|
|
18
|
+
* | `parent` | DataObjectClass | The parent object containing this property. | `undefined` |
|
|
19
|
+
* | `protected` | boolean | If true, the value can only be set once and becomes read-only. | `false` |
|
|
20
|
+
* | `mandatory` | boolean | If true, the property must have a value before saving. | `false` |
|
|
21
|
+
* | `defaultValue` | any | The default value or a function returning the default value. | `undefined` |
|
|
22
|
+
* | `htmlType` | PropertyHTMLType | The suggested HTML input type for rendering in a UI. | `'off'` |
|
|
23
|
+
* | `onChange` | function | Callback triggered whenever the property value is modified. | `undefined` |
|
|
24
|
+
*/
|
|
10
25
|
export interface BasePropertyType extends AbstractPropertyType {
|
|
11
26
|
parent?: DataObjectClass<any>
|
|
12
27
|
protected?: boolean
|
|
@@ -17,9 +32,30 @@ export interface BasePropertyType extends AbstractPropertyType {
|
|
|
17
32
|
}
|
|
18
33
|
|
|
19
34
|
// TODO: add `meta: boolean`. If meta is true, it is a meta-property strictly manipulated by the backend, and read-only for the user.
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The core foundation class for all Quatrain properties.
|
|
38
|
+
* It manages the state, immutability (protected), change tracking, and events of a data field.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const myProp = new BaseProperty({
|
|
43
|
+
* name: 'status',
|
|
44
|
+
* defaultValue: 'active',
|
|
45
|
+
* protected: false,
|
|
46
|
+
* onChange: (dao) => console.log('Status changed on', dao.id)
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* myProp.set('inactive');
|
|
50
|
+
* console.log(myProp.val()); // "inactive"
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
20
53
|
export class BaseProperty implements PropertyClassType {
|
|
54
|
+
/** The string literal type identifier for this property. */
|
|
21
55
|
static TYPE = 'any'
|
|
56
|
+
/** Event name triggered when the property value changes. */
|
|
22
57
|
static EVENT_ONCHANGE = 'onChange'
|
|
58
|
+
/** Event name triggered when the property is deleted. */
|
|
23
59
|
static EVENT_ONDELETE = 'onDelete'
|
|
24
60
|
|
|
25
61
|
protected _parent: DataObjectClass<any> | undefined
|
|
@@ -86,6 +122,14 @@ export class BaseProperty implements PropertyClassType {
|
|
|
86
122
|
this._hasChanged = val
|
|
87
123
|
}
|
|
88
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Sets a new value for the property and triggers the `onChange` event if modified.
|
|
127
|
+
*
|
|
128
|
+
* @param value - The new value to assign.
|
|
129
|
+
* @param setChanged - Whether to mark the property as modified (defaults to true).
|
|
130
|
+
* @returns The current property instance for chaining.
|
|
131
|
+
* @throws {Error} If the property is marked as `protected` and already has a value.
|
|
132
|
+
*/
|
|
89
133
|
set(value: any, setChanged: boolean = true) {
|
|
90
134
|
if (
|
|
91
135
|
this._value !== undefined &&
|
|
@@ -113,6 +157,12 @@ export class BaseProperty implements PropertyClassType {
|
|
|
113
157
|
return this
|
|
114
158
|
}
|
|
115
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Retrieves the current value of the property, or its default value if currently undefined.
|
|
162
|
+
*
|
|
163
|
+
* @param transform - An optional transformation function applied to the value before returning it.
|
|
164
|
+
* @returns The raw or transformed property value.
|
|
165
|
+
*/
|
|
116
166
|
val(transform: any = undefined): any {
|
|
117
167
|
// console.log(transform && transform(this._value), typeof transform);
|
|
118
168
|
return typeof transform === 'function'
|
|
@@ -126,10 +176,20 @@ export class BaseProperty implements PropertyClassType {
|
|
|
126
176
|
return value === undefined || value === true
|
|
127
177
|
}
|
|
128
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Serializes the property for JSON stringification.
|
|
181
|
+
*
|
|
182
|
+
* @returns The raw internal value of the property.
|
|
183
|
+
*/
|
|
129
184
|
toJSON() {
|
|
130
185
|
return this._value
|
|
131
186
|
}
|
|
132
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Creates a deep clone of the current property instance, preserving its prototype chain.
|
|
190
|
+
*
|
|
191
|
+
* @returns A new independent instance of the property.
|
|
192
|
+
*/
|
|
133
193
|
clone() {
|
|
134
194
|
const cloned = Object.create(
|
|
135
195
|
Object.getPrototypeOf(this),
|
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import { BaseProperty, BasePropertyType } from './BaseProperty'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration dictionary for instantiating a `BooleanProperty`.
|
|
5
|
+
* Inherits all core parameters from `BasePropertyType` with no additional constraints.
|
|
6
|
+
*/
|
|
3
7
|
export interface BooleanPropertyType extends BasePropertyType {}
|
|
4
8
|
|
|
9
|
+
/**
|
|
10
|
+
* A property type strictly handling boolean values (`true` or `false`).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const isActive = new BooleanProperty({
|
|
15
|
+
* name: 'isActive',
|
|
16
|
+
* defaultValue: false
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* isActive.set(true);
|
|
20
|
+
* console.log(isActive.val()); // true
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
5
23
|
export class BooleanProperty extends BaseProperty {
|
|
24
|
+
/** The string literal type identifier for this property. */
|
|
6
25
|
static TYPE = 'boolean'
|
|
7
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Assigns a new boolean value to the property.
|
|
29
|
+
*
|
|
30
|
+
* @param value - The boolean value to assign.
|
|
31
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
32
|
+
* @returns The property instance for chaining.
|
|
33
|
+
*/
|
|
8
34
|
set(value: boolean, setChanged = true) {
|
|
9
35
|
return super.set(value, setChanged)
|
|
10
36
|
}
|
|
@@ -4,13 +4,36 @@ import { Core } from '../Core'
|
|
|
4
4
|
import { DataObjectClass } from '../components/types/DataObjectClass'
|
|
5
5
|
import { BaseObject } from '../components/BaseObject'
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Configuration dictionary for instantiating a core `CollectionProperty`.
|
|
9
|
+
* Defines a relationship containing multiple objects.
|
|
10
|
+
*
|
|
11
|
+
* | Parameter | Type | Description | Default |
|
|
12
|
+
* | :--- | :--- | :--- | :--- |
|
|
13
|
+
* | `instanceOf` | typeof BaseObject | The class of the objects contained in this collection. | **Required** |
|
|
14
|
+
* | `backend` | any | An optional specific backend instance for persistence handling. | `undefined` |
|
|
15
|
+
* | `parentKey` | string | The foreign key field pointing back to the parent. | `parent.uri.collection` |
|
|
16
|
+
*/
|
|
7
17
|
export interface CollectionPropertyType extends BasePropertyType {
|
|
8
18
|
instanceOf: typeof BaseObject
|
|
9
19
|
backend?: any
|
|
10
20
|
parentKey?: string
|
|
11
21
|
}
|
|
12
22
|
|
|
23
|
+
/**
|
|
24
|
+
* A basic relational property type representing a collection of `BaseObject` instances.
|
|
25
|
+
* This core class manages the in-memory array representation. For dynamic querying, see the backend `CollectionProperty`.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const permissions = new CollectionProperty({
|
|
30
|
+
* name: 'permissions',
|
|
31
|
+
* instanceOf: Permission
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
13
35
|
export class CollectionProperty extends BaseProperty {
|
|
36
|
+
/** The string literal type identifier for this property. */
|
|
14
37
|
static TYPE = 'collection'
|
|
15
38
|
protected _value:
|
|
16
39
|
| Array<any>
|
|
@@ -33,10 +56,22 @@ export class CollectionProperty extends BaseProperty {
|
|
|
33
56
|
config.parentKey || this._parent?.uri?.collection || 'unknown'
|
|
34
57
|
}
|
|
35
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Assigns an array of related objects or URIs to the collection.
|
|
61
|
+
*
|
|
62
|
+
* @param value - The array of elements to assign.
|
|
63
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
64
|
+
* @returns The property instance for chaining.
|
|
65
|
+
*/
|
|
36
66
|
set(value: Array<any>, setChanged = true) {
|
|
37
67
|
return super.set(value, setChanged)
|
|
38
68
|
}
|
|
39
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Serializes the collection for JSON output.
|
|
72
|
+
*
|
|
73
|
+
* @returns The raw array of values.
|
|
74
|
+
*/
|
|
40
75
|
toJSON() {
|
|
41
76
|
return this._value
|
|
42
77
|
}
|
|
@@ -1,15 +1,42 @@
|
|
|
1
1
|
import { BaseProperty, BasePropertyType } from './BaseProperty'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration dictionary for instantiating a `DateTimeProperty`.
|
|
5
|
+
* Extends `BasePropertyType` to handle date and time manipulations.
|
|
6
|
+
*
|
|
7
|
+
* | Parameter | Type | Description | Default |
|
|
8
|
+
* | :--- | :--- | :--- | :--- |
|
|
9
|
+
* | `timezone` | string | The timezone string (e.g. 'UTC', 'Europe/Paris', or 'Z'). | `'Z'` |
|
|
10
|
+
*/
|
|
3
11
|
export interface DateTimePropertyType extends BasePropertyType {
|
|
4
12
|
timezone?: string
|
|
5
13
|
}
|
|
6
14
|
|
|
15
|
+
/**
|
|
16
|
+
* A property type that manages Dates, Timestamps, and ISO date strings.
|
|
17
|
+
* It automatically parses strings and standardizes UTC conversions depending on the global `RETURN_AS` setting.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const createdAt = new DateTimeProperty({
|
|
22
|
+
* name: 'createdAt',
|
|
23
|
+
* timezone: 'UTC'
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* createdAt.set(new Date()); // Will store as UNIX timestamp if RETURN_AS is configured
|
|
27
|
+
* console.log(createdAt.val());
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
7
30
|
export class DateTimeProperty extends BaseProperty {
|
|
31
|
+
/** Return behavior to return the original Date object or string as is. */
|
|
8
32
|
static AS_IS = 'asis'
|
|
33
|
+
/** Return behavior to auto-convert dates into numeric UNIX timestamps. */
|
|
9
34
|
static UNIX_TIMESTAMP = 'unix_timestamp'
|
|
10
35
|
|
|
36
|
+
/** The string literal type identifier for this property. */
|
|
11
37
|
static TYPE = 'datetime'
|
|
12
38
|
|
|
39
|
+
/** Global configuration determining the default format returned by `val()`. */
|
|
13
40
|
static RETURN_AS: string = DateTimeProperty.AS_IS
|
|
14
41
|
|
|
15
42
|
protected _timezone: string
|
|
@@ -19,6 +46,14 @@ export class DateTimeProperty extends BaseProperty {
|
|
|
19
46
|
this._timezone = config.timezone || 'Z'
|
|
20
47
|
}
|
|
21
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Assigns a new date value. If `RETURN_AS` is set to `unix_timestamp`,
|
|
51
|
+
* strings and JS Date objects are automatically parsed and converted to UNIX timestamps (milliseconds).
|
|
52
|
+
*
|
|
53
|
+
* @param value - The date string, timestamp, or Date object to assign.
|
|
54
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
55
|
+
* @returns The property instance for chaining.
|
|
56
|
+
*/
|
|
22
57
|
set(value: string | Date | number, setChanged = true) {
|
|
23
58
|
if (value && DateTimeProperty.RETURN_AS === 'unix_timestamp') {
|
|
24
59
|
if (typeof value === 'string') {
|
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
import { BaseProperty, BasePropertyType } from './BaseProperty'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration dictionary for instantiating an `EnumProperty`.
|
|
5
|
+
* Restricts the property value to a specific set of allowed strings.
|
|
6
|
+
*
|
|
7
|
+
* | Parameter | Type | Description | Default |
|
|
8
|
+
* | :--- | :--- | :--- | :--- |
|
|
9
|
+
* | `values` | string[] | Array of acceptable string values. | `[]` |
|
|
10
|
+
*/
|
|
3
11
|
export interface EnumPropertyType extends BasePropertyType {
|
|
4
12
|
values?: string[]
|
|
5
13
|
}
|
|
6
14
|
|
|
15
|
+
/**
|
|
16
|
+
* A property type that validates string values against a strict list of allowed options.
|
|
17
|
+
* Useful for status fields, categories, or predefined states.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const status = new EnumProperty({
|
|
22
|
+
* name: 'status',
|
|
23
|
+
* values: ['pending', 'active', 'deleted']
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* status.set('active'); // OK
|
|
27
|
+
* status.set('archived'); // Throws Error: Value 'archived' is not acceptable
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
7
30
|
export class EnumProperty extends BaseProperty {
|
|
31
|
+
/** Special wildcard value allowing any string to be accepted if configured in `values`. */
|
|
8
32
|
static WILDCARD = '*'
|
|
33
|
+
/** The string literal type identifier for this property. */
|
|
9
34
|
static TYPE = 'enum'
|
|
10
35
|
protected _values: string[] = []
|
|
11
36
|
|
|
@@ -14,6 +39,15 @@ export class EnumProperty extends BaseProperty {
|
|
|
14
39
|
this._values = config.values || []
|
|
15
40
|
}
|
|
16
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Assigns a new value, validating it against the allowed enum values.
|
|
44
|
+
* If the wildcard (`*`) is present in the allowed values, any value is accepted.
|
|
45
|
+
*
|
|
46
|
+
* @param value - The enum string to assign.
|
|
47
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
48
|
+
* @returns The property instance for chaining.
|
|
49
|
+
* @throws {Error} If the value is not in the allowed list.
|
|
50
|
+
*/
|
|
17
51
|
set(value: string, setChanged = true) {
|
|
18
52
|
if (
|
|
19
53
|
value !== null &&
|
|
@@ -2,10 +2,27 @@ import { ObjectUri } from '../components/ObjectUri'
|
|
|
2
2
|
import { BaseProperty, BasePropertyType } from './BaseProperty'
|
|
3
3
|
import { BaseObjectClass } from '../components/types/BaseObjectClass'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Configuration dictionary for instantiating a `FileProperty`.
|
|
7
|
+
* Inherits all core parameters from `BasePropertyType`.
|
|
8
|
+
*/
|
|
5
9
|
export interface FilePropertyType extends BasePropertyType {}
|
|
6
10
|
|
|
11
|
+
/**
|
|
12
|
+
* A property type designed to hold a reference to a File or Blob.
|
|
13
|
+
* It usually stores either the raw `BaseObjectClass` representing the file, or an `ObjectUri` pointing to the storage location.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const avatar = new FileProperty({
|
|
18
|
+
* name: 'avatar'
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
7
22
|
export class FileProperty extends BaseProperty {
|
|
23
|
+
/** The string literal type identifier for this property. */
|
|
8
24
|
static TYPE = 'file'
|
|
25
|
+
/** The internal stored value, either a class instance or a URI. */
|
|
9
26
|
_value: BaseObjectClass | ObjectUri | undefined = undefined
|
|
10
27
|
|
|
11
28
|
constructor(config: FilePropertyType) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
2
|
import { StringProperty, StringPropertyType } from './StringProperty'
|
|
3
|
+
import { Core } from '../Core'
|
|
3
4
|
|
|
4
5
|
export type HashPropertyAlgos =
|
|
5
6
|
| typeof HashProperty.ALGORITHM_MD5
|
|
@@ -7,17 +8,50 @@ export type HashPropertyAlgos =
|
|
|
7
8
|
| typeof HashProperty.ALGORITHM_SHA256
|
|
8
9
|
| typeof HashProperty.ALGORITHM_BCRYPT
|
|
9
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Configuration dictionary for instantiating a `HashProperty`.
|
|
13
|
+
* Extends `StringPropertyType` to add hashing capabilities.
|
|
14
|
+
*
|
|
15
|
+
* | Parameter | Type | Description | Default |
|
|
16
|
+
* | :--- | :--- | :--- | :--- |
|
|
17
|
+
* | `algorithm` | HashPropertyAlgos | The cryptographic hashing algorithm to use. | `ALGORITHM_MD5` |
|
|
18
|
+
* | `salt` | string | An optional salt string appended to the value before hashing. | `""` |
|
|
19
|
+
* | `prefixed` | boolean | If true, prepends the algorithm name to the output (e.g. `md5-abc...`). | `false` |
|
|
20
|
+
*/
|
|
10
21
|
export interface HashPropertyType extends StringPropertyType {
|
|
11
22
|
algorithm?: HashPropertyAlgos
|
|
12
23
|
salt?: string
|
|
13
24
|
prefixed?: boolean
|
|
14
25
|
}
|
|
15
26
|
|
|
27
|
+
/**
|
|
28
|
+
* A specialized string property that automatically hashes incoming values before storing them.
|
|
29
|
+
* Useful for storing passwords, secret tokens, or generating unique fingerprints.
|
|
30
|
+
* Values set on this property are one-way hashed and cannot be reversed.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const password = new HashProperty({
|
|
35
|
+
* name: 'password',
|
|
36
|
+
* algorithm: HashProperty.ALGORITHM_SHA256,
|
|
37
|
+
* salt: 'mySecretSalt'
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* password.set('mySuperPassword');
|
|
41
|
+
* console.log(password.val()); // Returns the SHA256 hashed string
|
|
42
|
+
* const isValid = password.compare('mySuperPassword'); // true
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
16
45
|
export class HashProperty extends StringProperty {
|
|
46
|
+
/** The string literal type identifier for this property. */
|
|
17
47
|
static TYPE = 'hash'
|
|
48
|
+
/** Identifier for the MD5 hashing algorithm. */
|
|
18
49
|
static ALGORITHM_MD5 = 'md5'
|
|
50
|
+
/** Identifier for the SHA1 hashing algorithm. */
|
|
19
51
|
static ALGORITHM_SHA1 = 'sha1'
|
|
52
|
+
/** Identifier for the SHA256 hashing algorithm. */
|
|
20
53
|
static ALGORITHM_SHA256 = 'sha256'
|
|
54
|
+
/** Identifier for the BCRYPT hashing algorithm. */
|
|
21
55
|
static ALGORITHM_BCRYPT = 'bcrypt'
|
|
22
56
|
|
|
23
57
|
protected _algorithm: HashPropertyAlgos
|
|
@@ -31,15 +65,29 @@ export class HashProperty extends StringProperty {
|
|
|
31
65
|
this._prefixed = config.prefixed || false
|
|
32
66
|
}
|
|
33
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Internal method to perform the cryptographic hash on a raw string.
|
|
70
|
+
* Uses Node.js native crypto module.
|
|
71
|
+
*
|
|
72
|
+
* @param value - The raw string to hash.
|
|
73
|
+
* @returns The hexadecimal representation of the hashed string.
|
|
74
|
+
* @throws {Error} If the chosen algorithm is unsupported.
|
|
75
|
+
*/
|
|
34
76
|
_hash(value: string): string {
|
|
35
77
|
let algo
|
|
36
78
|
switch (this._algorithm) {
|
|
37
79
|
case HashProperty.ALGORITHM_MD5:
|
|
38
80
|
algo = createHash('md5')
|
|
81
|
+
Core.warn(
|
|
82
|
+
`HashProperty: MD5 is deprecated for security reasons`
|
|
83
|
+
)
|
|
39
84
|
break
|
|
40
85
|
|
|
41
86
|
case HashProperty.ALGORITHM_SHA1:
|
|
42
87
|
algo = createHash('sha1')
|
|
88
|
+
Core.warn(
|
|
89
|
+
`HashProperty: SHA1 is deprecated for security reasons`
|
|
90
|
+
)
|
|
43
91
|
break
|
|
44
92
|
|
|
45
93
|
case HashProperty.ALGORITHM_SHA256:
|
|
@@ -60,10 +108,25 @@ export class HashProperty extends StringProperty {
|
|
|
60
108
|
return hash
|
|
61
109
|
}
|
|
62
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Hashes the provided value and stores the hashed result.
|
|
113
|
+
* String length constraints (from StringProperty) are bypassed after hashing.
|
|
114
|
+
*
|
|
115
|
+
* @param value - The raw cleartext string to hash and store.
|
|
116
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
117
|
+
* @returns The property instance for chaining.
|
|
118
|
+
*/
|
|
63
119
|
set(value: string, setChanged = true) {
|
|
64
120
|
return super.set(this._hash(value), setChanged)
|
|
65
121
|
}
|
|
66
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Compares a raw cleartext string against the stored hashed value.
|
|
125
|
+
* Automatically applies the configured salt and algorithm to the input before comparison.
|
|
126
|
+
*
|
|
127
|
+
* @param value - The raw cleartext string to test.
|
|
128
|
+
* @returns True if the hashed input matches the stored hash, false otherwise.
|
|
129
|
+
*/
|
|
67
130
|
compare(value: string): boolean {
|
|
68
131
|
return this._hash(value) === this._value
|
|
69
132
|
}
|
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import { BaseProperty, BasePropertyType } from './BaseProperty'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Configuration dictionary for instantiating a `MapProperty`.
|
|
5
|
+
* Inherits all core parameters from `BasePropertyType`.
|
|
6
|
+
*/
|
|
3
7
|
export interface MapPropertyType extends BasePropertyType {}
|
|
4
8
|
|
|
9
|
+
/**
|
|
10
|
+
* A property type designed to store arbitrary JSON objects or Key-Value maps.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const metadata = new MapProperty({
|
|
15
|
+
* name: 'metadata',
|
|
16
|
+
* defaultValue: {}
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* metadata.set({ theme: 'dark', version: 2 });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
5
22
|
export class MapProperty extends BaseProperty {
|
|
23
|
+
/** The string literal type identifier for this property. */
|
|
6
24
|
static TYPE = 'map'
|
|
7
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Assigns a new object or map to the property.
|
|
28
|
+
*
|
|
29
|
+
* @param value - The object to assign. Must be of type 'object'.
|
|
30
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
31
|
+
* @returns The property instance for chaining.
|
|
32
|
+
* @throws {Error} If the provided value is not an object.
|
|
33
|
+
*/
|
|
8
34
|
set(value: any, setChanged = true) {
|
|
9
35
|
if (typeof value! !== 'object') {
|
|
10
36
|
throw new Error(`value ${JSON.stringify(value)} is not an object`)
|
|
@@ -13,6 +39,11 @@ export class MapProperty extends BaseProperty {
|
|
|
13
39
|
return super.set(value, setChanged)
|
|
14
40
|
}
|
|
15
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Serializes the map property for database storage.
|
|
44
|
+
*
|
|
45
|
+
* @returns A JSON string representation of the map, or an empty object.
|
|
46
|
+
*/
|
|
16
47
|
toJSON() {
|
|
17
48
|
return this._value ? JSON.stringify(this._value) : {}
|
|
18
49
|
}
|
|
@@ -8,6 +8,20 @@ export type NumberType =
|
|
|
8
8
|
| typeof NumberProperty.TYPE_INTEGER
|
|
9
9
|
| typeof NumberProperty.TYPE_FLOAT
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Configuration dictionary for instantiating a `NumberProperty`.
|
|
13
|
+
* Enforces numeric bounds, types (integer vs float), signs, and UI formatting.
|
|
14
|
+
*
|
|
15
|
+
* | Parameter | Type | Description | Default |
|
|
16
|
+
* | :--- | :--- | :--- | :--- |
|
|
17
|
+
* | `minVal` | number | The minimum allowed value (inclusive). | `undefined` |
|
|
18
|
+
* | `maxVal` | number | The maximum allowed value (inclusive). | `undefined` |
|
|
19
|
+
* | `sign` | NumberSign | Restricts the number to `signed` or `unsigned` (positive only). | `TYPE_SIGNED` |
|
|
20
|
+
* | `type` | NumberType | The numeric type: `integer` (floored) or `float`. | `TYPE_INTEGER` |
|
|
21
|
+
* | `prefix` | string | A string prepended to the formatted output (e.g., "$"). | `""` |
|
|
22
|
+
* | `suffix` | string | A string appended to the formatted output (e.g., "kg"). | `""` |
|
|
23
|
+
* | `precision` | number | Number of decimal places for floats. | `0` |
|
|
24
|
+
*/
|
|
11
25
|
export interface NumberPropertyType extends BasePropertyType {
|
|
12
26
|
minVal?: number
|
|
13
27
|
maxVal?: number
|
|
@@ -18,16 +32,42 @@ export interface NumberPropertyType extends BasePropertyType {
|
|
|
18
32
|
precision?: number
|
|
19
33
|
}
|
|
20
34
|
|
|
35
|
+
/**
|
|
36
|
+
* A property type strictly validating and formatting numeric values.
|
|
37
|
+
* Allows enforcement of integers, positive-only limits, and boundary checking.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const price = new NumberProperty({
|
|
42
|
+
* name: 'price',
|
|
43
|
+
* type: NumberProperty.TYPE_FLOAT,
|
|
44
|
+
* sign: NumberProperty.TYPE_UNSIGNED,
|
|
45
|
+
* prefix: '$',
|
|
46
|
+
* minVal: 0
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* price.set(19.99);
|
|
50
|
+
* console.log(price.val(NumberProperty.TRANSFORM_FORMATTED)); // "$ 19.99"
|
|
51
|
+
* price.set(-5); // Throws Error: Value must be unsigned
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
21
54
|
export class NumberProperty extends BaseProperty {
|
|
55
|
+
/** The string literal type identifier for this property. */
|
|
22
56
|
static TYPE = 'number'
|
|
57
|
+
/** Constraint flag for signed numbers (positive and negative). */
|
|
23
58
|
static TYPE_SIGNED = 'signed'
|
|
59
|
+
/** Constraint flag for unsigned numbers (positive only). */
|
|
24
60
|
static TYPE_UNSIGNED = 'unsigned'
|
|
25
61
|
|
|
62
|
+
/** Type flag indicating an integer value. */
|
|
26
63
|
static TYPE_INTEGER = 'integer'
|
|
64
|
+
/** Type flag indicating a floating-point value. */
|
|
27
65
|
static TYPE_FLOAT = 'float'
|
|
28
66
|
|
|
67
|
+
/** Default separator used for string formatting. */
|
|
29
68
|
static SEPARATOR = ' '
|
|
30
69
|
|
|
70
|
+
/** Transformation identifier to return the number as a formatted string. */
|
|
31
71
|
static TRANSFORM_FORMATTED = 'formatted'
|
|
32
72
|
|
|
33
73
|
protected _minVal: number | undefined = undefined
|
|
@@ -58,6 +98,15 @@ export class NumberProperty extends BaseProperty {
|
|
|
58
98
|
}
|
|
59
99
|
}
|
|
60
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Assigns a new numeric value while strictly enforcing boundary, sign, and type constraints.
|
|
103
|
+
* If configured as an integer, the input is floored.
|
|
104
|
+
*
|
|
105
|
+
* @param value - The number to assign.
|
|
106
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
107
|
+
* @returns The property instance for chaining.
|
|
108
|
+
* @throws {Error} If the number violates the min, max, or sign constraints.
|
|
109
|
+
*/
|
|
61
110
|
set(value: number, setChanged = true) {
|
|
62
111
|
if (this._sign === NumberProperty.TYPE_UNSIGNED && value < 0) {
|
|
63
112
|
throw new Error(`Value must be unsigned`)
|
|
@@ -78,6 +127,12 @@ export class NumberProperty extends BaseProperty {
|
|
|
78
127
|
return super.set(value, setChanged)
|
|
79
128
|
}
|
|
80
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Retrieves the numeric value, optionally applying UI string formatting.
|
|
132
|
+
*
|
|
133
|
+
* @param transform - Use `TRANSFORM_FORMATTED` to return a string with the configured prefix and suffix.
|
|
134
|
+
* @returns The raw number or the formatted string representation.
|
|
135
|
+
*/
|
|
81
136
|
val(transform: string | undefined = undefined) {
|
|
82
137
|
switch (transform) {
|
|
83
138
|
case NumberProperty.TRANSFORM_FORMATTED:
|
|
@@ -12,13 +12,39 @@ export enum returnAs {
|
|
|
12
12
|
AS_IS = 'asIs',
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Configuration dictionary for instantiating an `ObjectProperty`.
|
|
17
|
+
* Defines the class type of the expected object.
|
|
18
|
+
*
|
|
19
|
+
* | Parameter | Type | Description | Default |
|
|
20
|
+
* | :--- | :--- | :--- | :--- |
|
|
21
|
+
* | `instanceOf` | any | The class constructor or class name string the object must match. | **Required** |
|
|
22
|
+
*/
|
|
15
23
|
export interface ObjectPropertyType extends BasePropertyType {
|
|
16
24
|
instanceOf: any //Function | string | Object
|
|
17
25
|
}
|
|
18
26
|
|
|
27
|
+
/**
|
|
28
|
+
* A relational property type designed to store references to other `BaseObjectClass` instances.
|
|
29
|
+
* Handles polymorphic resolution between raw `ObjectUri`, underlying `DataObject`, or the full class instance.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const owner = new ObjectProperty({
|
|
34
|
+
* name: 'owner',
|
|
35
|
+
* instanceOf: User
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* owner.set(userInstance);
|
|
39
|
+
* const uri = owner.val(returnAs.AS_OBJECTURIS); // Returns just the reference
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
19
42
|
export class ObjectProperty extends BaseProperty {
|
|
43
|
+
/** The string literal type identifier for this property. */
|
|
20
44
|
static TYPE = 'object'
|
|
45
|
+
/** The internal stored value, either a class instance or a URI. */
|
|
21
46
|
_value: BaseObjectClass | ObjectUri | undefined = undefined
|
|
47
|
+
/** The class constructor or class name string the object must match. */
|
|
22
48
|
_instanceOf: any //Function | string | Object
|
|
23
49
|
|
|
24
50
|
constructor(config: ObjectPropertyType) {
|
|
@@ -30,6 +56,12 @@ export class ObjectProperty extends BaseProperty {
|
|
|
30
56
|
return this._instanceOf
|
|
31
57
|
}
|
|
32
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Retrieves the object, optionally resolving it to a specific representation.
|
|
61
|
+
*
|
|
62
|
+
* @param transform - The desired format (`returnAs.AS_OBJECTURIS`, `AS_DATAOBJECTS`, `AS_INSTANCES`).
|
|
63
|
+
* @returns The resolved object, data object, or URI based on the requested transform.
|
|
64
|
+
*/
|
|
33
65
|
val(transform: string | undefined = undefined) {
|
|
34
66
|
try {
|
|
35
67
|
if (typeof this._instanceOf === 'string') {
|
|
@@ -89,6 +121,15 @@ export class ObjectProperty extends BaseProperty {
|
|
|
89
121
|
}
|
|
90
122
|
}
|
|
91
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Assigns an object or an object reference to the property.
|
|
126
|
+
* Validates that the provided object matches the `instanceOf` class definition.
|
|
127
|
+
*
|
|
128
|
+
* @param value - The `BaseObjectClass`, `DataObject`, or `ObjectUri` to assign.
|
|
129
|
+
* @param setChanged - Whether to mark the property as modified.
|
|
130
|
+
* @returns The property instance for chaining.
|
|
131
|
+
* @throws {Error} If the assigned value is not an instance of the configured class.
|
|
132
|
+
*/
|
|
92
133
|
set(value: object, setChanged = true) {
|
|
93
134
|
if (
|
|
94
135
|
value! instanceof ObjectUri &&
|
|
@@ -105,6 +146,11 @@ export class ObjectProperty extends BaseProperty {
|
|
|
105
146
|
return super.set(value, setChanged)
|
|
106
147
|
}
|
|
107
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Serializes the object property into a reference format suitable for storage.
|
|
151
|
+
*
|
|
152
|
+
* @returns The `ObjectUri` JSON representation, or a reference object.
|
|
153
|
+
*/
|
|
108
154
|
toJSON() {
|
|
109
155
|
if (this._value instanceof ObjectUri) {
|
|
110
156
|
return this._value.toJSON()
|