simplentity 0.1.2 → 1.0.0-alpha.1
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/README.md +10 -11
- package/dist/bun/entity.d.ts +53 -23
- package/dist/bun/field.d.ts +1 -1
- package/dist/bun/index.d.ts +3 -3
- package/dist/bun/index.js +1 -1
- package/dist/cjs/entity.cjs +32 -40
- package/dist/cjs/entity.d.ts +53 -23
- package/dist/cjs/field.d.ts +1 -1
- package/dist/cjs/fields/entity.cjs +68 -0
- package/dist/cjs/fields/index.cjs +9 -0
- package/dist/cjs/index.cjs +39 -38
- package/dist/cjs/index.d.ts +3 -3
- package/dist/entity.d.ts +53 -23
- package/dist/entity.js +31 -39
- package/dist/field.d.ts +1 -1
- package/dist/fields/entity.d.ts +5 -0
- package/dist/fields/entity.js +41 -0
- package/dist/fields/index.d.ts +2 -1
- package/dist/fields/index.js +8 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +38 -38
- package/package.json +2 -1
package/README.md
CHANGED
@@ -16,28 +16,27 @@ npm install simplentity
|
|
16
16
|
## Usage
|
17
17
|
|
18
18
|
```typescript
|
19
|
-
import {
|
19
|
+
import {createEntity, number, string, boolean} from 'simplentity';
|
20
20
|
|
21
21
|
// Define a user entity
|
22
|
-
|
22
|
+
const userFactory = createEntity({
|
23
23
|
id: string().defaultFn(() => randomUUID()), // randomUUID is a third-party library. Not included.
|
24
24
|
name: string(),
|
25
25
|
age: number().notRequired(),
|
26
26
|
isActive: boolean().default(true),
|
27
|
-
}) {
|
28
|
-
activate()
|
27
|
+
}, ({ set }) => ({
|
28
|
+
activate: () => {
|
29
29
|
// You can get suggestions for the properties of the entity.
|
30
|
-
|
30
|
+
set('isActive', true)
|
31
|
+
},
|
32
|
+
deactivate: () => {
|
33
|
+
set('isActive', false)
|
31
34
|
}
|
32
|
-
|
33
|
-
deactivate(): void {
|
34
|
-
this.set('isActive', false);
|
35
|
-
}
|
36
|
-
}
|
35
|
+
}))
|
37
36
|
|
38
37
|
// Properties that have NotRequired or Default(Fn) are optional.
|
39
38
|
// If a property has a default value, it is automatically assigned to the property when you create the entity instance.
|
40
|
-
const user =
|
39
|
+
const user = userFactory.create({
|
41
40
|
name: 'John Doe',
|
42
41
|
})
|
43
42
|
/*
|
package/dist/bun/entity.d.ts
CHANGED
@@ -14,29 +14,59 @@ type EntityPropInputResolver<T extends EntityConfig> = {
|
|
14
14
|
} & {
|
15
15
|
[K in keyof Omit<T, RequiredFieldKeys<T>>]?: FieldTypeResolver<T[K]>;
|
16
16
|
};
|
17
|
+
type MethodDefinition = {
|
18
|
+
[key: string]: (...args: any[]) => any;
|
19
|
+
};
|
20
|
+
interface EntityInterface<C extends EntityConfig> {
|
21
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
22
|
+
toJSON: () => EntityConfigTypeResolver<C>;
|
23
|
+
}
|
24
|
+
declare class EntityFactory<C extends EntityConfig, D extends MethodDefinition> {
|
25
|
+
private readonly fields;
|
26
|
+
private readonly methodDefinitionFunction?;
|
27
|
+
readonly $infer: EntityInterface<C> & D;
|
28
|
+
constructor(fields: C, methodDefinitionFunction?: (params: {
|
29
|
+
set: <K extends keyof C>(key: K, value: EntityConfigTypeResolver<C>[K]) => void;
|
30
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
31
|
+
}) => D);
|
32
|
+
create(props: EntityPropInputResolver<C>): EntityInterface<C> & D;
|
33
|
+
}
|
17
34
|
/**
|
18
|
-
*
|
19
|
-
*
|
35
|
+
* Creates an entity factory function that allows defining fields and optional methods for an entity.
|
36
|
+
* The returned factory provides a `create` method to instantiate entities with the specified fields
|
37
|
+
* and methods, while also supporting default values and runtime property manipulation.
|
38
|
+
*
|
39
|
+
* @template C - The configuration type for the entity fields.
|
40
|
+
* @template D - The type of the methods defined for the entity.
|
41
|
+
*
|
42
|
+
* @param fields - An object defining the fields of the entity. Each field should include its configuration
|
43
|
+
* and a method to retrieve its default value.
|
44
|
+
* @param methodDefinitionFunction - An optional function that defines additional methods for the entity.
|
45
|
+
* It receives an object with `set` and `get` functions to manipulate
|
46
|
+
* the entity's properties.
|
47
|
+
*
|
48
|
+
* @returns An object with a `create` method. The `create` method accepts an input object to initialize
|
49
|
+
* the entity's properties and returns an entity instance with the defined fields, methods,
|
50
|
+
* and utility functions (`get`, `set`, `toJSON`).
|
51
|
+
*
|
52
|
+
* @example
|
53
|
+
* ```typescript
|
54
|
+
* const userFactory = createEntity({
|
55
|
+
* name: string(),
|
56
|
+
* age: number().default(18),
|
57
|
+
* isActive: boolean().default(true),
|
58
|
+
* }, ({ set, get }) => ({
|
59
|
+
* incrementAge: () => set('age', get('age') + 1),
|
60
|
+
* }));
|
61
|
+
*
|
62
|
+
* const user = userFactory.create({ name: 'John' });
|
63
|
+
* console.log(user.props); // { name: 'John', age: 18, isActive: true }
|
64
|
+
* user.incrementAge();
|
65
|
+
* console.log(user.props.age); // 19
|
66
|
+
* ```
|
20
67
|
*/
|
21
|
-
export declare
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Get the value of the field by key
|
27
|
-
* @param key
|
28
|
-
*/
|
29
|
-
get<K extends keyof Config>(key: K): EntityConfigTypeResolver<Config>[K];
|
30
|
-
/**
|
31
|
-
* Set the value of the field by key
|
32
|
-
*
|
33
|
-
* WARNING: This method should be called only from the methods of the entity.
|
34
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
35
|
-
* @param key
|
36
|
-
* @param value
|
37
|
-
*/
|
38
|
-
set<K extends keyof Config>(key: K, value: EntityConfigTypeResolver<Config>[K]): void;
|
39
|
-
toJSON(): EntityConfigTypeResolver<Config>;
|
40
|
-
};
|
41
|
-
};
|
68
|
+
export declare function createEntity<C extends EntityConfig, D extends MethodDefinition>(fields: C, methodDefinitionFunction?: (params: {
|
69
|
+
set: <K extends keyof C>(key: K, value: EntityConfigTypeResolver<C>[K]) => void;
|
70
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
71
|
+
}) => D): EntityFactory<C, D>;
|
42
72
|
export {};
|
package/dist/bun/field.d.ts
CHANGED
@@ -24,7 +24,7 @@ type HasDefault<T extends ConfigurableFieldBase<unknown>> = T & {
|
|
24
24
|
};
|
25
25
|
export declare abstract class Field<T> implements ConfigurableFieldBase<T> {
|
26
26
|
_: FieldConfig<T>;
|
27
|
-
|
27
|
+
config: FieldRuntimeConfig<T>;
|
28
28
|
constructor();
|
29
29
|
notRequired(): NotRequired<this>;
|
30
30
|
default(value: T): HasDefault<this>;
|
package/dist/bun/index.d.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
import {
|
2
|
-
import { boolean, date, number, string } from "./fields/index.ts";
|
3
|
-
export {
|
1
|
+
import { createEntity } from "./entity.ts";
|
2
|
+
import { boolean, date, number, string, entity } from "./fields/index.ts";
|
3
|
+
export { createEntity, string, number, boolean, date, entity };
|
package/dist/bun/index.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
// @bun
|
2
|
-
class
|
2
|
+
class _{fields;methodDefinitionFunction;constructor(u,R){this.fields=u,this.methodDefinitionFunction=R}create(u){let R=Object.entries(this.fields).reduce((q,[x,C])=>{let D=u[x]??C.getDefaultValue();if(C.getConfig().hasDefault&&D===void 0)q[x]=C.getDefaultValue();else q[x]=D;return q},{}),W=(q,x)=>{R[q]=x},H=(q)=>{return R[q]},X=()=>{return R},Y=this.methodDefinitionFunction?.({set:W,get:H})??{};return{get:H,toJSON:X,...Y}}}function Z(u,R){return new _(u,R)}class T{config;constructor(){this.config={notRequired:!1,hasDefault:!1,default:void 0}}notRequired(){return this.config.notRequired=!0,this}default(u){return this.config.default=u,this.config.hasDefault=!0,this}defaultFn(u){return this.config.defaultFn=u,this.config.hasDefault=!0,this}getConfig(){return this.config}getDefaultValue(){return this.config.default??this.config.defaultFn?.()}}class b extends T{}var f=()=>{return new b};class B extends T{}var V=()=>{return new B};class G extends T{}var K=()=>{return new G};class L extends T{}var M=()=>{return new L};class Q extends T{}var U=()=>{return new Q};export{M as string,K as number,U as entity,V as date,Z as createEntity,f as boolean};
|
package/dist/cjs/entity.cjs
CHANGED
@@ -20,58 +20,50 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
20
20
|
// src/entity.ts
|
21
21
|
var entity_exports = {};
|
22
22
|
__export(entity_exports, {
|
23
|
-
|
23
|
+
createEntity: () => createEntity
|
24
24
|
});
|
25
25
|
module.exports = __toCommonJS(entity_exports);
|
26
|
-
var
|
27
|
-
|
28
|
-
|
29
|
-
constructor(
|
30
|
-
this
|
31
|
-
|
32
|
-
|
26
|
+
var EntityFactory = class {
|
27
|
+
fields;
|
28
|
+
methodDefinitionFunction;
|
29
|
+
constructor(fields, methodDefinitionFunction) {
|
30
|
+
this.fields = fields;
|
31
|
+
this.methodDefinitionFunction = methodDefinitionFunction;
|
32
|
+
}
|
33
|
+
create(props) {
|
34
|
+
const assignedProps = Object.entries(this.fields).reduce(
|
33
35
|
(acc, [key, field]) => {
|
34
36
|
const value = props[key] ?? field.getDefaultValue();
|
35
37
|
if (field.getConfig().hasDefault && value === void 0) {
|
36
|
-
|
38
|
+
acc[key] = field.getDefaultValue();
|
39
|
+
} else {
|
40
|
+
acc[key] = value;
|
37
41
|
}
|
38
|
-
acc[key] = value;
|
39
42
|
return acc;
|
40
43
|
},
|
41
44
|
{}
|
42
45
|
);
|
46
|
+
const set = (key, value) => {
|
47
|
+
assignedProps[key] = value;
|
48
|
+
};
|
49
|
+
const get = (key) => {
|
50
|
+
return assignedProps[key];
|
51
|
+
};
|
52
|
+
const toJSON = () => {
|
53
|
+
return assignedProps;
|
54
|
+
};
|
55
|
+
const methods = this.methodDefinitionFunction?.({ set, get }) ?? {};
|
56
|
+
return {
|
57
|
+
get,
|
58
|
+
toJSON,
|
59
|
+
...methods
|
60
|
+
};
|
43
61
|
}
|
44
|
-
/**
|
45
|
-
* Get the value of the field by key
|
46
|
-
* @param key
|
47
|
-
*/
|
48
|
-
get(key) {
|
49
|
-
return this.#props[key];
|
50
|
-
}
|
51
|
-
/**
|
52
|
-
* Set the value of the field by key
|
53
|
-
*
|
54
|
-
* WARNING: This method should be called only from the methods of the entity.
|
55
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
56
|
-
* @param key
|
57
|
-
* @param value
|
58
|
-
*/
|
59
|
-
set(key, value) {
|
60
|
-
this.#props[key] = value;
|
61
|
-
}
|
62
|
-
// biome-ignore lint/style/useNamingConvention: toJSON is a name to be used in JSON.stringify
|
63
|
-
toJSON() {
|
64
|
-
return this.#props;
|
65
|
-
}
|
66
|
-
};
|
67
|
-
var entity = (fields) => {
|
68
|
-
return class extends Entity {
|
69
|
-
constructor(props) {
|
70
|
-
super(props, fields);
|
71
|
-
}
|
72
|
-
};
|
73
62
|
};
|
63
|
+
function createEntity(fields, methodDefinitionFunction) {
|
64
|
+
return new EntityFactory(fields, methodDefinitionFunction);
|
65
|
+
}
|
74
66
|
// Annotate the CommonJS export names for ESM import in node:
|
75
67
|
0 && (module.exports = {
|
76
|
-
|
68
|
+
createEntity
|
77
69
|
});
|
package/dist/cjs/entity.d.ts
CHANGED
@@ -14,29 +14,59 @@ type EntityPropInputResolver<T extends EntityConfig> = {
|
|
14
14
|
} & {
|
15
15
|
[K in keyof Omit<T, RequiredFieldKeys<T>>]?: FieldTypeResolver<T[K]>;
|
16
16
|
};
|
17
|
+
type MethodDefinition = {
|
18
|
+
[key: string]: (...args: any[]) => any;
|
19
|
+
};
|
20
|
+
interface EntityInterface<C extends EntityConfig> {
|
21
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
22
|
+
toJSON: () => EntityConfigTypeResolver<C>;
|
23
|
+
}
|
24
|
+
declare class EntityFactory<C extends EntityConfig, D extends MethodDefinition> {
|
25
|
+
private readonly fields;
|
26
|
+
private readonly methodDefinitionFunction?;
|
27
|
+
readonly $infer: EntityInterface<C> & D;
|
28
|
+
constructor(fields: C, methodDefinitionFunction?: (params: {
|
29
|
+
set: <K extends keyof C>(key: K, value: EntityConfigTypeResolver<C>[K]) => void;
|
30
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
31
|
+
}) => D);
|
32
|
+
create(props: EntityPropInputResolver<C>): EntityInterface<C> & D;
|
33
|
+
}
|
17
34
|
/**
|
18
|
-
*
|
19
|
-
*
|
35
|
+
* Creates an entity factory function that allows defining fields and optional methods for an entity.
|
36
|
+
* The returned factory provides a `create` method to instantiate entities with the specified fields
|
37
|
+
* and methods, while also supporting default values and runtime property manipulation.
|
38
|
+
*
|
39
|
+
* @template C - The configuration type for the entity fields.
|
40
|
+
* @template D - The type of the methods defined for the entity.
|
41
|
+
*
|
42
|
+
* @param fields - An object defining the fields of the entity. Each field should include its configuration
|
43
|
+
* and a method to retrieve its default value.
|
44
|
+
* @param methodDefinitionFunction - An optional function that defines additional methods for the entity.
|
45
|
+
* It receives an object with `set` and `get` functions to manipulate
|
46
|
+
* the entity's properties.
|
47
|
+
*
|
48
|
+
* @returns An object with a `create` method. The `create` method accepts an input object to initialize
|
49
|
+
* the entity's properties and returns an entity instance with the defined fields, methods,
|
50
|
+
* and utility functions (`get`, `set`, `toJSON`).
|
51
|
+
*
|
52
|
+
* @example
|
53
|
+
* ```typescript
|
54
|
+
* const userFactory = createEntity({
|
55
|
+
* name: string(),
|
56
|
+
* age: number().default(18),
|
57
|
+
* isActive: boolean().default(true),
|
58
|
+
* }, ({ set, get }) => ({
|
59
|
+
* incrementAge: () => set('age', get('age') + 1),
|
60
|
+
* }));
|
61
|
+
*
|
62
|
+
* const user = userFactory.create({ name: 'John' });
|
63
|
+
* console.log(user.props); // { name: 'John', age: 18, isActive: true }
|
64
|
+
* user.incrementAge();
|
65
|
+
* console.log(user.props.age); // 19
|
66
|
+
* ```
|
20
67
|
*/
|
21
|
-
export declare
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Get the value of the field by key
|
27
|
-
* @param key
|
28
|
-
*/
|
29
|
-
get<K extends keyof Config>(key: K): EntityConfigTypeResolver<Config>[K];
|
30
|
-
/**
|
31
|
-
* Set the value of the field by key
|
32
|
-
*
|
33
|
-
* WARNING: This method should be called only from the methods of the entity.
|
34
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
35
|
-
* @param key
|
36
|
-
* @param value
|
37
|
-
*/
|
38
|
-
set<K extends keyof Config>(key: K, value: EntityConfigTypeResolver<Config>[K]): void;
|
39
|
-
toJSON(): EntityConfigTypeResolver<Config>;
|
40
|
-
};
|
41
|
-
};
|
68
|
+
export declare function createEntity<C extends EntityConfig, D extends MethodDefinition>(fields: C, methodDefinitionFunction?: (params: {
|
69
|
+
set: <K extends keyof C>(key: K, value: EntityConfigTypeResolver<C>[K]) => void;
|
70
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
71
|
+
}) => D): EntityFactory<C, D>;
|
42
72
|
export {};
|
package/dist/cjs/field.d.ts
CHANGED
@@ -24,7 +24,7 @@ type HasDefault<T extends ConfigurableFieldBase<unknown>> = T & {
|
|
24
24
|
};
|
25
25
|
export declare abstract class Field<T> implements ConfigurableFieldBase<T> {
|
26
26
|
_: FieldConfig<T>;
|
27
|
-
|
27
|
+
config: FieldRuntimeConfig<T>;
|
28
28
|
constructor();
|
29
29
|
notRequired(): NotRequired<this>;
|
30
30
|
default(value: T): HasDefault<this>;
|
@@ -0,0 +1,68 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __defProp = Object.defineProperty;
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
6
|
+
var __export = (target, all) => {
|
7
|
+
for (var name in all)
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
9
|
+
};
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
12
|
+
for (let key of __getOwnPropNames(from))
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
15
|
+
}
|
16
|
+
return to;
|
17
|
+
};
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
19
|
+
|
20
|
+
// src/fields/entity.ts
|
21
|
+
var entity_exports = {};
|
22
|
+
__export(entity_exports, {
|
23
|
+
entity: () => entity
|
24
|
+
});
|
25
|
+
module.exports = __toCommonJS(entity_exports);
|
26
|
+
|
27
|
+
// src/field.ts
|
28
|
+
var Field = class {
|
29
|
+
config;
|
30
|
+
constructor() {
|
31
|
+
this.config = {
|
32
|
+
notRequired: false,
|
33
|
+
hasDefault: false,
|
34
|
+
default: void 0
|
35
|
+
};
|
36
|
+
}
|
37
|
+
notRequired() {
|
38
|
+
this.config.notRequired = true;
|
39
|
+
return this;
|
40
|
+
}
|
41
|
+
default(value) {
|
42
|
+
this.config.default = value;
|
43
|
+
this.config.hasDefault = true;
|
44
|
+
return this;
|
45
|
+
}
|
46
|
+
defaultFn(fn) {
|
47
|
+
this.config.defaultFn = fn;
|
48
|
+
this.config.hasDefault = true;
|
49
|
+
return this;
|
50
|
+
}
|
51
|
+
getConfig() {
|
52
|
+
return this.config;
|
53
|
+
}
|
54
|
+
getDefaultValue() {
|
55
|
+
return this.config.default ?? this.config.defaultFn?.();
|
56
|
+
}
|
57
|
+
};
|
58
|
+
|
59
|
+
// src/fields/entity.ts
|
60
|
+
var EntityField = class extends Field {
|
61
|
+
};
|
62
|
+
var entity = () => {
|
63
|
+
return new EntityField();
|
64
|
+
};
|
65
|
+
// Annotate the CommonJS export names for ESM import in node:
|
66
|
+
0 && (module.exports = {
|
67
|
+
entity
|
68
|
+
});
|
@@ -22,6 +22,7 @@ var fields_exports = {};
|
|
22
22
|
__export(fields_exports, {
|
23
23
|
boolean: () => boolean,
|
24
24
|
date: () => date,
|
25
|
+
entity: () => entity,
|
25
26
|
number: () => number,
|
26
27
|
string: () => string
|
27
28
|
});
|
@@ -86,10 +87,18 @@ var StringField = class extends Field {
|
|
86
87
|
var string = () => {
|
87
88
|
return new StringField();
|
88
89
|
};
|
90
|
+
|
91
|
+
// src/fields/entity.ts
|
92
|
+
var EntityField = class extends Field {
|
93
|
+
};
|
94
|
+
var entity = () => {
|
95
|
+
return new EntityField();
|
96
|
+
};
|
89
97
|
// Annotate the CommonJS export names for ESM import in node:
|
90
98
|
0 && (module.exports = {
|
91
99
|
boolean,
|
92
100
|
date,
|
101
|
+
entity,
|
93
102
|
number,
|
94
103
|
string
|
95
104
|
});
|
package/dist/cjs/index.cjs
CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
21
21
|
var index_exports = {};
|
22
22
|
__export(index_exports, {
|
23
23
|
boolean: () => boolean,
|
24
|
+
createEntity: () => createEntity,
|
24
25
|
date: () => date,
|
25
26
|
entity: () => entity,
|
26
27
|
number: () => number,
|
@@ -29,54 +30,46 @@ __export(index_exports, {
|
|
29
30
|
module.exports = __toCommonJS(index_exports);
|
30
31
|
|
31
32
|
// src/entity.ts
|
32
|
-
var
|
33
|
-
|
34
|
-
|
35
|
-
constructor(
|
36
|
-
this
|
37
|
-
|
38
|
-
|
33
|
+
var EntityFactory = class {
|
34
|
+
fields;
|
35
|
+
methodDefinitionFunction;
|
36
|
+
constructor(fields, methodDefinitionFunction) {
|
37
|
+
this.fields = fields;
|
38
|
+
this.methodDefinitionFunction = methodDefinitionFunction;
|
39
|
+
}
|
40
|
+
create(props) {
|
41
|
+
const assignedProps = Object.entries(this.fields).reduce(
|
39
42
|
(acc, [key, field]) => {
|
40
43
|
const value = props[key] ?? field.getDefaultValue();
|
41
44
|
if (field.getConfig().hasDefault && value === void 0) {
|
42
|
-
|
45
|
+
acc[key] = field.getDefaultValue();
|
46
|
+
} else {
|
47
|
+
acc[key] = value;
|
43
48
|
}
|
44
|
-
acc[key] = value;
|
45
49
|
return acc;
|
46
50
|
},
|
47
51
|
{}
|
48
52
|
);
|
53
|
+
const set = (key, value) => {
|
54
|
+
assignedProps[key] = value;
|
55
|
+
};
|
56
|
+
const get = (key) => {
|
57
|
+
return assignedProps[key];
|
58
|
+
};
|
59
|
+
const toJSON = () => {
|
60
|
+
return assignedProps;
|
61
|
+
};
|
62
|
+
const methods = this.methodDefinitionFunction?.({ set, get }) ?? {};
|
63
|
+
return {
|
64
|
+
get,
|
65
|
+
toJSON,
|
66
|
+
...methods
|
67
|
+
};
|
49
68
|
}
|
50
|
-
/**
|
51
|
-
* Get the value of the field by key
|
52
|
-
* @param key
|
53
|
-
*/
|
54
|
-
get(key) {
|
55
|
-
return this.#props[key];
|
56
|
-
}
|
57
|
-
/**
|
58
|
-
* Set the value of the field by key
|
59
|
-
*
|
60
|
-
* WARNING: This method should be called only from the methods of the entity.
|
61
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
62
|
-
* @param key
|
63
|
-
* @param value
|
64
|
-
*/
|
65
|
-
set(key, value) {
|
66
|
-
this.#props[key] = value;
|
67
|
-
}
|
68
|
-
// biome-ignore lint/style/useNamingConvention: toJSON is a name to be used in JSON.stringify
|
69
|
-
toJSON() {
|
70
|
-
return this.#props;
|
71
|
-
}
|
72
|
-
};
|
73
|
-
var entity = (fields) => {
|
74
|
-
return class extends Entity {
|
75
|
-
constructor(props) {
|
76
|
-
super(props, fields);
|
77
|
-
}
|
78
|
-
};
|
79
69
|
};
|
70
|
+
function createEntity(fields, methodDefinitionFunction) {
|
71
|
+
return new EntityFactory(fields, methodDefinitionFunction);
|
72
|
+
}
|
80
73
|
|
81
74
|
// src/field.ts
|
82
75
|
var Field = class {
|
@@ -137,9 +130,17 @@ var StringField = class extends Field {
|
|
137
130
|
var string = () => {
|
138
131
|
return new StringField();
|
139
132
|
};
|
133
|
+
|
134
|
+
// src/fields/entity.ts
|
135
|
+
var EntityField = class extends Field {
|
136
|
+
};
|
137
|
+
var entity = () => {
|
138
|
+
return new EntityField();
|
139
|
+
};
|
140
140
|
// Annotate the CommonJS export names for ESM import in node:
|
141
141
|
0 && (module.exports = {
|
142
142
|
boolean,
|
143
|
+
createEntity,
|
143
144
|
date,
|
144
145
|
entity,
|
145
146
|
number,
|
package/dist/cjs/index.d.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
import {
|
2
|
-
import { boolean, date, number, string } from "./fields/index.ts";
|
3
|
-
export {
|
1
|
+
import { createEntity } from "./entity.ts";
|
2
|
+
import { boolean, date, number, string, entity } from "./fields/index.ts";
|
3
|
+
export { createEntity, string, number, boolean, date, entity };
|
package/dist/entity.d.ts
CHANGED
@@ -14,29 +14,59 @@ type EntityPropInputResolver<T extends EntityConfig> = {
|
|
14
14
|
} & {
|
15
15
|
[K in keyof Omit<T, RequiredFieldKeys<T>>]?: FieldTypeResolver<T[K]>;
|
16
16
|
};
|
17
|
+
type MethodDefinition = {
|
18
|
+
[key: string]: (...args: any[]) => any;
|
19
|
+
};
|
20
|
+
interface EntityInterface<C extends EntityConfig> {
|
21
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
22
|
+
toJSON: () => EntityConfigTypeResolver<C>;
|
23
|
+
}
|
24
|
+
declare class EntityFactory<C extends EntityConfig, D extends MethodDefinition> {
|
25
|
+
private readonly fields;
|
26
|
+
private readonly methodDefinitionFunction?;
|
27
|
+
readonly $infer: EntityInterface<C> & D;
|
28
|
+
constructor(fields: C, methodDefinitionFunction?: (params: {
|
29
|
+
set: <K extends keyof C>(key: K, value: EntityConfigTypeResolver<C>[K]) => void;
|
30
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
31
|
+
}) => D);
|
32
|
+
create(props: EntityPropInputResolver<C>): EntityInterface<C> & D;
|
33
|
+
}
|
17
34
|
/**
|
18
|
-
*
|
19
|
-
*
|
35
|
+
* Creates an entity factory function that allows defining fields and optional methods for an entity.
|
36
|
+
* The returned factory provides a `create` method to instantiate entities with the specified fields
|
37
|
+
* and methods, while also supporting default values and runtime property manipulation.
|
38
|
+
*
|
39
|
+
* @template C - The configuration type for the entity fields.
|
40
|
+
* @template D - The type of the methods defined for the entity.
|
41
|
+
*
|
42
|
+
* @param fields - An object defining the fields of the entity. Each field should include its configuration
|
43
|
+
* and a method to retrieve its default value.
|
44
|
+
* @param methodDefinitionFunction - An optional function that defines additional methods for the entity.
|
45
|
+
* It receives an object with `set` and `get` functions to manipulate
|
46
|
+
* the entity's properties.
|
47
|
+
*
|
48
|
+
* @returns An object with a `create` method. The `create` method accepts an input object to initialize
|
49
|
+
* the entity's properties and returns an entity instance with the defined fields, methods,
|
50
|
+
* and utility functions (`get`, `set`, `toJSON`).
|
51
|
+
*
|
52
|
+
* @example
|
53
|
+
* ```typescript
|
54
|
+
* const userFactory = createEntity({
|
55
|
+
* name: string(),
|
56
|
+
* age: number().default(18),
|
57
|
+
* isActive: boolean().default(true),
|
58
|
+
* }, ({ set, get }) => ({
|
59
|
+
* incrementAge: () => set('age', get('age') + 1),
|
60
|
+
* }));
|
61
|
+
*
|
62
|
+
* const user = userFactory.create({ name: 'John' });
|
63
|
+
* console.log(user.props); // { name: 'John', age: 18, isActive: true }
|
64
|
+
* user.incrementAge();
|
65
|
+
* console.log(user.props.age); // 19
|
66
|
+
* ```
|
20
67
|
*/
|
21
|
-
export declare
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Get the value of the field by key
|
27
|
-
* @param key
|
28
|
-
*/
|
29
|
-
get<K extends keyof Config>(key: K): EntityConfigTypeResolver<Config>[K];
|
30
|
-
/**
|
31
|
-
* Set the value of the field by key
|
32
|
-
*
|
33
|
-
* WARNING: This method should be called only from the methods of the entity.
|
34
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
35
|
-
* @param key
|
36
|
-
* @param value
|
37
|
-
*/
|
38
|
-
set<K extends keyof Config>(key: K, value: EntityConfigTypeResolver<Config>[K]): void;
|
39
|
-
toJSON(): EntityConfigTypeResolver<Config>;
|
40
|
-
};
|
41
|
-
};
|
68
|
+
export declare function createEntity<C extends EntityConfig, D extends MethodDefinition>(fields: C, methodDefinitionFunction?: (params: {
|
69
|
+
set: <K extends keyof C>(key: K, value: EntityConfigTypeResolver<C>[K]) => void;
|
70
|
+
get: <K extends keyof C>(key: K) => EntityConfigTypeResolver<C>[K];
|
71
|
+
}) => D): EntityFactory<C, D>;
|
42
72
|
export {};
|
package/dist/entity.js
CHANGED
@@ -1,52 +1,44 @@
|
|
1
1
|
// src/entity.ts
|
2
|
-
var
|
3
|
-
|
4
|
-
|
5
|
-
constructor(
|
6
|
-
this
|
7
|
-
|
8
|
-
|
2
|
+
var EntityFactory = class {
|
3
|
+
fields;
|
4
|
+
methodDefinitionFunction;
|
5
|
+
constructor(fields, methodDefinitionFunction) {
|
6
|
+
this.fields = fields;
|
7
|
+
this.methodDefinitionFunction = methodDefinitionFunction;
|
8
|
+
}
|
9
|
+
create(props) {
|
10
|
+
const assignedProps = Object.entries(this.fields).reduce(
|
9
11
|
(acc, [key, field]) => {
|
10
12
|
const value = props[key] ?? field.getDefaultValue();
|
11
13
|
if (field.getConfig().hasDefault && value === void 0) {
|
12
|
-
|
14
|
+
acc[key] = field.getDefaultValue();
|
15
|
+
} else {
|
16
|
+
acc[key] = value;
|
13
17
|
}
|
14
|
-
acc[key] = value;
|
15
18
|
return acc;
|
16
19
|
},
|
17
20
|
{}
|
18
21
|
);
|
22
|
+
const set = (key, value) => {
|
23
|
+
assignedProps[key] = value;
|
24
|
+
};
|
25
|
+
const get = (key) => {
|
26
|
+
return assignedProps[key];
|
27
|
+
};
|
28
|
+
const toJSON = () => {
|
29
|
+
return assignedProps;
|
30
|
+
};
|
31
|
+
const methods = this.methodDefinitionFunction?.({ set, get }) ?? {};
|
32
|
+
return {
|
33
|
+
get,
|
34
|
+
toJSON,
|
35
|
+
...methods
|
36
|
+
};
|
19
37
|
}
|
20
|
-
/**
|
21
|
-
* Get the value of the field by key
|
22
|
-
* @param key
|
23
|
-
*/
|
24
|
-
get(key) {
|
25
|
-
return this.#props[key];
|
26
|
-
}
|
27
|
-
/**
|
28
|
-
* Set the value of the field by key
|
29
|
-
*
|
30
|
-
* WARNING: This method should be called only from the methods of the entity.
|
31
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
32
|
-
* @param key
|
33
|
-
* @param value
|
34
|
-
*/
|
35
|
-
set(key, value) {
|
36
|
-
this.#props[key] = value;
|
37
|
-
}
|
38
|
-
// biome-ignore lint/style/useNamingConvention: toJSON is a name to be used in JSON.stringify
|
39
|
-
toJSON() {
|
40
|
-
return this.#props;
|
41
|
-
}
|
42
|
-
};
|
43
|
-
var entity = (fields) => {
|
44
|
-
return class extends Entity {
|
45
|
-
constructor(props) {
|
46
|
-
super(props, fields);
|
47
|
-
}
|
48
|
-
};
|
49
38
|
};
|
39
|
+
function createEntity(fields, methodDefinitionFunction) {
|
40
|
+
return new EntityFactory(fields, methodDefinitionFunction);
|
41
|
+
}
|
50
42
|
export {
|
51
|
-
|
43
|
+
createEntity
|
52
44
|
};
|
package/dist/field.d.ts
CHANGED
@@ -24,7 +24,7 @@ type HasDefault<T extends ConfigurableFieldBase<unknown>> = T & {
|
|
24
24
|
};
|
25
25
|
export declare abstract class Field<T> implements ConfigurableFieldBase<T> {
|
26
26
|
_: FieldConfig<T>;
|
27
|
-
|
27
|
+
config: FieldRuntimeConfig<T>;
|
28
28
|
constructor();
|
29
29
|
notRequired(): NotRequired<this>;
|
30
30
|
default(value: T): HasDefault<this>;
|
@@ -0,0 +1,41 @@
|
|
1
|
+
// src/field.ts
|
2
|
+
var Field = class {
|
3
|
+
config;
|
4
|
+
constructor() {
|
5
|
+
this.config = {
|
6
|
+
notRequired: false,
|
7
|
+
hasDefault: false,
|
8
|
+
default: void 0
|
9
|
+
};
|
10
|
+
}
|
11
|
+
notRequired() {
|
12
|
+
this.config.notRequired = true;
|
13
|
+
return this;
|
14
|
+
}
|
15
|
+
default(value) {
|
16
|
+
this.config.default = value;
|
17
|
+
this.config.hasDefault = true;
|
18
|
+
return this;
|
19
|
+
}
|
20
|
+
defaultFn(fn) {
|
21
|
+
this.config.defaultFn = fn;
|
22
|
+
this.config.hasDefault = true;
|
23
|
+
return this;
|
24
|
+
}
|
25
|
+
getConfig() {
|
26
|
+
return this.config;
|
27
|
+
}
|
28
|
+
getDefaultValue() {
|
29
|
+
return this.config.default ?? this.config.defaultFn?.();
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
// src/fields/entity.ts
|
34
|
+
var EntityField = class extends Field {
|
35
|
+
};
|
36
|
+
var entity = () => {
|
37
|
+
return new EntityField();
|
38
|
+
};
|
39
|
+
export {
|
40
|
+
entity
|
41
|
+
};
|
package/dist/fields/index.d.ts
CHANGED
@@ -2,4 +2,5 @@ import { boolean } from "./boolean.ts";
|
|
2
2
|
import { date } from "./date.ts";
|
3
3
|
import { number } from "./number.ts";
|
4
4
|
import { string } from "./string.ts";
|
5
|
-
|
5
|
+
import { entity } from "./entity.ts";
|
6
|
+
export { string, number, boolean, date, entity };
|
package/dist/fields/index.js
CHANGED
@@ -57,9 +57,17 @@ var StringField = class extends Field {
|
|
57
57
|
var string = () => {
|
58
58
|
return new StringField();
|
59
59
|
};
|
60
|
+
|
61
|
+
// src/fields/entity.ts
|
62
|
+
var EntityField = class extends Field {
|
63
|
+
};
|
64
|
+
var entity = () => {
|
65
|
+
return new EntityField();
|
66
|
+
};
|
60
67
|
export {
|
61
68
|
boolean,
|
62
69
|
date,
|
70
|
+
entity,
|
63
71
|
number,
|
64
72
|
string
|
65
73
|
};
|
package/dist/index.d.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
import {
|
2
|
-
import { boolean, date, number, string } from "./fields/index.ts";
|
3
|
-
export {
|
1
|
+
import { createEntity } from "./entity.ts";
|
2
|
+
import { boolean, date, number, string, entity } from "./fields/index.ts";
|
3
|
+
export { createEntity, string, number, boolean, date, entity };
|
package/dist/index.js
CHANGED
@@ -1,52 +1,44 @@
|
|
1
1
|
// src/entity.ts
|
2
|
-
var
|
3
|
-
|
4
|
-
|
5
|
-
constructor(
|
6
|
-
this
|
7
|
-
|
8
|
-
|
2
|
+
var EntityFactory = class {
|
3
|
+
fields;
|
4
|
+
methodDefinitionFunction;
|
5
|
+
constructor(fields, methodDefinitionFunction) {
|
6
|
+
this.fields = fields;
|
7
|
+
this.methodDefinitionFunction = methodDefinitionFunction;
|
8
|
+
}
|
9
|
+
create(props) {
|
10
|
+
const assignedProps = Object.entries(this.fields).reduce(
|
9
11
|
(acc, [key, field]) => {
|
10
12
|
const value = props[key] ?? field.getDefaultValue();
|
11
13
|
if (field.getConfig().hasDefault && value === void 0) {
|
12
|
-
|
14
|
+
acc[key] = field.getDefaultValue();
|
15
|
+
} else {
|
16
|
+
acc[key] = value;
|
13
17
|
}
|
14
|
-
acc[key] = value;
|
15
18
|
return acc;
|
16
19
|
},
|
17
20
|
{}
|
18
21
|
);
|
22
|
+
const set = (key, value) => {
|
23
|
+
assignedProps[key] = value;
|
24
|
+
};
|
25
|
+
const get = (key) => {
|
26
|
+
return assignedProps[key];
|
27
|
+
};
|
28
|
+
const toJSON = () => {
|
29
|
+
return assignedProps;
|
30
|
+
};
|
31
|
+
const methods = this.methodDefinitionFunction?.({ set, get }) ?? {};
|
32
|
+
return {
|
33
|
+
get,
|
34
|
+
toJSON,
|
35
|
+
...methods
|
36
|
+
};
|
19
37
|
}
|
20
|
-
/**
|
21
|
-
* Get the value of the field by key
|
22
|
-
* @param key
|
23
|
-
*/
|
24
|
-
get(key) {
|
25
|
-
return this.#props[key];
|
26
|
-
}
|
27
|
-
/**
|
28
|
-
* Set the value of the field by key
|
29
|
-
*
|
30
|
-
* WARNING: This method should be called only from the methods of the entity.
|
31
|
-
* Its accessor should be protected but TypeScript declaration does not allow protected methods in exported classes.
|
32
|
-
* @param key
|
33
|
-
* @param value
|
34
|
-
*/
|
35
|
-
set(key, value) {
|
36
|
-
this.#props[key] = value;
|
37
|
-
}
|
38
|
-
// biome-ignore lint/style/useNamingConvention: toJSON is a name to be used in JSON.stringify
|
39
|
-
toJSON() {
|
40
|
-
return this.#props;
|
41
|
-
}
|
42
|
-
};
|
43
|
-
var entity = (fields) => {
|
44
|
-
return class extends Entity {
|
45
|
-
constructor(props) {
|
46
|
-
super(props, fields);
|
47
|
-
}
|
48
|
-
};
|
49
38
|
};
|
39
|
+
function createEntity(fields, methodDefinitionFunction) {
|
40
|
+
return new EntityFactory(fields, methodDefinitionFunction);
|
41
|
+
}
|
50
42
|
|
51
43
|
// src/field.ts
|
52
44
|
var Field = class {
|
@@ -107,8 +99,16 @@ var StringField = class extends Field {
|
|
107
99
|
var string = () => {
|
108
100
|
return new StringField();
|
109
101
|
};
|
102
|
+
|
103
|
+
// src/fields/entity.ts
|
104
|
+
var EntityField = class extends Field {
|
105
|
+
};
|
106
|
+
var entity = () => {
|
107
|
+
return new EntityField();
|
108
|
+
};
|
110
109
|
export {
|
111
110
|
boolean,
|
111
|
+
createEntity,
|
112
112
|
date,
|
113
113
|
entity,
|
114
114
|
number,
|