@snowtop/ent 0.2.3-alpha1 → 0.2.3-alpha2

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/base.d.ts CHANGED
@@ -95,6 +95,7 @@ export interface QueryDataOptions<T extends Data = Data, K = keyof T> {
95
95
  orderby?: OrderBy;
96
96
  groupby?: K;
97
97
  limit?: number;
98
+ offset?: number;
98
99
  disableTransformations?: boolean;
99
100
  join?: JoinOptions[];
100
101
  }
package/core/clause.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare class inClause<T extends Data, K = keyof T> implements Clause<T,
19
19
  private overrideAlias?;
20
20
  protected op: InClauseOperator;
21
21
  static getPostgresInClauseValuesThreshold(): number;
22
- constructor(col: K, value: any[], type?: string, overrideAlias?: string | undefined);
22
+ constructor(col: K, value: any[], type?: string, overrideAlias?: string | null | undefined);
23
23
  clause(idx: number, alias?: string): string;
24
24
  columns(): K[];
25
25
  values(): any[];
@@ -34,37 +34,37 @@ export declare class notInClause<T extends Data, K = keyof T> extends inClause<T
34
34
  * only works with postgres gin indexes
35
35
  * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
36
36
  */
37
- export declare function PostgresArrayContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
37
+ export declare function PostgresArrayContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
38
38
  /**
39
39
  * creates a clause to determine if every item in the list is stored in the array stored in the column in the db
40
40
  * only works with postgres gin indexes
41
41
  * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
42
42
  */
43
- export declare function PostgresArrayContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
43
+ export declare function PostgresArrayContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
44
44
  /**
45
45
  * creates a clause to determine if the given value is NOT contained in the array stored in the column in the db
46
46
  * only works with postgres gin indexes
47
47
  * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
48
48
  */
49
- export declare function PostgresArrayNotContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
49
+ export declare function PostgresArrayNotContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
50
50
  /**
51
51
  * creates a clause to determine if every item in the list is NOT stored in the array stored in the column in the db
52
52
  * only works with postgres gin indexes
53
53
  * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
54
54
  */
55
- export declare function PostgresArrayNotContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
55
+ export declare function PostgresArrayNotContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
56
56
  /**
57
57
  * creates a clause to determine if the arrays overlap, that is, do they have any elements in common
58
58
  * only works with postgres gin indexes
59
59
  * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
60
60
  */
61
- export declare function PostgresArrayOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
61
+ export declare function PostgresArrayOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
62
62
  /**
63
63
  * creates a clause to determine if the arrays do not overlap, that is, do they have any elements in common
64
64
  * only works with postgres gin indexes
65
65
  * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
66
66
  */
67
- export declare function PostgresArrayNotOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
67
+ export declare function PostgresArrayNotOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
68
68
  /**
69
69
  * @deprecated use PostgresArrayContainsValue
70
70
  */
@@ -73,18 +73,18 @@ export declare function ArrayEq<T extends Data, K = keyof T>(col: K, value: any)
73
73
  * @deprecated use PostgresNotArrayContains
74
74
  */
75
75
  export declare function ArrayNotEq<T extends Data, K = keyof T>(col: K, value: any): Clause<T, K>;
76
- export declare function Eq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
77
- export declare function StartsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
78
- export declare function EndsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
79
- export declare function Contains<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
80
- export declare function StartsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
81
- export declare function EndsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
82
- export declare function ContainsIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
83
- export declare function NotEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
84
- export declare function Greater<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
85
- export declare function Less<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
86
- export declare function GreaterEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
87
- export declare function LessEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
76
+ export declare function Eq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
77
+ export declare function StartsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
78
+ export declare function EndsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
79
+ export declare function Contains<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
80
+ export declare function StartsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
81
+ export declare function EndsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
82
+ export declare function ContainsIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
83
+ export declare function NotEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
84
+ export declare function Greater<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
85
+ export declare function Less<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
86
+ export declare function GreaterEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
87
+ export declare function LessEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
88
88
  export declare function And<T extends Data, K = keyof T>(...args: Clause<T, K>[]): Clause<T, K>;
89
89
  export declare function AndOptional<T extends Data, K = keyof T>(...args: (Clause<T, K> | undefined)[]): Clause<T, K>;
90
90
  export declare function Or<T extends Data, K = keyof T>(...args: Clause<T, K>[]): Clause<T, K>;
@@ -97,41 +97,41 @@ export declare function In<T extends Data, K = keyof T>(col: K, ...values: any):
97
97
  * @deprecated use UUidIn, TextIn, IntegerIn, or TypeIn
98
98
  */
99
99
  export declare function In<T extends Data, K = keyof T>(col: K, values: any[], type?: string): Clause<T, K>;
100
- export declare function UuidIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string): Clause<T, K>;
101
- export declare function IntegerIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string): Clause<T, K>;
102
- export declare function TextIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string): Clause<T, K>;
103
- export declare function DBTypeIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string): Clause<T, K>;
104
- export declare function UuidNotIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string): Clause<T, K>;
105
- export declare function IntegerNotIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string): Clause<T, K>;
106
- export declare function TextNotIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string): Clause<T, K>;
107
- export declare function DBTypeNotIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string): Clause<T, K>;
100
+ export declare function UuidIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string | null): Clause<T, K>;
101
+ export declare function IntegerIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string | null): Clause<T, K>;
102
+ export declare function TextIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string | null): Clause<T, K>;
103
+ export declare function DBTypeIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string | null): Clause<T, K>;
104
+ export declare function UuidNotIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string | null): Clause<T, K>;
105
+ export declare function IntegerNotIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string | null): Clause<T, K>;
106
+ export declare function TextNotIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string | null): Clause<T, K>;
107
+ export declare function DBTypeNotIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string | null): Clause<T, K>;
108
108
  interface TsQuery {
109
109
  language: "english" | "french" | "german" | "simple";
110
110
  value: string;
111
111
  }
112
- export declare function TsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
113
- export declare function PlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
114
- export declare function PhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
115
- export declare function WebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
116
- export declare function TsVectorColTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
117
- export declare function TsVectorPlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
118
- export declare function TsVectorPhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
119
- export declare function TsVectorWebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
112
+ export declare function TsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
113
+ export declare function PlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
114
+ export declare function PhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
115
+ export declare function WebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
116
+ export declare function TsVectorColTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
117
+ export declare function TsVectorPlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
118
+ export declare function TsVectorPhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
119
+ export declare function TsVectorWebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
120
120
  export declare function sensitiveValue(val: any): SensitiveValue;
121
- export declare function JSONObjectFieldKeyASJSON<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string): keyof T;
122
- export declare function JSONObjectFieldKeyAsText<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string): keyof T;
121
+ export declare function JSONObjectFieldKeyASJSON<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string | null): keyof T;
122
+ export declare function JSONObjectFieldKeyAsText<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string | null): keyof T;
123
123
  type predicate = "==" | ">" | "<" | "!=" | ">=" | "<=";
124
- export declare function JSONPathValuePredicate<T extends Data, K = keyof T>(dbCol: K, path: string, val: any, pred: predicate, overrideAlias?: string): Clause<T, K>;
125
- export declare function JSONKeyExists<T extends Data, K = keyof T>(dbCol: K, val: any, overrideAlias?: string): Clause<T, K>;
126
- export declare function JSONBKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string): Clause<T, K>;
127
- export declare function JSONKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string): Clause<T, K>;
128
- export declare function PaginationMultipleColsSubQuery<T extends Data, K = keyof T>(col: K, op: string, tableName: string, uniqueCol: K, val: any, overrideAlias?: string): Clause<T, K>;
124
+ export declare function JSONPathValuePredicate<T extends Data, K = keyof T>(dbCol: K, path: string, val: any, pred: predicate, overrideAlias?: string | null): Clause<T, K>;
125
+ export declare function JSONKeyExists<T extends Data, K = keyof T>(dbCol: K, val: any, overrideAlias?: string | null): Clause<T, K>;
126
+ export declare function JSONBKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string | null): Clause<T, K>;
127
+ export declare function JSONKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string | null): Clause<T, K>;
128
+ export declare function PaginationMultipleColsSubQuery<T extends Data, K = keyof T>(col: K, op: string, tableName: string, uniqueCol: K, val: any, overrideAlias?: string | null): Clause<T, K>;
129
129
  export type PaginationUnboundColsQueryOrdering<T extends Data, K = keyof T> = {
130
130
  sortCol: K;
131
131
  direction: "ASC" | "DESC";
132
132
  sortValue: string | number | null;
133
133
  nullsPlacement?: "first" | "last";
134
- overrideAlias?: string;
134
+ overrideAlias?: string | null;
135
135
  };
136
136
  /**
137
137
  * When paginating over multiple ordered columns, we need to construct a nested
@@ -171,12 +171,12 @@ export type PaginationUnboundColsQueryOrdering<T extends Data, K = keyof T> = {
171
171
  */
172
172
  export declare function PaginationUnboundColsQuery<T extends Data, K = keyof T>(ordering: PaginationUnboundColsQueryOrdering<T, K>[]): Clause<T, K> | undefined;
173
173
  export declare function PaginationMultipleColsQuery<T extends Data, K = keyof T>(sortCol: K, cursorCol: K, less: boolean, // if true, <, if false, >
174
- sortValue: any, cursorValue: any, overrideAlias?: string): Clause<T, K>;
175
- export declare function Add<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
176
- export declare function Subtract<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
177
- export declare function Multiply<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
178
- export declare function Divide<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
179
- export declare function Modulo<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
174
+ sortValue: any, cursorValue: any, overrideAlias?: string | null): Clause<T, K>;
175
+ export declare function Add<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
176
+ export declare function Subtract<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
177
+ export declare function Multiply<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
178
+ export declare function Divide<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
179
+ export declare function Modulo<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
180
180
  export declare function getCombinedClause<V extends Data = Data, K = keyof V>(options: Pick<SelectDataOptions, "clause">, cls: Clause<V, K>, checkIntersection?: boolean): Clause<V, K>;
181
181
  export declare function getCombinedClause<V extends Data = Data, K = keyof V>(options: Pick<SelectDataOptions, "clause">, cls: Clause<V, K> | undefined, checkIntersection?: boolean): Clause<V, K> | undefined;
182
182
  export declare function Expression<T extends Data, K = keyof T>(expression: string): Clause<T, K>;
package/core/clause.js CHANGED
@@ -39,6 +39,10 @@ function rawValue(val) {
39
39
  return val;
40
40
  }
41
41
  function renderCol(col, overrideAlias, alias) {
42
+ // null explicitly disables aliasing for this column.
43
+ if (overrideAlias === null) {
44
+ return `${col}`;
45
+ }
42
46
  if (overrideAlias) {
43
47
  return `${overrideAlias}.${col}`;
44
48
  }
package/core/ent.d.ts CHANGED
@@ -74,6 +74,7 @@ export type CustomQuery<T extends Data = Data, K = keyof T> = string | parameter
74
74
  * Foo.loadCustom(opts, {
75
75
  * clause: query.LessEq('time', Date.now()),
76
76
  * limit: 100,
77
+ * offset: 200,
77
78
  * orderby: 'time',
78
79
  * }) // changes the query
79
80
  * Foo.loadCustom(opts, {
@@ -88,6 +89,8 @@ export type CustomQuery<T extends Data = Data, K = keyof T> = string | parameter
88
89
  *
89
90
  * If a raw or parameterized query is passed in, we don't attempt to batch them together and they're executed as is.
90
91
  * If you end up with a scenario where you may need to coalesce or batch (non-clause) queries here, you should use some kind of memoization here.
92
+ *
93
+ * Note: QueryDataOptions limit/offset are applied before privacy filtering, so the final ent list may be shorter.
91
94
  */
92
95
  export declare function loadCustomData<TQueryData extends Data = Data, TResultData extends Data = TQueryData, K = keyof TQueryData>(options: SelectCustomDataOptions<TResultData>, query: CustomQuery<TQueryData, K>, context: Context | undefined): Promise<TResultData[]>;
93
96
  export declare function loadCustomCount<T extends Data = Data, K = keyof T>(options: SelectCustomDataOptions<T>, query: CustomQuery<T, K>, context: Context | undefined): Promise<number>;
package/core/ent.js CHANGED
@@ -379,6 +379,7 @@ function isParameterizedQuery(opts) {
379
379
  * Foo.loadCustom(opts, {
380
380
  * clause: query.LessEq('time', Date.now()),
381
381
  * limit: 100,
382
+ * offset: 200,
382
383
  * orderby: 'time',
383
384
  * }) // changes the query
384
385
  * Foo.loadCustom(opts, {
@@ -393,6 +394,8 @@ function isParameterizedQuery(opts) {
393
394
  *
394
395
  * If a raw or parameterized query is passed in, we don't attempt to batch them together and they're executed as is.
395
396
  * If you end up with a scenario where you may need to coalesce or batch (non-clause) queries here, you should use some kind of memoization here.
397
+ *
398
+ * Note: QueryDataOptions limit/offset are applied before privacy filtering, so the final ent list may be shorter.
396
399
  */
397
400
  async function loadCustomData(options, query, context) {
398
401
  const rows = await loadCustomDataImpl(options, query, context);
@@ -418,6 +421,7 @@ async function loadCustomCount(options, query, context) {
418
421
  const rows = await loadCustomDataImpl({
419
422
  ...options,
420
423
  fields: ["count(1) as count"],
424
+ disableFieldsAlias: true,
421
425
  }, query, context);
422
426
  if (rows.length) {
423
427
  return parseInt(rows[0].count);
@@ -102,9 +102,12 @@ function buildQuery(options) {
102
102
  if (options.orderby) {
103
103
  parts.push(`ORDER BY ${getOrderByPhrase(options.orderby, options.disableDefaultOrderByAlias ? undefined : fieldsAlias)}`);
104
104
  }
105
- if (options.limit) {
105
+ if (options.limit !== undefined) {
106
106
  parts.push(`LIMIT ${options.limit}`);
107
107
  }
108
+ if (options.offset !== undefined) {
109
+ parts.push(`OFFSET ${options.offset}`);
110
+ }
108
111
  return parts.join(" ");
109
112
  }
110
113
  exports.buildQuery = buildQuery;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snowtop/ent",
3
- "version": "0.2.3-alpha1",
3
+ "version": "0.2.3-alpha2",
4
4
  "description": "snowtop ent framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,5 +1,5 @@
1
1
  import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
2
- import { ActionField, Type, FieldMap, GlobalSchema, TransformReadBetaResult, CanViewerDo } from "../schema/schema";
2
+ import { ActionField, Type, FieldMap, GlobalSchema, EdgeIndex, TransformReadBetaResult, CanViewerDo } from "../schema/schema";
3
3
  export declare function processFields(src: FieldMap | Field[], patternName?: string): Promise<ProcessedField[]>;
4
4
  declare enum NullableResult {
5
5
  CONTENTS = "contents",
@@ -87,6 +87,7 @@ interface BiomeConfig {
87
87
  interface ProcessedGlobalSchema {
88
88
  globalEdges: ProcessedAssocEdge[];
89
89
  extraEdgeFields: ProcessedField[];
90
+ edgeIndices?: EdgeIndex[];
90
91
  init?: boolean;
91
92
  transformsEdges?: boolean;
92
93
  globalFields?: ProcessedField[];
@@ -502,6 +502,7 @@ async function parseGlobalSchema(s) {
502
502
  globalEdges: [],
503
503
  extraEdgeFields: [],
504
504
  init: !!s.extraEdgeFields ||
505
+ !!s.edgeIndices ||
505
506
  s.transformEdgeRead !== undefined ||
506
507
  s.transformEdgeWrite !== undefined ||
507
508
  s.fields !== undefined,
@@ -510,6 +511,9 @@ async function parseGlobalSchema(s) {
510
511
  if (s.extraEdgeFields) {
511
512
  ret.extraEdgeFields = await processFields(s.extraEdgeFields);
512
513
  }
514
+ if (s.edgeIndices) {
515
+ ret.edgeIndices = s.edgeIndices;
516
+ }
513
517
  if (s.edges) {
514
518
  ret.globalEdges = processEdges(s.edges);
515
519
  }
package/schema/field.d.ts CHANGED
@@ -11,6 +11,8 @@ export declare abstract class BaseField {
11
11
  sensitive?: boolean;
12
12
  graphqlName?: string;
13
13
  index?: boolean;
14
+ indexConcurrently?: boolean;
15
+ indexWhere?: string;
14
16
  foreignKey?: ForeignKey;
15
17
  polymorphic?: boolean | PolymorphicOptions;
16
18
  derivedWhenEmbedded?: boolean;
package/schema/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import Schema from "./schema";
2
2
  export { Schema };
3
- export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getFieldsWithEditPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, ActionField, } from "./schema";
3
+ export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getFieldsWithEditPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, EdgeIndex, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, ActionField, } from "./schema";
4
4
  export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, SchemaConfig, } from "./base_schema";
5
5
  export * from "./field";
6
6
  export * from "./json_field";
@@ -16,11 +16,12 @@ export type FieldInfoMap = {
16
16
  export interface GlobalSchema {
17
17
  edges?: Edge[];
18
18
  extraEdgeFields?: FieldMap;
19
+ edgeIndices?: EdgeIndex[];
19
20
  transformEdgeRead?: () => Clause;
20
21
  transformEdgeWrite?: (stmt: EdgeUpdateOperation) => TransformedEdgeUpdateOperation | null;
21
22
  fields?: FieldMap;
22
23
  }
23
- type FieldOverride = Pick<FieldOptions, "nullable" | "storageKey" | "serverDefault" | "unique" | "hideFromGraphQL" | "graphqlName" | "index">;
24
+ type FieldOverride = Pick<FieldOptions, "nullable" | "storageKey" | "serverDefault" | "unique" | "hideFromGraphQL" | "graphqlName" | "index" | "indexConcurrently" | "indexWhere">;
24
25
  export type FieldOverrideMap = {
25
26
  [key: string]: FieldOverride;
26
27
  };
@@ -233,6 +234,8 @@ export interface FieldOptions {
233
234
  sensitive?: boolean;
234
235
  graphqlName?: string;
235
236
  index?: boolean;
237
+ indexConcurrently?: boolean;
238
+ indexWhere?: string;
236
239
  foreignKey?: ForeignKey;
237
240
  fieldEdge?: FieldEdge;
238
241
  primaryKey?: boolean;
@@ -359,8 +362,13 @@ export interface Index {
359
362
  unique?: boolean;
360
363
  fulltext?: FullText;
361
364
  indexType?: "gin" | "btree";
365
+ concurrently?: boolean;
366
+ where?: string;
362
367
  [x: string]: any;
363
368
  }
369
+ export interface EdgeIndex extends Omit<Index, "name"> {
370
+ name?: string;
371
+ }
364
372
  export interface ForeignKeyInfo {
365
373
  tableName: string;
366
374
  ondelete?: OnDeleteFkey;
@@ -354,11 +354,46 @@ map) {
354
354
  const colsInfo = getColumns(ast.columns);
355
355
  // console.log(tableName, columns, allColumns);
356
356
  let limit = null;
357
+ let offset = null;
357
358
  if (ast.limit !== null) {
358
- assert(ast.limit.seperator == "", "ast limit separator not as expected");
359
- assert(ast.limit.value.length == 1, "ast limit not as expected");
360
- assert(ast.limit.value[0].type == "number", "limit type was not 0");
361
- limit = ast.limit.value[0].value;
359
+ const limitInfo = ast.limit;
360
+ const values = limitInfo.value || [];
361
+ assert(values.length >= 1 && values.length <= 2, "ast limit not as expected");
362
+ const parsedValues = values.map((value) => {
363
+ assert(value.type == "number", "limit type was not 0");
364
+ return value.value;
365
+ });
366
+ const separator = limitInfo.seperator || "";
367
+ if (parsedValues.length === 1) {
368
+ limit = parsedValues[0];
369
+ }
370
+ else if (separator === ",") {
371
+ offset = parsedValues[0];
372
+ limit = parsedValues[1];
373
+ }
374
+ else if (separator === "offset") {
375
+ limit = parsedValues[0];
376
+ offset = parsedValues[1];
377
+ }
378
+ else {
379
+ throw new Error(`unsupported limit separator: ${separator}`);
380
+ }
381
+ }
382
+ const astOffset = ast.offset;
383
+ if (astOffset !== undefined && astOffset !== null && offset === null) {
384
+ if (typeof astOffset === "number") {
385
+ offset = astOffset;
386
+ }
387
+ else if (typeof astOffset === "object") {
388
+ const offsetValue = astOffset.value ?? astOffset;
389
+ if (typeof offsetValue === "number") {
390
+ offset = offsetValue;
391
+ }
392
+ else if (Array.isArray(offsetValue) && offsetValue.length) {
393
+ assert(offsetValue[0].type == "number", "offset type was not 0");
394
+ offset = offsetValue[0].value;
395
+ }
396
+ }
362
397
  }
363
398
  let orderings = [];
364
399
  if (ast.orderby !== null) {
@@ -374,11 +409,18 @@ map) {
374
409
  let where = buildWhereStatement(ast, values);
375
410
  const list = map.get(tableName) || [];
376
411
  let results = [];
412
+ const canLimitEarly = orderings.length === 0 && !colsInfo.count;
377
413
  let limitApplied = false;
414
+ const offsetAppliedEarly = canLimitEarly && offset !== null;
415
+ let offsetRemaining = offsetAppliedEarly ? offset || 0 : 0;
378
416
  for (const data of list) {
379
417
  if (where && !where.apply(data)) {
380
418
  continue;
381
419
  }
420
+ if (canLimitEarly && offsetRemaining > 0) {
421
+ offsetRemaining--;
422
+ continue;
423
+ }
382
424
  if (colsInfo.allCols) {
383
425
  results.push(getDataToReturn(data, undefined, true));
384
426
  }
@@ -389,11 +431,7 @@ map) {
389
431
  }
390
432
  results.push(getDataToReturn(data, cols));
391
433
  }
392
- // don't apply limit early if there's an ordering or count
393
- if (orderings.length === 0 &&
394
- !colsInfo.count &&
395
- limit !== null &&
396
- limit == results.length) {
434
+ if (canLimitEarly && limit !== null && limit == results.length) {
397
435
  limitApplied = true;
398
436
  break;
399
437
  }
@@ -424,9 +462,11 @@ map) {
424
462
  return 0;
425
463
  });
426
464
  }
427
- // apply limit after if not applied e.g. there was an ordering or no where clause
428
- if (limit !== null && !limitApplied) {
429
- results = results.slice(0, limit);
465
+ // apply limit/offset after if not applied e.g. there was an ordering or no where clause
466
+ if (!limitApplied && (limit !== null || offset !== null)) {
467
+ const start = offsetAppliedEarly ? 0 : offset || 0;
468
+ const end = limit !== null ? start + limit : undefined;
469
+ results = results.slice(start, end);
430
470
  }
431
471
  return results;
432
472
  }
@@ -10,6 +10,9 @@ export declare const testEdgeGlobalSchema: {
10
10
  extraEdgeFields: {
11
11
  deletedAt: import("../schema").TimestampField;
12
12
  };
13
+ edgeIndices: {
14
+ columns: string[];
15
+ }[];
13
16
  transformEdgeRead(): clause.Clause;
14
17
  transformEdgeWrite(stmt: EdgeUpdateOperation): TransformedEdgeUpdateOperation | null;
15
18
  };
@@ -38,10 +38,14 @@ exports.testEdgeGlobalSchema = {
38
38
  extraEdgeFields: {
39
39
  deletedAt: (0, schema_1.TimestampType)({
40
40
  nullable: true,
41
- index: true,
42
41
  defaultValueOnCreate: () => null,
43
42
  }),
44
43
  },
44
+ edgeIndices: [
45
+ {
46
+ columns: ["id1", "edge_type", "deleted_at"],
47
+ },
48
+ ],
45
49
  transformEdgeRead() {
46
50
  return clause.Eq("deleted_at", null);
47
51
  },