@snowtop/ent 0.0.37 → 0.0.39-alpha14
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/action.d.ts +2 -0
- package/action/orchestrator.d.ts +7 -1
- package/action/orchestrator.js +108 -28
- package/core/base.d.ts +3 -0
- package/core/clause.d.ts +24 -3
- package/core/clause.js +246 -5
- package/core/config.d.ts +18 -0
- package/core/config.js +17 -0
- package/core/ent.d.ts +2 -4
- package/core/ent.js +54 -22
- package/core/loaders/index_loader.js +1 -0
- package/core/loaders/object_loader.d.ts +1 -0
- package/core/loaders/object_loader.js +22 -4
- package/graphql/graphql.d.ts +3 -2
- package/graphql/graphql.js +22 -21
- package/graphql/node_resolver.d.ts +0 -1
- package/index.d.ts +16 -1
- package/index.js +17 -4
- package/package.json +2 -2
- package/parse_schema/parse.d.ts +9 -2
- package/parse_schema/parse.js +22 -1
- package/schema/index.d.ts +1 -1
- package/schema/index.js +4 -1
- package/schema/schema.d.ts +43 -1
- package/schema/schema.js +78 -5
- package/scripts/custom_graphql.js +122 -15
- package/testutils/builder.js +5 -0
package/core/config.d.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Database, DBDict } from "./db";
|
|
3
3
|
declare type logType = "query" | "warn" | "info" | "error" | "debug";
|
|
4
|
+
declare enum graphqlMutationName {
|
|
5
|
+
NOUN_VERB = "NounVerb",
|
|
6
|
+
VERB_NOUN = "VerbNoun"
|
|
7
|
+
}
|
|
8
|
+
declare enum graphQLFieldFormat {
|
|
9
|
+
LOWER_CAMEL = "lowerCamel",
|
|
10
|
+
SNAKE_CASE = "snake_case"
|
|
11
|
+
}
|
|
12
|
+
declare enum fieldPrivacyEvaluated {
|
|
13
|
+
AT_ENT_LOAD = "at_ent_load",
|
|
14
|
+
ON_DEMAND = "on_demand"
|
|
15
|
+
}
|
|
4
16
|
export interface Config {
|
|
5
17
|
dbConnectionString?: string;
|
|
6
18
|
dbFile?: string;
|
|
7
19
|
db?: Database | DBDict;
|
|
8
20
|
log?: logType | logType[];
|
|
9
21
|
codegen?: CodegenConfig;
|
|
22
|
+
customGraphQLJSONPath?: string;
|
|
10
23
|
}
|
|
11
24
|
interface CodegenConfig {
|
|
12
25
|
defaultEntPolicy?: PrivacyConfig;
|
|
@@ -17,6 +30,11 @@ interface CodegenConfig {
|
|
|
17
30
|
generatedHeader?: string;
|
|
18
31
|
disableBase64Encoding?: boolean;
|
|
19
32
|
generateRootResolvers?: boolean;
|
|
33
|
+
defaultGraphQLMutationName?: graphqlMutationName;
|
|
34
|
+
defaultGraphQLFieldFormat?: graphQLFieldFormat;
|
|
35
|
+
schemaSQLFilePath?: boolean;
|
|
36
|
+
databaseToCompareTo?: string;
|
|
37
|
+
fieldPrivacyEvaluated?: fieldPrivacyEvaluated;
|
|
20
38
|
}
|
|
21
39
|
interface PrettierConfig {
|
|
22
40
|
custom?: boolean;
|
package/core/config.js
CHANGED
|
@@ -28,6 +28,23 @@ const js_yaml_1 = require("js-yaml");
|
|
|
28
28
|
const db_1 = __importDefault(require("./db"));
|
|
29
29
|
const path = __importStar(require("path"));
|
|
30
30
|
const logger_1 = require("./logger");
|
|
31
|
+
// ent.config.ts eventually. for now ent.yml
|
|
32
|
+
// or ent.yml?
|
|
33
|
+
var graphqlMutationName;
|
|
34
|
+
(function (graphqlMutationName) {
|
|
35
|
+
graphqlMutationName["NOUN_VERB"] = "NounVerb";
|
|
36
|
+
graphqlMutationName["VERB_NOUN"] = "VerbNoun";
|
|
37
|
+
})(graphqlMutationName || (graphqlMutationName = {}));
|
|
38
|
+
var graphQLFieldFormat;
|
|
39
|
+
(function (graphQLFieldFormat) {
|
|
40
|
+
graphQLFieldFormat["LOWER_CAMEL"] = "lowerCamel";
|
|
41
|
+
graphQLFieldFormat["SNAKE_CASE"] = "snake_case";
|
|
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 = {}));
|
|
31
48
|
function setConfig(cfg) {
|
|
32
49
|
if (cfg.log) {
|
|
33
50
|
(0, logger_1.setLogLevels)(cfg.log);
|
package/core/ent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Queryer, SyncQueryer } from "./db";
|
|
2
|
-
import { Viewer, Ent, ID, LoadRowsOptions, LoadRowOptions, Data, DataOptions, QueryableDataOptions, EditRowOptions, LoadEntOptions, LoadCustomEntOptions, EdgeQueryableDataOptions, Context, SelectBaseDataOptions, CreateRowOptions, QueryDataOptions
|
|
2
|
+
import { Viewer, Ent, ID, LoadRowsOptions, LoadRowOptions, Data, DataOptions, QueryableDataOptions, EditRowOptions, LoadEntOptions, LoadCustomEntOptions, EdgeQueryableDataOptions, Context, SelectBaseDataOptions, CreateRowOptions, QueryDataOptions } from "./base";
|
|
3
3
|
import { Executor } from "../action/action";
|
|
4
4
|
import * as clause from "./clause";
|
|
5
5
|
import { Builder } from "../action";
|
|
@@ -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[]>;
|
|
@@ -51,7 +49,7 @@ export interface DataOperation<T extends Ent = Ent> {
|
|
|
51
49
|
}
|
|
52
50
|
export interface EditNodeOptions<T extends Ent> extends EditRowOptions {
|
|
53
51
|
fieldsToResolve: string[];
|
|
54
|
-
|
|
52
|
+
loadEntOptions: LoadEntOptions<T>;
|
|
55
53
|
placeholderID?: ID;
|
|
56
54
|
}
|
|
57
55
|
export declare class EditNodeOperation<T extends Ent> implements DataOperation {
|
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 doFieldPrivcy(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 doFieldPrivcy(viewer, ent, data, options);
|
|
281
|
+
}
|
|
282
|
+
async function doFieldPrivcy(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,
|
|
@@ -434,6 +458,8 @@ class EditNodeOperation {
|
|
|
434
458
|
};
|
|
435
459
|
if (this.existingEnt) {
|
|
436
460
|
if (this.hasData(options.fields)) {
|
|
461
|
+
// even this with returning * may not always work if transformed...
|
|
462
|
+
// we can have a transformed flag to see if it should be returned?
|
|
437
463
|
this.row = await editRow(queryer, options, this.existingEnt.id, "RETURNING *");
|
|
438
464
|
}
|
|
439
465
|
else {
|
|
@@ -445,20 +471,27 @@ class EditNodeOperation {
|
|
|
445
471
|
}
|
|
446
472
|
}
|
|
447
473
|
reloadRow(queryer, id, options) {
|
|
474
|
+
// TODO this isn't always an ObjectLoader. should throw or figure out a way to get query
|
|
475
|
+
// and run this on its own...
|
|
476
|
+
const loader = this.options.loadEntOptions.loaderFactory.createLoader(options.context);
|
|
477
|
+
const opts = loader.getOptions();
|
|
478
|
+
let cls = clause.Eq(options.key, id);
|
|
479
|
+
if (opts.clause) {
|
|
480
|
+
cls = clause.And(opts.clause, cls);
|
|
481
|
+
}
|
|
448
482
|
const query = buildQuery({
|
|
449
|
-
fields: ["*"],
|
|
483
|
+
fields: opts.fields.length ? opts.fields : ["*"],
|
|
450
484
|
tableName: options.tableName,
|
|
451
|
-
clause:
|
|
485
|
+
clause: cls,
|
|
452
486
|
});
|
|
453
487
|
// special case log here because we're not going through any of the normal
|
|
454
488
|
// methods here because those are async and this is sync
|
|
455
489
|
// this is the only place we're doing this so only handling here
|
|
456
490
|
logQuery(query, [id]);
|
|
457
491
|
const r = queryer.querySync(query, [id]);
|
|
458
|
-
if (r.rows.length
|
|
459
|
-
|
|
492
|
+
if (r.rows.length === 1) {
|
|
493
|
+
this.row = r.rows[0];
|
|
460
494
|
}
|
|
461
|
-
this.row = r.rows[0];
|
|
462
495
|
}
|
|
463
496
|
performWriteSync(queryer, context) {
|
|
464
497
|
let options = {
|
|
@@ -487,7 +520,7 @@ class EditNodeOperation {
|
|
|
487
520
|
if (!this.row) {
|
|
488
521
|
return null;
|
|
489
522
|
}
|
|
490
|
-
return new this.options.ent(viewer, this.row);
|
|
523
|
+
return new this.options.loadEntOptions.ent(viewer, this.row);
|
|
491
524
|
}
|
|
492
525
|
}
|
|
493
526
|
exports.EditNodeOperation = EditNodeOperation;
|
|
@@ -1141,20 +1174,19 @@ async function applyPrivacyPolicyForRow(viewer, options, row) {
|
|
|
1141
1174
|
return null;
|
|
1142
1175
|
}
|
|
1143
1176
|
const ent = new options.ent(viewer, row);
|
|
1144
|
-
return await applyPrivacyPolicyForEnt(viewer, ent);
|
|
1177
|
+
return await applyPrivacyPolicyForEnt(viewer, ent, row, options);
|
|
1145
1178
|
}
|
|
1146
1179
|
exports.applyPrivacyPolicyForRow = applyPrivacyPolicyForRow;
|
|
1147
1180
|
async function applyPrivacyPolicyForRowX(viewer, options, row) {
|
|
1148
1181
|
const ent = new options.ent(viewer, row);
|
|
1149
|
-
return await applyPrivacyPolicyForEntX(viewer, ent);
|
|
1182
|
+
return await applyPrivacyPolicyForEntX(viewer, ent, row, options);
|
|
1150
1183
|
}
|
|
1151
1184
|
exports.applyPrivacyPolicyForRowX = applyPrivacyPolicyForRowX;
|
|
1152
1185
|
async function applyPrivacyPolicyForRows(viewer, rows, options) {
|
|
1153
1186
|
let m = new Map();
|
|
1154
1187
|
// apply privacy logic
|
|
1155
1188
|
await Promise.all(rows.map(async (row) => {
|
|
1156
|
-
|
|
1157
|
-
let privacyEnt = await applyPrivacyPolicyForEnt(viewer, ent);
|
|
1189
|
+
let privacyEnt = await applyPrivacyPolicyForRow(viewer, options, row);
|
|
1158
1190
|
if (privacyEnt) {
|
|
1159
1191
|
m.set(privacyEnt.id, privacyEnt);
|
|
1160
1192
|
}
|
|
@@ -4,6 +4,7 @@ exports.IndexLoaderFactory = void 0;
|
|
|
4
4
|
const query_loader_1 = require("./query_loader");
|
|
5
5
|
// we're keeping this for legacy reasons so as to not break existing callers
|
|
6
6
|
// and to decouple the change here but all callers can safely be changed here to use QueryLoaderFactory
|
|
7
|
+
// @deprecated use QueryLoaderFactory
|
|
7
8
|
class IndexLoaderFactory {
|
|
8
9
|
constructor(options, col, opts) {
|
|
9
10
|
this.factory = new query_loader_1.QueryLoaderFactory({
|
|
@@ -7,6 +7,7 @@ export declare class ObjectLoader<T> implements Loader<T, Data | null> {
|
|
|
7
7
|
private primedLoaders;
|
|
8
8
|
private memoizedInitPrime;
|
|
9
9
|
constructor(options: SelectDataOptions, context?: Context | undefined, toPrime?: ObjectLoaderFactory<T>[] | undefined);
|
|
10
|
+
getOptions(): SelectDataOptions;
|
|
10
11
|
private initPrime;
|
|
11
12
|
load(key: T): Promise<Data | null>;
|
|
12
13
|
clearAll(): void;
|
|
@@ -29,6 +29,9 @@ const clause = __importStar(require("../clause"));
|
|
|
29
29
|
const logger_1 = require("../logger");
|
|
30
30
|
const loader_1 = require("./loader");
|
|
31
31
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
32
|
+
// optional clause...
|
|
33
|
+
// so ObjectLoaderFactory and createDataLoader need to take a new optional field which is a clause that's always added here
|
|
34
|
+
// and we need a disableTransform which skips loader completely and uses loadRow...
|
|
32
35
|
function createDataLoader(options) {
|
|
33
36
|
const loaderOptions = {};
|
|
34
37
|
// if query logging is enabled, we should log what's happening with loader
|
|
@@ -40,9 +43,13 @@ function createDataLoader(options) {
|
|
|
40
43
|
return [];
|
|
41
44
|
}
|
|
42
45
|
let col = options.key;
|
|
46
|
+
let cls = clause.In(col, ...ids);
|
|
47
|
+
if (options.clause) {
|
|
48
|
+
cls = clause.And(options.clause, cls);
|
|
49
|
+
}
|
|
43
50
|
const rowOptions = {
|
|
44
51
|
...options,
|
|
45
|
-
clause:
|
|
52
|
+
clause: cls,
|
|
46
53
|
};
|
|
47
54
|
let m = new Map();
|
|
48
55
|
let result = [];
|
|
@@ -77,6 +84,9 @@ class ObjectLoader {
|
|
|
77
84
|
}
|
|
78
85
|
this.memoizedInitPrime = (0, memoizee_1.default)(this.initPrime.bind(this));
|
|
79
86
|
}
|
|
87
|
+
getOptions() {
|
|
88
|
+
return this.options;
|
|
89
|
+
}
|
|
80
90
|
initPrime() {
|
|
81
91
|
if (!this.context || !this.toPrime) {
|
|
82
92
|
return;
|
|
@@ -107,9 +117,13 @@ class ObjectLoader {
|
|
|
107
117
|
}
|
|
108
118
|
return result;
|
|
109
119
|
}
|
|
120
|
+
let cls = clause.Eq(this.options.key, key);
|
|
121
|
+
if (this.options.clause) {
|
|
122
|
+
cls = clause.And(this.options.clause, cls);
|
|
123
|
+
}
|
|
110
124
|
const rowOptions = {
|
|
111
125
|
...this.options,
|
|
112
|
-
clause:
|
|
126
|
+
clause: cls,
|
|
113
127
|
context: this.context,
|
|
114
128
|
};
|
|
115
129
|
return await (0, ent_1.loadRow)(rowOptions);
|
|
@@ -121,9 +135,13 @@ class ObjectLoader {
|
|
|
121
135
|
if (this.loader) {
|
|
122
136
|
return await this.loader.loadMany(keys);
|
|
123
137
|
}
|
|
138
|
+
let cls = clause.In(this.options.key, ...keys);
|
|
139
|
+
if (this.options.clause) {
|
|
140
|
+
cls = clause.And(this.options.clause, cls);
|
|
141
|
+
}
|
|
124
142
|
const rowOptions = {
|
|
125
143
|
...this.options,
|
|
126
|
-
clause:
|
|
144
|
+
clause: cls,
|
|
127
145
|
context: this.context,
|
|
128
146
|
};
|
|
129
147
|
return await (0, ent_1.loadRows)(rowOptions);
|
|
@@ -142,7 +160,7 @@ class ObjectLoaderFactory {
|
|
|
142
160
|
constructor(options) {
|
|
143
161
|
this.options = options;
|
|
144
162
|
this.toPrime = [];
|
|
145
|
-
this.name = `${options.tableName}:${options.key}`;
|
|
163
|
+
this.name = `${options.tableName}:${options.key}:${options.clause?.instanceKey() || ""}`;
|
|
146
164
|
}
|
|
147
165
|
createLoader(context) {
|
|
148
166
|
return (0, loader_1.getLoader)(this, () => {
|
package/graphql/graphql.d.ts
CHANGED
|
@@ -82,6 +82,9 @@ declare enum NullableResult {
|
|
|
82
82
|
CONTENTS_AND_LIST = "contentsAndList",
|
|
83
83
|
ITEM = "true"
|
|
84
84
|
}
|
|
85
|
+
export declare const knownAllowedNames: Map<string, string>;
|
|
86
|
+
export declare const knownDisAllowedNames: Map<string, boolean>;
|
|
87
|
+
export declare const isCustomType: (type: Type) => type is CustomType;
|
|
85
88
|
export declare const addCustomType: (type: CustomType) => void;
|
|
86
89
|
export declare class GQLCapture {
|
|
87
90
|
private static enabled;
|
|
@@ -107,8 +110,6 @@ export declare class GQLCapture {
|
|
|
107
110
|
static getProcessedCustomMutations(): ProcessedCustomField[];
|
|
108
111
|
static getProcessedCustomQueries(): ProcessedCustomField[];
|
|
109
112
|
private static getProcessedCustomFieldsImpl;
|
|
110
|
-
private static knownAllowedNames;
|
|
111
|
-
private static knownDisAllowedNames;
|
|
112
113
|
private static getResultFromMetadata;
|
|
113
114
|
static gqlField(options?: gqlFieldOptions): any;
|
|
114
115
|
private static getCustomField;
|
package/graphql/graphql.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.gqlFileUpload = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = exports.GQLCapture = exports.addCustomType = exports.CustomFieldType = void 0;
|
|
3
|
+
exports.gqlFileUpload = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = exports.GQLCapture = exports.addCustomType = exports.isCustomType = exports.knownDisAllowedNames = exports.knownAllowedNames = exports.CustomFieldType = void 0;
|
|
4
4
|
require("reflect-metadata");
|
|
5
5
|
// export interface gqlTopLevelOptions
|
|
6
6
|
// name?: string;
|
|
@@ -20,6 +20,22 @@ var NullableResult;
|
|
|
20
20
|
NullableResult["CONTENTS_AND_LIST"] = "contentsAndList";
|
|
21
21
|
NullableResult["ITEM"] = "true";
|
|
22
22
|
})(NullableResult || (NullableResult = {}));
|
|
23
|
+
exports.knownAllowedNames = new Map([
|
|
24
|
+
["Date", "Date"],
|
|
25
|
+
["Boolean", "boolean"],
|
|
26
|
+
["Number", "number"],
|
|
27
|
+
["String", "string"],
|
|
28
|
+
// TODO not right to have this and Number
|
|
29
|
+
["Int", "number"],
|
|
30
|
+
["Float", "number"],
|
|
31
|
+
["ID", "ID"],
|
|
32
|
+
]);
|
|
33
|
+
exports.knownDisAllowedNames = new Map([
|
|
34
|
+
["Function", true],
|
|
35
|
+
["Object", true],
|
|
36
|
+
["Array", true],
|
|
37
|
+
["Promise", true],
|
|
38
|
+
]);
|
|
23
39
|
const isArray = (type) => {
|
|
24
40
|
if (typeof type === "function") {
|
|
25
41
|
return false;
|
|
@@ -41,6 +57,7 @@ const isString = (type) => {
|
|
|
41
57
|
const isCustomType = (type) => {
|
|
42
58
|
return type.importPath !== undefined;
|
|
43
59
|
};
|
|
60
|
+
exports.isCustomType = isCustomType;
|
|
44
61
|
const isGraphQLScalarType = (type) => {
|
|
45
62
|
return type.serialize !== undefined;
|
|
46
63
|
};
|
|
@@ -92,7 +109,7 @@ const getType = (typ, result) => {
|
|
|
92
109
|
}
|
|
93
110
|
return;
|
|
94
111
|
}
|
|
95
|
-
if (isCustomType(typ)) {
|
|
112
|
+
if ((0, exports.isCustomType)(typ)) {
|
|
96
113
|
result.type = typ.type;
|
|
97
114
|
(0, exports.addCustomType)(typ);
|
|
98
115
|
return;
|
|
@@ -197,20 +214,20 @@ class GQLCapture {
|
|
|
197
214
|
connection = r.connection;
|
|
198
215
|
type = r.type;
|
|
199
216
|
}
|
|
200
|
-
if (
|
|
217
|
+
if (exports.knownDisAllowedNames.has(type)) {
|
|
201
218
|
throw new Error(`${type} isn't a valid type for accessor/function/property`);
|
|
202
219
|
}
|
|
203
220
|
let result = {
|
|
204
221
|
name: metadata.paramName || "",
|
|
205
222
|
type,
|
|
206
|
-
tsType:
|
|
223
|
+
tsType: exports.knownAllowedNames.get(type) || this.customTypes.get(type)?.tsType,
|
|
207
224
|
nullable: options?.nullable,
|
|
208
225
|
list: list,
|
|
209
226
|
connection: connection,
|
|
210
227
|
isContextArg: metadata.isContextArg,
|
|
211
228
|
};
|
|
212
229
|
// unknown type. we need to flag that this field needs to eventually be resolved
|
|
213
|
-
if (!
|
|
230
|
+
if (!exports.knownAllowedNames.has(type)) {
|
|
214
231
|
if (scalarType) {
|
|
215
232
|
throw new Error(`custom scalar type ${type} is not supported this way. use CustomType syntax. see \`gqlFileUpload\` as an example`);
|
|
216
233
|
}
|
|
@@ -461,22 +478,6 @@ GQLCapture.customArgs = new Map();
|
|
|
461
478
|
GQLCapture.customInputObjects = new Map();
|
|
462
479
|
GQLCapture.customObjects = new Map();
|
|
463
480
|
GQLCapture.customTypes = new Map();
|
|
464
|
-
GQLCapture.knownAllowedNames = new Map([
|
|
465
|
-
["Date", "Date"],
|
|
466
|
-
["Boolean", "boolean"],
|
|
467
|
-
["Number", "number"],
|
|
468
|
-
["String", "string"],
|
|
469
|
-
// TODO not right to have this and Number
|
|
470
|
-
["Int", "number"],
|
|
471
|
-
["Float", "number"],
|
|
472
|
-
["ID", "ID"],
|
|
473
|
-
]);
|
|
474
|
-
GQLCapture.knownDisAllowedNames = new Map([
|
|
475
|
-
["Function", true],
|
|
476
|
-
["Object", true],
|
|
477
|
-
["Array", true],
|
|
478
|
-
["Promise", true],
|
|
479
|
-
]);
|
|
480
481
|
// User -> add -> [{name, options}, {}, {}]
|
|
481
482
|
GQLCapture.argMap = new Map();
|
|
482
483
|
// why is this a static class lol?
|
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 };
|
|
@@ -11,12 +11,27 @@ declare const query: {
|
|
|
11
11
|
Eq: typeof q.Eq;
|
|
12
12
|
NotEq: typeof q.NotEq;
|
|
13
13
|
And: typeof q.And;
|
|
14
|
+
AndOptional: typeof q.AndOptional;
|
|
14
15
|
Or: typeof q.Or;
|
|
15
16
|
In: typeof q.In;
|
|
16
17
|
Greater: typeof q.Greater;
|
|
17
18
|
Less: typeof q.Less;
|
|
18
19
|
GreaterEq: typeof q.GreaterEq;
|
|
19
20
|
LessEq: typeof q.LessEq;
|
|
21
|
+
ArrayEq: typeof q.ArrayEq;
|
|
22
|
+
ArrayNotEq: typeof q.ArrayNotEq;
|
|
23
|
+
ArrayGreater: typeof q.ArrayGreater;
|
|
24
|
+
ArrayLess: typeof q.ArrayLess;
|
|
25
|
+
ArrayGreaterEq: typeof q.ArrayGreaterEq;
|
|
26
|
+
ArrayLessEq: typeof q.ArrayLessEq;
|
|
27
|
+
TsQuery: typeof q.TsQuery;
|
|
28
|
+
PlainToTsQuery: typeof q.PlainToTsQuery;
|
|
29
|
+
PhraseToTsQuery: typeof q.PhraseToTsQuery;
|
|
30
|
+
WebsearchToTsQuery: typeof q.WebsearchToTsQuery;
|
|
31
|
+
TsVectorColTsQuery: typeof q.TsVectorColTsQuery;
|
|
32
|
+
TsVectorPlainToTsQuery: typeof q.TsVectorPlainToTsQuery;
|
|
33
|
+
TsVectorPhraseToTsQuery: typeof q.TsVectorPhraseToTsQuery;
|
|
34
|
+
TsVectorWebsearchToTsQuery: typeof q.TsVectorWebsearchToTsQuery;
|
|
20
35
|
};
|
|
21
36
|
export { query };
|
|
22
37
|
export { RequestContext, ContextCache } from "./core/context";
|
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; } });
|
|
@@ -109,12 +107,27 @@ const query = {
|
|
|
109
107
|
Eq: q.Eq,
|
|
110
108
|
NotEq: q.NotEq,
|
|
111
109
|
And: q.And,
|
|
110
|
+
AndOptional: q.AndOptional,
|
|
112
111
|
Or: q.Or,
|
|
113
112
|
In: q.In,
|
|
114
113
|
Greater: q.Greater,
|
|
115
114
|
Less: q.Less,
|
|
116
115
|
GreaterEq: q.GreaterEq,
|
|
117
116
|
LessEq: q.LessEq,
|
|
117
|
+
ArrayEq: q.ArrayEq,
|
|
118
|
+
ArrayNotEq: q.ArrayNotEq,
|
|
119
|
+
ArrayGreater: q.ArrayGreater,
|
|
120
|
+
ArrayLess: q.ArrayLess,
|
|
121
|
+
ArrayGreaterEq: q.ArrayGreaterEq,
|
|
122
|
+
ArrayLessEq: q.ArrayLessEq,
|
|
123
|
+
TsQuery: q.TsQuery,
|
|
124
|
+
PlainToTsQuery: q.PlainToTsQuery,
|
|
125
|
+
PhraseToTsQuery: q.PhraseToTsQuery,
|
|
126
|
+
WebsearchToTsQuery: q.WebsearchToTsQuery,
|
|
127
|
+
TsVectorColTsQuery: q.TsVectorColTsQuery,
|
|
128
|
+
TsVectorPlainToTsQuery: q.TsVectorPlainToTsQuery,
|
|
129
|
+
TsVectorPhraseToTsQuery: q.TsVectorPhraseToTsQuery,
|
|
130
|
+
TsVectorWebsearchToTsQuery: q.TsVectorWebsearchToTsQuery,
|
|
118
131
|
};
|
|
119
132
|
exports.query = query;
|
|
120
133
|
var context_1 = require("./core/context");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowtop/ent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39-alpha14",
|
|
4
4
|
"description": "snowtop ent framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"json5": "^2.1.3",
|
|
18
18
|
"luxon": "^1.25.0",
|
|
19
19
|
"memoizee": "^0.4.15",
|
|
20
|
-
"minimist": "^1.2.
|
|
20
|
+
"minimist": "^1.2.6",
|
|
21
21
|
"pascal-case": "^3.1.2",
|
|
22
22
|
"pg": "^8.0.3",
|
|
23
23
|
"prettier": "^2.3.2",
|
package/parse_schema/parse.d.ts
CHANGED
|
@@ -12,7 +12,13 @@ declare type ProcessedAssocEdge = Omit<AssocEdge, "actionOnlyFields" | "edgeActi
|
|
|
12
12
|
patternName?: string;
|
|
13
13
|
edgeActions?: OutputAction[];
|
|
14
14
|
};
|
|
15
|
-
|
|
15
|
+
interface TransformFlags {
|
|
16
|
+
transformsSelect?: boolean;
|
|
17
|
+
transformsDelete?: boolean;
|
|
18
|
+
transformsInsert?: boolean;
|
|
19
|
+
transformsUpdate?: boolean;
|
|
20
|
+
}
|
|
21
|
+
declare type ProcessedSchema = Omit<Schema, "edges" | "actions" | "edgeGroups" | "fields"> & TransformFlags & {
|
|
16
22
|
actions: OutputAction[];
|
|
17
23
|
assocEdges: ProcessedAssocEdge[];
|
|
18
24
|
assocEdgeGroups: ProcessedAssocEdgeGroup[];
|
|
@@ -32,10 +38,11 @@ interface ProcessedPattern {
|
|
|
32
38
|
assocEdges: ProcessedAssocEdge[];
|
|
33
39
|
fields: ProcessedField[];
|
|
34
40
|
}
|
|
35
|
-
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate"> & {
|
|
41
|
+
declare type ProcessedField = Omit<Field, "defaultValueOnEdit" | "defaultValueOnCreate" | "privacyPolicy"> & {
|
|
36
42
|
hasDefaultValueOnCreate?: boolean;
|
|
37
43
|
hasDefaultValueOnEdit?: boolean;
|
|
38
44
|
patternName?: string;
|
|
45
|
+
hasFieldPrivacy?: boolean;
|
|
39
46
|
};
|
|
40
47
|
interface patternsDict {
|
|
41
48
|
[key: string]: ProcessedPattern;
|