@snowtop/ent 0.2.14 → 0.2.15
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/action/orchestrator.d.ts +1 -1
- package/action/orchestrator.js +14 -2
- package/package.json +1 -1
- package/schema/base_schema.js +26 -39
- package/testutils/builder.d.ts +1 -0
- package/testutils/builder.js +11 -2
package/action/orchestrator.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface OrchestratorOptions<TEnt extends Ent<TViewer>, TInput extends D
|
|
|
17
17
|
action?: Action<TEnt, Builder<TEnt, TViewer>, TViewer, TInput>;
|
|
18
18
|
schema: SchemaInputType;
|
|
19
19
|
editedFields(): Map<string, any> | Promise<Map<string, any>>;
|
|
20
|
-
updateInput?: (data: TInput, operation?: WriteOperation) => void;
|
|
20
|
+
updateInput?: (data: TInput, operation?: WriteOperation, defaultKeys?: ReadonlySet<string>) => void;
|
|
21
21
|
expressions?: Map<string, clause.Clause>;
|
|
22
22
|
fieldInfo: FieldInfoMap;
|
|
23
23
|
}
|
package/action/orchestrator.js
CHANGED
|
@@ -708,6 +708,8 @@ class Orchestrator {
|
|
|
708
708
|
async getFieldsWithDefaultValues(builder, schemaFields, editedFields, action) {
|
|
709
709
|
let data = {};
|
|
710
710
|
let defaultData = {};
|
|
711
|
+
const defaultKeys = new Set();
|
|
712
|
+
const transformedFields = new Set();
|
|
711
713
|
let input = action?.getInput() || {};
|
|
712
714
|
let updateInput = false;
|
|
713
715
|
// transformations
|
|
@@ -760,6 +762,7 @@ class Orchestrator {
|
|
|
760
762
|
}
|
|
761
763
|
data[this.getStorageKey(k)] = dbVal;
|
|
762
764
|
if (!field.immutable) {
|
|
765
|
+
transformedFields.add(k);
|
|
763
766
|
this.defaultFieldsByTSName[this.getInputKey(k)] = inputVal;
|
|
764
767
|
}
|
|
765
768
|
// hmm do we need this?
|
|
@@ -797,7 +800,7 @@ class Orchestrator {
|
|
|
797
800
|
if (value !== undefined) {
|
|
798
801
|
userDefinedKeys.add(dbKey);
|
|
799
802
|
}
|
|
800
|
-
if (value === undefined) {
|
|
803
|
+
if (value === undefined && !transformedFields.has(fieldName)) {
|
|
801
804
|
if (this.actualOperation === action_1.WriteOperation.Insert) {
|
|
802
805
|
if (field.defaultToViewerOnCreate && field.defaultValueOnCreate) {
|
|
803
806
|
throw new Error(`cannot set both defaultToViewerOnCreate and defaultValueOnCreate`);
|
|
@@ -836,6 +839,9 @@ class Orchestrator {
|
|
|
836
839
|
}
|
|
837
840
|
this.defaultFieldsByFieldName[fieldName] = defaultValue;
|
|
838
841
|
this.defaultFieldsByTSName[this.getInputKey(fieldName)] = defaultValue;
|
|
842
|
+
if (field.disableUserEditable || updateOnlyIfOther) {
|
|
843
|
+
defaultKeys.add(this.getInputKey(fieldName));
|
|
844
|
+
}
|
|
839
845
|
}
|
|
840
846
|
}
|
|
841
847
|
// if there's data changing, add data
|
|
@@ -846,7 +852,7 @@ class Orchestrator {
|
|
|
846
852
|
};
|
|
847
853
|
if (updateInput && this.options.updateInput) {
|
|
848
854
|
// this basically fixes #605. just needs to be exposed correctly
|
|
849
|
-
this.options.updateInput(this.defaultFieldsByTSName, this.actualOperation);
|
|
855
|
+
this.options.updateInput(this.defaultFieldsByTSName, this.actualOperation, defaultKeys);
|
|
850
856
|
}
|
|
851
857
|
}
|
|
852
858
|
return { data, userDefinedKeys };
|
|
@@ -941,6 +947,12 @@ class Orchestrator {
|
|
|
941
947
|
for (const fieldName of needsFullDataChecks) {
|
|
942
948
|
const field = schemaFields.get(fieldName);
|
|
943
949
|
let value = editedFields.get(fieldName);
|
|
950
|
+
// Deferred defaults are absent from editedFields, but validators must
|
|
951
|
+
// still receive the value that will be saved when this operation writes.
|
|
952
|
+
if (value === undefined &&
|
|
953
|
+
(op === action_1.WriteOperation.Insert || this.hasData(data))) {
|
|
954
|
+
value = this.defaultFieldsByFieldName[fieldName];
|
|
955
|
+
}
|
|
944
956
|
// @ts-ignore...
|
|
945
957
|
// type hackery because it's hard
|
|
946
958
|
const v = await field.validateWithFullData(value, this.options.builder);
|
package/package.json
CHANGED
package/schema/base_schema.js
CHANGED
|
@@ -3,26 +3,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.EntSchemaWithTZ = exports.EntSchema = exports.Node = exports.Timestamps = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
const field_1 = require("./field");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
6
|
+
function timestampFields(withTimezone) {
|
|
7
|
+
return {
|
|
8
|
+
createdAt: (0, field_1.TimestampType)({
|
|
9
|
+
withTimezone,
|
|
10
|
+
hideFromGraphQL: true,
|
|
11
|
+
disableUserEditable: true,
|
|
12
|
+
defaultValueOnCreate: () => {
|
|
13
|
+
return new Date();
|
|
14
|
+
},
|
|
15
|
+
}),
|
|
16
|
+
updatedAt: (0, field_1.TimestampType)({
|
|
17
|
+
withTimezone,
|
|
18
|
+
hideFromGraphQL: true,
|
|
19
|
+
disableUserEditable: true,
|
|
20
|
+
defaultValueOnCreate: () => {
|
|
21
|
+
return new Date();
|
|
22
|
+
},
|
|
23
|
+
onlyUpdateIfOtherFieldsBeingSet_BETA: true,
|
|
24
|
+
defaultValueOnEdit: () => {
|
|
25
|
+
return new Date();
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
let tsFields = timestampFields(false);
|
|
26
31
|
// Timestamps is a Pattern that adds a createdAt and updatedAt timestamp fields to the ent
|
|
27
32
|
exports.Timestamps = {
|
|
28
33
|
name: "timestamps",
|
|
@@ -43,25 +48,7 @@ let nodeFields = {
|
|
|
43
48
|
let nodeFieldsWithTZ = {
|
|
44
49
|
// inconsistent naming :(
|
|
45
50
|
id: nodeField,
|
|
46
|
-
|
|
47
|
-
hideFromGraphQL: true,
|
|
48
|
-
disableUserEditable: true,
|
|
49
|
-
defaultValueOnCreate: () => {
|
|
50
|
-
return new Date();
|
|
51
|
-
},
|
|
52
|
-
withTimezone: true,
|
|
53
|
-
}),
|
|
54
|
-
updatedAt: (0, field_1.TimestampType)({
|
|
55
|
-
hideFromGraphQL: true,
|
|
56
|
-
disableUserEditable: true,
|
|
57
|
-
defaultValueOnCreate: () => {
|
|
58
|
-
return new Date();
|
|
59
|
-
},
|
|
60
|
-
defaultValueOnEdit: () => {
|
|
61
|
-
return new Date();
|
|
62
|
-
},
|
|
63
|
-
withTimezone: true,
|
|
64
|
-
}),
|
|
51
|
+
...timestampFields(true),
|
|
65
52
|
};
|
|
66
53
|
// Node is a Pattern that adds 3 fields to the ent: (id, createdAt, and updatedAt timestamps)
|
|
67
54
|
exports.Node = {
|
package/testutils/builder.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ export declare class SimpleBuilder<T extends Ent, TExistingEnt extends TMaybleNu
|
|
|
81
81
|
placeholderID: ID;
|
|
82
82
|
orchestrator: Orchestrator<T, Data, Viewer, TExistingEnt>;
|
|
83
83
|
fields: Map<string, any>;
|
|
84
|
+
private defaultInput;
|
|
84
85
|
nodeType: string;
|
|
85
86
|
m: Map<string, any>;
|
|
86
87
|
constructor(viewer: Viewer, schema: BuilderSchema<T>, fields: Map<string, any>, operation: WriteOperation | undefined, existingEnt: TExistingEnt, action?: Action<T, SimpleBuilder<T, TExistingEnt>, Viewer, Data, TExistingEnt> | undefined, expressions?: Map<string, Clause>);
|
package/testutils/builder.js
CHANGED
|
@@ -191,6 +191,7 @@ class SimpleBuilder {
|
|
|
191
191
|
this.schema = schema;
|
|
192
192
|
this.operation = operation;
|
|
193
193
|
this.existingEnt = existingEnt;
|
|
194
|
+
this.defaultInput = new Map();
|
|
194
195
|
this.m = new Map();
|
|
195
196
|
// create dynamic placeholder
|
|
196
197
|
// TODO: do we need to use this as the node when there's an existingEnt
|
|
@@ -247,11 +248,18 @@ class SimpleBuilder {
|
|
|
247
248
|
// to simulate what we do in generated builders where we return a new Map
|
|
248
249
|
const m = new Map();
|
|
249
250
|
for (const [k, v] of this.fields) {
|
|
250
|
-
|
|
251
|
+
if (!this.defaultInput.has(k) || this.defaultInput.get(k) !== v) {
|
|
252
|
+
m.set(k, v);
|
|
253
|
+
}
|
|
251
254
|
}
|
|
252
255
|
return m;
|
|
253
256
|
},
|
|
254
|
-
updateInput:
|
|
257
|
+
updateInput: (input, _operation, defaultKeys) => {
|
|
258
|
+
this.updateInput(input);
|
|
259
|
+
for (const key of defaultKeys ?? []) {
|
|
260
|
+
this.defaultInput.set(key, input[key]);
|
|
261
|
+
}
|
|
262
|
+
},
|
|
255
263
|
});
|
|
256
264
|
}
|
|
257
265
|
getInput() {
|
|
@@ -264,6 +272,7 @@ class SimpleBuilder {
|
|
|
264
272
|
updateInput(input) {
|
|
265
273
|
const knownFields = (0, schema_1.getFields)(this.schema);
|
|
266
274
|
for (const k in input) {
|
|
275
|
+
this.defaultInput.delete(k);
|
|
267
276
|
if (knownFields.has(k)) {
|
|
268
277
|
this.fields.set(k, input[k]);
|
|
269
278
|
}
|