@snowtop/ent 0.1.0-alpha110 → 0.1.0-alpha112
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.js
CHANGED
|
@@ -35,6 +35,7 @@ const executor_1 = require("./executor");
|
|
|
35
35
|
const logger_1 = require("../core/logger");
|
|
36
36
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
37
37
|
const clause = __importStar(require("../core/clause"));
|
|
38
|
+
const util_1 = require("util");
|
|
38
39
|
var edgeDirection;
|
|
39
40
|
(function (edgeDirection) {
|
|
40
41
|
edgeDirection[edgeDirection["inboundEdge"] = 0] = "inboundEdge";
|
|
@@ -272,12 +273,32 @@ class Orchestrator {
|
|
|
272
273
|
}
|
|
273
274
|
return new EntCannotDeleteEntError(privacyPolicy, action, this.existingEnt);
|
|
274
275
|
}
|
|
275
|
-
getEntForPrivacyPolicyImpl(editedData) {
|
|
276
|
+
async getEntForPrivacyPolicyImpl(schemaFields, editedData) {
|
|
276
277
|
if (this.actualOperation !== action_1.WriteOperation.Insert) {
|
|
277
278
|
return this.existingEnt;
|
|
278
279
|
}
|
|
280
|
+
// need to format fields if possible because ent constructors expect data that's
|
|
281
|
+
// in the format that's coming from the db
|
|
282
|
+
// required for object fields...
|
|
283
|
+
const formatted = { ...editedData };
|
|
284
|
+
for (const [fieldName, field] of schemaFields) {
|
|
285
|
+
if (!field.format) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
let dbKey = this.getStorageKey(fieldName);
|
|
289
|
+
let val = formatted[dbKey];
|
|
290
|
+
if (!val) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
// nested so it's not JSON stringified or anything like that
|
|
294
|
+
val = field.format(formatted[dbKey], true);
|
|
295
|
+
if (util_1.types.isPromise(val)) {
|
|
296
|
+
val = await val;
|
|
297
|
+
}
|
|
298
|
+
formatted[dbKey] = val;
|
|
299
|
+
}
|
|
279
300
|
// we create an unsafe ent to be used for privacy policies
|
|
280
|
-
return new this.options.builder.ent(this.options.builder.viewer,
|
|
301
|
+
return new this.options.builder.ent(this.options.builder.viewer, formatted);
|
|
281
302
|
}
|
|
282
303
|
getSQLStatementOperation() {
|
|
283
304
|
switch (this.actualOperation) {
|
|
@@ -307,8 +328,8 @@ class Orchestrator {
|
|
|
307
328
|
if (this.actualOperation !== action_1.WriteOperation.Insert) {
|
|
308
329
|
return this.existingEnt;
|
|
309
330
|
}
|
|
310
|
-
const { editedData } = await this.memoizedGetFields();
|
|
311
|
-
return this.getEntForPrivacyPolicyImpl(editedData);
|
|
331
|
+
const { schemaFields, editedData } = await this.memoizedGetFields();
|
|
332
|
+
return this.getEntForPrivacyPolicyImpl(schemaFields, editedData);
|
|
312
333
|
}
|
|
313
334
|
// this gets the fields that were explicitly set plus any default or transformed values
|
|
314
335
|
// mainly exists to get default fields e.g. default id to be used in triggers
|
|
@@ -359,7 +380,7 @@ class Orchestrator {
|
|
|
359
380
|
let privacyError = null;
|
|
360
381
|
if (privacyPolicy) {
|
|
361
382
|
try {
|
|
362
|
-
await (0, privacy_1.applyPrivacyPolicyX)(this.options.viewer, privacyPolicy, this.getEntForPrivacyPolicyImpl(editedData), this.throwError.bind(this));
|
|
383
|
+
await (0, privacy_1.applyPrivacyPolicyX)(this.options.viewer, privacyPolicy, await this.getEntForPrivacyPolicyImpl(schemaFields, editedData), this.throwError.bind(this));
|
|
363
384
|
}
|
|
364
385
|
catch (err) {
|
|
365
386
|
privacyError = err;
|
|
@@ -536,11 +557,17 @@ class Orchestrator {
|
|
|
536
557
|
if (defaultValue === undefined) {
|
|
537
558
|
throw new Error(`defaultValueOnCreate() returned undefined for field ${fieldName}`);
|
|
538
559
|
}
|
|
560
|
+
if (util_1.types.isPromise(defaultValue)) {
|
|
561
|
+
defaultValue = await defaultValue;
|
|
562
|
+
}
|
|
539
563
|
}
|
|
540
564
|
}
|
|
541
565
|
if (field.defaultValueOnEdit &&
|
|
542
566
|
this.actualOperation === action_1.WriteOperation.Edit) {
|
|
543
567
|
defaultValue = field.defaultValueOnEdit(builder, input);
|
|
568
|
+
if (util_1.types.isPromise(defaultValue)) {
|
|
569
|
+
defaultValue = await defaultValue;
|
|
570
|
+
}
|
|
544
571
|
}
|
|
545
572
|
}
|
|
546
573
|
if (value !== undefined) {
|
package/package.json
CHANGED
package/schema/json_field.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare class JSONField extends BaseField implements Field {
|
|
|
11
11
|
private options?;
|
|
12
12
|
type: Type;
|
|
13
13
|
constructor(jsonb: boolean, options?: allJSONOptions | undefined);
|
|
14
|
-
format(val: any):
|
|
14
|
+
format(val: any, nested?: boolean): any;
|
|
15
15
|
valid(val: any): boolean;
|
|
16
16
|
}
|
|
17
17
|
export declare function JSONType(options?: JSONOptions): JSONField;
|
package/schema/json_field.js
CHANGED
package/schema/schema.d.ts
CHANGED
|
@@ -203,6 +203,7 @@ export interface FieldOptions {
|
|
|
203
203
|
foreignKey?: ForeignKey;
|
|
204
204
|
fieldEdge?: FieldEdge;
|
|
205
205
|
primaryKey?: boolean;
|
|
206
|
+
immutable?: boolean;
|
|
206
207
|
disableUserEditable?: boolean;
|
|
207
208
|
disableUserGraphQLEditable?: boolean;
|
|
208
209
|
defaultValueOnCreate?(builder: Builder<Ent>, input: Data): any;
|
|
@@ -162,8 +162,9 @@ function makeGraphQLRequest(config, query, fieldArgs) {
|
|
|
162
162
|
}
|
|
163
163
|
function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
164
164
|
let fields;
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
const [typ] = getInnerType(fieldType, false);
|
|
166
|
+
if (typ instanceof graphql_1.GraphQLObjectType) {
|
|
167
|
+
fields = typ.getFields();
|
|
167
168
|
}
|
|
168
169
|
let topLevelTree = {};
|
|
169
170
|
options.forEach((option) => {
|
|
@@ -201,10 +202,11 @@ function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
|
201
202
|
}
|
|
202
203
|
// TODO this needs to be aware of paths etc so this part works for complicated
|
|
203
204
|
// cases but inlineFragmentRoot is a workaround for now.
|
|
204
|
-
function handleSubtree(obj, tree) {
|
|
205
|
+
function handleSubtree(obj, tree, parts) {
|
|
206
|
+
let parts2 = [...parts];
|
|
205
207
|
if (Array.isArray(obj)) {
|
|
206
208
|
for (const obj2 of obj) {
|
|
207
|
-
handleSubtree(obj2, tree);
|
|
209
|
+
handleSubtree(obj2, tree, parts2);
|
|
208
210
|
}
|
|
209
211
|
return;
|
|
210
212
|
}
|
|
@@ -213,28 +215,36 @@ function buildTreeFromQueryPaths(schema, fieldType, ...options) {
|
|
|
213
215
|
tree[key] = {};
|
|
214
216
|
}
|
|
215
217
|
if (typeof obj[key] === "object") {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
+
let parts2 = [...parts, key];
|
|
219
|
+
if (!scalarFieldAtLeaf(parts2)) {
|
|
220
|
+
handleSubtree(obj[key], tree[key], parts2);
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
}
|
|
221
224
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (!subField) {
|
|
225
|
+
function scalarFieldAtLeaf(pathFromRoot) {
|
|
226
|
+
let root = fields;
|
|
227
|
+
if (!root) {
|
|
226
228
|
return false;
|
|
227
229
|
}
|
|
228
|
-
|
|
230
|
+
let subField;
|
|
231
|
+
for (const p of pathFromRoot) {
|
|
232
|
+
subField = root?.[p];
|
|
233
|
+
if (subField) {
|
|
234
|
+
[subField] = getInnerType(subField.type, false);
|
|
235
|
+
if (subField instanceof graphql_1.GraphQLObjectType) {
|
|
236
|
+
root = subField.getFields();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (!subField) {
|
|
229
241
|
return false;
|
|
230
242
|
}
|
|
231
|
-
|
|
232
|
-
const [typ, _] = getInnerType(subField.type, true);
|
|
233
|
-
return (0, graphql_1.isScalarType)(typ) || (0, graphql_1.isEnumType)(typ);
|
|
243
|
+
return (0, graphql_1.isScalarType)(subField) || (0, graphql_1.isEnumType)(subField);
|
|
234
244
|
}
|
|
235
245
|
if (i === parts.length - 1 && typeof option[1] === "object") {
|
|
236
|
-
if (!
|
|
237
|
-
handleSubtree(option[1], tree);
|
|
246
|
+
if (!scalarFieldAtLeaf(parts)) {
|
|
247
|
+
handleSubtree(option[1], tree, parts);
|
|
238
248
|
}
|
|
239
249
|
}
|
|
240
250
|
}
|