@snowtop/ent 0.1.0-alpha144 → 0.1.0-alpha146
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 +2 -1
- package/action/orchestrator.js +71 -23
- package/core/ent.js +4 -3
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +1 -0
- package/parse_schema/parse.js +1 -0
- package/schema/index.d.ts +1 -1
- package/schema/index.js +2 -1
- package/schema/schema.d.ts +3 -1
- package/schema/schema.js +18 -37
package/action/orchestrator.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import * as clause from "../core/clause";
|
|
|
8
8
|
type MaybeNull<T extends Ent> = T | null;
|
|
9
9
|
type TMaybleNullableEnt<T extends Ent> = T | MaybeNull<T>;
|
|
10
10
|
export interface OrchestratorOptions<TEnt extends Ent<TViewer>, TInput extends Data, TViewer extends Viewer, TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>> {
|
|
11
|
-
viewer:
|
|
11
|
+
viewer: TViewer;
|
|
12
12
|
operation: WriteOperation;
|
|
13
13
|
tableName: string;
|
|
14
14
|
loaderOptions: LoadEntOptions<TEnt, TViewer>;
|
|
@@ -68,6 +68,7 @@ export declare class Orchestrator<TEnt extends Ent<TViewer>, TInput extends Data
|
|
|
68
68
|
private getEdgeOperation;
|
|
69
69
|
private buildEdgeOps;
|
|
70
70
|
private throwError;
|
|
71
|
+
private getRowForPrivacyPolicyImpl;
|
|
71
72
|
private getEntForPrivacyPolicyImpl;
|
|
72
73
|
private getSQLStatementOperation;
|
|
73
74
|
private getWriteOpForSQLStamentOp;
|
package/action/orchestrator.js
CHANGED
|
@@ -51,31 +51,38 @@ class edgeInputData {
|
|
|
51
51
|
return id.placeholderID !== undefined;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
function getViewer(
|
|
55
|
-
if (!
|
|
54
|
+
function getViewer(viewer) {
|
|
55
|
+
if (!viewer.viewerID) {
|
|
56
56
|
return "Logged out Viewer";
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
return `Viewer with ID ${
|
|
59
|
+
return `Viewer with ID ${viewer.viewerID}`;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
class EntCannotCreateEntError extends Error {
|
|
63
63
|
constructor(privacyPolicy, action) {
|
|
64
|
-
let msg = `${getViewer(action)} does not have permission to create ${action.builder.ent.name}`;
|
|
64
|
+
let msg = `${getViewer(action.viewer)} does not have permission to create ${action.builder.ent.name}`;
|
|
65
65
|
super(msg);
|
|
66
66
|
this.privacyPolicy = privacyPolicy;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
class EntCannotEditEntError extends Error {
|
|
70
70
|
constructor(privacyPolicy, action, ent) {
|
|
71
|
-
let msg = `${getViewer(action)} does not have permission to edit ${ent.constructor.name}`;
|
|
71
|
+
let msg = `${getViewer(action.viewer)} does not have permission to edit ${ent.constructor.name}`;
|
|
72
|
+
super(msg);
|
|
73
|
+
this.privacyPolicy = privacyPolicy;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
class EntCannotEditEntFieldError extends Error {
|
|
77
|
+
constructor(privacyPolicy, viewer, field, ent) {
|
|
78
|
+
let msg = `${getViewer(viewer)} does not have permission to edit field ${field} ${ent.constructor.name}`;
|
|
72
79
|
super(msg);
|
|
73
80
|
this.privacyPolicy = privacyPolicy;
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
class EntCannotDeleteEntError extends Error {
|
|
77
84
|
constructor(privacyPolicy, action, ent) {
|
|
78
|
-
let msg = `${getViewer(action)} does not have permission to delete ${ent.constructor.name}`;
|
|
85
|
+
let msg = `${getViewer(action.viewer)} does not have permission to delete ${ent.constructor.name}`;
|
|
79
86
|
super(msg);
|
|
80
87
|
this.privacyPolicy = privacyPolicy;
|
|
81
88
|
}
|
|
@@ -314,10 +321,7 @@ class Orchestrator {
|
|
|
314
321
|
}
|
|
315
322
|
return new EntCannotDeleteEntError(privacyPolicy, action, this.existingEnt);
|
|
316
323
|
}
|
|
317
|
-
async
|
|
318
|
-
if (this.actualOperation !== action_1.WriteOperation.Insert) {
|
|
319
|
-
return this.existingEnt;
|
|
320
|
-
}
|
|
324
|
+
async getRowForPrivacyPolicyImpl(schemaFields, editedData) {
|
|
321
325
|
// need to format fields if possible because ent constructors expect data that's
|
|
322
326
|
// in the format that's coming from the db
|
|
323
327
|
// required for object fields...
|
|
@@ -350,8 +354,17 @@ class Orchestrator {
|
|
|
350
354
|
}
|
|
351
355
|
formatted[dbKey] = val;
|
|
352
356
|
}
|
|
357
|
+
return formatted;
|
|
358
|
+
}
|
|
359
|
+
async getEntForPrivacyPolicyImpl(schemaFields, editedData, viewerToUse, rowToUse) {
|
|
360
|
+
if (this.actualOperation !== action_1.WriteOperation.Insert) {
|
|
361
|
+
return this.existingEnt;
|
|
362
|
+
}
|
|
363
|
+
if (!rowToUse) {
|
|
364
|
+
rowToUse = await this.getRowForPrivacyPolicyImpl(schemaFields, editedData);
|
|
365
|
+
}
|
|
353
366
|
// we create an unsafe ent to be used for privacy policies
|
|
354
|
-
return new this.options.builder.ent(
|
|
367
|
+
return new this.options.builder.ent(viewerToUse, rowToUse);
|
|
355
368
|
}
|
|
356
369
|
getSQLStatementOperation() {
|
|
357
370
|
switch (this.actualOperation) {
|
|
@@ -382,7 +395,7 @@ class Orchestrator {
|
|
|
382
395
|
return this.existingEnt;
|
|
383
396
|
}
|
|
384
397
|
const { schemaFields, editedData } = await this.memoizedGetFields();
|
|
385
|
-
return this.getEntForPrivacyPolicyImpl(schemaFields, editedData);
|
|
398
|
+
return this.getEntForPrivacyPolicyImpl(schemaFields, editedData, this.options.viewer);
|
|
386
399
|
}
|
|
387
400
|
// this gets the fields that were explicitly set plus any default or transformed values
|
|
388
401
|
// mainly exists to get default fields e.g. default id to be used in triggers
|
|
@@ -408,9 +421,17 @@ class Orchestrator {
|
|
|
408
421
|
const builder = this.options.builder;
|
|
409
422
|
// future optimization: can get schemaFields to memoize based on different values
|
|
410
423
|
const schemaFields = (0, schema_1.getFields)(this.options.schema);
|
|
424
|
+
// also future optimization, no need to go through the list of fields multiple times
|
|
425
|
+
const editPrivacyFields = (0, schema_1.getFieldsWithEditPrivacy)(this.options.schema, this.options.fieldInfo);
|
|
411
426
|
const editedFields = await this.options.editedFields();
|
|
412
|
-
let editedData = await this.getFieldsWithDefaultValues(builder, schemaFields, editedFields, action);
|
|
413
|
-
return {
|
|
427
|
+
let { data: editedData, userDefinedKeys } = await this.getFieldsWithDefaultValues(builder, schemaFields, editedFields, action);
|
|
428
|
+
return {
|
|
429
|
+
editedData,
|
|
430
|
+
editedFields,
|
|
431
|
+
schemaFields,
|
|
432
|
+
userDefinedKeys,
|
|
433
|
+
editPrivacyFields,
|
|
434
|
+
};
|
|
414
435
|
}
|
|
415
436
|
async validate() {
|
|
416
437
|
// existing ent required for edit or delete operations
|
|
@@ -421,7 +442,7 @@ class Orchestrator {
|
|
|
421
442
|
throw new Error(`existing ent required with operation ${this.actualOperation}`);
|
|
422
443
|
}
|
|
423
444
|
}
|
|
424
|
-
const { schemaFields, editedData } = await this.memoizedGetFields();
|
|
445
|
+
const { schemaFields, editedData, userDefinedKeys, editPrivacyFields } = await this.memoizedGetFields();
|
|
425
446
|
const action = this.options.action;
|
|
426
447
|
const builder = this.options.builder;
|
|
427
448
|
// this runs in following phases:
|
|
@@ -430,18 +451,40 @@ class Orchestrator {
|
|
|
430
451
|
// * triggers
|
|
431
452
|
// * validators
|
|
432
453
|
let privacyPolicy = action?.getPrivacyPolicy();
|
|
433
|
-
|
|
454
|
+
const errors = [];
|
|
434
455
|
if (privacyPolicy) {
|
|
456
|
+
const ent = await this.getEntForPrivacyPolicyImpl(schemaFields, editedData, this.options.viewer);
|
|
435
457
|
try {
|
|
436
|
-
await (0, privacy_1.applyPrivacyPolicyX)(this.options.viewer, privacyPolicy,
|
|
458
|
+
await (0, privacy_1.applyPrivacyPolicyX)(this.options.viewer, privacyPolicy, ent, () => this.throwError());
|
|
437
459
|
}
|
|
438
460
|
catch (err) {
|
|
439
|
-
|
|
461
|
+
errors.push(err);
|
|
440
462
|
}
|
|
441
463
|
}
|
|
442
|
-
//
|
|
443
|
-
|
|
444
|
-
|
|
464
|
+
// we have edit privacy fields, so we need to apply privacy policy on those
|
|
465
|
+
const promises = [];
|
|
466
|
+
if (editPrivacyFields.size) {
|
|
467
|
+
// get row based on edited data
|
|
468
|
+
const row = await this.getRowForPrivacyPolicyImpl(schemaFields, editedData);
|
|
469
|
+
// get viewer for ent load based on formatted row
|
|
470
|
+
const viewer = await this.viewerForEntLoad(row);
|
|
471
|
+
const ent = await this.getEntForPrivacyPolicyImpl(schemaFields, editedData, viewer, row);
|
|
472
|
+
for (const [k, policy] of editPrivacyFields) {
|
|
473
|
+
if (editedData[k] === undefined || !userDefinedKeys.has(k)) {
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
promises.push((async () => {
|
|
477
|
+
const r = await (0, privacy_1.applyPrivacyPolicy)(viewer, policy, ent);
|
|
478
|
+
if (!r) {
|
|
479
|
+
errors.push(new EntCannotEditEntFieldError(policy, viewer, k, ent));
|
|
480
|
+
}
|
|
481
|
+
})());
|
|
482
|
+
}
|
|
483
|
+
await Promise.all(promises);
|
|
484
|
+
}
|
|
485
|
+
// privacy or field errors should return first so it's less confusing
|
|
486
|
+
if (errors.length) {
|
|
487
|
+
return errors;
|
|
445
488
|
}
|
|
446
489
|
// have to run triggers which update fields first before field and other validators
|
|
447
490
|
// so running this first to build things up
|
|
@@ -455,11 +498,12 @@ class Orchestrator {
|
|
|
455
498
|
// not ideal we're calling this twice. fix...
|
|
456
499
|
// needed for now. may need to rewrite some of this?
|
|
457
500
|
const editedFields2 = await this.options.editedFields();
|
|
458
|
-
const [
|
|
501
|
+
const [errs2, errs3] = await Promise.all([
|
|
459
502
|
this.formatAndValidateFields(schemaFields, editedFields2),
|
|
460
503
|
this.validators(validators, action, builder),
|
|
461
504
|
]);
|
|
462
505
|
errors.push(...errs2);
|
|
506
|
+
errors.push(...errs3);
|
|
463
507
|
return errors;
|
|
464
508
|
}
|
|
465
509
|
async triggers(action, builder, triggers) {
|
|
@@ -595,11 +639,15 @@ class Orchestrator {
|
|
|
595
639
|
}
|
|
596
640
|
// transforming before doing default fields so that we don't create a new id
|
|
597
641
|
// and anything that depends on the type of operations knows what it is
|
|
642
|
+
const userDefinedKeys = new Set();
|
|
598
643
|
for (const [fieldName, field] of schemaFields) {
|
|
599
644
|
let value = editedFields.get(fieldName);
|
|
600
645
|
let defaultValue = undefined;
|
|
601
646
|
let dbKey = this.getStorageKey(fieldName);
|
|
602
647
|
let updateOnlyIfOther = field.onlyUpdateIfOtherFieldsBeingSet_BETA;
|
|
648
|
+
if (value !== undefined) {
|
|
649
|
+
userDefinedKeys.add(dbKey);
|
|
650
|
+
}
|
|
603
651
|
if (value === undefined) {
|
|
604
652
|
if (this.actualOperation === action_1.WriteOperation.Insert) {
|
|
605
653
|
if (field.defaultToViewerOnCreate && field.defaultValueOnCreate) {
|
|
@@ -652,7 +700,7 @@ class Orchestrator {
|
|
|
652
700
|
this.options.updateInput(this.defaultFieldsByTSName);
|
|
653
701
|
}
|
|
654
702
|
}
|
|
655
|
-
return data;
|
|
703
|
+
return { data, userDefinedKeys };
|
|
656
704
|
}
|
|
657
705
|
hasData(data) {
|
|
658
706
|
for (const _k in data) {
|
package/core/ent.js
CHANGED
|
@@ -509,11 +509,12 @@ async function doFieldPrivacy(viewer, ent, data, options) {
|
|
|
509
509
|
}
|
|
510
510
|
const promises = [];
|
|
511
511
|
let somethingChanged = false;
|
|
512
|
+
const clone = { ...data };
|
|
512
513
|
const origData = {
|
|
513
514
|
...data,
|
|
514
515
|
};
|
|
515
516
|
for (const [k, policy] of options.fieldPrivacy) {
|
|
516
|
-
const curr =
|
|
517
|
+
const curr = clone[k];
|
|
517
518
|
if (curr === null || curr === undefined) {
|
|
518
519
|
continue;
|
|
519
520
|
}
|
|
@@ -521,7 +522,7 @@ async function doFieldPrivacy(viewer, ent, data, options) {
|
|
|
521
522
|
// don't do anything if key is null or for some reason missing
|
|
522
523
|
const r = await (0, privacy_1.applyPrivacyPolicy)(viewer, policy, ent);
|
|
523
524
|
if (!r) {
|
|
524
|
-
|
|
525
|
+
clone[k] = null;
|
|
525
526
|
somethingChanged = true;
|
|
526
527
|
}
|
|
527
528
|
})());
|
|
@@ -529,7 +530,7 @@ async function doFieldPrivacy(viewer, ent, data, options) {
|
|
|
529
530
|
await Promise.all(promises);
|
|
530
531
|
if (somethingChanged) {
|
|
531
532
|
// have to create new instance
|
|
532
|
-
const ent = new options.ent(viewer,
|
|
533
|
+
const ent = new options.ent(viewer, clone);
|
|
533
534
|
ent.__setRawDBData(origData);
|
|
534
535
|
return ent;
|
|
535
536
|
}
|
package/package.json
CHANGED
package/parse_schema/parse.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"
|
|
|
53
53
|
hasDefaultValueOnEdit?: boolean;
|
|
54
54
|
patternName?: string;
|
|
55
55
|
hasFieldPrivacy?: boolean;
|
|
56
|
+
hasEditFieldPrivacy?: boolean;
|
|
56
57
|
derivedFields?: ProcessedField[];
|
|
57
58
|
type: ProcessedType;
|
|
58
59
|
serverDefault?: string;
|
package/parse_schema/parse.js
CHANGED
|
@@ -26,6 +26,7 @@ async function processFields(src, patternName) {
|
|
|
26
26
|
f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
|
|
27
27
|
f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
|
|
28
28
|
f.hasFieldPrivacy = field.privacyPolicy !== undefined;
|
|
29
|
+
f.hasEditFieldPrivacy = field.editPrivacyPolicy !== undefined;
|
|
29
30
|
if (field.polymorphic) {
|
|
30
31
|
// convert boolean into object
|
|
31
32
|
// we keep boolean as an option to keep API simple
|
package/schema/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Schema from "./schema";
|
|
2
2
|
export { Schema };
|
|
3
|
-
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, ActionField, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getFieldsWithEditPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, ActionField, } from "./schema";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, SchemaConfig, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
package/schema/index.js
CHANGED
|
@@ -14,11 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.EntSchemaWithTZ = exports.EntSchema = exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = exports.getObjectLoaderProperties = exports.getTransformedReadClause = exports.SQLStatementOperation = exports.optionalField = exports.requiredField = exports.ConstraintType = exports.NoFields = exports.ActionOperation = exports.getStorageKey = exports.getFieldsWithPrivacy = exports.getFields = exports.DBType = void 0;
|
|
17
|
+
exports.EntSchemaWithTZ = exports.EntSchema = exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = exports.getObjectLoaderProperties = exports.getTransformedReadClause = exports.SQLStatementOperation = exports.optionalField = exports.requiredField = exports.ConstraintType = exports.NoFields = exports.ActionOperation = exports.getStorageKey = exports.getFieldsWithEditPrivacy = exports.getFieldsWithPrivacy = exports.getFields = exports.DBType = void 0;
|
|
18
18
|
var schema_1 = require("./schema");
|
|
19
19
|
Object.defineProperty(exports, "DBType", { enumerable: true, get: function () { return schema_1.DBType; } });
|
|
20
20
|
Object.defineProperty(exports, "getFields", { enumerable: true, get: function () { return schema_1.getFields; } });
|
|
21
21
|
Object.defineProperty(exports, "getFieldsWithPrivacy", { enumerable: true, get: function () { return schema_1.getFieldsWithPrivacy; } });
|
|
22
|
+
Object.defineProperty(exports, "getFieldsWithEditPrivacy", { enumerable: true, get: function () { return schema_1.getFieldsWithEditPrivacy; } });
|
|
22
23
|
Object.defineProperty(exports, "getStorageKey", { enumerable: true, get: function () { return schema_1.getStorageKey; } });
|
|
23
24
|
Object.defineProperty(exports, "ActionOperation", { enumerable: true, get: function () { return schema_1.ActionOperation; } });
|
|
24
25
|
Object.defineProperty(exports, "NoFields", { enumerable: true, get: function () { return schema_1.NoFields; } });
|
package/schema/schema.d.ts
CHANGED
|
@@ -234,6 +234,7 @@ export interface FieldOptions {
|
|
|
234
234
|
derivedWhenEmbedded?: boolean;
|
|
235
235
|
polymorphic?: boolean | PolymorphicOptions;
|
|
236
236
|
privacyPolicy?: PrivacyPolicy | (() => PrivacyPolicy);
|
|
237
|
+
editPrivacyPolicy?: PrivacyPolicy | (() => PrivacyPolicy);
|
|
237
238
|
getDerivedFields?(name: string): FieldMap;
|
|
238
239
|
convert?: ConvertType;
|
|
239
240
|
fetchOnDemand?: boolean;
|
|
@@ -265,7 +266,8 @@ export declare function getFields(value: SchemaInputType): Map<string, Field>;
|
|
|
265
266
|
* @deprecated should only be used by tests
|
|
266
267
|
*/
|
|
267
268
|
export declare function getStorageKey(field: Field, fieldName: string): string;
|
|
268
|
-
export declare function getFieldsWithPrivacy(value: SchemaInputType,
|
|
269
|
+
export declare function getFieldsWithPrivacy(value: SchemaInputType, fieldInfoMap: FieldInfoMap): Map<string, PrivacyPolicy>;
|
|
270
|
+
export declare function getFieldsWithEditPrivacy(value: SchemaInputType, fieldInfoMap: FieldInfoMap): Map<string, PrivacyPolicy>;
|
|
269
271
|
export declare function getTransformedReadClause(value: SchemaInputType): Clause | undefined;
|
|
270
272
|
interface objectLoaderOptions {
|
|
271
273
|
clause?: () => Clause | undefined;
|
package/schema/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ConstraintType = exports.optionalField = exports.requiredField = exports.NoFields = exports.ActionOperation = exports.getTransformedUpdateOp = exports.getObjectLoaderProperties = exports.getTransformedReadClause = exports.getFieldsWithPrivacy = exports.getStorageKey = exports.getFields = exports.getSchema = exports.DBType = exports.SQLStatementOperation = void 0;
|
|
3
|
+
exports.ConstraintType = exports.optionalField = exports.requiredField = exports.NoFields = exports.ActionOperation = exports.getTransformedUpdateOp = exports.getObjectLoaderProperties = exports.getTransformedReadClause = exports.getFieldsWithEditPrivacy = exports.getFieldsWithPrivacy = exports.getStorageKey = exports.getFields = exports.getSchema = exports.DBType = exports.SQLStatementOperation = void 0;
|
|
4
4
|
const snake_case_1 = require("snake-case");
|
|
5
5
|
// we also want this transformation to exist on a per-action basis
|
|
6
6
|
// if it exists on an action, we don't do the global schema transformation
|
|
@@ -85,49 +85,31 @@ function getStorageKey(field, fieldName) {
|
|
|
85
85
|
}
|
|
86
86
|
exports.getStorageKey = getStorageKey;
|
|
87
87
|
// returns a mapping of storage key to field privacy
|
|
88
|
-
function getFieldsWithPrivacy(value,
|
|
88
|
+
function getFieldsWithPrivacy(value, fieldInfoMap) {
|
|
89
|
+
return getFieldsWithPrivacyImpl(value, fieldInfoMap, "privacyPolicy");
|
|
90
|
+
}
|
|
91
|
+
exports.getFieldsWithPrivacy = getFieldsWithPrivacy;
|
|
92
|
+
function getFieldsWithEditPrivacy(value, fieldInfoMap) {
|
|
93
|
+
return getFieldsWithPrivacyImpl(value, fieldInfoMap, "editPrivacyPolicy");
|
|
94
|
+
}
|
|
95
|
+
exports.getFieldsWithEditPrivacy = getFieldsWithEditPrivacy;
|
|
96
|
+
function getFieldsWithPrivacyImpl(value, fieldInfoMap, key) {
|
|
89
97
|
const schema = getSchema(value);
|
|
90
98
|
function addFields(fields) {
|
|
91
|
-
if (Array.isArray(fields)) {
|
|
92
|
-
for (const field of fields) {
|
|
93
|
-
const name = field.name;
|
|
94
|
-
if (!field.name) {
|
|
95
|
-
throw new Error(`name required`);
|
|
96
|
-
}
|
|
97
|
-
if (field.getDerivedFields !== undefined) {
|
|
98
|
-
addFields(field.getDerivedFields(name));
|
|
99
|
-
}
|
|
100
|
-
if (field.privacyPolicy) {
|
|
101
|
-
let privacyPolicy;
|
|
102
|
-
if (typeof field.privacyPolicy === "function") {
|
|
103
|
-
privacyPolicy = field.privacyPolicy();
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
privacyPolicy = field.privacyPolicy;
|
|
107
|
-
}
|
|
108
|
-
const info = fieldMap[name];
|
|
109
|
-
if (!info) {
|
|
110
|
-
throw new Error(`field with name ${name} not passed in fieldMap`);
|
|
111
|
-
}
|
|
112
|
-
m.set(info.dbCol, privacyPolicy);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
99
|
for (const name in fields) {
|
|
118
100
|
const field = fields[name];
|
|
101
|
+
if (field.dbOnly) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
119
104
|
if (field.getDerivedFields !== undefined) {
|
|
120
105
|
addFields(field.getDerivedFields(name));
|
|
121
106
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (typeof
|
|
125
|
-
privacyPolicy =
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
privacyPolicy = field.privacyPolicy;
|
|
107
|
+
let privacyPolicy = field[key];
|
|
108
|
+
if (privacyPolicy) {
|
|
109
|
+
if (typeof privacyPolicy === "function") {
|
|
110
|
+
privacyPolicy = privacyPolicy();
|
|
129
111
|
}
|
|
130
|
-
const info =
|
|
112
|
+
const info = fieldInfoMap[name];
|
|
131
113
|
if (!info) {
|
|
132
114
|
throw new Error(`field with name ${name} not passed in fieldMap`);
|
|
133
115
|
}
|
|
@@ -144,7 +126,6 @@ function getFieldsWithPrivacy(value, fieldMap) {
|
|
|
144
126
|
addFields(schema.fields);
|
|
145
127
|
return m;
|
|
146
128
|
}
|
|
147
|
-
exports.getFieldsWithPrivacy = getFieldsWithPrivacy;
|
|
148
129
|
function getTransformedReadClause(value) {
|
|
149
130
|
const schema = getSchema(value);
|
|
150
131
|
if (!schema.patterns) {
|