@snowtop/ent 0.1.0-alpha160-test7 → 0.1.0-alpha160
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/core/query/shared_assoc_test.d.ts +2 -0
- package/core/query/shared_assoc_test.js +804 -0
- package/core/query/shared_test.d.ts +21 -0
- package/core/query/shared_test.js +736 -0
- package/graphql/query/shared_assoc_test.d.ts +1 -0
- package/graphql/query/shared_assoc_test.js +203 -0
- package/package.json +8 -53
- package/dist/package.json +0 -64
- package/src/action/action.ts +0 -330
- package/src/action/executor.ts +0 -453
- package/src/action/experimental_action.ts +0 -277
- package/src/action/index.ts +0 -31
- package/src/action/operations.ts +0 -967
- package/src/action/orchestrator.ts +0 -1527
- package/src/action/privacy.ts +0 -37
- package/src/action/relative_value.ts +0 -242
- package/src/action/transaction.ts +0 -38
- package/src/auth/auth.ts +0 -77
- package/src/auth/index.ts +0 -8
- package/src/core/base.ts +0 -367
- package/src/core/clause.ts +0 -1065
- package/src/core/config.ts +0 -219
- package/src/core/const.ts +0 -5
- package/src/core/context.ts +0 -135
- package/src/core/convert.ts +0 -106
- package/src/core/date.ts +0 -23
- package/src/core/db.ts +0 -498
- package/src/core/ent.ts +0 -1740
- package/src/core/global_schema.ts +0 -49
- package/src/core/loaders/assoc_count_loader.ts +0 -99
- package/src/core/loaders/assoc_edge_loader.ts +0 -250
- package/src/core/loaders/index.ts +0 -12
- package/src/core/loaders/loader.ts +0 -66
- package/src/core/loaders/object_loader.ts +0 -489
- package/src/core/loaders/query_loader.ts +0 -314
- package/src/core/loaders/raw_count_loader.ts +0 -175
- package/src/core/logger.ts +0 -49
- package/src/core/privacy.ts +0 -660
- package/src/core/query/assoc_query.ts +0 -240
- package/src/core/query/custom_clause_query.ts +0 -174
- package/src/core/query/custom_query.ts +0 -302
- package/src/core/query/index.ts +0 -9
- package/src/core/query/query.ts +0 -674
- package/src/core/query_impl.ts +0 -32
- package/src/core/viewer.ts +0 -52
- package/src/ent.code-workspace +0 -73
- package/src/graphql/builtins/connection.ts +0 -25
- package/src/graphql/builtins/edge.ts +0 -16
- package/src/graphql/builtins/node.ts +0 -12
- package/src/graphql/graphql.ts +0 -891
- package/src/graphql/graphql_field_helpers.ts +0 -221
- package/src/graphql/index.ts +0 -42
- package/src/graphql/mutations/union.ts +0 -39
- package/src/graphql/node_resolver.ts +0 -122
- package/src/graphql/query/connection_type.ts +0 -113
- package/src/graphql/query/edge_connection.ts +0 -171
- package/src/graphql/query/page_info.ts +0 -34
- package/src/graphql/query/shared_edge_connection.ts +0 -287
- package/src/graphql/scalars/orderby_direction.ts +0 -13
- package/src/graphql/scalars/time.ts +0 -38
- package/src/imports/dataz/example1/_auth.ts +0 -51
- package/src/imports/dataz/example1/_viewer.ts +0 -35
- package/src/imports/index.ts +0 -213
- package/src/index.ts +0 -145
- package/src/parse_schema/parse.ts +0 -585
- package/src/schema/base_schema.ts +0 -224
- package/src/schema/field.ts +0 -1087
- package/src/schema/index.ts +0 -53
- package/src/schema/json_field.ts +0 -94
- package/src/schema/schema.ts +0 -1028
- package/src/schema/struct_field.ts +0 -234
- package/src/schema/union_field.ts +0 -105
- package/src/scripts/custom_compiler.ts +0 -331
- package/src/scripts/custom_graphql.ts +0 -550
- package/src/scripts/migrate_v0.1.ts +0 -41
- package/src/scripts/move_types.ts +0 -131
- package/src/scripts/read_schema.ts +0 -67
- package/src/setupPackage.js +0 -42
- package/src/testutils/action/complex_schemas.ts +0 -517
- package/src/testutils/builder.ts +0 -422
- package/src/testutils/context/test_context.ts +0 -25
- package/src/testutils/db/fixture.ts +0 -32
- package/src/testutils/db/temp_db.ts +0 -941
- package/src/testutils/db/value.ts +0 -294
- package/src/testutils/db_mock.ts +0 -351
- package/src/testutils/db_time_zone.ts +0 -40
- package/src/testutils/ent-graphql-tests/index.ts +0 -653
- package/src/testutils/fake_comms.ts +0 -50
- package/src/testutils/fake_data/const.ts +0 -64
- package/src/testutils/fake_data/events_query.ts +0 -145
- package/src/testutils/fake_data/fake_contact.ts +0 -150
- package/src/testutils/fake_data/fake_event.ts +0 -150
- package/src/testutils/fake_data/fake_tag.ts +0 -139
- package/src/testutils/fake_data/fake_user.ts +0 -232
- package/src/testutils/fake_data/index.ts +0 -1
- package/src/testutils/fake_data/internal.ts +0 -8
- package/src/testutils/fake_data/tag_query.ts +0 -56
- package/src/testutils/fake_data/test_helpers.ts +0 -388
- package/src/testutils/fake_data/user_query.ts +0 -524
- package/src/testutils/fake_log.ts +0 -52
- package/src/testutils/mock_date.ts +0 -10
- package/src/testutils/mock_log.ts +0 -39
- package/src/testutils/parse_sql.ts +0 -685
- package/src/testutils/test_edge_global_schema.ts +0 -49
- package/src/testutils/write.ts +0 -70
- package/src/tsc/ast.ts +0 -351
- package/src/tsc/compilerOptions.ts +0 -85
- package/src/tsc/move_generated.ts +0 -191
- package/src/tsc/transform.ts +0 -226
- package/src/tsc/transform_action.ts +0 -224
- package/src/tsc/transform_ent.ts +0 -66
- package/src/tsc/transform_schema.ts +0 -546
- package/tsconfig.json +0 -20
- /package/{dist/action → action}/action.d.ts +0 -0
- /package/{dist/action → action}/action.js +0 -0
- /package/{dist/action → action}/executor.d.ts +0 -0
- /package/{dist/action → action}/executor.js +0 -0
- /package/{dist/action → action}/experimental_action.d.ts +0 -0
- /package/{dist/action → action}/experimental_action.js +0 -0
- /package/{dist/action → action}/index.d.ts +0 -0
- /package/{dist/action → action}/index.js +0 -0
- /package/{dist/action → action}/operations.d.ts +0 -0
- /package/{dist/action → action}/operations.js +0 -0
- /package/{dist/action → action}/orchestrator.d.ts +0 -0
- /package/{dist/action → action}/orchestrator.js +0 -0
- /package/{dist/action → action}/privacy.d.ts +0 -0
- /package/{dist/action → action}/privacy.js +0 -0
- /package/{dist/action → action}/relative_value.d.ts +0 -0
- /package/{dist/action → action}/relative_value.js +0 -0
- /package/{dist/action → action}/transaction.d.ts +0 -0
- /package/{dist/action → action}/transaction.js +0 -0
- /package/{dist/auth → auth}/auth.d.ts +0 -0
- /package/{dist/auth → auth}/auth.js +0 -0
- /package/{dist/auth → auth}/index.d.ts +0 -0
- /package/{dist/auth → auth}/index.js +0 -0
- /package/{dist/core → core}/base.d.ts +0 -0
- /package/{dist/core → core}/base.js +0 -0
- /package/{dist/core → core}/clause.d.ts +0 -0
- /package/{dist/core → core}/clause.js +0 -0
- /package/{dist/core → core}/config.d.ts +0 -0
- /package/{dist/core → core}/config.js +0 -0
- /package/{dist/core → core}/const.d.ts +0 -0
- /package/{dist/core → core}/const.js +0 -0
- /package/{dist/core → core}/context.d.ts +0 -0
- /package/{dist/core → core}/context.js +0 -0
- /package/{dist/core → core}/convert.d.ts +0 -0
- /package/{dist/core → core}/convert.js +0 -0
- /package/{dist/core → core}/date.d.ts +0 -0
- /package/{dist/core → core}/date.js +0 -0
- /package/{dist/core → core}/db.d.ts +0 -0
- /package/{dist/core → core}/db.js +0 -0
- /package/{dist/core → core}/ent.d.ts +0 -0
- /package/{dist/core → core}/ent.js +0 -0
- /package/{dist/core → core}/global_schema.d.ts +0 -0
- /package/{dist/core → core}/global_schema.js +0 -0
- /package/{dist/core → core}/loaders/assoc_count_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/assoc_count_loader.js +0 -0
- /package/{dist/core → core}/loaders/assoc_edge_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/assoc_edge_loader.js +0 -0
- /package/{dist/core → core}/loaders/index.d.ts +0 -0
- /package/{dist/core → core}/loaders/index.js +0 -0
- /package/{dist/core → core}/loaders/loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/loader.js +0 -0
- /package/{dist/core → core}/loaders/object_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/object_loader.js +0 -0
- /package/{dist/core → core}/loaders/query_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/query_loader.js +0 -0
- /package/{dist/core → core}/loaders/raw_count_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/raw_count_loader.js +0 -0
- /package/{dist/core → core}/logger.d.ts +0 -0
- /package/{dist/core → core}/logger.js +0 -0
- /package/{dist/core → core}/privacy.d.ts +0 -0
- /package/{dist/core → core}/privacy.js +0 -0
- /package/{dist/core → core}/query/assoc_query.d.ts +0 -0
- /package/{dist/core → core}/query/assoc_query.js +0 -0
- /package/{dist/core → core}/query/custom_clause_query.d.ts +0 -0
- /package/{dist/core → core}/query/custom_clause_query.js +0 -0
- /package/{dist/core → core}/query/custom_query.d.ts +0 -0
- /package/{dist/core → core}/query/custom_query.js +0 -0
- /package/{dist/core → core}/query/index.d.ts +0 -0
- /package/{dist/core → core}/query/index.js +0 -0
- /package/{dist/core → core}/query/query.d.ts +0 -0
- /package/{dist/core → core}/query/query.js +0 -0
- /package/{dist/core → core}/query_impl.d.ts +0 -0
- /package/{dist/core → core}/query_impl.js +0 -0
- /package/{dist/core → core}/viewer.d.ts +0 -0
- /package/{dist/core → core}/viewer.js +0 -0
- /package/{dist/graphql → graphql}/builtins/connection.d.ts +0 -0
- /package/{dist/graphql → graphql}/builtins/connection.js +0 -0
- /package/{dist/graphql → graphql}/builtins/edge.d.ts +0 -0
- /package/{dist/graphql → graphql}/builtins/edge.js +0 -0
- /package/{dist/graphql → graphql}/builtins/node.d.ts +0 -0
- /package/{dist/graphql → graphql}/builtins/node.js +0 -0
- /package/{dist/graphql → graphql}/graphql.d.ts +0 -0
- /package/{dist/graphql → graphql}/graphql.js +0 -0
- /package/{dist/graphql → graphql}/graphql_field_helpers.d.ts +0 -0
- /package/{dist/graphql → graphql}/graphql_field_helpers.js +0 -0
- /package/{dist/graphql → graphql}/index.d.ts +0 -0
- /package/{dist/graphql → graphql}/index.js +0 -0
- /package/{dist/graphql → graphql}/mutations/union.d.ts +0 -0
- /package/{dist/graphql → graphql}/mutations/union.js +0 -0
- /package/{dist/graphql → graphql}/node_resolver.d.ts +0 -0
- /package/{dist/graphql → graphql}/node_resolver.js +0 -0
- /package/{dist/graphql → graphql}/query/connection_type.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/connection_type.js +0 -0
- /package/{dist/graphql → graphql}/query/edge_connection.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/edge_connection.js +0 -0
- /package/{dist/graphql → graphql}/query/page_info.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/page_info.js +0 -0
- /package/{dist/graphql → graphql}/query/shared_edge_connection.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/shared_edge_connection.js +0 -0
- /package/{dist/graphql → graphql}/scalars/orderby_direction.d.ts +0 -0
- /package/{dist/graphql → graphql}/scalars/orderby_direction.js +0 -0
- /package/{dist/graphql → graphql}/scalars/time.d.ts +0 -0
- /package/{dist/graphql → graphql}/scalars/time.js +0 -0
- /package/{dist/imports → imports}/dataz/example1/_auth.d.ts +0 -0
- /package/{dist/imports → imports}/dataz/example1/_auth.js +0 -0
- /package/{dist/imports → imports}/dataz/example1/_viewer.d.ts +0 -0
- /package/{dist/imports → imports}/dataz/example1/_viewer.js +0 -0
- /package/{dist/imports → imports}/index.d.ts +0 -0
- /package/{dist/imports → imports}/index.js +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
- /package/{dist/index.js → index.js} +0 -0
- /package/{dist/parse_schema → parse_schema}/parse.d.ts +0 -0
- /package/{dist/parse_schema → parse_schema}/parse.js +0 -0
- /package/{dist/schema → schema}/base_schema.d.ts +0 -0
- /package/{dist/schema → schema}/base_schema.js +0 -0
- /package/{dist/schema → schema}/field.d.ts +0 -0
- /package/{dist/schema → schema}/field.js +0 -0
- /package/{dist/schema → schema}/index.d.ts +0 -0
- /package/{dist/schema → schema}/index.js +0 -0
- /package/{dist/schema → schema}/json_field.d.ts +0 -0
- /package/{dist/schema → schema}/json_field.js +0 -0
- /package/{dist/schema → schema}/schema.d.ts +0 -0
- /package/{dist/schema → schema}/schema.js +0 -0
- /package/{dist/schema → schema}/struct_field.d.ts +0 -0
- /package/{dist/schema → schema}/struct_field.js +0 -0
- /package/{dist/schema → schema}/union_field.d.ts +0 -0
- /package/{dist/schema → schema}/union_field.js +0 -0
- /package/{dist/scripts → scripts}/custom_compiler.d.ts +0 -0
- /package/{dist/scripts → scripts}/custom_compiler.js +0 -0
- /package/{dist/scripts → scripts}/custom_graphql.d.ts +0 -0
- /package/{dist/scripts → scripts}/custom_graphql.js +0 -0
- /package/{dist/scripts → scripts}/migrate_v0.1.d.ts +0 -0
- /package/{dist/scripts → scripts}/migrate_v0.1.js +0 -0
- /package/{dist/scripts → scripts}/move_types.d.ts +0 -0
- /package/{dist/scripts → scripts}/move_types.js +0 -0
- /package/{dist/scripts → scripts}/read_schema.d.ts +0 -0
- /package/{dist/scripts → scripts}/read_schema.js +0 -0
- /package/{dist/testutils → testutils}/action/complex_schemas.d.ts +0 -0
- /package/{dist/testutils → testutils}/action/complex_schemas.js +0 -0
- /package/{dist/testutils → testutils}/builder.d.ts +0 -0
- /package/{dist/testutils → testutils}/builder.js +0 -0
- /package/{dist/testutils → testutils}/context/test_context.d.ts +0 -0
- /package/{dist/testutils → testutils}/context/test_context.js +0 -0
- /package/{dist/testutils → testutils}/db/fixture.d.ts +0 -0
- /package/{dist/testutils → testutils}/db/fixture.js +0 -0
- /package/{dist/testutils → testutils}/db/temp_db.d.ts +0 -0
- /package/{dist/testutils → testutils}/db/temp_db.js +0 -0
- /package/{dist/testutils → testutils}/db/value.d.ts +0 -0
- /package/{dist/testutils → testutils}/db/value.js +0 -0
- /package/{dist/testutils → testutils}/db_mock.d.ts +0 -0
- /package/{dist/testutils → testutils}/db_mock.js +0 -0
- /package/{dist/testutils → testutils}/db_time_zone.d.ts +0 -0
- /package/{dist/testutils → testutils}/db_time_zone.js +0 -0
- /package/{dist/testutils → testutils}/ent-graphql-tests/index.d.ts +0 -0
- /package/{dist/testutils → testutils}/ent-graphql-tests/index.js +0 -0
- /package/{dist/testutils → testutils}/fake_comms.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_comms.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/const.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/const.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/events_query.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/events_query.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_contact.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_contact.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_event.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_event.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_tag.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_tag.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_user.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_user.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/index.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/index.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/internal.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/internal.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/tag_query.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/tag_query.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/test_helpers.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/test_helpers.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/user_query.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/user_query.js +0 -0
- /package/{dist/testutils → testutils}/fake_log.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_log.js +0 -0
- /package/{dist/testutils → testutils}/mock_date.d.ts +0 -0
- /package/{dist/testutils → testutils}/mock_date.js +0 -0
- /package/{dist/testutils → testutils}/mock_log.d.ts +0 -0
- /package/{dist/testutils → testutils}/mock_log.js +0 -0
- /package/{dist/testutils → testutils}/parse_sql.d.ts +0 -0
- /package/{dist/testutils → testutils}/parse_sql.js +0 -0
- /package/{dist/testutils → testutils}/test_edge_global_schema.d.ts +0 -0
- /package/{dist/testutils → testutils}/test_edge_global_schema.js +0 -0
- /package/{dist/testutils → testutils}/write.d.ts +0 -0
- /package/{dist/testutils → testutils}/write.js +0 -0
- /package/{dist/tsc → tsc}/ast.d.ts +0 -0
- /package/{dist/tsc → tsc}/ast.js +0 -0
- /package/{dist/tsc → tsc}/compilerOptions.d.ts +0 -0
- /package/{dist/tsc → tsc}/compilerOptions.js +0 -0
- /package/{dist/tsc → tsc}/move_generated.d.ts +0 -0
- /package/{dist/tsc → tsc}/move_generated.js +0 -0
- /package/{dist/tsc → tsc}/transform.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform.js +0 -0
- /package/{dist/tsc → tsc}/transform_action.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform_action.js +0 -0
- /package/{dist/tsc → tsc}/transform_ent.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform_ent.js +0 -0
- /package/{dist/tsc → tsc}/transform_schema.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform_schema.js +0 -0
package/src/core/query/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
EdgeQuery,
|
|
3
|
-
BaseEdgeQuery,
|
|
4
|
-
EdgeQueryFilter,
|
|
5
|
-
PaginationInfo,
|
|
6
|
-
} from "./query";
|
|
7
|
-
export { AssocEdgeQueryBase, EdgeQuerySource } from "./assoc_query";
|
|
8
|
-
export { CustomEdgeQueryBase } from "./custom_query";
|
|
9
|
-
export { CustomClauseQuery } from "./custom_clause_query";
|
package/src/core/query/query.ts
DELETED
|
@@ -1,674 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ID,
|
|
3
|
-
Ent,
|
|
4
|
-
Viewer,
|
|
5
|
-
EdgeQueryableDataOptions,
|
|
6
|
-
Data,
|
|
7
|
-
PrivacyPolicy,
|
|
8
|
-
EdgeQueryableDataOptionsConfigureLoader,
|
|
9
|
-
} from "../base";
|
|
10
|
-
import { getDefaultLimit, getCursor } from "../ent";
|
|
11
|
-
import * as clause from "../clause";
|
|
12
|
-
import memoize from "memoizee";
|
|
13
|
-
import { AlwaysAllowPrivacyPolicy, applyPrivacyPolicy } from "../privacy";
|
|
14
|
-
import { validate } from "uuid";
|
|
15
|
-
import { OrderBy, reverseOrderBy } from "../query_impl";
|
|
16
|
-
import { isPromise } from "util/types";
|
|
17
|
-
|
|
18
|
-
export interface EdgeQuery<
|
|
19
|
-
TSource extends Ent,
|
|
20
|
-
TDest extends Ent,
|
|
21
|
-
TEdge extends Data,
|
|
22
|
-
> {
|
|
23
|
-
// if more than one, the single-version methods should throw
|
|
24
|
-
|
|
25
|
-
// TODO determine if these should return null if the edge isn't visible
|
|
26
|
-
// might be helpful to have the distinction in the API where null = privacy check failed and []|0 etc equals no data
|
|
27
|
-
queryEdges(): Promise<TEdge[]>;
|
|
28
|
-
queryAllEdges(): Promise<Map<ID, TEdge[]>>;
|
|
29
|
-
queryIDs(): Promise<ID[]>;
|
|
30
|
-
queryAllIDs(): Promise<Map<ID, ID[]>>;
|
|
31
|
-
queryCount(): Promise<number>;
|
|
32
|
-
queryAllCount(): Promise<Map<ID, number>>;
|
|
33
|
-
queryRawCount(): Promise<number>;
|
|
34
|
-
queryAllRawCount(): Promise<Map<ID, number>>;
|
|
35
|
-
queryEnts(): Promise<TDest[]>;
|
|
36
|
-
queryAllEnts(): Promise<Map<ID, TDest[]>>;
|
|
37
|
-
|
|
38
|
-
first(n: number, after?: string): EdgeQuery<TSource, TDest, TEdge>;
|
|
39
|
-
last(n: number, before?: string): EdgeQuery<TSource, TDest, TEdge>;
|
|
40
|
-
|
|
41
|
-
paginationInfo(): Map<ID, PaginationInfo>;
|
|
42
|
-
getCursor(row: TEdge): string;
|
|
43
|
-
dataToID(edge: TEdge): ID;
|
|
44
|
-
|
|
45
|
-
getPrivacyPolicy(): PrivacyPolicy;
|
|
46
|
-
|
|
47
|
-
// there's no requirement that you have to be able to see
|
|
48
|
-
// an ent to see edges from that ent so the ent is optional
|
|
49
|
-
// however, a few privacy policies and rules are dependent on the Ent so we try and load
|
|
50
|
-
// the Ent if the ent isn't passed as the source to the query.
|
|
51
|
-
// If the Viewer can see the Ent, that's what's passed to the Privacy Policies
|
|
52
|
-
// to determine if the edge is visible
|
|
53
|
-
sourceEnt(id: ID): Promise<Ent | null>;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
//maybe id2 shouldn't return EdgeQuery but a different object from which you can query edge. the ent you don't need to query since you can just query that on your own.
|
|
57
|
-
|
|
58
|
-
export interface EdgeQueryFilter<T extends Data> {
|
|
59
|
-
// this is a filter that does the processing in TypeScript instead of (or in addition to) the SQL layer
|
|
60
|
-
filter?(id: ID, edges: T[]): T[];
|
|
61
|
-
|
|
62
|
-
// there's 2 ways to do it.
|
|
63
|
-
// apply it in SQL
|
|
64
|
-
// or process it after the fact
|
|
65
|
-
query?(
|
|
66
|
-
options: EdgeQueryableDataOptions,
|
|
67
|
-
): EdgeQueryableDataOptions | Promise<EdgeQueryableDataOptions>;
|
|
68
|
-
// maybe it's a dynamic decision to do so and then query returns what was passed to it and filter returns what was passed to it based on the decision flow
|
|
69
|
-
// preProcess
|
|
70
|
-
|
|
71
|
-
// filter affects pagination.
|
|
72
|
-
// If filter implements this and returns a value, we use that info for the pagination details
|
|
73
|
-
// if we somehow have multiple filters in a query that use this, behavior is undefined
|
|
74
|
-
paginationInfo?(id: ID): PaginationInfo | undefined;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface PaginationInfo {
|
|
78
|
-
hasNextPage: boolean;
|
|
79
|
-
hasPreviousPage: boolean;
|
|
80
|
-
startCursor: string;
|
|
81
|
-
endCursor: string;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// TODO can we generalize EdgeQuery to support any clause
|
|
85
|
-
function assertPositive(n: number) {
|
|
86
|
-
if (n < 0) {
|
|
87
|
-
throw new Error("cannot use a negative number");
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function assertValidCursor(cursor: string, col: string): any {
|
|
92
|
-
let decoded = Buffer.from(cursor, "base64").toString("ascii");
|
|
93
|
-
let parts = decoded.split(":");
|
|
94
|
-
// uuid, don't parse int since it tries to validate just first part
|
|
95
|
-
if (validate(parts[1])) {
|
|
96
|
-
return parts[1];
|
|
97
|
-
}
|
|
98
|
-
// invalid or unknown cursor. nothing to do here.
|
|
99
|
-
if (parts.length !== 2 || parts[0] !== col) {
|
|
100
|
-
throw new Error(`invalid cursor ${cursor} passed`);
|
|
101
|
-
}
|
|
102
|
-
// TODO handle both cases... (time vs not) better
|
|
103
|
-
// TODO change this to only do the parseInt part if time...
|
|
104
|
-
// pass flag indicating if time?
|
|
105
|
-
const time = parseInt(parts[1], 10);
|
|
106
|
-
if (isNaN(time)) {
|
|
107
|
-
return parts[1];
|
|
108
|
-
}
|
|
109
|
-
return time;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
interface FilterOptions<T extends Data> {
|
|
113
|
-
limit: number;
|
|
114
|
-
query: BaseEdgeQuery<Ent, Ent, T>;
|
|
115
|
-
sortCol: string;
|
|
116
|
-
cursorCol: string;
|
|
117
|
-
orderby: OrderBy;
|
|
118
|
-
// TODO provide this option
|
|
119
|
-
// if sortCol is Unique and time, we need to pass different values for comparisons and checks...
|
|
120
|
-
sortColTime?: boolean;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
interface FirstFilterOptions<T extends Data> extends FilterOptions<T> {
|
|
124
|
-
after?: string;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
interface LastFilterOptions<T extends Data> extends FilterOptions<T> {
|
|
128
|
-
before?: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const orderbyRegex = new RegExp(/([0-9a-z_]+)[ ]?([0-9a-z_]+)?/i);
|
|
132
|
-
|
|
133
|
-
class FirstFilter<T extends Data> implements EdgeQueryFilter<T> {
|
|
134
|
-
private offset: any | undefined;
|
|
135
|
-
private sortCol: string;
|
|
136
|
-
private edgeQuery: BaseEdgeQuery<Ent, Ent, T>;
|
|
137
|
-
private pageMap: Map<ID, PaginationInfo> = new Map();
|
|
138
|
-
|
|
139
|
-
constructor(private options: FirstFilterOptions<T>) {
|
|
140
|
-
assertPositive(options.limit);
|
|
141
|
-
|
|
142
|
-
this.sortCol = options.sortCol;
|
|
143
|
-
if (options.after) {
|
|
144
|
-
this.offset = assertValidCursor(options.after, options.cursorCol);
|
|
145
|
-
}
|
|
146
|
-
this.edgeQuery = options.query;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
filter(id: ID, edges: T[]): T[] {
|
|
150
|
-
if (edges.length > this.options.limit) {
|
|
151
|
-
const ret = edges.slice(0, this.options.limit);
|
|
152
|
-
this.pageMap.set(id, {
|
|
153
|
-
hasNextPage: true,
|
|
154
|
-
// hasPreviousPage always false even if there's a previous page because
|
|
155
|
-
// we shouldn't be querying in both directions at the same
|
|
156
|
-
hasPreviousPage: false,
|
|
157
|
-
startCursor: this.edgeQuery.getCursor(ret[0]),
|
|
158
|
-
endCursor: this.edgeQuery.getCursor(ret[ret.length - 1]),
|
|
159
|
-
});
|
|
160
|
-
return ret;
|
|
161
|
-
}
|
|
162
|
-
// TODO: in the future, when we have caching for edges
|
|
163
|
-
// we'll want to hit that cache instead of passing the limit down to the
|
|
164
|
-
// SQL query so we'll need a way to indicate whether this is done in SQL or not
|
|
165
|
-
// and then the slice will always happen
|
|
166
|
-
// so we'd need a way to indicate whether this is done in sql or not
|
|
167
|
-
return edges;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async query(
|
|
171
|
-
options: EdgeQueryableDataOptions,
|
|
172
|
-
): Promise<EdgeQueryableDataOptions> {
|
|
173
|
-
// we fetch an extra one to see if we're at the end
|
|
174
|
-
const limit = this.options.limit + 1;
|
|
175
|
-
|
|
176
|
-
options.limit = limit;
|
|
177
|
-
|
|
178
|
-
// we sort by most recent first
|
|
179
|
-
// so when paging, we fetch afterCursor X
|
|
180
|
-
const less = this.options.orderby[0].direction === "DESC";
|
|
181
|
-
const orderby = this.options.orderby;
|
|
182
|
-
|
|
183
|
-
if (this.options.cursorCol !== this.sortCol) {
|
|
184
|
-
// we also sort cursor col in same direction. (direction doesn't matter)
|
|
185
|
-
orderby.push({
|
|
186
|
-
column: this.options.cursorCol,
|
|
187
|
-
direction: orderby[0].direction,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
if (this.offset) {
|
|
191
|
-
const res = this.edgeQuery.getTableName();
|
|
192
|
-
const tableName = isPromise(res) ? await res : res;
|
|
193
|
-
// inner col time
|
|
194
|
-
options.clause = clause.PaginationMultipleColsSubQuery(
|
|
195
|
-
this.sortCol,
|
|
196
|
-
less ? "<" : ">",
|
|
197
|
-
tableName,
|
|
198
|
-
this.options.cursorCol,
|
|
199
|
-
this.offset,
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
} else {
|
|
203
|
-
if (this.offset) {
|
|
204
|
-
let clauseFn = less ? clause.Less : clause.Greater;
|
|
205
|
-
let val = this.options.sortColTime
|
|
206
|
-
? new Date(this.offset).toISOString()
|
|
207
|
-
: this.offset;
|
|
208
|
-
options.clause = clauseFn(this.sortCol, val);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
options.orderby = orderby;
|
|
212
|
-
|
|
213
|
-
return options;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// TODO?
|
|
217
|
-
paginationInfo(id: ID): PaginationInfo | undefined {
|
|
218
|
-
return this.pageMap.get(id);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
class LastFilter<T extends Data> implements EdgeQueryFilter<T> {
|
|
223
|
-
private offset: any | undefined;
|
|
224
|
-
private sortCol: string;
|
|
225
|
-
private pageMap: Map<ID, PaginationInfo> = new Map();
|
|
226
|
-
private edgeQuery: BaseEdgeQuery<Ent, Ent, T>;
|
|
227
|
-
|
|
228
|
-
constructor(private options: LastFilterOptions<T>) {
|
|
229
|
-
assertPositive(options.limit);
|
|
230
|
-
|
|
231
|
-
this.sortCol = options.sortCol;
|
|
232
|
-
if (options.before) {
|
|
233
|
-
this.offset = assertValidCursor(options.before, options.cursorCol);
|
|
234
|
-
}
|
|
235
|
-
this.edgeQuery = options.query;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
filter(id: ID, edges: T[]): T[] {
|
|
239
|
-
let ret: T[] = [];
|
|
240
|
-
if (this.offset) {
|
|
241
|
-
// we have an extra one, get rid of it. we only got it to see if hasPreviousPage = true
|
|
242
|
-
if (edges.length > this.options.limit) {
|
|
243
|
-
ret = edges.slice(0, edges.length - 1);
|
|
244
|
-
} else {
|
|
245
|
-
// done in SQL. nothing to do here.
|
|
246
|
-
ret = edges;
|
|
247
|
-
}
|
|
248
|
-
} else {
|
|
249
|
-
ret = edges.slice(0, this.options.limit);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (edges.length > this.options.limit) {
|
|
253
|
-
this.pageMap.set(id, {
|
|
254
|
-
hasPreviousPage: true,
|
|
255
|
-
// hasNextPage always false even if there's a next page because
|
|
256
|
-
// we shouldn't be querying in both directions at the same
|
|
257
|
-
hasNextPage: false,
|
|
258
|
-
startCursor: this.edgeQuery.getCursor(ret[0]),
|
|
259
|
-
endCursor: this.edgeQuery.getCursor(ret[ret.length - 1]),
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
return ret;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
async query(
|
|
266
|
-
options: EdgeQueryableDataOptions,
|
|
267
|
-
): Promise<EdgeQueryableDataOptions> {
|
|
268
|
-
const orderby = reverseOrderBy(this.options.orderby);
|
|
269
|
-
const greater = orderby[0].direction === "ASC";
|
|
270
|
-
|
|
271
|
-
options.limit = this.options.limit + 1; // fetch an extra so we know if previous pag
|
|
272
|
-
|
|
273
|
-
if (this.options.cursorCol !== this.sortCol) {
|
|
274
|
-
const res = this.edgeQuery.getTableName();
|
|
275
|
-
const tableName = isPromise(res) ? await res : res;
|
|
276
|
-
|
|
277
|
-
if (this.offset) {
|
|
278
|
-
// inner col time
|
|
279
|
-
options.clause = clause.PaginationMultipleColsSubQuery(
|
|
280
|
-
this.sortCol,
|
|
281
|
-
greater ? ">" : "<",
|
|
282
|
-
tableName,
|
|
283
|
-
this.options.cursorCol,
|
|
284
|
-
this.offset,
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
// we also sort cursor col in same direction. (direction doesn't matter)
|
|
288
|
-
orderby.push({
|
|
289
|
-
column: this.options.cursorCol,
|
|
290
|
-
direction: orderby[0].direction,
|
|
291
|
-
});
|
|
292
|
-
} else {
|
|
293
|
-
if (this.offset) {
|
|
294
|
-
let clauseFn = greater ? clause.Greater : clause.Less;
|
|
295
|
-
let val = this.options.sortColTime
|
|
296
|
-
? new Date(this.offset).toISOString()
|
|
297
|
-
: this.offset;
|
|
298
|
-
options.clause = clauseFn(this.sortCol, val);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
options.orderby = orderby;
|
|
302
|
-
|
|
303
|
-
return options;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
paginationInfo(id: ID): PaginationInfo | undefined {
|
|
307
|
-
return this.pageMap.get(id);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
interface EdgeQueryOptions {
|
|
312
|
-
cursorCol: string;
|
|
313
|
-
orderby: OrderBy;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
export abstract class BaseEdgeQuery<
|
|
317
|
-
TSource extends Ent,
|
|
318
|
-
TDest extends Ent,
|
|
319
|
-
TEdge extends Data,
|
|
320
|
-
> implements EdgeQuery<TSource, TDest, TEdge>
|
|
321
|
-
{
|
|
322
|
-
private filters: EdgeQueryFilter<TEdge>[] = [];
|
|
323
|
-
private queryDispatched: boolean;
|
|
324
|
-
protected edges: Map<ID, TEdge[]> = new Map();
|
|
325
|
-
private pagination: Map<ID, PaginationInfo> = new Map();
|
|
326
|
-
private memoizedloadEdges: () => Promise<Map<ID, TEdge[]>>;
|
|
327
|
-
protected genIDInfosToFetch: () => Promise<IDInfo[]>;
|
|
328
|
-
private idMap: Map<ID, TSource> = new Map();
|
|
329
|
-
private idsToFetch: ID[] = [];
|
|
330
|
-
private sortCol: string;
|
|
331
|
-
private cursorCol: string;
|
|
332
|
-
private edgeQueryOptions: EdgeQueryOptions;
|
|
333
|
-
|
|
334
|
-
constructor(viewer: Viewer, sortCol: string, cursorCol: string);
|
|
335
|
-
constructor(viewer: Viewer, options: EdgeQueryOptions);
|
|
336
|
-
|
|
337
|
-
constructor(
|
|
338
|
-
public viewer: Viewer,
|
|
339
|
-
sortColOrOptions: string | EdgeQueryOptions,
|
|
340
|
-
cursorColMaybe?: string,
|
|
341
|
-
) {
|
|
342
|
-
let sortCol: string;
|
|
343
|
-
let cursorCol: string;
|
|
344
|
-
if (typeof sortColOrOptions === "string") {
|
|
345
|
-
sortCol = sortColOrOptions;
|
|
346
|
-
cursorCol = cursorColMaybe!;
|
|
347
|
-
this.edgeQueryOptions = {
|
|
348
|
-
cursorCol,
|
|
349
|
-
orderby: [
|
|
350
|
-
{
|
|
351
|
-
column: sortCol,
|
|
352
|
-
direction: "DESC",
|
|
353
|
-
},
|
|
354
|
-
],
|
|
355
|
-
};
|
|
356
|
-
} else {
|
|
357
|
-
if (typeof sortColOrOptions.orderby === "string") {
|
|
358
|
-
sortCol = sortColOrOptions.orderby;
|
|
359
|
-
} else {
|
|
360
|
-
// TODO this orderby isn't consistent and this logic needs to be changed anywhere that's using this and this.getSortCol()
|
|
361
|
-
sortCol = sortColOrOptions.orderby[0].column;
|
|
362
|
-
}
|
|
363
|
-
cursorCol = sortColOrOptions.cursorCol;
|
|
364
|
-
this.edgeQueryOptions = sortColOrOptions;
|
|
365
|
-
}
|
|
366
|
-
this.sortCol = sortCol;
|
|
367
|
-
|
|
368
|
-
let m = orderbyRegex.exec(sortCol);
|
|
369
|
-
if (!m) {
|
|
370
|
-
throw new Error(`invalid sort column ${sortCol}`);
|
|
371
|
-
}
|
|
372
|
-
this.sortCol = m[1];
|
|
373
|
-
if (m[2]) {
|
|
374
|
-
throw new Error(
|
|
375
|
-
`passing direction in sort column is not supproted. use orderby`,
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
this.cursorCol = cursorCol;
|
|
380
|
-
this.memoizedloadEdges = memoize(this.loadEdges.bind(this));
|
|
381
|
-
this.genIDInfosToFetch = memoize(this.genIDInfosToFetchImpl.bind(this));
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
protected getSortCol(): string {
|
|
385
|
-
return this.sortCol;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
getPrivacyPolicy() {
|
|
389
|
-
// default PrivacyPolicy is always allow. nothing to do here
|
|
390
|
-
return AlwaysAllowPrivacyPolicy;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
394
|
-
|
|
395
|
-
first(n: number, after?: string): this {
|
|
396
|
-
this.assertQueryNotDispatched("first");
|
|
397
|
-
this.filters.push(
|
|
398
|
-
new FirstFilter({
|
|
399
|
-
limit: n,
|
|
400
|
-
after,
|
|
401
|
-
sortCol: this.sortCol,
|
|
402
|
-
cursorCol: this.cursorCol,
|
|
403
|
-
orderby: this.edgeQueryOptions.orderby,
|
|
404
|
-
query: this,
|
|
405
|
-
}),
|
|
406
|
-
);
|
|
407
|
-
return this;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
last(n: number, before?: string): this {
|
|
411
|
-
this.assertQueryNotDispatched("last");
|
|
412
|
-
this.filters.push(
|
|
413
|
-
new LastFilter({
|
|
414
|
-
limit: n,
|
|
415
|
-
before,
|
|
416
|
-
sortCol: this.sortCol,
|
|
417
|
-
cursorCol: this.cursorCol,
|
|
418
|
-
orderby: this.edgeQueryOptions.orderby,
|
|
419
|
-
query: this,
|
|
420
|
-
}),
|
|
421
|
-
);
|
|
422
|
-
return this;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
private async querySingleEdge(method: string): Promise<TEdge[]> {
|
|
426
|
-
const edges = await this.memoizedloadEdges();
|
|
427
|
-
if (edges.size !== 1) {
|
|
428
|
-
throw new Error(
|
|
429
|
-
`cannot call ${method} when more than one id is requested`,
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
for (const [_, v] of edges) {
|
|
433
|
-
return v;
|
|
434
|
-
}
|
|
435
|
-
throw new Error(`should be impossible to get here`);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// this is basically just raw rows
|
|
439
|
-
readonly queryEdges = async (): Promise<TEdge[]> => {
|
|
440
|
-
return await this.querySingleEdge("queryEdges");
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
abstract queryRawCount(): Promise<number>;
|
|
444
|
-
|
|
445
|
-
abstract queryAllRawCount(): Promise<Map<ID, number>>;
|
|
446
|
-
|
|
447
|
-
readonly queryAllEdges = async (): Promise<Map<ID, TEdge[]>> => {
|
|
448
|
-
return this.memoizedloadEdges();
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
abstract dataToID(edge: TEdge): ID;
|
|
452
|
-
|
|
453
|
-
readonly queryIDs = async (): Promise<ID[]> => {
|
|
454
|
-
const edges = await this.querySingleEdge("queryIDs");
|
|
455
|
-
return edges.map((edge) => this.dataToID(edge));
|
|
456
|
-
};
|
|
457
|
-
|
|
458
|
-
readonly queryAllIDs = async (): Promise<Map<ID, ID[]>> => {
|
|
459
|
-
const edges = await this.memoizedloadEdges();
|
|
460
|
-
let results: Map<ID, ID[]> = new Map();
|
|
461
|
-
for (const [id, edge_data] of edges) {
|
|
462
|
-
results.set(
|
|
463
|
-
id,
|
|
464
|
-
edge_data.map((edge) => this.dataToID(edge)),
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
return results;
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
readonly queryCount = async (): Promise<number> => {
|
|
471
|
-
const edges = await this.querySingleEdge("queryCount");
|
|
472
|
-
return edges.length;
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
readonly queryAllCount = async (): Promise<Map<ID, number>> => {
|
|
476
|
-
let results: Map<ID, number> = new Map();
|
|
477
|
-
const edges = await this.memoizedloadEdges();
|
|
478
|
-
edges.forEach((list, id) => {
|
|
479
|
-
results.set(id, list.length);
|
|
480
|
-
});
|
|
481
|
-
return results;
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
protected abstract loadEntsFromEdges(
|
|
485
|
-
id: ID,
|
|
486
|
-
edges: TEdge[],
|
|
487
|
-
): Promise<TDest[]>;
|
|
488
|
-
|
|
489
|
-
readonly queryEnts = async (): Promise<TDest[]> => {
|
|
490
|
-
const edges = await this.querySingleEdge("queryEnts");
|
|
491
|
-
return this.loadEntsFromEdges("id", edges);
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
readonly queryAllEnts = async (): Promise<Map<ID, TDest[]>> => {
|
|
495
|
-
// applies filters and then gets things after
|
|
496
|
-
const edges = await this.memoizedloadEdges();
|
|
497
|
-
let promises: Promise<void>[] = [];
|
|
498
|
-
const results: Map<ID, TDest[]> = new Map();
|
|
499
|
-
|
|
500
|
-
const loadEntsForID = async (id: ID, edges: TEdge[]) => {
|
|
501
|
-
const ents = await this.loadEntsFromEdges(id, edges);
|
|
502
|
-
results.set(id, ents);
|
|
503
|
-
};
|
|
504
|
-
for (const [id, edgesList] of edges) {
|
|
505
|
-
promises.push(loadEntsForID(id, edgesList));
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
await Promise.all(promises);
|
|
509
|
-
return results;
|
|
510
|
-
};
|
|
511
|
-
|
|
512
|
-
paginationInfo(): Map<ID, PaginationInfo> {
|
|
513
|
-
this.assertQueryDispatched("paginationInfo");
|
|
514
|
-
return this.pagination;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
private assertQueryDispatched(str: string) {
|
|
518
|
-
if (!this.queryDispatched) {
|
|
519
|
-
throw new Error(`cannot call ${str} until query is dispatched`);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
private assertQueryNotDispatched(str: string) {
|
|
524
|
-
if (this.queryDispatched) {
|
|
525
|
-
throw new Error(`cannot call ${str} after query is dispatched`);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// loadIDs, given an addID function which resolves ID or Ent dependening on what we have
|
|
530
|
-
// if Ent, that's passed to privacy function
|
|
531
|
-
// if ID and entForPrivacy() method, that's called with the id
|
|
532
|
-
// if still no Ent (default/lots of cases), no ent is passed to applyPrivacyPolicy
|
|
533
|
-
protected abstract loadRawIDs(
|
|
534
|
-
addID: (src: ID | TSource) => void,
|
|
535
|
-
): Promise<void>;
|
|
536
|
-
|
|
537
|
-
protected abstract loadRawData(
|
|
538
|
-
infos: IDInfo[],
|
|
539
|
-
options: EdgeQueryableDataOptions,
|
|
540
|
-
): Promise<void>;
|
|
541
|
-
|
|
542
|
-
private addID(id: ID | TSource) {
|
|
543
|
-
if (typeof id === "object") {
|
|
544
|
-
this.idMap.set(id.id, id);
|
|
545
|
-
this.idsToFetch.push(id.id);
|
|
546
|
-
} else {
|
|
547
|
-
this.idsToFetch.push(id);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
abstract getTableName(): string | Promise<string>;
|
|
552
|
-
|
|
553
|
-
protected async genIDInfosToFetchImpl() {
|
|
554
|
-
await this.loadRawIDs(this.addID.bind(this));
|
|
555
|
-
|
|
556
|
-
return applyPrivacyPolicyForEdgeQ(
|
|
557
|
-
this.viewer,
|
|
558
|
-
this,
|
|
559
|
-
this.idsToFetch,
|
|
560
|
-
this.idMap,
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
private _defaultEdgeQueryableOptions: EdgeQueryableDataOptions | undefined;
|
|
565
|
-
|
|
566
|
-
// FYI: this should be used sparingly.
|
|
567
|
-
// currently only exists so that disableTransformations can be configured by the developer
|
|
568
|
-
// so we're only exposing a partial API for now but maybe in the future we can expose
|
|
569
|
-
// the full API if there's a reason to use this that's not via filters
|
|
570
|
-
protected configureEdgeQueryableDataOptions(
|
|
571
|
-
opts: EdgeQueryableDataOptionsConfigureLoader,
|
|
572
|
-
) {
|
|
573
|
-
this._defaultEdgeQueryableOptions = opts;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
protected getDefaultEdgeQueryOptions() {
|
|
577
|
-
return this._defaultEdgeQueryableOptions;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
private async loadEdges(): Promise<Map<ID, TEdge[]>> {
|
|
581
|
-
const idsInfo = await this.genIDInfosToFetch();
|
|
582
|
-
|
|
583
|
-
if (!this.filters.length) {
|
|
584
|
-
// if no filter, we add the firstN filter to ensure we get pagination info
|
|
585
|
-
this.first(getDefaultLimit());
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
let options: EdgeQueryableDataOptions =
|
|
589
|
-
this._defaultEdgeQueryableOptions ?? {};
|
|
590
|
-
|
|
591
|
-
// TODO once we add a lot of complex filters, this needs to be more complicated
|
|
592
|
-
// e.g. commutative filters. what can be done in sql or combined together etc
|
|
593
|
-
// may need to bring sql mode or something back
|
|
594
|
-
for (const filter of this.filters) {
|
|
595
|
-
if (filter.query) {
|
|
596
|
-
let res = filter.query(options);
|
|
597
|
-
options = isPromise(res) ? await res : res;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
await this.loadRawData(idsInfo, options);
|
|
602
|
-
|
|
603
|
-
// no filters. nothing to do here.
|
|
604
|
-
if (!this.filters.length) {
|
|
605
|
-
return this.edges;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
// filter as needed
|
|
609
|
-
for (let [id, edges] of this.edges) {
|
|
610
|
-
this.filters.forEach((filter) => {
|
|
611
|
-
if (filter.filter) {
|
|
612
|
-
edges = filter.filter(id, edges);
|
|
613
|
-
}
|
|
614
|
-
if (filter.paginationInfo) {
|
|
615
|
-
const pagination = filter.paginationInfo(id);
|
|
616
|
-
if (pagination) {
|
|
617
|
-
this.pagination.set(id, pagination);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
this.edges.set(id, edges);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
this.queryDispatched = true;
|
|
625
|
-
|
|
626
|
-
return this.edges;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
getCursor(row: TEdge): string {
|
|
630
|
-
return getCursor({
|
|
631
|
-
row,
|
|
632
|
-
col: this.cursorCol,
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
export interface IDInfo {
|
|
638
|
-
id: ID;
|
|
639
|
-
// if invalidated (usually for privacy), don't fetch data for it, feel free to store the 0-value e.g. 0, [], for the result
|
|
640
|
-
// may eventually be null instead
|
|
641
|
-
invalidated?: boolean;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
async function applyPrivacyPolicyForEdgeQ<
|
|
645
|
-
TSource extends Ent,
|
|
646
|
-
TDest extends Ent,
|
|
647
|
-
TEdge extends Data,
|
|
648
|
-
>(
|
|
649
|
-
viewer: Viewer,
|
|
650
|
-
edgeQ: EdgeQuery<TSource, TDest, TEdge>,
|
|
651
|
-
ids: ID[],
|
|
652
|
-
map: Map<ID, TSource>,
|
|
653
|
-
): Promise<IDInfo[]> {
|
|
654
|
-
const result: IDInfo[] = [];
|
|
655
|
-
|
|
656
|
-
await Promise.all(
|
|
657
|
-
ids.map(async (id) => {
|
|
658
|
-
let ent: Ent | null | undefined = map.get(id);
|
|
659
|
-
if (!ent) {
|
|
660
|
-
ent = await edgeQ.sourceEnt(id);
|
|
661
|
-
}
|
|
662
|
-
const r = await applyPrivacyPolicy(
|
|
663
|
-
viewer,
|
|
664
|
-
edgeQ.getPrivacyPolicy(),
|
|
665
|
-
ent || undefined,
|
|
666
|
-
);
|
|
667
|
-
result.push({
|
|
668
|
-
id,
|
|
669
|
-
invalidated: !r,
|
|
670
|
-
});
|
|
671
|
-
}),
|
|
672
|
-
);
|
|
673
|
-
return result;
|
|
674
|
-
}
|
package/src/core/query_impl.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export interface OrderByOption {
|
|
2
|
-
column: string;
|
|
3
|
-
direction: "ASC" | "DESC";
|
|
4
|
-
nullsPlacement?: "first" | "last";
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export type OrderBy = OrderByOption[];
|
|
8
|
-
|
|
9
|
-
export function getOrderByPhrase(orderby: OrderBy): string {
|
|
10
|
-
return orderby
|
|
11
|
-
.map((v) => {
|
|
12
|
-
let nullsPlacement = "";
|
|
13
|
-
switch (v.nullsPlacement) {
|
|
14
|
-
case "first":
|
|
15
|
-
nullsPlacement = " NULLS FIRST";
|
|
16
|
-
break;
|
|
17
|
-
case "last":
|
|
18
|
-
nullsPlacement = " NULLS LAST";
|
|
19
|
-
break;
|
|
20
|
-
}
|
|
21
|
-
return `${v.column} ${v.direction}${nullsPlacement}`;
|
|
22
|
-
})
|
|
23
|
-
.join(", ");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function reverseOrderBy(orderby: OrderBy): OrderBy {
|
|
27
|
-
return orderby.map((o) => {
|
|
28
|
-
const o2 = { ...o };
|
|
29
|
-
o2.direction = o.direction === "ASC" ? "DESC" : "ASC";
|
|
30
|
-
return o2;
|
|
31
|
-
});
|
|
32
|
-
}
|