@ibgib/core-gib 0.0.29 → 0.0.30
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/witness/factory/dynamic-form-factory-base.d.mts +80 -0
- package/dist/witness/factory/dynamic-form-factory-base.d.mts.map +1 -0
- package/dist/witness/factory/dynamic-form-factory-base.mjs +86 -0
- package/dist/witness/factory/dynamic-form-factory-base.mjs.map +1 -0
- package/dist/witness/factory/witness-factory-base.d.mts +57 -0
- package/dist/witness/factory/witness-factory-base.d.mts.map +1 -0
- package/dist/witness/factory/witness-factory-base.mjs +34 -0
- package/dist/witness/factory/witness-factory-base.mjs.map +1 -0
- package/package.json +1 -1
- package/src/witness/factory/dynamic-form-factory-base.mts +132 -0
- package/src/witness/factory/witness-factory-base.mts +69 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module dynamic-form-factory-base
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* @see {@link WitnessFactoryBase}
|
|
6
|
+
*/
|
|
7
|
+
import { TransformResult } from "@ibgib/ts-gib/dist/types.mjs";
|
|
8
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
9
|
+
import { DynamicForm, FormItemInfo } from "../../common/form/form-items.mjs";
|
|
10
|
+
import { WitnessFactoryBase } from "./witness-factory-base.mjs";
|
|
11
|
+
import { Witness, WitnessData_V1, WitnessRel8ns_V1 } from "../witness-types.mjs";
|
|
12
|
+
/**
|
|
13
|
+
* The idea is that any model can be injected via this factory provider.
|
|
14
|
+
*
|
|
15
|
+
* So when you create a witness that you want to be able to instantiate via
|
|
16
|
+
* just metadata, you also provide an accompanying factory that knows
|
|
17
|
+
* how to map from a
|
|
18
|
+
* * witness(model) -> form data (to generate dynamic forms)
|
|
19
|
+
* * form data -> witness (to instantiate witness from data)
|
|
20
|
+
*/
|
|
21
|
+
export declare abstract class DynamicFormFactoryBase<TWitnessData extends WitnessData_V1, TWitnessRel8ns extends WitnessRel8ns_V1, TWitness extends Witness<IbGib_V1, IbGib_V1, TWitnessData, TWitnessRel8ns>> extends WitnessFactoryBase<TWitnessData, TWitnessRel8ns, TWitness> {
|
|
22
|
+
protected lc: string;
|
|
23
|
+
/**
|
|
24
|
+
* override this with something that maps from the ibgib/model to the form infos.
|
|
25
|
+
*/
|
|
26
|
+
abstract witnessToForm({ witness }: {
|
|
27
|
+
witness: TWitness;
|
|
28
|
+
}): Promise<DynamicForm>;
|
|
29
|
+
/**
|
|
30
|
+
* override this with specific behavior that will reify an instance based on
|
|
31
|
+
* the given {@link form}.
|
|
32
|
+
*/
|
|
33
|
+
abstract formToWitness({ form }: {
|
|
34
|
+
form: DynamicForm;
|
|
35
|
+
}): Promise<TransformResult<TWitness>>;
|
|
36
|
+
/**
|
|
37
|
+
* iterates through the given {@link items}.
|
|
38
|
+
*
|
|
39
|
+
* If the item has child items, it is considered a grouping (i.e. FormGroup
|
|
40
|
+
* or FormArray) and this function is called recursively with the
|
|
41
|
+
* {@link contextPath} adjusted per the {@link pathDelimiter} and
|
|
42
|
+
* `item.name`.
|
|
43
|
+
*
|
|
44
|
+
* If the item does not have child items, it's considered to be a setting at
|
|
45
|
+
* the current path level and it's value is assigned per its `item.name` as
|
|
46
|
+
* the key.
|
|
47
|
+
*/
|
|
48
|
+
protected patchDataFromItems({ data, contextPath, items, pathDelimiter, }: {
|
|
49
|
+
/**
|
|
50
|
+
* ibgib.data object that we are patching/setting from the form items.
|
|
51
|
+
*/
|
|
52
|
+
data: any;
|
|
53
|
+
/**
|
|
54
|
+
* source items whose values we are patching the {@link data} with.
|
|
55
|
+
*/
|
|
56
|
+
items: FormItemInfo[];
|
|
57
|
+
/**
|
|
58
|
+
* Separates sections of pathing into the data object.
|
|
59
|
+
*
|
|
60
|
+
* @default @see {@link DEFAULT_DATA_PATH_DELIMITER}
|
|
61
|
+
*/
|
|
62
|
+
pathDelimiter: string;
|
|
63
|
+
/**
|
|
64
|
+
* we're patching the data object as follows:
|
|
65
|
+
*
|
|
66
|
+
* data[contextPath/item.name] = value
|
|
67
|
+
*
|
|
68
|
+
* where the '/' is the data path delimiter.
|
|
69
|
+
*
|
|
70
|
+
* So if the incoming items are nested deeper, this will look like
|
|
71
|
+
*
|
|
72
|
+
* data['mysetting/subsetting/color'] = "red"
|
|
73
|
+
*
|
|
74
|
+
* @see {@link pathDelimiter}
|
|
75
|
+
* @see {@link DEFAULT_DATA_PATH_DELIMITER}
|
|
76
|
+
*/
|
|
77
|
+
contextPath?: string;
|
|
78
|
+
}): void;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=dynamic-form-factory-base.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-form-factory-base.d.mts","sourceRoot":"","sources":["../../../src/witness/factory/dynamic-form-factory-base.mts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAkB,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKjF;;;;;;;;GAQG;AACH,8BAAsB,sBAAsB,CACxC,YAAY,SAAS,cAAc,EACnC,cAAc,SAAS,gBAAgB,EACvC,QAAQ,SAAS,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,CAAC,CAE1E,SAAQ,kBAAkB,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,CAAC;IAClE,SAAS,CAAC,EAAE,EAAE,MAAM,CAAsC;IAC1D;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAChF;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE3F;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,kBAAkB,CAAC,EACzB,IAAI,EACJ,WAAW,EACX,KAAK,EACL,aAAa,GAChB,EAAE;QACC;;WAEG;QACH,IAAI,EAAE,GAAG,CAAC;QACV;;WAEG;QACH,KAAK,EAAE,YAAY,EAAE,CAAC;QACtB;;;;WAIG;QACH,aAAa,EAAE,MAAM,CAAC;QACtB;;;;;;;;;;;;;WAaG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI;CAwCX"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module dynamic-form-factory-base
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* @see {@link WitnessFactoryBase}
|
|
6
|
+
*/
|
|
7
|
+
import { patchObject } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
8
|
+
import { WitnessFactoryBase } from "./witness-factory-base.mjs";
|
|
9
|
+
import { GLOBAL_LOG_A_LOT } from "../../core-constants.mjs";
|
|
10
|
+
const logalot = GLOBAL_LOG_A_LOT || false;
|
|
11
|
+
/**
|
|
12
|
+
* The idea is that any model can be injected via this factory provider.
|
|
13
|
+
*
|
|
14
|
+
* So when you create a witness that you want to be able to instantiate via
|
|
15
|
+
* just metadata, you also provide an accompanying factory that knows
|
|
16
|
+
* how to map from a
|
|
17
|
+
* * witness(model) -> form data (to generate dynamic forms)
|
|
18
|
+
* * form data -> witness (to instantiate witness from data)
|
|
19
|
+
*/
|
|
20
|
+
export class DynamicFormFactoryBase extends WitnessFactoryBase {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.lc = `[${DynamicFormFactoryBase.name}]`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* iterates through the given {@link items}.
|
|
27
|
+
*
|
|
28
|
+
* If the item has child items, it is considered a grouping (i.e. FormGroup
|
|
29
|
+
* or FormArray) and this function is called recursively with the
|
|
30
|
+
* {@link contextPath} adjusted per the {@link pathDelimiter} and
|
|
31
|
+
* `item.name`.
|
|
32
|
+
*
|
|
33
|
+
* If the item does not have child items, it's considered to be a setting at
|
|
34
|
+
* the current path level and it's value is assigned per its `item.name` as
|
|
35
|
+
* the key.
|
|
36
|
+
*/
|
|
37
|
+
patchDataFromItems({ data, contextPath, items, pathDelimiter, }) {
|
|
38
|
+
const lc = `${this.lc}[${this.patchDataFromItems.name}]`;
|
|
39
|
+
try {
|
|
40
|
+
if (logalot) {
|
|
41
|
+
console.log(`${lc} starting...`);
|
|
42
|
+
}
|
|
43
|
+
if (!pathDelimiter) {
|
|
44
|
+
throw new Error(`pathDelimiter required (E: 958d472a15fb71e45cd2925883f2ec22)`);
|
|
45
|
+
}
|
|
46
|
+
for (let i = 0; i < items.length; i++) {
|
|
47
|
+
const item = items[i];
|
|
48
|
+
const path = contextPath ?
|
|
49
|
+
contextPath + pathDelimiter + item.name :
|
|
50
|
+
item.name;
|
|
51
|
+
if (!item.items) {
|
|
52
|
+
// it's a property (FormControl, not FormGroup/Array)
|
|
53
|
+
patchObject({
|
|
54
|
+
obj: data,
|
|
55
|
+
value: item.value,
|
|
56
|
+
path,
|
|
57
|
+
logalot,
|
|
58
|
+
pathDelimiter,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else if (item.items.length > 0) {
|
|
62
|
+
// it's a group, so call this function recursively
|
|
63
|
+
this.patchDataFromItems({
|
|
64
|
+
data,
|
|
65
|
+
contextPath: path,
|
|
66
|
+
items: item.items,
|
|
67
|
+
pathDelimiter,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
throw new Error(`invalid item. items is truthy but with a length of 0. items should either be falsy or have at least one child. (E: ee2765e0b920477f919fcb09e9d951b4)`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error(`${lc} ${error.message}`);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
if (logalot) {
|
|
81
|
+
console.log(`${lc} complete.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=dynamic-form-factory-base.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-form-factory-base.mjs","sourceRoot":"","sources":["../../../src/witness/factory/dynamic-form-factory-base.mts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAK9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,MAAM,OAAO,GAAG,gBAAgB,IAAI,KAAK,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,OAAgB,sBAKlB,SAAQ,kBAA0D;IALtE;;QAMc,OAAE,GAAW,IAAI,sBAAsB,CAAC,IAAI,GAAG,CAAC;IAkG9D,CAAC;IAvFG;;;;;;;;;;;OAWG;IACO,kBAAkB,CAAC,EACzB,IAAI,EACJ,WAAW,EACX,KAAK,EACL,aAAa,GA+BhB;QACG,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,GAAG,CAAC;QACzD,IAAI;YACA,IAAI,OAAO,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;aAAE;YAClD,IAAI,CAAC,aAAa,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;aAAE;YAExG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC;oBACtB,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;oBACzC,IAAI,CAAC,IAAI,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;oBACb,qDAAqD;oBACrD,WAAW,CAAC;wBACR,GAAG,EAAE,IAAI;wBACT,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,IAAI;wBACJ,OAAO;wBACP,aAAa;qBAChB,CAAC,CAAC;iBACN;qBAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC9B,kDAAkD;oBAClD,IAAI,CAAC,kBAAkB,CAAC;wBACpB,IAAI;wBACJ,WAAW,EAAE,IAAI;wBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,aAAa;qBAChB,CAAC,CAAC;iBACN;qBAAM;oBACH,MAAM,IAAI,KAAK,CAAC,sJAAsJ,CAAC,CAAC;iBAC3K;aACJ;SACJ;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACxC,MAAM,KAAK,CAAC;SACf;gBAAS;YACN,IAAI,OAAO,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;aAAE;SACnD;IACL,CAAC;CAEJ"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module witness-factory-base
|
|
3
|
+
*
|
|
4
|
+
* this was a probably-klugy plumbing attempt for ionic-gib to instantiate ibgib
|
|
5
|
+
* witness objects.
|
|
6
|
+
*
|
|
7
|
+
* Specifically this was to go from angular forms to witness ibgibs. The trick
|
|
8
|
+
* was that ibgib's are data objects and you had to load the witness ibgibs
|
|
9
|
+
* which actually had functions/methods on them.
|
|
10
|
+
*
|
|
11
|
+
* So the workflow was you get a form component with some fields, and you
|
|
12
|
+
* generate the witness via this factory.
|
|
13
|
+
*
|
|
14
|
+
* it worked, but it's not strong I don't think.
|
|
15
|
+
*
|
|
16
|
+
* the main weak point is that i didn't fill out the form-items enough and i
|
|
17
|
+
* never got it so that you could create nested forms.
|
|
18
|
+
*
|
|
19
|
+
* in its favor, i do use this (although klugily) in the ibgib rcli app, where
|
|
20
|
+
* instead of a visual form it prompts the user. terrible ux but it did "work"
|
|
21
|
+
* as a quick and dirty implementation. it could be polished going forward (i
|
|
22
|
+
* dont think the design is inherently flawed).
|
|
23
|
+
*/
|
|
24
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
25
|
+
import { TransformResult } from "@ibgib/ts-gib/dist/types.mjs";
|
|
26
|
+
import { Witness, WitnessData_V1, WitnessRel8ns_V1 } from "../witness-types.mjs";
|
|
27
|
+
/**
|
|
28
|
+
* The idea is that any model can be injected via this factory provider.
|
|
29
|
+
*/
|
|
30
|
+
export declare abstract class WitnessFactoryBase<TWitnessData extends WitnessData_V1, TWitnessRel8ns extends WitnessRel8ns_V1, TWitness extends Witness<IbGib_V1, IbGib_V1, TWitnessData, TWitnessRel8ns>> {
|
|
31
|
+
protected lc: string;
|
|
32
|
+
/**
|
|
33
|
+
* override this to provide the name of the class for the factory.
|
|
34
|
+
*
|
|
35
|
+
* ## usage
|
|
36
|
+
*
|
|
37
|
+
* atm I'm using this to return the classname for the witness.
|
|
38
|
+
*
|
|
39
|
+
* @example MyWitnessClass.classname
|
|
40
|
+
*/
|
|
41
|
+
abstract getName(): string;
|
|
42
|
+
/**
|
|
43
|
+
* creates a new witness. This should return the transform result with the
|
|
44
|
+
* new ibgib being the witness class itself, not just the ibgib dto.
|
|
45
|
+
*
|
|
46
|
+
* So said in another way, the `result.newIbGib` should include the class
|
|
47
|
+
* instantiation which has the `witness` function on it.
|
|
48
|
+
*
|
|
49
|
+
* @see {@link WitnessB}
|
|
50
|
+
*/
|
|
51
|
+
abstract newUp({ data, rel8ns }: {
|
|
52
|
+
data?: TWitnessData;
|
|
53
|
+
rel8ns?: TWitnessRel8ns;
|
|
54
|
+
}): Promise<TransformResult<TWitness>>;
|
|
55
|
+
}
|
|
56
|
+
export type WitnessFactoryAny = WitnessFactoryBase<any, any, any>;
|
|
57
|
+
//# sourceMappingURL=witness-factory-base.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"witness-factory-base.d.mts","sourceRoot":"","sources":["../../../src/witness/factory/witness-factory-base.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAkB,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAMjF;;GAEG;AACH,8BAAsB,kBAAkB,CACpC,YAAY,SAAS,cAAc,EACnC,cAAc,SAAS,gBAAgB,EACvC,QAAQ,SAAS,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,CAAC;IAE1E,SAAS,CAAC,EAAE,EAAE,MAAM,CAAkC;IAEtD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,IAAI,MAAM;IAE1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAAE,IAAI,CAAC,EAAE,YAAY,CAAC;QAAC,MAAM,CAAC,EAAE,cAAc,CAAA;KAAE,GAC7E,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;CAEzC;AAED,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module witness-factory-base
|
|
3
|
+
*
|
|
4
|
+
* this was a probably-klugy plumbing attempt for ionic-gib to instantiate ibgib
|
|
5
|
+
* witness objects.
|
|
6
|
+
*
|
|
7
|
+
* Specifically this was to go from angular forms to witness ibgibs. The trick
|
|
8
|
+
* was that ibgib's are data objects and you had to load the witness ibgibs
|
|
9
|
+
* which actually had functions/methods on them.
|
|
10
|
+
*
|
|
11
|
+
* So the workflow was you get a form component with some fields, and you
|
|
12
|
+
* generate the witness via this factory.
|
|
13
|
+
*
|
|
14
|
+
* it worked, but it's not strong I don't think.
|
|
15
|
+
*
|
|
16
|
+
* the main weak point is that i didn't fill out the form-items enough and i
|
|
17
|
+
* never got it so that you could create nested forms.
|
|
18
|
+
*
|
|
19
|
+
* in its favor, i do use this (although klugily) in the ibgib rcli app, where
|
|
20
|
+
* instead of a visual form it prompts the user. terrible ux but it did "work"
|
|
21
|
+
* as a quick and dirty implementation. it could be polished going forward (i
|
|
22
|
+
* dont think the design is inherently flawed).
|
|
23
|
+
*/
|
|
24
|
+
// import * as c from '../constants';
|
|
25
|
+
// const logalot = c.GLOBAL_LOG_A_LOT || false;
|
|
26
|
+
/**
|
|
27
|
+
* The idea is that any model can be injected via this factory provider.
|
|
28
|
+
*/
|
|
29
|
+
export class WitnessFactoryBase {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.lc = `[${WitnessFactoryBase.name}]`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=witness-factory-base.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"witness-factory-base.mjs","sourceRoot":"","sources":["../../../src/witness/factory/witness-factory-base.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAOH,qCAAqC;AAErC,+CAA+C;AAE/C;;GAEG;AACH,MAAM,OAAgB,kBAAkB;IAAxC;QAKc,OAAE,GAAW,IAAI,kBAAkB,CAAC,IAAI,GAAG,CAAC;IAyB1D,CAAC;CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ibgib/core-gib",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
4
4
|
"description": "ibgib core functionality, including base architecture for witnesses, spaces, apps, robbots, etc., as well as shared utility functions. Node v19+ needed for heavily-used isomorphic webcrypto hashing consumed in both node and browsers.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://gitlab.com/ibgib/core-gib",
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module dynamic-form-factory-base
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* @see {@link WitnessFactoryBase}
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { patchObject } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
9
|
+
import { TransformResult } from "@ibgib/ts-gib/dist/types.mjs";
|
|
10
|
+
import { IbGibRel8ns_V1, IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
11
|
+
|
|
12
|
+
import { DynamicForm, FormItemInfo } from "../../common/form/form-items.mjs";
|
|
13
|
+
import { WitnessFactoryBase } from "./witness-factory-base.mjs";
|
|
14
|
+
import { Witness, WitnessData_V1, WitnessRel8ns_V1 } from "../witness-types.mjs";
|
|
15
|
+
|
|
16
|
+
import { GLOBAL_LOG_A_LOT } from "../../core-constants.mjs";
|
|
17
|
+
const logalot = GLOBAL_LOG_A_LOT || false;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The idea is that any model can be injected via this factory provider.
|
|
21
|
+
*
|
|
22
|
+
* So when you create a witness that you want to be able to instantiate via
|
|
23
|
+
* just metadata, you also provide an accompanying factory that knows
|
|
24
|
+
* how to map from a
|
|
25
|
+
* * witness(model) -> form data (to generate dynamic forms)
|
|
26
|
+
* * form data -> witness (to instantiate witness from data)
|
|
27
|
+
*/
|
|
28
|
+
export abstract class DynamicFormFactoryBase<
|
|
29
|
+
TWitnessData extends WitnessData_V1,
|
|
30
|
+
TWitnessRel8ns extends WitnessRel8ns_V1,
|
|
31
|
+
TWitness extends Witness<IbGib_V1, IbGib_V1, TWitnessData, TWitnessRel8ns>
|
|
32
|
+
>
|
|
33
|
+
extends WitnessFactoryBase<TWitnessData, TWitnessRel8ns, TWitness>{
|
|
34
|
+
protected lc: string = `[${DynamicFormFactoryBase.name}]`;
|
|
35
|
+
/**
|
|
36
|
+
* override this with something that maps from the ibgib/model to the form infos.
|
|
37
|
+
*/
|
|
38
|
+
abstract witnessToForm({ witness }: { witness: TWitness }): Promise<DynamicForm>;
|
|
39
|
+
/**
|
|
40
|
+
* override this with specific behavior that will reify an instance based on
|
|
41
|
+
* the given {@link form}.
|
|
42
|
+
*/
|
|
43
|
+
abstract formToWitness({ form }: { form: DynamicForm }): Promise<TransformResult<TWitness>>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* iterates through the given {@link items}.
|
|
47
|
+
*
|
|
48
|
+
* If the item has child items, it is considered a grouping (i.e. FormGroup
|
|
49
|
+
* or FormArray) and this function is called recursively with the
|
|
50
|
+
* {@link contextPath} adjusted per the {@link pathDelimiter} and
|
|
51
|
+
* `item.name`.
|
|
52
|
+
*
|
|
53
|
+
* If the item does not have child items, it's considered to be a setting at
|
|
54
|
+
* the current path level and it's value is assigned per its `item.name` as
|
|
55
|
+
* the key.
|
|
56
|
+
*/
|
|
57
|
+
protected patchDataFromItems({
|
|
58
|
+
data,
|
|
59
|
+
contextPath,
|
|
60
|
+
items,
|
|
61
|
+
pathDelimiter,
|
|
62
|
+
}: {
|
|
63
|
+
/**
|
|
64
|
+
* ibgib.data object that we are patching/setting from the form items.
|
|
65
|
+
*/
|
|
66
|
+
data: any,
|
|
67
|
+
/**
|
|
68
|
+
* source items whose values we are patching the {@link data} with.
|
|
69
|
+
*/
|
|
70
|
+
items: FormItemInfo[],
|
|
71
|
+
/**
|
|
72
|
+
* Separates sections of pathing into the data object.
|
|
73
|
+
*
|
|
74
|
+
* @default @see {@link DEFAULT_DATA_PATH_DELIMITER}
|
|
75
|
+
*/
|
|
76
|
+
pathDelimiter: string,
|
|
77
|
+
/**
|
|
78
|
+
* we're patching the data object as follows:
|
|
79
|
+
*
|
|
80
|
+
* data[contextPath/item.name] = value
|
|
81
|
+
*
|
|
82
|
+
* where the '/' is the data path delimiter.
|
|
83
|
+
*
|
|
84
|
+
* So if the incoming items are nested deeper, this will look like
|
|
85
|
+
*
|
|
86
|
+
* data['mysetting/subsetting/color'] = "red"
|
|
87
|
+
*
|
|
88
|
+
* @see {@link pathDelimiter}
|
|
89
|
+
* @see {@link DEFAULT_DATA_PATH_DELIMITER}
|
|
90
|
+
*/
|
|
91
|
+
contextPath?: string,
|
|
92
|
+
}): void {
|
|
93
|
+
const lc = `${this.lc}[${this.patchDataFromItems.name}]`;
|
|
94
|
+
try {
|
|
95
|
+
if (logalot) { console.log(`${lc} starting...`); }
|
|
96
|
+
if (!pathDelimiter) { throw new Error(`pathDelimiter required (E: 958d472a15fb71e45cd2925883f2ec22)`); }
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < items.length; i++) {
|
|
99
|
+
const item = items[i];
|
|
100
|
+
const path = contextPath ?
|
|
101
|
+
contextPath + pathDelimiter + item.name :
|
|
102
|
+
item.name;
|
|
103
|
+
if (!item.items) {
|
|
104
|
+
// it's a property (FormControl, not FormGroup/Array)
|
|
105
|
+
patchObject({
|
|
106
|
+
obj: data,
|
|
107
|
+
value: item.value,
|
|
108
|
+
path,
|
|
109
|
+
logalot,
|
|
110
|
+
pathDelimiter,
|
|
111
|
+
});
|
|
112
|
+
} else if (item.items.length > 0) {
|
|
113
|
+
// it's a group, so call this function recursively
|
|
114
|
+
this.patchDataFromItems({
|
|
115
|
+
data,
|
|
116
|
+
contextPath: path,
|
|
117
|
+
items: item.items,
|
|
118
|
+
pathDelimiter,
|
|
119
|
+
});
|
|
120
|
+
} else {
|
|
121
|
+
throw new Error(`invalid item. items is truthy but with a length of 0. items should either be falsy or have at least one child. (E: ee2765e0b920477f919fcb09e9d951b4)`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error(`${lc} ${error.message}`);
|
|
126
|
+
throw error;
|
|
127
|
+
} finally {
|
|
128
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module witness-factory-base
|
|
3
|
+
*
|
|
4
|
+
* this was a probably-klugy plumbing attempt for ionic-gib to instantiate ibgib
|
|
5
|
+
* witness objects.
|
|
6
|
+
*
|
|
7
|
+
* Specifically this was to go from angular forms to witness ibgibs. The trick
|
|
8
|
+
* was that ibgib's are data objects and you had to load the witness ibgibs
|
|
9
|
+
* which actually had functions/methods on them.
|
|
10
|
+
*
|
|
11
|
+
* So the workflow was you get a form component with some fields, and you
|
|
12
|
+
* generate the witness via this factory.
|
|
13
|
+
*
|
|
14
|
+
* it worked, but it's not strong I don't think.
|
|
15
|
+
*
|
|
16
|
+
* the main weak point is that i didn't fill out the form-items enough and i
|
|
17
|
+
* never got it so that you could create nested forms.
|
|
18
|
+
*
|
|
19
|
+
* in its favor, i do use this (although klugily) in the ibgib rcli app, where
|
|
20
|
+
* instead of a visual form it prompts the user. terrible ux but it did "work"
|
|
21
|
+
* as a quick and dirty implementation. it could be polished going forward (i
|
|
22
|
+
* dont think the design is inherently flawed).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { IbGibRel8ns_V1, IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
26
|
+
import { TransformResult } from "@ibgib/ts-gib/dist/types.mjs";
|
|
27
|
+
|
|
28
|
+
import { Witness, WitnessData_V1, WitnessRel8ns_V1 } from "../witness-types.mjs";
|
|
29
|
+
|
|
30
|
+
// import * as c from '../constants';
|
|
31
|
+
|
|
32
|
+
// const logalot = c.GLOBAL_LOG_A_LOT || false;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The idea is that any model can be injected via this factory provider.
|
|
36
|
+
*/
|
|
37
|
+
export abstract class WitnessFactoryBase<
|
|
38
|
+
TWitnessData extends WitnessData_V1,
|
|
39
|
+
TWitnessRel8ns extends WitnessRel8ns_V1,
|
|
40
|
+
TWitness extends Witness<IbGib_V1, IbGib_V1, TWitnessData, TWitnessRel8ns>
|
|
41
|
+
> {
|
|
42
|
+
protected lc: string = `[${WitnessFactoryBase.name}]`;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* override this to provide the name of the class for the factory.
|
|
46
|
+
*
|
|
47
|
+
* ## usage
|
|
48
|
+
*
|
|
49
|
+
* atm I'm using this to return the classname for the witness.
|
|
50
|
+
*
|
|
51
|
+
* @example MyWitnessClass.classname
|
|
52
|
+
*/
|
|
53
|
+
abstract getName(): string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* creates a new witness. This should return the transform result with the
|
|
57
|
+
* new ibgib being the witness class itself, not just the ibgib dto.
|
|
58
|
+
*
|
|
59
|
+
* So said in another way, the `result.newIbGib` should include the class
|
|
60
|
+
* instantiation which has the `witness` function on it.
|
|
61
|
+
*
|
|
62
|
+
* @see {@link WitnessB}
|
|
63
|
+
*/
|
|
64
|
+
abstract newUp({ data, rel8ns }: { data?: TWitnessData, rel8ns?: TWitnessRel8ns }):
|
|
65
|
+
Promise<TransformResult<TWitness>>;
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type WitnessFactoryAny = WitnessFactoryBase<any, any, any>;
|