@snowtop/ent 0.0.39 → 0.0.40-alpha5
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 +13 -12
- package/core/base.d.ts +3 -1
- package/core/config.d.ts +5 -0
- package/core/config.js +5 -0
- package/core/db.d.ts +3 -3
- package/core/db.js +2 -0
- package/core/ent.d.ts +0 -2
- package/core/ent.js +51 -17
- package/core/loaders/object_loader.d.ts +6 -2
- package/core/loaders/object_loader.js +41 -4
- package/index.d.ts +1 -1
- package/index.js +3 -5
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +2 -1
- package/parse_schema/parse.js +1 -0
- package/schema/index.d.ts +1 -1
- package/schema/index.js +3 -1
- package/schema/schema.d.ts +9 -1
- package/schema/schema.js +44 -1
- package/testutils/builder.js +18 -2
- package/testutils/db/test_db.d.ts +2 -1
- package/testutils/db/test_db.js +13 -4
package/action/orchestrator.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface OrchestratorOptions<T extends Ent, TData extends Data> {
|
|
|
12
12
|
builder: Builder<T>;
|
|
13
13
|
action?: Action<T>;
|
|
14
14
|
schema: SchemaInputType;
|
|
15
|
-
editedFields(): Map<string, any
|
|
15
|
+
editedFields(): Map<string, any> | Promise<Map<string, any>>;
|
|
16
16
|
updateInput?: (data: TData) => void;
|
|
17
17
|
}
|
|
18
18
|
interface edgeInputDataOpts {
|
package/action/orchestrator.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.EntChangeset = exports.Orchestrator = exports.edgeDirection = void 0;
|
|
|
4
4
|
const ent_1 = require("../core/ent");
|
|
5
5
|
const schema_1 = require("../schema/schema");
|
|
6
6
|
const action_1 = require("../action");
|
|
7
|
-
const snake_case_1 = require("snake-case");
|
|
8
7
|
const camel_case_1 = require("camel-case");
|
|
9
8
|
const privacy_1 = require("../core/privacy");
|
|
10
9
|
const executor_1 = require("./executor");
|
|
@@ -277,7 +276,8 @@ class Orchestrator {
|
|
|
277
276
|
const builder = this.options.builder;
|
|
278
277
|
// future optimization: can get schemaFields to memoize based on different values
|
|
279
278
|
const schemaFields = (0, schema_1.getFields)(this.options.schema);
|
|
280
|
-
|
|
279
|
+
const editedFields = await this.options.editedFields();
|
|
280
|
+
let editedData = await this.getFieldsWithDefaultValues(builder, schemaFields, editedFields, action);
|
|
281
281
|
// this runs in following phases:
|
|
282
282
|
// * set default fields and pass to builder so the value can be checked by triggers/observers/validators
|
|
283
283
|
// * privacy policy (use unsafe ent if we have it)
|
|
@@ -294,8 +294,11 @@ class Orchestrator {
|
|
|
294
294
|
await this.triggers(action, builder, triggers);
|
|
295
295
|
}
|
|
296
296
|
let validators = action?.validators || [];
|
|
297
|
+
// not ideal we're calling this twice. fix...
|
|
298
|
+
// needed for now. may need to write somet of this?
|
|
299
|
+
const editedFields2 = await this.options.editedFields();
|
|
297
300
|
await Promise.all([
|
|
298
|
-
this.formatAndValidateFields(schemaFields),
|
|
301
|
+
this.formatAndValidateFields(schemaFields, editedFields2),
|
|
299
302
|
this.validators(validators, action, builder),
|
|
300
303
|
]);
|
|
301
304
|
}
|
|
@@ -330,8 +333,7 @@ class Orchestrator {
|
|
|
330
333
|
isBuilder(val) {
|
|
331
334
|
return val.placeholderID !== undefined;
|
|
332
335
|
}
|
|
333
|
-
async getFieldsWithDefaultValues(builder, schemaFields, action) {
|
|
334
|
-
const editedFields = this.options.editedFields();
|
|
336
|
+
async getFieldsWithDefaultValues(builder, schemaFields, editedFields, action) {
|
|
335
337
|
let data = {};
|
|
336
338
|
let defaultData = {};
|
|
337
339
|
let input = action?.getInput() || {};
|
|
@@ -369,12 +371,12 @@ class Orchestrator {
|
|
|
369
371
|
if (field.format) {
|
|
370
372
|
val = field.format(transformed.data[k]);
|
|
371
373
|
}
|
|
372
|
-
let dbKey =
|
|
374
|
+
let dbKey = (0, schema_1.getStorageKey)(field);
|
|
373
375
|
data[dbKey] = val;
|
|
374
376
|
this.defaultFieldsByTSName[(0, camel_case_1.camelCase)(k)] = val;
|
|
375
377
|
// hmm do we need this?
|
|
376
378
|
// TODO how to do this for local tests?
|
|
377
|
-
//
|
|
379
|
+
// this.defaultFieldsByFieldName[k] = val;
|
|
378
380
|
}
|
|
379
381
|
}
|
|
380
382
|
this.actualOperation = this.getWriteOpForSQLStamentOp(transformed.op);
|
|
@@ -387,7 +389,7 @@ class Orchestrator {
|
|
|
387
389
|
for (const [fieldName, field] of schemaFields) {
|
|
388
390
|
let value = editedFields.get(fieldName);
|
|
389
391
|
let defaultValue = undefined;
|
|
390
|
-
let dbKey =
|
|
392
|
+
let dbKey = (0, schema_1.getStorageKey)(field);
|
|
391
393
|
if (value === undefined) {
|
|
392
394
|
if (this.actualOperation === action_1.WriteOperation.Insert) {
|
|
393
395
|
if (field.defaultToViewerOnCreate && field.defaultValueOnCreate) {
|
|
@@ -483,12 +485,11 @@ class Orchestrator {
|
|
|
483
485
|
}
|
|
484
486
|
return value;
|
|
485
487
|
}
|
|
486
|
-
async formatAndValidateFields(schemaFields) {
|
|
488
|
+
async formatAndValidateFields(schemaFields, editedFields) {
|
|
487
489
|
const op = this.actualOperation;
|
|
488
490
|
if (op === action_1.WriteOperation.Delete) {
|
|
489
491
|
return;
|
|
490
492
|
}
|
|
491
|
-
const editedFields = this.options.editedFields();
|
|
492
493
|
// build up data to be saved...
|
|
493
494
|
let data = {};
|
|
494
495
|
let logValues = {};
|
|
@@ -498,7 +499,7 @@ class Orchestrator {
|
|
|
498
499
|
// null allowed
|
|
499
500
|
value = this.defaultFieldsByFieldName[fieldName];
|
|
500
501
|
}
|
|
501
|
-
let dbKey =
|
|
502
|
+
let dbKey = (0, schema_1.getStorageKey)(field);
|
|
502
503
|
value = await this.transformFieldValue(field, dbKey, value);
|
|
503
504
|
if (value !== undefined) {
|
|
504
505
|
data[dbKey] = value;
|
|
@@ -511,7 +512,7 @@ class Orchestrator {
|
|
|
511
512
|
for (const fieldName in this.defaultFieldsByFieldName) {
|
|
512
513
|
const defaultValue = this.defaultFieldsByFieldName[fieldName];
|
|
513
514
|
let field = schemaFields.get(fieldName);
|
|
514
|
-
let dbKey =
|
|
515
|
+
let dbKey = (0, schema_1.getStorageKey)(field);
|
|
515
516
|
// no value, let's just default
|
|
516
517
|
if (data[dbKey] === undefined) {
|
|
517
518
|
const value = await this.transformFieldValue(field, dbKey, defaultValue);
|
package/core/base.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export interface SelectBaseDataOptions extends DataOptions {
|
|
|
62
62
|
}
|
|
63
63
|
export interface SelectDataOptions extends SelectBaseDataOptions {
|
|
64
64
|
key: string;
|
|
65
|
-
clause?: clause.Clause;
|
|
65
|
+
clause?: clause.Clause | (() => clause.Clause | undefined);
|
|
66
66
|
}
|
|
67
67
|
export interface QueryableDataOptions extends SelectBaseDataOptions, QueryDataOptions {
|
|
68
68
|
}
|
|
@@ -89,9 +89,11 @@ interface LoadableEntOptions<T extends Ent> {
|
|
|
89
89
|
ent: EntConstructor<T>;
|
|
90
90
|
}
|
|
91
91
|
export interface LoadEntOptions<T extends Ent> extends LoadableEntOptions<T>, SelectBaseDataOptions {
|
|
92
|
+
fieldPrivacy?: Map<string, PrivacyPolicy>;
|
|
92
93
|
}
|
|
93
94
|
export interface LoadCustomEntOptions<T extends Ent> extends SelectBaseDataOptions {
|
|
94
95
|
ent: EntConstructor<T>;
|
|
96
|
+
fieldPrivacy?: Map<string, PrivacyPolicy>;
|
|
95
97
|
}
|
|
96
98
|
export interface LoaderInfo {
|
|
97
99
|
tableName: string;
|
package/core/config.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ declare enum graphQLFieldFormat {
|
|
|
9
9
|
LOWER_CAMEL = "lowerCamel",
|
|
10
10
|
SNAKE_CASE = "snake_case"
|
|
11
11
|
}
|
|
12
|
+
declare enum fieldPrivacyEvaluated {
|
|
13
|
+
AT_ENT_LOAD = "at_ent_load",
|
|
14
|
+
ON_DEMAND = "on_demand"
|
|
15
|
+
}
|
|
12
16
|
export interface Config {
|
|
13
17
|
dbConnectionString?: string;
|
|
14
18
|
dbFile?: string;
|
|
@@ -30,6 +34,7 @@ interface CodegenConfig {
|
|
|
30
34
|
defaultGraphQLFieldFormat?: graphQLFieldFormat;
|
|
31
35
|
schemaSQLFilePath?: boolean;
|
|
32
36
|
databaseToCompareTo?: string;
|
|
37
|
+
fieldPrivacyEvaluated?: fieldPrivacyEvaluated;
|
|
33
38
|
}
|
|
34
39
|
interface PrettierConfig {
|
|
35
40
|
custom?: boolean;
|
package/core/config.js
CHANGED
|
@@ -40,6 +40,11 @@ var graphQLFieldFormat;
|
|
|
40
40
|
graphQLFieldFormat["LOWER_CAMEL"] = "lowerCamel";
|
|
41
41
|
graphQLFieldFormat["SNAKE_CASE"] = "snake_case";
|
|
42
42
|
})(graphQLFieldFormat || (graphQLFieldFormat = {}));
|
|
43
|
+
var fieldPrivacyEvaluated;
|
|
44
|
+
(function (fieldPrivacyEvaluated) {
|
|
45
|
+
fieldPrivacyEvaluated["AT_ENT_LOAD"] = "at_ent_load";
|
|
46
|
+
fieldPrivacyEvaluated["ON_DEMAND"] = "on_demand";
|
|
47
|
+
})(fieldPrivacyEvaluated || (fieldPrivacyEvaluated = {}));
|
|
43
48
|
function setConfig(cfg) {
|
|
44
49
|
if (cfg.log) {
|
|
45
50
|
(0, logger_1.setLogLevels)(cfg.log);
|
package/core/db.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Pool,
|
|
2
|
-
export interface Database {
|
|
1
|
+
import { Pool, PoolClient, PoolConfig } from "pg";
|
|
2
|
+
export interface Database extends PoolConfig {
|
|
3
3
|
database?: string;
|
|
4
4
|
user?: string;
|
|
5
5
|
password?: string;
|
|
@@ -16,7 +16,7 @@ export declare enum Dialect {
|
|
|
16
16
|
}
|
|
17
17
|
interface DatabaseInfo {
|
|
18
18
|
dialect: Dialect;
|
|
19
|
-
config:
|
|
19
|
+
config: PoolConfig;
|
|
20
20
|
filePath?: string;
|
|
21
21
|
}
|
|
22
22
|
export default class DB {
|
package/core/db.js
CHANGED
package/core/ent.d.ts
CHANGED
|
@@ -22,8 +22,6 @@ export declare type CustomQuery = string | rawQueryOptions | clause.Clause | Que
|
|
|
22
22
|
export declare function loadCustomData(options: SelectBaseDataOptions, query: CustomQuery, context: Context | undefined): Promise<Data[]>;
|
|
23
23
|
export declare function loadDerivedEnt<T extends Ent>(viewer: Viewer, data: Data, loader: new (viewer: Viewer, data: Data) => T): Promise<T | null>;
|
|
24
24
|
export declare function loadDerivedEntX<T extends Ent>(viewer: Viewer, data: Data, loader: new (viewer: Viewer, data: Data) => T): Promise<T>;
|
|
25
|
-
export declare function applyPrivacyPolicyForEnt<T extends Ent>(viewer: Viewer, ent: T | null): Promise<T | null>;
|
|
26
|
-
export declare function applyPrivacyPolicyForEntX<T extends Ent>(viewer: Viewer, ent: T): Promise<T>;
|
|
27
25
|
export declare function loadRowX(options: LoadRowOptions): Promise<Data>;
|
|
28
26
|
export declare function loadRow(options: LoadRowOptions): Promise<Data | null>;
|
|
29
27
|
export declare function performRawQuery(query: string, values: any[], logValues?: any[]): Promise<Data[]>;
|
package/core/ent.js
CHANGED
|
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.getEdgeTypeInGroup = exports.applyPrivacyPolicyForRows = exports.applyPrivacyPolicyForRowX = exports.applyPrivacyPolicyForRow = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadCustomEdges = exports.loadEdges = exports.defaultEdgeQueryOptions = exports.DefaultLimit = exports.loadEdgeDatas = exports.loadEdgeData = exports.assocEdgeLoader = exports.AssocEdgeData = exports.getCursor = exports.AssocEdge = exports.DeleteNodeOperation = exports.deleteRowsSync = exports.deleteRows = exports.editRowSync = exports.editRow = exports.buildUpdateQuery = exports.createRowSync = exports.createRow = exports.buildInsertQuery = exports.EdgeOperation = exports.EditNodeOperation = exports.buildGroupQuery = exports.buildQuery = exports.loadRows = exports.performRawQuery = exports.loadRow = exports.loadRowX = exports.
|
|
25
|
+
exports.getEdgeTypeInGroup = exports.applyPrivacyPolicyForRows = exports.applyPrivacyPolicyForRowX = exports.applyPrivacyPolicyForRow = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadCustomEdges = exports.loadEdges = exports.defaultEdgeQueryOptions = exports.DefaultLimit = exports.loadEdgeDatas = exports.loadEdgeData = exports.assocEdgeLoader = exports.AssocEdgeData = exports.getCursor = exports.AssocEdge = exports.DeleteNodeOperation = exports.deleteRowsSync = exports.deleteRows = exports.editRowSync = exports.editRow = exports.buildUpdateQuery = exports.createRowSync = exports.createRow = exports.buildInsertQuery = exports.EdgeOperation = exports.EditNodeOperation = exports.buildGroupQuery = exports.buildQuery = exports.loadRows = exports.performRawQuery = exports.loadRow = exports.loadRowX = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadCustomData = exports.loadCustomEnts = exports.loadEntsFromClause = exports.loadEnts = exports.loadEntXFromClause = exports.loadEntFromClause = exports.loadEntXViaKey = exports.loadEntX = exports.loadEntViaKey = exports.loadEnt = void 0;
|
|
26
26
|
const db_1 = __importStar(require("./db"));
|
|
27
27
|
const privacy_1 = require("./privacy");
|
|
28
28
|
const clause = __importStar(require("./clause"));
|
|
@@ -139,8 +139,7 @@ async function loadEntXFromClause(viewer, options, clause) {
|
|
|
139
139
|
context: viewer.context,
|
|
140
140
|
};
|
|
141
141
|
const row = await loadRowX(rowOptions);
|
|
142
|
-
|
|
143
|
-
return await applyPrivacyPolicyForEntX(viewer, ent);
|
|
142
|
+
return await applyPrivacyPolicyForRowX(viewer, options, row);
|
|
144
143
|
}
|
|
145
144
|
exports.loadEntXFromClause = loadEntXFromClause;
|
|
146
145
|
async function loadEnts(viewer, options, ...ids) {
|
|
@@ -207,7 +206,7 @@ async function loadCustomEnts(viewer, options, query) {
|
|
|
207
206
|
const result = new Array(rows.length);
|
|
208
207
|
await Promise.all(rows.map(async (row, idx) => {
|
|
209
208
|
const ent = new options.ent(viewer, row);
|
|
210
|
-
let privacyEnt = await applyPrivacyPolicyForEnt(viewer, ent);
|
|
209
|
+
let privacyEnt = await applyPrivacyPolicyForEnt(viewer, ent, row, options);
|
|
211
210
|
if (privacyEnt) {
|
|
212
211
|
result[idx] = privacyEnt;
|
|
213
212
|
}
|
|
@@ -253,30 +252,55 @@ exports.loadCustomData = loadCustomData;
|
|
|
253
252
|
// Derived ents
|
|
254
253
|
async function loadDerivedEnt(viewer, data, loader) {
|
|
255
254
|
const ent = new loader(viewer, data);
|
|
256
|
-
return await applyPrivacyPolicyForEnt(viewer, ent
|
|
255
|
+
return await applyPrivacyPolicyForEnt(viewer, ent, data, {
|
|
256
|
+
ent: loader,
|
|
257
|
+
});
|
|
257
258
|
}
|
|
258
259
|
exports.loadDerivedEnt = loadDerivedEnt;
|
|
259
260
|
async function loadDerivedEntX(viewer, data, loader) {
|
|
260
261
|
const ent = new loader(viewer, data);
|
|
261
|
-
return await applyPrivacyPolicyForEntX(viewer, ent);
|
|
262
|
+
return await applyPrivacyPolicyForEntX(viewer, ent, data, { ent: loader });
|
|
262
263
|
}
|
|
263
264
|
exports.loadDerivedEntX = loadDerivedEntX;
|
|
264
|
-
|
|
265
|
+
// everything calls into this two so should be fine
|
|
266
|
+
// TODO is there a smarter way to not instantiate two objects here?
|
|
267
|
+
async function applyPrivacyPolicyForEnt(viewer, ent, data, fieldPrivacyOptions) {
|
|
265
268
|
if (ent) {
|
|
266
269
|
const visible = await (0, privacy_1.applyPrivacyPolicy)(viewer, ent.privacyPolicy, ent);
|
|
267
|
-
if (visible) {
|
|
268
|
-
return
|
|
270
|
+
if (!visible) {
|
|
271
|
+
return null;
|
|
269
272
|
}
|
|
273
|
+
return doFieldPrivacy(viewer, ent, data, fieldPrivacyOptions);
|
|
270
274
|
}
|
|
271
275
|
return null;
|
|
272
276
|
}
|
|
273
|
-
|
|
274
|
-
async function applyPrivacyPolicyForEntX(viewer, ent) {
|
|
277
|
+
async function applyPrivacyPolicyForEntX(viewer, ent, data, options) {
|
|
275
278
|
// this will throw
|
|
276
279
|
await (0, privacy_1.applyPrivacyPolicyX)(viewer, ent.privacyPolicy, ent);
|
|
280
|
+
return doFieldPrivacy(viewer, ent, data, options);
|
|
281
|
+
}
|
|
282
|
+
async function doFieldPrivacy(viewer, ent, data, options) {
|
|
283
|
+
if (!options.fieldPrivacy) {
|
|
284
|
+
return ent;
|
|
285
|
+
}
|
|
286
|
+
const promises = [];
|
|
287
|
+
let somethingChanged = false;
|
|
288
|
+
for (const [k, policy] of options.fieldPrivacy) {
|
|
289
|
+
promises.push((async () => {
|
|
290
|
+
const r = await (0, privacy_1.applyPrivacyPolicy)(viewer, policy, ent);
|
|
291
|
+
if (!r) {
|
|
292
|
+
data[k] = null;
|
|
293
|
+
somethingChanged = true;
|
|
294
|
+
}
|
|
295
|
+
})());
|
|
296
|
+
}
|
|
297
|
+
await Promise.all(promises);
|
|
298
|
+
if (somethingChanged) {
|
|
299
|
+
// have to create new instance
|
|
300
|
+
return new options.ent(viewer, data);
|
|
301
|
+
}
|
|
277
302
|
return ent;
|
|
278
303
|
}
|
|
279
|
-
exports.applyPrivacyPolicyForEntX = applyPrivacyPolicyForEntX;
|
|
280
304
|
function logQuery(query, logValues) {
|
|
281
305
|
(0, logger_1.log)("query", {
|
|
282
306
|
query: query,
|
|
@@ -322,6 +346,8 @@ async function loadRow(options) {
|
|
|
322
346
|
return res.rows[0];
|
|
323
347
|
}
|
|
324
348
|
catch (e) {
|
|
349
|
+
// an example of an error being suppressed
|
|
350
|
+
// another one. TODO https://github.com/lolopinto/ent/issues/862
|
|
325
351
|
(0, logger_1.log)("error", e);
|
|
326
352
|
return null;
|
|
327
353
|
}
|
|
@@ -453,7 +479,16 @@ class EditNodeOperation {
|
|
|
453
479
|
const opts = loader.getOptions();
|
|
454
480
|
let cls = clause.Eq(options.key, id);
|
|
455
481
|
if (opts.clause) {
|
|
456
|
-
|
|
482
|
+
let optionClause;
|
|
483
|
+
if (typeof opts.clause === "function") {
|
|
484
|
+
optionClause = opts.clause();
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
optionClause = opts.clause;
|
|
488
|
+
}
|
|
489
|
+
if (optionClause) {
|
|
490
|
+
cls = clause.And(optionClause, cls);
|
|
491
|
+
}
|
|
457
492
|
}
|
|
458
493
|
const query = buildQuery({
|
|
459
494
|
fields: opts.fields.length ? opts.fields : ["*"],
|
|
@@ -1150,20 +1185,19 @@ async function applyPrivacyPolicyForRow(viewer, options, row) {
|
|
|
1150
1185
|
return null;
|
|
1151
1186
|
}
|
|
1152
1187
|
const ent = new options.ent(viewer, row);
|
|
1153
|
-
return await applyPrivacyPolicyForEnt(viewer, ent);
|
|
1188
|
+
return await applyPrivacyPolicyForEnt(viewer, ent, row, options);
|
|
1154
1189
|
}
|
|
1155
1190
|
exports.applyPrivacyPolicyForRow = applyPrivacyPolicyForRow;
|
|
1156
1191
|
async function applyPrivacyPolicyForRowX(viewer, options, row) {
|
|
1157
1192
|
const ent = new options.ent(viewer, row);
|
|
1158
|
-
return await applyPrivacyPolicyForEntX(viewer, ent);
|
|
1193
|
+
return await applyPrivacyPolicyForEntX(viewer, ent, row, options);
|
|
1159
1194
|
}
|
|
1160
1195
|
exports.applyPrivacyPolicyForRowX = applyPrivacyPolicyForRowX;
|
|
1161
1196
|
async function applyPrivacyPolicyForRows(viewer, rows, options) {
|
|
1162
1197
|
let m = new Map();
|
|
1163
1198
|
// apply privacy logic
|
|
1164
1199
|
await Promise.all(rows.map(async (row) => {
|
|
1165
|
-
|
|
1166
|
-
let privacyEnt = await applyPrivacyPolicyForEnt(viewer, ent);
|
|
1200
|
+
let privacyEnt = await applyPrivacyPolicyForRow(viewer, options, row);
|
|
1167
1201
|
if (privacyEnt) {
|
|
1168
1202
|
m.set(privacyEnt.id, privacyEnt);
|
|
1169
1203
|
}
|
|
@@ -14,11 +14,15 @@ export declare class ObjectLoader<T> implements Loader<T, Data | null> {
|
|
|
14
14
|
loadMany(keys: T[]): Promise<Data[]>;
|
|
15
15
|
prime(data: Data): void;
|
|
16
16
|
}
|
|
17
|
+
interface ObjectLoaderOptions extends SelectDataOptions {
|
|
18
|
+
instanceKey?: string;
|
|
19
|
+
}
|
|
17
20
|
export declare class ObjectLoaderFactory<T> implements LoaderFactory<T, Data | null> {
|
|
18
|
-
options:
|
|
21
|
+
options: ObjectLoaderOptions;
|
|
19
22
|
name: string;
|
|
20
23
|
private toPrime;
|
|
21
|
-
constructor(options:
|
|
24
|
+
constructor(options: ObjectLoaderOptions);
|
|
22
25
|
createLoader(context?: Context): ObjectLoader<T>;
|
|
23
26
|
addToPrime(factory: ObjectLoaderFactory<T>): void;
|
|
24
27
|
}
|
|
28
|
+
export {};
|
|
@@ -45,7 +45,16 @@ function createDataLoader(options) {
|
|
|
45
45
|
let col = options.key;
|
|
46
46
|
let cls = clause.In(col, ...ids);
|
|
47
47
|
if (options.clause) {
|
|
48
|
-
|
|
48
|
+
let optionClause;
|
|
49
|
+
if (typeof options.clause === "function") {
|
|
50
|
+
optionClause = options.clause();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
optionClause = options.clause;
|
|
54
|
+
}
|
|
55
|
+
if (optionClause) {
|
|
56
|
+
cls = clause.And(optionClause, cls);
|
|
57
|
+
}
|
|
49
58
|
}
|
|
50
59
|
const rowOptions = {
|
|
51
60
|
...options,
|
|
@@ -119,7 +128,16 @@ class ObjectLoader {
|
|
|
119
128
|
}
|
|
120
129
|
let cls = clause.Eq(this.options.key, key);
|
|
121
130
|
if (this.options.clause) {
|
|
122
|
-
|
|
131
|
+
let optionClause;
|
|
132
|
+
if (typeof this.options.clause === "function") {
|
|
133
|
+
optionClause = this.options.clause();
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
optionClause = this.options.clause;
|
|
137
|
+
}
|
|
138
|
+
if (optionClause) {
|
|
139
|
+
cls = clause.And(optionClause, cls);
|
|
140
|
+
}
|
|
123
141
|
}
|
|
124
142
|
const rowOptions = {
|
|
125
143
|
...this.options,
|
|
@@ -137,7 +155,16 @@ class ObjectLoader {
|
|
|
137
155
|
}
|
|
138
156
|
let cls = clause.In(this.options.key, ...keys);
|
|
139
157
|
if (this.options.clause) {
|
|
140
|
-
|
|
158
|
+
let optionClause;
|
|
159
|
+
if (typeof this.options.clause === "function") {
|
|
160
|
+
optionClause = this.options.clause();
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
optionClause = this.options.clause;
|
|
164
|
+
}
|
|
165
|
+
if (optionClause) {
|
|
166
|
+
cls = clause.And(optionClause, cls);
|
|
167
|
+
}
|
|
141
168
|
}
|
|
142
169
|
const rowOptions = {
|
|
143
170
|
...this.options,
|
|
@@ -160,7 +187,17 @@ class ObjectLoaderFactory {
|
|
|
160
187
|
constructor(options) {
|
|
161
188
|
this.options = options;
|
|
162
189
|
this.toPrime = [];
|
|
163
|
-
|
|
190
|
+
// we don't wanna do it here because we want it to be delayed
|
|
191
|
+
let instanceKey = "";
|
|
192
|
+
if (typeof this.options.clause === "function") {
|
|
193
|
+
if (!options.instanceKey) {
|
|
194
|
+
throw new Error(`need to pass an instanceKey to ObjectLoader if clause is a function`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else if (this.options.clause) {
|
|
198
|
+
instanceKey = this.options.clause.instanceKey();
|
|
199
|
+
}
|
|
200
|
+
this.name = `${options.tableName}:${options.key}:${instanceKey}`;
|
|
164
201
|
}
|
|
165
202
|
createLoader(context) {
|
|
166
203
|
return (0, loader_1.getLoader)(this, () => {
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./core/base";
|
|
2
|
-
export { loadEnt, loadCustomData, loadCustomEnts, loadEntX, loadEnts, CustomQuery, loadDerivedEnt, loadDerivedEntX, loadEntViaKey, loadEntXViaKey,
|
|
2
|
+
export { loadEnt, loadCustomData, loadCustomEnts, loadEntX, loadEnts, CustomQuery, loadDerivedEnt, loadDerivedEntX, loadEntViaKey, loadEntXViaKey, performRawQuery, loadRowX, loadRow, loadRows, DataOperation, EditNodeOptions, EditNodeOperation, EdgeOperation, DeleteNodeOperation, AssocEdge, AssocEdgeInputOptions, AssocEdgeInput, AssocEdgeData, loadEdgeData, loadEdgeDatas, loadEdges, loadUniqueEdge, loadUniqueNode, loadRawEdgeCountX, loadEdgeForID2, loadNodesByEdge, getEdgeTypeInGroup, } from "./core/ent";
|
|
3
3
|
import DB from "./core/db";
|
|
4
4
|
export * from "./core/loaders";
|
|
5
5
|
export { DB };
|
package/index.js
CHANGED
|
@@ -25,8 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.DeleteNodeOperation = exports.EdgeOperation = exports.EditNodeOperation = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.
|
|
29
|
-
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule =
|
|
28
|
+
exports.DenyIfViewerInboundEdgeDoesNotExistRule = exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.DeleteNodeOperation = exports.EdgeOperation = exports.EditNodeOperation = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.loadEntXViaKey = exports.loadEntViaKey = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadEnts = exports.loadEntX = exports.loadCustomEnts = exports.loadCustomData = exports.loadEnt = void 0;
|
|
29
|
+
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = void 0;
|
|
30
30
|
__exportStar(require("./core/base"), exports);
|
|
31
31
|
var ent_1 = require("./core/ent");
|
|
32
32
|
Object.defineProperty(exports, "loadEnt", { enumerable: true, get: function () { return ent_1.loadEnt; } });
|
|
@@ -38,8 +38,6 @@ Object.defineProperty(exports, "loadDerivedEnt", { enumerable: true, get: functi
|
|
|
38
38
|
Object.defineProperty(exports, "loadDerivedEntX", { enumerable: true, get: function () { return ent_1.loadDerivedEntX; } });
|
|
39
39
|
Object.defineProperty(exports, "loadEntViaKey", { enumerable: true, get: function () { return ent_1.loadEntViaKey; } });
|
|
40
40
|
Object.defineProperty(exports, "loadEntXViaKey", { enumerable: true, get: function () { return ent_1.loadEntXViaKey; } });
|
|
41
|
-
Object.defineProperty(exports, "applyPrivacyPolicyForEnt", { enumerable: true, get: function () { return ent_1.applyPrivacyPolicyForEnt; } });
|
|
42
|
-
Object.defineProperty(exports, "applyPrivacyPolicyForEntX", { enumerable: true, get: function () { return ent_1.applyPrivacyPolicyForEntX; } });
|
|
43
41
|
Object.defineProperty(exports, "performRawQuery", { enumerable: true, get: function () { return ent_1.performRawQuery; } });
|
|
44
42
|
// even these 3 need to change...
|
|
45
43
|
Object.defineProperty(exports, "loadRowX", { enumerable: true, get: function () { return ent_1.loadRowX; } });
|
|
@@ -62,7 +60,7 @@ Object.defineProperty(exports, "getEdgeTypeInGroup", { enumerable: true, get: fu
|
|
|
62
60
|
const db_1 = __importDefault(require("./core/db"));
|
|
63
61
|
exports.DB = db_1.default;
|
|
64
62
|
__exportStar(require("./core/loaders"), exports);
|
|
65
|
-
// TODO figure out if this should be its own
|
|
63
|
+
// TODO figure out if this should be its own import path e.g. @snowtop/ent/privacy
|
|
66
64
|
var privacy_1 = require("./core/privacy");
|
|
67
65
|
Object.defineProperty(exports, "EntPrivacyError", { enumerable: true, get: function () { return privacy_1.EntPrivacyError; } });
|
|
68
66
|
Object.defineProperty(exports, "AlwaysAllowRule", { enumerable: true, get: function () { return privacy_1.AlwaysAllowRule; } });
|
package/package.json
CHANGED
package/parse_schema/parse.d.ts
CHANGED
|
@@ -38,10 +38,11 @@ interface ProcessedPattern {
|
|
|
38
38
|
assocEdges: ProcessedAssocEdge[];
|
|
39
39
|
fields: ProcessedField[];
|
|
40
40
|
}
|
|
41
|
-
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"> & {
|
|
41
|
+
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate" | "privacyPolicy"> & {
|
|
42
42
|
hasDefaultValueOnCreate?: boolean;
|
|
43
43
|
hasDefaultValueOnEdit?: boolean;
|
|
44
44
|
patternName?: string;
|
|
45
|
+
hasFieldPrivacy?: boolean;
|
|
45
46
|
};
|
|
46
47
|
interface patternsDict {
|
|
47
48
|
[key: string]: ProcessedPattern;
|
package/parse_schema/parse.js
CHANGED
|
@@ -7,6 +7,7 @@ function processFields(src, patternName) {
|
|
|
7
7
|
let f = { ...field };
|
|
8
8
|
f.hasDefaultValueOnCreate = field.defaultValueOnCreate != undefined;
|
|
9
9
|
f.hasDefaultValueOnEdit = field.defaultValueOnEdit != undefined;
|
|
10
|
+
f.hasFieldPrivacy = field.privacyPolicy !== undefined;
|
|
10
11
|
if (field.polymorphic) {
|
|
11
12
|
// convert boolean into object
|
|
12
13
|
// 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, ActionOperation, Action, EdgeAction, NoFields, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, getTransformedReadClause, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, ActionOperation, Action, EdgeAction, NoFields, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, getTransformedReadClause, getObjectLoaderProperties, } from "./schema";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
package/schema/index.js
CHANGED
|
@@ -10,10 +10,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
10
10
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = exports.getTransformedReadClause = exports.SQLStatementOperation = exports.optionalField = exports.requiredField = exports.ConstraintType = exports.NoFields = exports.ActionOperation = exports.getFields = exports.DBType = void 0;
|
|
13
|
+
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.getFieldsWithPrivacy = exports.getFields = exports.DBType = void 0;
|
|
14
14
|
var schema_1 = require("./schema");
|
|
15
15
|
Object.defineProperty(exports, "DBType", { enumerable: true, get: function () { return schema_1.DBType; } });
|
|
16
16
|
Object.defineProperty(exports, "getFields", { enumerable: true, get: function () { return schema_1.getFields; } });
|
|
17
|
+
Object.defineProperty(exports, "getFieldsWithPrivacy", { enumerable: true, get: function () { return schema_1.getFieldsWithPrivacy; } });
|
|
17
18
|
Object.defineProperty(exports, "ActionOperation", { enumerable: true, get: function () { return schema_1.ActionOperation; } });
|
|
18
19
|
Object.defineProperty(exports, "NoFields", { enumerable: true, get: function () { return schema_1.NoFields; } });
|
|
19
20
|
Object.defineProperty(exports, "ConstraintType", { enumerable: true, get: function () { return schema_1.ConstraintType; } });
|
|
@@ -21,6 +22,7 @@ Object.defineProperty(exports, "requiredField", { enumerable: true, get: functio
|
|
|
21
22
|
Object.defineProperty(exports, "optionalField", { enumerable: true, get: function () { return schema_1.optionalField; } });
|
|
22
23
|
Object.defineProperty(exports, "SQLStatementOperation", { enumerable: true, get: function () { return schema_1.SQLStatementOperation; } });
|
|
23
24
|
Object.defineProperty(exports, "getTransformedReadClause", { enumerable: true, get: function () { return schema_1.getTransformedReadClause; } });
|
|
25
|
+
Object.defineProperty(exports, "getObjectLoaderProperties", { enumerable: true, get: function () { return schema_1.getObjectLoaderProperties; } });
|
|
24
26
|
var base_schema_1 = require("./base_schema");
|
|
25
27
|
Object.defineProperty(exports, "Timestamps", { enumerable: true, get: function () { return base_schema_1.Timestamps; } });
|
|
26
28
|
Object.defineProperty(exports, "Node", { enumerable: true, get: function () { return base_schema_1.Node; } });
|
package/schema/schema.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Data, Ent, LoaderInfo, Viewer } from "../core/base";
|
|
1
|
+
import { Data, Ent, LoaderInfo, PrivacyPolicy, Viewer } from "../core/base";
|
|
2
2
|
import { Builder } from "../action/action";
|
|
3
3
|
import { Clause } from "../core/clause";
|
|
4
4
|
export default interface Schema {
|
|
@@ -161,6 +161,7 @@ export interface FieldOptions {
|
|
|
161
161
|
derivedWhenEmbedded?: boolean;
|
|
162
162
|
polymorphic?: boolean | PolymorphicOptions;
|
|
163
163
|
derivedFields?: Field[];
|
|
164
|
+
privacyPolicy?: PrivacyPolicy | (() => PrivacyPolicy);
|
|
164
165
|
}
|
|
165
166
|
export interface PolymorphicOptions {
|
|
166
167
|
types?: string[];
|
|
@@ -179,7 +180,14 @@ export interface SchemaConstructor {
|
|
|
179
180
|
export declare type SchemaInputType = Schema | SchemaConstructor;
|
|
180
181
|
export declare function getSchema(value: SchemaInputType): Schema;
|
|
181
182
|
export declare function getFields(value: SchemaInputType): Map<string, Field>;
|
|
183
|
+
export declare function getStorageKey(field: Field): string;
|
|
184
|
+
export declare function getFieldsWithPrivacy(value: SchemaInputType): Map<string, PrivacyPolicy>;
|
|
182
185
|
export declare function getTransformedReadClause(value: SchemaInputType): Clause | undefined;
|
|
186
|
+
interface objectLoaderOptions {
|
|
187
|
+
clause?: () => Clause | undefined;
|
|
188
|
+
instanceKey?: string;
|
|
189
|
+
}
|
|
190
|
+
export declare function getObjectLoaderProperties(value: SchemaInputType, tableName: string): objectLoaderOptions | undefined;
|
|
183
191
|
export declare function getTransformedUpdateOp<T extends Ent>(value: SchemaInputType, stmt: UpdateOperation<T>): TransformedUpdateOperation<T> | undefined;
|
|
184
192
|
export declare enum ActionOperation {
|
|
185
193
|
Create = 1,
|
package/schema/schema.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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.getTransformedReadClause = 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.getFieldsWithPrivacy = exports.getStorageKey = exports.getFields = exports.getSchema = exports.DBType = exports.SQLStatementOperation = void 0;
|
|
4
|
+
const snake_case_1 = require("snake-case");
|
|
4
5
|
// we also want this transformation to exist on a per-action basis
|
|
5
6
|
// if it exists on an action, we don't do the global schema transformation
|
|
6
7
|
var SQLStatementOperation;
|
|
@@ -72,6 +73,41 @@ function getFields(value) {
|
|
|
72
73
|
return m;
|
|
73
74
|
}
|
|
74
75
|
exports.getFields = getFields;
|
|
76
|
+
function getStorageKey(field) {
|
|
77
|
+
return field.storageKey || (0, snake_case_1.snakeCase)(field.name);
|
|
78
|
+
}
|
|
79
|
+
exports.getStorageKey = getStorageKey;
|
|
80
|
+
// returns a mapping of storage key to field privacy
|
|
81
|
+
function getFieldsWithPrivacy(value) {
|
|
82
|
+
const schema = getSchema(value);
|
|
83
|
+
function addFields(fields) {
|
|
84
|
+
for (const field of fields) {
|
|
85
|
+
const derivedFields = field.derivedFields;
|
|
86
|
+
if (derivedFields !== undefined) {
|
|
87
|
+
addFields(derivedFields);
|
|
88
|
+
}
|
|
89
|
+
if (field.privacyPolicy) {
|
|
90
|
+
let privacyPolicy;
|
|
91
|
+
if (typeof field.privacyPolicy === "function") {
|
|
92
|
+
privacyPolicy = field.privacyPolicy();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
privacyPolicy = field.privacyPolicy;
|
|
96
|
+
}
|
|
97
|
+
m.set(getStorageKey(field), privacyPolicy);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
let m = new Map();
|
|
102
|
+
if (schema.patterns) {
|
|
103
|
+
for (const pattern of schema.patterns) {
|
|
104
|
+
addFields(pattern.fields);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
addFields(schema.fields);
|
|
108
|
+
return m;
|
|
109
|
+
}
|
|
110
|
+
exports.getFieldsWithPrivacy = getFieldsWithPrivacy;
|
|
75
111
|
function getTransformedReadClause(value) {
|
|
76
112
|
const schema = getSchema(value);
|
|
77
113
|
if (!schema.patterns) {
|
|
@@ -87,6 +123,13 @@ function getTransformedReadClause(value) {
|
|
|
87
123
|
return;
|
|
88
124
|
}
|
|
89
125
|
exports.getTransformedReadClause = getTransformedReadClause;
|
|
126
|
+
function getObjectLoaderProperties(value, tableName) {
|
|
127
|
+
return {
|
|
128
|
+
clause: () => getTransformedReadClause(value),
|
|
129
|
+
instanceKey: `${tableName}:transformedReadClause`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
exports.getObjectLoaderProperties = getObjectLoaderProperties;
|
|
90
133
|
function getTransformedUpdateOp(value, stmt) {
|
|
91
134
|
const schema = getSchema(value);
|
|
92
135
|
if (!schema.patterns) {
|
package/testutils/builder.js
CHANGED
|
@@ -147,11 +147,27 @@ class SimpleBuilder {
|
|
|
147
147
|
action: action,
|
|
148
148
|
schema: this.schema,
|
|
149
149
|
editedFields: () => {
|
|
150
|
-
return
|
|
150
|
+
// to simulate what we do in generated builders where we return a new Map
|
|
151
|
+
const m = new Map();
|
|
152
|
+
for (const [k, v] of this.fields) {
|
|
153
|
+
m.set(k, v);
|
|
154
|
+
}
|
|
155
|
+
return m;
|
|
151
156
|
},
|
|
152
157
|
updateInput: (input) => {
|
|
158
|
+
const knownFields = (0, schema_1.getFields)(this.schema);
|
|
153
159
|
for (const k in input) {
|
|
154
|
-
|
|
160
|
+
if (knownFields.has(k)) {
|
|
161
|
+
this.fields.set(k, input[k]);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// related to #510. we do camelCase to pass fields in here but fields may be snakeCase and we want that to pass in tests
|
|
165
|
+
// we do camelCase in
|
|
166
|
+
const sc = (0, snake_case_1.snakeCase)(k);
|
|
167
|
+
if (knownFields.has(sc)) {
|
|
168
|
+
this.fields.set(sc, input[k]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
155
171
|
}
|
|
156
172
|
},
|
|
157
173
|
});
|
|
@@ -71,10 +71,11 @@ export declare class TempDB {
|
|
|
71
71
|
constructor(tables: CoreConcept[]);
|
|
72
72
|
getDialect(): Dialect;
|
|
73
73
|
getTables(): Map<string, CoreConcept>;
|
|
74
|
-
beforeAll(): Promise<void>;
|
|
74
|
+
beforeAll(setupConnString?: boolean): Promise<void>;
|
|
75
75
|
getSqliteClient(): SqliteDatabase;
|
|
76
76
|
getPostgresClient(): PGClient;
|
|
77
77
|
afterAll(): Promise<void>;
|
|
78
|
+
getDB(): string;
|
|
78
79
|
dropAll(): Promise<void>;
|
|
79
80
|
drop(...tables: string[]): Promise<void>;
|
|
80
81
|
create(...tables: CoreConcept[]): Promise<void>;
|
package/testutils/db/test_db.js
CHANGED
|
@@ -336,7 +336,7 @@ class TempDB {
|
|
|
336
336
|
getTables() {
|
|
337
337
|
return this.tables;
|
|
338
338
|
}
|
|
339
|
-
async beforeAll() {
|
|
339
|
+
async beforeAll(setupConnString = true) {
|
|
340
340
|
if (this.dialect === db_1.Dialect.Postgres) {
|
|
341
341
|
const user = process.env.POSTGRES_USER || "";
|
|
342
342
|
const password = process.env.POSTGRES_PASSWORD || "";
|
|
@@ -348,11 +348,17 @@ class TempDB {
|
|
|
348
348
|
await this.client.connect();
|
|
349
349
|
this.db = randomDB();
|
|
350
350
|
await this.client.query(`CREATE DATABASE ${this.db}`);
|
|
351
|
-
if (
|
|
352
|
-
|
|
351
|
+
if (setupConnString) {
|
|
352
|
+
if (user && password) {
|
|
353
|
+
process.env.DB_CONNECTION_STRING = `postgres://${user}:${password}@localhost:5432/${this.db}`;
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
process.env.DB_CONNECTION_STRING = `postgres://localhost/${this.db}?`;
|
|
357
|
+
}
|
|
353
358
|
}
|
|
354
359
|
else {
|
|
355
|
-
|
|
360
|
+
// will probably be setup via loadConfig
|
|
361
|
+
delete process.env.DB_CONNECTION_STRING;
|
|
356
362
|
}
|
|
357
363
|
this.dbClient = new pg_1.Client({
|
|
358
364
|
host: "localhost",
|
|
@@ -397,6 +403,9 @@ class TempDB {
|
|
|
397
403
|
await this.client.query(`DROP DATABASE ${this.db}`);
|
|
398
404
|
await this.client.end();
|
|
399
405
|
}
|
|
406
|
+
getDB() {
|
|
407
|
+
return this.db;
|
|
408
|
+
}
|
|
400
409
|
async dropAll() {
|
|
401
410
|
for (const [t, _] of this.tables) {
|
|
402
411
|
await this.drop(t);
|