@snowtop/ent 0.1.0-alpha9 → 0.1.0-alpha90
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 +36 -31
- package/action/action.js +2 -6
- package/action/executor.d.ts +3 -3
- package/action/executor.js +2 -2
- package/action/experimental_action.d.ts +29 -22
- package/action/experimental_action.js +29 -6
- package/action/orchestrator.d.ts +38 -16
- package/action/orchestrator.js +219 -61
- package/action/privacy.d.ts +2 -2
- package/core/base.d.ts +45 -24
- package/core/base.js +7 -1
- package/core/clause.d.ts +68 -7
- package/core/clause.js +291 -62
- package/core/config.d.ts +8 -0
- package/core/context.d.ts +5 -3
- package/core/context.js +20 -2
- package/core/convert.d.ts +1 -1
- package/core/db.d.ts +2 -2
- package/core/db.js +1 -1
- package/core/ent.d.ts +79 -24
- package/core/ent.js +520 -168
- package/core/loaders/assoc_count_loader.d.ts +2 -2
- package/core/loaders/assoc_count_loader.js +6 -1
- package/core/loaders/assoc_edge_loader.d.ts +2 -2
- package/core/loaders/index.d.ts +1 -1
- package/core/loaders/index.js +1 -3
- package/core/loaders/index_loader.d.ts +2 -2
- package/core/loaders/loader.js +5 -5
- package/core/loaders/object_loader.d.ts +6 -5
- package/core/loaders/object_loader.js +62 -58
- package/core/loaders/query_loader.d.ts +6 -12
- package/core/loaders/query_loader.js +47 -10
- package/core/loaders/raw_count_loader.d.ts +2 -2
- package/core/logger.d.ts +1 -1
- package/core/logger.js +1 -0
- package/core/privacy.d.ts +26 -25
- package/core/privacy.js +21 -25
- package/core/query/assoc_query.d.ts +6 -6
- package/core/query/custom_clause_query.d.ts +24 -0
- package/core/query/custom_clause_query.js +72 -0
- package/core/query/custom_query.d.ts +20 -5
- package/core/query/custom_query.js +77 -10
- package/core/query/index.d.ts +1 -0
- package/core/query/index.js +3 -1
- package/core/query/query.d.ts +1 -1
- package/core/query/query.js +8 -1
- package/core/query/shared_assoc_test.d.ts +1 -1
- package/core/query/shared_assoc_test.js +17 -5
- package/core/query/shared_test.d.ts +3 -0
- package/core/query/shared_test.js +211 -30
- package/core/viewer.d.ts +3 -3
- package/core/viewer.js +1 -1
- package/graphql/graphql.js +6 -0
- package/graphql/query/edge_connection.d.ts +9 -9
- package/graphql/query/page_info.d.ts +1 -1
- package/index.d.ts +11 -5
- package/index.js +15 -6
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +12 -3
- package/parse_schema/parse.js +70 -11
- package/schema/base_schema.js +3 -0
- package/schema/field.d.ts +44 -8
- package/schema/field.js +125 -9
- package/schema/index.d.ts +2 -2
- package/schema/json_field.d.ts +13 -1
- package/schema/json_field.js +28 -1
- package/schema/schema.d.ts +65 -11
- package/schema/schema.js +18 -4
- package/schema/struct_field.d.ts +11 -1
- package/schema/struct_field.js +44 -5
- package/scripts/custom_graphql.js +8 -3
- package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
- package/scripts/migrate_v0.1.js +36 -0
- package/scripts/read_schema.js +15 -4
- package/testutils/builder.d.ts +31 -21
- package/testutils/builder.js +83 -29
- package/testutils/db/fixture.d.ts +10 -0
- package/testutils/db/fixture.js +26 -0
- package/testutils/db/{test_db.d.ts → temp_db.d.ts} +15 -3
- package/testutils/db/{test_db.js → temp_db.js} +70 -16
- package/testutils/db/value.d.ts +6 -0
- package/testutils/db/value.js +251 -0
- package/testutils/db_time_zone.d.ts +4 -0
- package/testutils/db_time_zone.js +41 -0
- package/testutils/fake_data/fake_contact.d.ts +5 -4
- package/testutils/fake_data/fake_contact.js +14 -6
- package/testutils/fake_data/fake_event.d.ts +5 -3
- package/testutils/fake_data/fake_event.js +8 -5
- package/testutils/fake_data/fake_user.d.ts +4 -4
- package/testutils/fake_data/fake_user.js +16 -13
- package/testutils/fake_data/test_helpers.d.ts +3 -2
- package/testutils/fake_data/test_helpers.js +8 -6
- package/testutils/fake_data/user_query.d.ts +8 -6
- package/testutils/fake_data/user_query.js +28 -21
- package/testutils/fake_log.d.ts +3 -3
- package/testutils/parse_sql.d.ts +6 -0
- package/testutils/parse_sql.js +16 -2
- package/testutils/test_edge_global_schema.d.ts +15 -0
- package/testutils/test_edge_global_schema.js +58 -0
- package/testutils/write.d.ts +2 -2
- package/testutils/write.js +29 -7
- package/tsc/ast.d.ts +44 -0
- package/tsc/ast.js +267 -0
- package/tsc/compilerOptions.d.ts +6 -0
- package/tsc/compilerOptions.js +40 -1
- package/tsc/move_generated.d.ts +1 -0
- package/tsc/move_generated.js +160 -0
- package/tsc/transform.d.ts +21 -0
- package/tsc/transform.js +167 -0
- package/tsc/transform_action.d.ts +22 -0
- package/tsc/transform_action.js +179 -0
- package/tsc/transform_ent.d.ts +17 -0
- package/tsc/transform_ent.js +59 -0
- package/tsc/transform_schema.d.ts +27 -0
- package/tsc/transform_schema.js +379 -0
- package/scripts/transform_schema.js +0 -445
package/core/privacy.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.DelayedResultRule = exports.AllowIfConditionAppliesRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = exports.DenyIfViewerInboundEdgeDoesNotExistRule = exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.DenyIfFuncRule = exports.AllowIfFuncRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedInRule = exports.DenyIfLoggedOutRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = void 0;
|
|
3
|
+
exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyImpl = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.DelayedResultRule = exports.AllowIfConditionAppliesRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = exports.DenyIfViewerInboundEdgeDoesNotExistRule = exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.DenyIfFuncRule = exports.AllowIfFuncRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedInRule = exports.DenyIfLoggedOutRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = void 0;
|
|
4
4
|
const base_1 = require("./base");
|
|
5
5
|
const ent_1 = require("./ent");
|
|
6
|
-
const logger_1 = require("./logger");
|
|
7
6
|
// copied from ./base
|
|
8
7
|
var privacyResult;
|
|
9
8
|
(function (privacyResult) {
|
|
@@ -437,45 +436,42 @@ class AllowIfSubPolicyAllowsRule {
|
|
|
437
436
|
}
|
|
438
437
|
exports.AllowIfSubPolicyAllowsRule = AllowIfSubPolicyAllowsRule;
|
|
439
438
|
async function applyPrivacyPolicy(v, policy, ent) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
catch (e) {
|
|
444
|
-
// TODO privacy errors should not throw
|
|
445
|
-
// but other expected errors should throw...
|
|
446
|
-
// we shouldn't just hide them
|
|
447
|
-
(0, logger_1.log)("debug", e);
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
439
|
+
const err = await applyPrivacyPolicyImpl(v, policy, ent);
|
|
440
|
+
return err === null;
|
|
450
441
|
}
|
|
451
442
|
exports.applyPrivacyPolicy = applyPrivacyPolicy;
|
|
452
|
-
// this will throw an exception if fails or return error | null?
|
|
453
443
|
async function applyPrivacyPolicyX(v, policy, ent, throwErr) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
444
|
+
const err = await applyPrivacyPolicyImpl(v, policy, ent, throwErr);
|
|
445
|
+
if (err !== null) {
|
|
446
|
+
throw err;
|
|
447
|
+
}
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
exports.applyPrivacyPolicyX = applyPrivacyPolicyX;
|
|
451
|
+
// this will throw an exception if fails or return error | null?
|
|
452
|
+
async function applyPrivacyPolicyImpl(v, policy, ent, throwErr) {
|
|
453
|
+
for (const rule of policy.rules) {
|
|
454
|
+
const res = await rule.apply(v, ent);
|
|
459
455
|
if (res.result == privacyResult.Allow) {
|
|
460
|
-
return
|
|
456
|
+
return null;
|
|
461
457
|
}
|
|
462
458
|
else if (res.result == privacyResult.Deny) {
|
|
463
459
|
// specific error throw that
|
|
464
460
|
if (res.error) {
|
|
465
|
-
|
|
461
|
+
return res.error;
|
|
466
462
|
}
|
|
467
463
|
if (res.getError) {
|
|
468
|
-
|
|
464
|
+
return res.getError(policy, rule, ent);
|
|
469
465
|
}
|
|
470
466
|
if (throwErr) {
|
|
471
|
-
|
|
467
|
+
return throwErr();
|
|
472
468
|
}
|
|
473
|
-
|
|
469
|
+
return new EntPrivacyError(policy, rule, ent);
|
|
474
470
|
}
|
|
475
471
|
}
|
|
476
|
-
|
|
472
|
+
return new EntInvalidPrivacyPolicyError(policy, ent);
|
|
477
473
|
}
|
|
478
|
-
exports.
|
|
474
|
+
exports.applyPrivacyPolicyImpl = applyPrivacyPolicyImpl;
|
|
479
475
|
exports.AlwaysAllowPrivacyPolicy = {
|
|
480
476
|
rules: [exports.AlwaysAllowRule],
|
|
481
477
|
};
|
|
@@ -3,15 +3,15 @@ import { AssocEdge } from "../ent";
|
|
|
3
3
|
import { AssocEdgeCountLoaderFactory } from "../loaders/assoc_count_loader";
|
|
4
4
|
import { AssocEdgeLoaderFactory } from "../loaders/assoc_edge_loader";
|
|
5
5
|
import { EdgeQuery, BaseEdgeQuery, IDInfo } from "./query";
|
|
6
|
-
export declare type EdgeQuerySource<TSource extends Ent
|
|
7
|
-
declare type loaderOptionsFunc = (type: string) => LoadEntOptions<Ent>;
|
|
8
|
-
export declare abstract class AssocEdgeQueryBase<TSource extends Ent
|
|
9
|
-
viewer:
|
|
10
|
-
src: EdgeQuerySource<TSource, TDest>;
|
|
6
|
+
export declare type EdgeQuerySource<TSource extends Ent<TViewer>, TDest extends Ent<TViewer> = Ent<any>, TViewer extends Viewer = Viewer> = TSource | TSource[] | ID | ID[] | EdgeQuery<TDest, Ent, AssocEdge>;
|
|
7
|
+
declare type loaderOptionsFunc<TViewer extends Viewer> = (type: string) => LoadEntOptions<Ent, TViewer>;
|
|
8
|
+
export declare abstract class AssocEdgeQueryBase<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TEdge extends AssocEdge, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<TSource, TDest, TEdge> implements EdgeQuery<TSource, TDest, TEdge> {
|
|
9
|
+
viewer: TViewer;
|
|
10
|
+
src: EdgeQuerySource<TSource, TDest, TViewer>;
|
|
11
11
|
private countLoaderFactory;
|
|
12
12
|
private dataLoaderFactory;
|
|
13
13
|
private options;
|
|
14
|
-
constructor(viewer:
|
|
14
|
+
constructor(viewer: TViewer, src: EdgeQuerySource<TSource, TDest, TViewer>, countLoaderFactory: AssocEdgeCountLoaderFactory, dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>, options: LoadEntOptions<TDest, TViewer> | loaderOptionsFunc<TViewer>);
|
|
15
15
|
private isEdgeQuery;
|
|
16
16
|
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
17
17
|
private getSingleID;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Data, EdgeQueryableDataOptions, Ent, ID, LoadEntOptions, Viewer } from "../base";
|
|
2
|
+
import { Clause } from "../clause";
|
|
3
|
+
import { BaseEdgeQuery, IDInfo } from "./query";
|
|
4
|
+
interface CustomClauseQueryOptions<TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
5
|
+
loadEntOptions: LoadEntOptions<TDest, TViewer>;
|
|
6
|
+
clause: Clause;
|
|
7
|
+
name: string;
|
|
8
|
+
sortColumn?: string;
|
|
9
|
+
disableTransformations?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare class CustomClauseQuery<TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<any, TDest, Data> {
|
|
12
|
+
viewer: TViewer;
|
|
13
|
+
private options;
|
|
14
|
+
private clause;
|
|
15
|
+
constructor(viewer: TViewer, options: CustomClauseQueryOptions<TDest, TViewer>);
|
|
16
|
+
sourceEnt(_id: ID): Promise<null>;
|
|
17
|
+
queryRawCount(): Promise<number>;
|
|
18
|
+
queryAllRawCount(): Promise<Map<ID, number>>;
|
|
19
|
+
protected loadRawIDs(_addID: (src: ID) => void): Promise<void>;
|
|
20
|
+
protected loadRawData(_infos: IDInfo[], options: EdgeQueryableDataOptions): Promise<void>;
|
|
21
|
+
dataToID(edge: Data): ID;
|
|
22
|
+
protected loadEntsFromEdges(id: ID, rows: Data[]): Promise<TDest[]>;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomClauseQuery = void 0;
|
|
4
|
+
const clause_1 = require("../clause");
|
|
5
|
+
const ent_1 = require("../ent");
|
|
6
|
+
const query_loader_1 = require("../loaders/query_loader");
|
|
7
|
+
const query_1 = require("./query");
|
|
8
|
+
function getClause(opts) {
|
|
9
|
+
let cls = opts.clause;
|
|
10
|
+
if (opts.disableTransformations) {
|
|
11
|
+
return cls;
|
|
12
|
+
}
|
|
13
|
+
let optClause = opts.loadEntOptions.loaderFactory?.options?.clause;
|
|
14
|
+
if (typeof optClause === "function") {
|
|
15
|
+
optClause = optClause();
|
|
16
|
+
}
|
|
17
|
+
if (!optClause) {
|
|
18
|
+
return cls;
|
|
19
|
+
}
|
|
20
|
+
return (0, clause_1.AndOptional)(cls, optClause);
|
|
21
|
+
}
|
|
22
|
+
class CustomClauseQuery extends query_1.BaseEdgeQuery {
|
|
23
|
+
constructor(viewer, options) {
|
|
24
|
+
super(viewer, options.sortColumn || "created_at");
|
|
25
|
+
this.viewer = viewer;
|
|
26
|
+
this.options = options;
|
|
27
|
+
this.clause = getClause(options);
|
|
28
|
+
}
|
|
29
|
+
async sourceEnt(_id) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
async queryRawCount() {
|
|
33
|
+
const row = await (0, ent_1.loadRow)({
|
|
34
|
+
tableName: this.options.loadEntOptions.tableName,
|
|
35
|
+
// sqlite needs as count otherwise it returns count(1)
|
|
36
|
+
fields: ["count(1) as count"],
|
|
37
|
+
clause: this.clause,
|
|
38
|
+
context: this.viewer.context,
|
|
39
|
+
});
|
|
40
|
+
return parseInt(row?.count, 10) || 0;
|
|
41
|
+
}
|
|
42
|
+
async queryAllRawCount() {
|
|
43
|
+
throw new Error(`queryAllRawCount doesn't make sense in CustomClauseQuery`);
|
|
44
|
+
}
|
|
45
|
+
// nothing to do here
|
|
46
|
+
async loadRawIDs(_addID) { }
|
|
47
|
+
async loadRawData(_infos, options) {
|
|
48
|
+
if (!options.orderby) {
|
|
49
|
+
options.orderby = `${this.options.sortColumn} DESC`;
|
|
50
|
+
}
|
|
51
|
+
if (!options.limit) {
|
|
52
|
+
options.limit = ent_1.DefaultLimit;
|
|
53
|
+
}
|
|
54
|
+
let sortCol = this.options.sortColumn || "created_at";
|
|
55
|
+
const rows = await (0, ent_1.loadRows)({
|
|
56
|
+
tableName: this.options.loadEntOptions.tableName,
|
|
57
|
+
fields: this.options.loadEntOptions.fields,
|
|
58
|
+
clause: (0, clause_1.AndOptional)(this.clause, options.clause),
|
|
59
|
+
orderby: (0, query_loader_1.getOrderBy)(sortCol, options?.orderby),
|
|
60
|
+
limit: options?.limit || ent_1.DefaultLimit,
|
|
61
|
+
context: this.viewer.context,
|
|
62
|
+
});
|
|
63
|
+
this.edges.set(1, rows);
|
|
64
|
+
}
|
|
65
|
+
dataToID(edge) {
|
|
66
|
+
return edge.id;
|
|
67
|
+
}
|
|
68
|
+
async loadEntsFromEdges(id, rows) {
|
|
69
|
+
return (0, ent_1.applyPrivacyPolicyForRows)(this.viewer, rows, this.options.loadEntOptions);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.CustomClauseQuery = CustomClauseQuery;
|
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
import { Data, Ent, ID, EdgeQueryableDataOptions, LoadEntOptions, Viewer, LoaderFactory, ConfigurableLoaderFactory } from "../base";
|
|
2
|
+
import { Clause } from "../clause";
|
|
2
3
|
import { BaseEdgeQuery, IDInfo, EdgeQuery } from "./query";
|
|
3
|
-
export interface
|
|
4
|
+
export interface CustomEdgeQueryOptionsDeprecated<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
4
5
|
src: TSource | ID;
|
|
5
6
|
countLoaderFactory: LoaderFactory<ID, number>;
|
|
6
7
|
dataLoaderFactory: ConfigurableLoaderFactory<ID, Data[]>;
|
|
7
|
-
options: LoadEntOptions<TDest>;
|
|
8
|
+
options: LoadEntOptions<TDest, TViewer>;
|
|
8
9
|
sortColumn?: string;
|
|
9
10
|
}
|
|
10
|
-
export
|
|
11
|
-
|
|
11
|
+
export interface CustomEdgeQueryOptions<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
12
|
+
src: TSource | ID;
|
|
13
|
+
loadEntOptions: LoadEntOptions<TDest, TViewer>;
|
|
14
|
+
groupCol?: string;
|
|
15
|
+
clause?: Clause;
|
|
16
|
+
name: string;
|
|
17
|
+
sortColumn?: string;
|
|
18
|
+
disableTransformations?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare abstract class CustomEdgeQueryBase<TSource extends Ent<TViewer>, TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<TSource, TDest, Data> implements EdgeQuery<TSource, TDest, Data> {
|
|
21
|
+
viewer: TViewer;
|
|
12
22
|
private options;
|
|
13
23
|
private id;
|
|
14
|
-
|
|
24
|
+
private opts;
|
|
25
|
+
constructor(viewer: TViewer, options: CustomEdgeQueryOptionsDeprecated<TSource, TDest, TViewer> | CustomEdgeQueryOptions<TSource, TDest, TViewer>);
|
|
15
26
|
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
16
27
|
private idVisible;
|
|
28
|
+
private isDeprecatedOptions;
|
|
29
|
+
private getCountLoader;
|
|
30
|
+
private getQueryLoader;
|
|
17
31
|
queryRawCount(): Promise<number>;
|
|
18
32
|
queryAllRawCount(): Promise<Map<ID, number>>;
|
|
19
33
|
protected loadRawIDs(addID: (src: ID | TSource) => void): Promise<void>;
|
|
34
|
+
private getLoadEntOptions;
|
|
20
35
|
protected loadRawData(infos: IDInfo[], options: EdgeQueryableDataOptions): Promise<void>;
|
|
21
36
|
dataToID(edge: Data): ID;
|
|
22
37
|
protected loadEntsFromEdges(id: ID, rows: Data[]): Promise<TDest[]>;
|
|
@@ -1,11 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CustomEdgeQueryBase = void 0;
|
|
4
|
+
const clause_1 = require("../clause");
|
|
4
5
|
const ent_1 = require("../ent");
|
|
6
|
+
const loaders_1 = require("../loaders");
|
|
5
7
|
const query_1 = require("./query");
|
|
8
|
+
function getClause(opts) {
|
|
9
|
+
let cls = opts.clause;
|
|
10
|
+
if (opts.disableTransformations) {
|
|
11
|
+
return cls;
|
|
12
|
+
}
|
|
13
|
+
let optClause = opts.loadEntOptions.loaderFactory?.options?.clause;
|
|
14
|
+
if (typeof optClause === "function") {
|
|
15
|
+
optClause = optClause();
|
|
16
|
+
}
|
|
17
|
+
if (!optClause) {
|
|
18
|
+
return cls;
|
|
19
|
+
}
|
|
20
|
+
return (0, clause_1.AndOptional)(cls, optClause);
|
|
21
|
+
}
|
|
22
|
+
function getRawCountLoader(viewer, opts) {
|
|
23
|
+
if (!viewer.context?.cache) {
|
|
24
|
+
return new loaders_1.RawCountLoader({
|
|
25
|
+
tableName: opts.loadEntOptions.tableName,
|
|
26
|
+
groupCol: opts.groupCol,
|
|
27
|
+
clause: getClause(opts),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const name = `custom_query_count_loader:${opts.name}`;
|
|
31
|
+
return viewer.context.cache.getLoader(name, () => new loaders_1.RawCountLoader({
|
|
32
|
+
tableName: opts.loadEntOptions.tableName,
|
|
33
|
+
groupCol: opts.groupCol,
|
|
34
|
+
clause: getClause(opts),
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
function getQueryLoader(viewer, opts, options) {
|
|
38
|
+
const loader = opts.loadEntOptions.loaderFactory;
|
|
39
|
+
const name = `custom_query_loader:${opts.name}`;
|
|
40
|
+
return loaders_1.QueryLoaderFactory.createConfigurableLoader(name, {
|
|
41
|
+
tableName: opts.loadEntOptions.tableName,
|
|
42
|
+
fields: opts.loadEntOptions.fields,
|
|
43
|
+
groupCol: opts.groupCol,
|
|
44
|
+
clause: getClause(opts),
|
|
45
|
+
toPrime: [loader],
|
|
46
|
+
}, options, viewer.context);
|
|
47
|
+
}
|
|
6
48
|
class CustomEdgeQueryBase extends query_1.BaseEdgeQuery {
|
|
7
49
|
constructor(viewer, options) {
|
|
8
|
-
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
super(viewer, options?.sortColumn || "created_at");
|
|
9
52
|
this.viewer = viewer;
|
|
10
53
|
this.options = options;
|
|
11
54
|
options.sortColumn = options.sortColumn || "created_at";
|
|
@@ -15,6 +58,7 @@ class CustomEdgeQueryBase extends query_1.BaseEdgeQuery {
|
|
|
15
58
|
else {
|
|
16
59
|
this.id = options.src;
|
|
17
60
|
}
|
|
61
|
+
this.opts = this.getLoadEntOptions();
|
|
18
62
|
}
|
|
19
63
|
async idVisible() {
|
|
20
64
|
const ids = await this.genIDInfosToFetch();
|
|
@@ -23,14 +67,28 @@ class CustomEdgeQueryBase extends query_1.BaseEdgeQuery {
|
|
|
23
67
|
}
|
|
24
68
|
return !ids[0].invalidated;
|
|
25
69
|
}
|
|
70
|
+
isDeprecatedOptions(options) {
|
|
71
|
+
return (options
|
|
72
|
+
.countLoaderFactory !== undefined);
|
|
73
|
+
}
|
|
74
|
+
getCountLoader() {
|
|
75
|
+
if (this.isDeprecatedOptions(this.options)) {
|
|
76
|
+
return this.options.countLoaderFactory.createLoader(this.viewer.context);
|
|
77
|
+
}
|
|
78
|
+
return getRawCountLoader(this.viewer, this.options);
|
|
79
|
+
}
|
|
80
|
+
getQueryLoader(options) {
|
|
81
|
+
if (this.isDeprecatedOptions(this.options)) {
|
|
82
|
+
return this.options.dataLoaderFactory.createConfigurableLoader(options, this.viewer.context);
|
|
83
|
+
}
|
|
84
|
+
return getQueryLoader(this.viewer, this.options, options);
|
|
85
|
+
}
|
|
26
86
|
async queryRawCount() {
|
|
27
87
|
const idVisible = await this.idVisible();
|
|
28
88
|
if (!idVisible) {
|
|
29
89
|
return 0;
|
|
30
90
|
}
|
|
31
|
-
return
|
|
32
|
-
.createLoader(this.viewer.context)
|
|
33
|
-
.load(this.id);
|
|
91
|
+
return this.getCountLoader().load(this.id);
|
|
34
92
|
}
|
|
35
93
|
async queryAllRawCount() {
|
|
36
94
|
let count = 0;
|
|
@@ -43,17 +101,27 @@ class CustomEdgeQueryBase extends query_1.BaseEdgeQuery {
|
|
|
43
101
|
async loadRawIDs(addID) {
|
|
44
102
|
addID(this.options.src);
|
|
45
103
|
}
|
|
104
|
+
getLoadEntOptions() {
|
|
105
|
+
let opts;
|
|
106
|
+
if (this.isDeprecatedOptions(this.options)) {
|
|
107
|
+
opts = this.options.options;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
opts = this.options.loadEntOptions;
|
|
111
|
+
}
|
|
112
|
+
return opts;
|
|
113
|
+
}
|
|
46
114
|
async loadRawData(infos, options) {
|
|
47
|
-
|
|
115
|
+
if (infos.length !== 1) {
|
|
116
|
+
throw new Error(`expected 1 info passed to loadRawData. ${infos.length} passed`);
|
|
117
|
+
}
|
|
48
118
|
if (!options.orderby) {
|
|
49
119
|
options.orderby = `${this.options.sortColumn} DESC`;
|
|
50
120
|
}
|
|
51
121
|
if (!options.limit) {
|
|
52
122
|
options.limit = ent_1.DefaultLimit;
|
|
53
123
|
}
|
|
54
|
-
|
|
55
|
-
throw new Error(`expected 1 info passed to loadRawData. ${infos.length} passed`);
|
|
56
|
-
}
|
|
124
|
+
const loader = this.getQueryLoader(options);
|
|
57
125
|
const info = infos[0];
|
|
58
126
|
if (info.invalidated) {
|
|
59
127
|
this.edges.set(this.id, []);
|
|
@@ -66,8 +134,7 @@ class CustomEdgeQueryBase extends query_1.BaseEdgeQuery {
|
|
|
66
134
|
return edge.id;
|
|
67
135
|
}
|
|
68
136
|
async loadEntsFromEdges(id, rows) {
|
|
69
|
-
|
|
70
|
-
return Array.from(ents.values());
|
|
137
|
+
return (0, ent_1.applyPrivacyPolicyForRows)(this.viewer, rows, this.opts);
|
|
71
138
|
}
|
|
72
139
|
}
|
|
73
140
|
exports.CustomEdgeQueryBase = CustomEdgeQueryBase;
|
package/core/query/index.d.ts
CHANGED
package/core/query/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CustomEdgeQueryBase = exports.AssocEdgeQueryBase = exports.BaseEdgeQuery = void 0;
|
|
3
|
+
exports.CustomClauseQuery = exports.CustomEdgeQueryBase = exports.AssocEdgeQueryBase = exports.BaseEdgeQuery = void 0;
|
|
4
4
|
var query_1 = require("./query");
|
|
5
5
|
Object.defineProperty(exports, "BaseEdgeQuery", { enumerable: true, get: function () { return query_1.BaseEdgeQuery; } });
|
|
6
6
|
var assoc_query_1 = require("./assoc_query");
|
|
7
7
|
Object.defineProperty(exports, "AssocEdgeQueryBase", { enumerable: true, get: function () { return assoc_query_1.AssocEdgeQueryBase; } });
|
|
8
8
|
var custom_query_1 = require("./custom_query");
|
|
9
9
|
Object.defineProperty(exports, "CustomEdgeQueryBase", { enumerable: true, get: function () { return custom_query_1.CustomEdgeQueryBase; } });
|
|
10
|
+
var custom_clause_query_1 = require("./custom_clause_query");
|
|
11
|
+
Object.defineProperty(exports, "CustomClauseQuery", { enumerable: true, get: function () { return custom_clause_query_1.CustomClauseQuery; } });
|
package/core/query/query.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare abstract class BaseEdgeQuery<TSource extends Ent, TDest extends E
|
|
|
41
41
|
private idMap;
|
|
42
42
|
private idsToFetch;
|
|
43
43
|
constructor(viewer: Viewer, sortCol: string);
|
|
44
|
-
getPrivacyPolicy(): PrivacyPolicy<Ent
|
|
44
|
+
getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
|
|
45
45
|
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
46
46
|
first(n: number, after?: string): this;
|
|
47
47
|
last(n: number, before?: string): this;
|
package/core/query/query.js
CHANGED
|
@@ -89,7 +89,13 @@ class FirstFilter {
|
|
|
89
89
|
// todo may not be desc
|
|
90
90
|
// and if asc
|
|
91
91
|
// clause below should switch to greater...
|
|
92
|
-
|
|
92
|
+
const sortCol = this.sortCol.toLowerCase();
|
|
93
|
+
if (sortCol.endsWith("desc") || sortCol.endsWith("asc")) {
|
|
94
|
+
options.orderby = `${this.sortCol}`;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
options.orderby = `${this.sortCol} DESC`;
|
|
98
|
+
}
|
|
93
99
|
// we sort by most recent first
|
|
94
100
|
// so when paging, we fetch afterCursor X
|
|
95
101
|
if (this.offset) {
|
|
@@ -100,6 +106,7 @@ class FirstFilter {
|
|
|
100
106
|
options.clause = clause.Less(this.sortCol, new Date(this.offset).toISOString());
|
|
101
107
|
}
|
|
102
108
|
}
|
|
109
|
+
// console.debug("filter opts", options, this.options);
|
|
103
110
|
return options;
|
|
104
111
|
}
|
|
105
112
|
// TODO?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function assocTests(): void;
|
|
1
|
+
export declare function assocTests(global?: boolean): void;
|
|
@@ -27,7 +27,7 @@ const jest_date_mock_1 = require("jest-date-mock");
|
|
|
27
27
|
const index_1 = require("../../testutils/fake_data/index");
|
|
28
28
|
const test_helpers_1 = require("../../testutils/fake_data/test_helpers");
|
|
29
29
|
const db_1 = __importStar(require("../db"));
|
|
30
|
-
function assocTests() {
|
|
30
|
+
function assocTests(global = false) {
|
|
31
31
|
describe("custom edge", () => {
|
|
32
32
|
let user1, user2;
|
|
33
33
|
beforeEach(async () => {
|
|
@@ -76,9 +76,16 @@ function assocTests() {
|
|
|
76
76
|
for (let i = 0; i < numQueries; i++) {
|
|
77
77
|
const query = queries[i];
|
|
78
78
|
let expLimit = disablePaginationBump ? limit : limit + 1;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
if (global) {
|
|
80
|
+
expect(query.qs?.whereClause, `${i}`).toBe(
|
|
81
|
+
// default limit
|
|
82
|
+
`id1 = $1 AND edge_type = $2 AND deleted_at IS NULL ORDER BY time DESC LIMIT ${expLimit}`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
expect(query.qs?.whereClause, `${i}`).toBe(
|
|
86
|
+
// default limit
|
|
87
|
+
`id1 = $1 AND edge_type = $2 ORDER BY time DESC LIMIT ${expLimit}`);
|
|
88
|
+
}
|
|
82
89
|
}
|
|
83
90
|
}
|
|
84
91
|
function verifyCountQuery({ length = 1, numQueries = 1 }) {
|
|
@@ -89,7 +96,12 @@ function assocTests() {
|
|
|
89
96
|
expect(queries.length).toBe(length);
|
|
90
97
|
for (let i = 0; i < numQueries; i++) {
|
|
91
98
|
const query = queries[i];
|
|
92
|
-
|
|
99
|
+
if (global) {
|
|
100
|
+
expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2 AND deleted_at IS NULL`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2`);
|
|
104
|
+
}
|
|
93
105
|
}
|
|
94
106
|
}
|
|
95
107
|
// TODO need to test multi-ids with id1s that aren't visible...
|
|
@@ -4,11 +4,14 @@ import { EdgeQuery } from "./query";
|
|
|
4
4
|
interface options<TData extends Data> {
|
|
5
5
|
newQuery: (v: Viewer, user: FakeUser) => EdgeQuery<FakeUser, FakeContact, TData>;
|
|
6
6
|
tableName: string;
|
|
7
|
+
uniqKey: string;
|
|
7
8
|
entsLength?: number;
|
|
8
9
|
where: string;
|
|
9
10
|
sortCol: string;
|
|
10
11
|
livePostgresDB?: boolean;
|
|
11
12
|
sqlite?: boolean;
|
|
13
|
+
globalSchema?: boolean;
|
|
14
|
+
rawDataVerify?(user: FakeUser): Promise<void>;
|
|
12
15
|
}
|
|
13
16
|
export declare const commonTests: <TData extends Data>(opts: options<TData>) => void;
|
|
14
17
|
export {};
|