zitejs 0.9.97 → 0.9.99
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.
|
@@ -15,9 +15,9 @@ export type FilterCondition<V> = {
|
|
|
15
15
|
contains?: any;
|
|
16
16
|
/** Not equal, or — against `null` — "is set". */
|
|
17
17
|
not?: V | null;
|
|
18
|
-
/**
|
|
18
|
+
/** An empty array matches NOTHING — the SDK's filters convert to the nested format, where `in: []` is "is one of nothing". */
|
|
19
19
|
in?: V extends Array<infer E> ? E[] : V[];
|
|
20
|
-
/**
|
|
20
|
+
/** An empty array applies no filter at all — "is not one of nothing" is always true. */
|
|
21
21
|
notIn?: V extends Array<infer E> ? E[] : V[];
|
|
22
22
|
lt?: V | number | Date;
|
|
23
23
|
lte?: V | number | Date;
|
|
@@ -26,6 +26,34 @@ export type FilterCondition<V> = {
|
|
|
26
26
|
};
|
|
27
27
|
/** Pre-monorepo name for {@link FilterCondition}. Kept so migrated app code that spells the type out still compiles. */
|
|
28
28
|
export type FilterOperators<V> = FilterCondition<V> | V;
|
|
29
|
+
/**
|
|
30
|
+
* Airtable's filter set is the shared one plus `ilike`, compiled to a formula in
|
|
31
|
+
* `integrations/airtable/formulas.ts`:
|
|
32
|
+
*
|
|
33
|
+
* - `ilike` — case-insensitive equality (`LOWER(f) = LOWER(v)`). Load-bearing:
|
|
34
|
+
* the `zite.auth.ts` generated for a migrated user-sync app matches rostered
|
|
35
|
+
* emails with it, because Airtable compares text case-sensitively while Zite
|
|
36
|
+
* lowercases emails on some sign-in paths and not others.
|
|
37
|
+
*
|
|
38
|
+
* Kept separate from `FilterCondition` rather than merged into it, so a Zite DB
|
|
39
|
+
* filter can't offer an operator its runtime ignores.
|
|
40
|
+
*
|
|
41
|
+
* NOT `equals`, despite `formulas.ts` having a `case 'equals'`: that case only
|
|
42
|
+
* fires for the bare-value shorthand. `equals` is absent from
|
|
43
|
+
* `WhereConditionOperators`, so `isNestedCondition` doesn't recognize the
|
|
44
|
+
* object, the whole `{ equals: … }` is stringified as the operand, and Airtable
|
|
45
|
+
* 422s on `{Email}=[object Object]`.
|
|
46
|
+
*
|
|
47
|
+
* One operator per field on this path — `formulas.ts` reads
|
|
48
|
+
* `Object.keys(condition)[0]` and drops the rest, unlike the Zite DB filter
|
|
49
|
+
* builder which iterates them all.
|
|
50
|
+
*/
|
|
51
|
+
export type AirtableFilterCondition<V> = FilterCondition<V> & {
|
|
52
|
+
ilike?: V | V[];
|
|
53
|
+
};
|
|
54
|
+
export type AirtableRecordFilters<T> = {
|
|
55
|
+
[K in keyof T]?: T[K] | (T[K] extends Array<infer E> ? E : never) | AirtableFilterCondition<T[K]>;
|
|
56
|
+
};
|
|
29
57
|
/**
|
|
30
58
|
* Filters keyed by the record's own field names. Typed rather than `unknown`
|
|
31
59
|
* because an unrecognized key is not an error at runtime — it passes through
|
|
@@ -53,6 +81,13 @@ export type FieldSelector<T> = Extract<keyof T, string> | (string & {});
|
|
|
53
81
|
export interface TableFindAllOptions<T = Record<string, unknown>> {
|
|
54
82
|
limit?: number;
|
|
55
83
|
offset?: number;
|
|
84
|
+
/**
|
|
85
|
+
* IGNORED on the table path. `DatabasesFindAllParamsSchema` has no `sort`
|
|
86
|
+
* key, so zod strips it before either dispatch, and neither destructures it.
|
|
87
|
+
* Kept in the type because removing it would only turn a silent no-op into a
|
|
88
|
+
* compile error for apps already passing it — the real fix is to forward it.
|
|
89
|
+
* It DOES work on `zite.auth.findAllUsers`, which is dispatched separately.
|
|
90
|
+
*/
|
|
56
91
|
sort?: unknown[];
|
|
57
92
|
filters?: RecordFilters<T>;
|
|
58
93
|
fields?: Array<FieldSelector<T>>;
|
|
@@ -150,7 +185,7 @@ export interface AirtableTableClient<T, TInput = T> {
|
|
|
150
185
|
/** An opaque cursor from a previous call — not a row count. */
|
|
151
186
|
offset?: string;
|
|
152
187
|
limit?: number;
|
|
153
|
-
filters?:
|
|
188
|
+
filters?: AirtableRecordFilters<T>;
|
|
154
189
|
}): Promise<{
|
|
155
190
|
records: T[];
|
|
156
191
|
offset: string | undefined;
|
|
@@ -158,7 +193,7 @@ export interface AirtableTableClient<T, TInput = T> {
|
|
|
158
193
|
}>;
|
|
159
194
|
findOne(params: {
|
|
160
195
|
id?: string;
|
|
161
|
-
filters?:
|
|
196
|
+
filters?: AirtableRecordFilters<T>;
|
|
162
197
|
}): Promise<T | undefined>;
|
|
163
198
|
create(params: {
|
|
164
199
|
record: Partial<TInput>;
|
package/dist/cjs/sync/lib.js
CHANGED
|
@@ -411,8 +411,8 @@ function generateDbTs(schema) {
|
|
|
411
411
|
lines.push("// .findAll({ filters?, sort?, offset?, limit?, fields? }) → { records: T[], hasMore: boolean }");
|
|
412
412
|
lines.push("// filters: { fieldName: value } for equality, or { fieldName: { <op>: value } }");
|
|
413
413
|
lines.push("// operators: contains, not, in, notIn, lt, lte, gt, gte");
|
|
414
|
-
lines.push('// `not: null` means "is set"
|
|
415
|
-
lines.push("// sort
|
|
414
|
+
lines.push('// `not: null` means "is set". An empty `in: []` matches nothing; an', '// empty `notIn: []` applies no filter.');
|
|
415
|
+
lines.push("// sort is currently IGNORED here — it is stripped before the request.", "// (it does work on zite.auth.findAllUsers). Order in SQL instead.");
|
|
416
416
|
lines.push("// limit defaults to 500, max 2000; offset is a row count (a number)");
|
|
417
417
|
lines.push("// .findOne({ id?, filters?, fields? }) → T | undefined");
|
|
418
418
|
lines.push("// .create({ record }) → T");
|
|
@@ -15,9 +15,9 @@ export type FilterCondition<V> = {
|
|
|
15
15
|
contains?: any;
|
|
16
16
|
/** Not equal, or — against `null` — "is set". */
|
|
17
17
|
not?: V | null;
|
|
18
|
-
/**
|
|
18
|
+
/** An empty array matches NOTHING — the SDK's filters convert to the nested format, where `in: []` is "is one of nothing". */
|
|
19
19
|
in?: V extends Array<infer E> ? E[] : V[];
|
|
20
|
-
/**
|
|
20
|
+
/** An empty array applies no filter at all — "is not one of nothing" is always true. */
|
|
21
21
|
notIn?: V extends Array<infer E> ? E[] : V[];
|
|
22
22
|
lt?: V | number | Date;
|
|
23
23
|
lte?: V | number | Date;
|
|
@@ -26,6 +26,34 @@ export type FilterCondition<V> = {
|
|
|
26
26
|
};
|
|
27
27
|
/** Pre-monorepo name for {@link FilterCondition}. Kept so migrated app code that spells the type out still compiles. */
|
|
28
28
|
export type FilterOperators<V> = FilterCondition<V> | V;
|
|
29
|
+
/**
|
|
30
|
+
* Airtable's filter set is the shared one plus `ilike`, compiled to a formula in
|
|
31
|
+
* `integrations/airtable/formulas.ts`:
|
|
32
|
+
*
|
|
33
|
+
* - `ilike` — case-insensitive equality (`LOWER(f) = LOWER(v)`). Load-bearing:
|
|
34
|
+
* the `zite.auth.ts` generated for a migrated user-sync app matches rostered
|
|
35
|
+
* emails with it, because Airtable compares text case-sensitively while Zite
|
|
36
|
+
* lowercases emails on some sign-in paths and not others.
|
|
37
|
+
*
|
|
38
|
+
* Kept separate from `FilterCondition` rather than merged into it, so a Zite DB
|
|
39
|
+
* filter can't offer an operator its runtime ignores.
|
|
40
|
+
*
|
|
41
|
+
* NOT `equals`, despite `formulas.ts` having a `case 'equals'`: that case only
|
|
42
|
+
* fires for the bare-value shorthand. `equals` is absent from
|
|
43
|
+
* `WhereConditionOperators`, so `isNestedCondition` doesn't recognize the
|
|
44
|
+
* object, the whole `{ equals: … }` is stringified as the operand, and Airtable
|
|
45
|
+
* 422s on `{Email}=[object Object]`.
|
|
46
|
+
*
|
|
47
|
+
* One operator per field on this path — `formulas.ts` reads
|
|
48
|
+
* `Object.keys(condition)[0]` and drops the rest, unlike the Zite DB filter
|
|
49
|
+
* builder which iterates them all.
|
|
50
|
+
*/
|
|
51
|
+
export type AirtableFilterCondition<V> = FilterCondition<V> & {
|
|
52
|
+
ilike?: V | V[];
|
|
53
|
+
};
|
|
54
|
+
export type AirtableRecordFilters<T> = {
|
|
55
|
+
[K in keyof T]?: T[K] | (T[K] extends Array<infer E> ? E : never) | AirtableFilterCondition<T[K]>;
|
|
56
|
+
};
|
|
29
57
|
/**
|
|
30
58
|
* Filters keyed by the record's own field names. Typed rather than `unknown`
|
|
31
59
|
* because an unrecognized key is not an error at runtime — it passes through
|
|
@@ -53,6 +81,13 @@ export type FieldSelector<T> = Extract<keyof T, string> | (string & {});
|
|
|
53
81
|
export interface TableFindAllOptions<T = Record<string, unknown>> {
|
|
54
82
|
limit?: number;
|
|
55
83
|
offset?: number;
|
|
84
|
+
/**
|
|
85
|
+
* IGNORED on the table path. `DatabasesFindAllParamsSchema` has no `sort`
|
|
86
|
+
* key, so zod strips it before either dispatch, and neither destructures it.
|
|
87
|
+
* Kept in the type because removing it would only turn a silent no-op into a
|
|
88
|
+
* compile error for apps already passing it — the real fix is to forward it.
|
|
89
|
+
* It DOES work on `zite.auth.findAllUsers`, which is dispatched separately.
|
|
90
|
+
*/
|
|
56
91
|
sort?: unknown[];
|
|
57
92
|
filters?: RecordFilters<T>;
|
|
58
93
|
fields?: Array<FieldSelector<T>>;
|
|
@@ -150,7 +185,7 @@ export interface AirtableTableClient<T, TInput = T> {
|
|
|
150
185
|
/** An opaque cursor from a previous call — not a row count. */
|
|
151
186
|
offset?: string;
|
|
152
187
|
limit?: number;
|
|
153
|
-
filters?:
|
|
188
|
+
filters?: AirtableRecordFilters<T>;
|
|
154
189
|
}): Promise<{
|
|
155
190
|
records: T[];
|
|
156
191
|
offset: string | undefined;
|
|
@@ -158,7 +193,7 @@ export interface AirtableTableClient<T, TInput = T> {
|
|
|
158
193
|
}>;
|
|
159
194
|
findOne(params: {
|
|
160
195
|
id?: string;
|
|
161
|
-
filters?:
|
|
196
|
+
filters?: AirtableRecordFilters<T>;
|
|
162
197
|
}): Promise<T | undefined>;
|
|
163
198
|
create(params: {
|
|
164
199
|
record: Partial<TInput>;
|
package/dist/esm/sync/lib.js
CHANGED
|
@@ -401,8 +401,8 @@ export function generateDbTs(schema) {
|
|
|
401
401
|
lines.push("// .findAll({ filters?, sort?, offset?, limit?, fields? }) → { records: T[], hasMore: boolean }");
|
|
402
402
|
lines.push("// filters: { fieldName: value } for equality, or { fieldName: { <op>: value } }");
|
|
403
403
|
lines.push("// operators: contains, not, in, notIn, lt, lte, gt, gte");
|
|
404
|
-
lines.push('// `not: null` means "is set"
|
|
405
|
-
lines.push("// sort
|
|
404
|
+
lines.push('// `not: null` means "is set". An empty `in: []` matches nothing; an', '// empty `notIn: []` applies no filter.');
|
|
405
|
+
lines.push("// sort is currently IGNORED here — it is stripped before the request.", "// (it does work on zite.auth.findAllUsers). Order in SQL instead.");
|
|
406
406
|
lines.push("// limit defaults to 500, max 2000; offset is a row count (a number)");
|
|
407
407
|
lines.push("// .findOne({ id?, filters?, fields? }) → T | undefined");
|
|
408
408
|
lines.push("// .create({ record }) → T");
|