zitejs 0.9.93 → 0.9.95
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/dist/cjs/api/index.js +5 -0
- package/dist/cjs/auth/index.d.ts +23 -4
- package/dist/cjs/auth/index.js +8 -0
- package/dist/cjs/auth-server/index.d.ts +3 -2
- package/dist/cjs/backend/index.d.ts +39 -15
- package/dist/cjs/backend/index.js +10 -4
- package/dist/cjs/bundle/index.js +28 -4
- package/dist/cjs/check/index.js +57 -3
- package/dist/cjs/db/index.js +5 -0
- package/dist/cjs/dev/index.js +9 -0
- package/dist/cjs/runtime/index.d.ts +57 -22
- package/dist/cjs/sync/index.js +5 -0
- package/dist/cjs/sync/lib.js +314 -74
- package/dist/esm/api/index.d.ts +2 -0
- package/dist/esm/api/index.js +1 -0
- package/dist/esm/auth/index.d.ts +23 -4
- package/dist/esm/auth/index.js +8 -0
- package/dist/esm/auth-server/index.d.ts +3 -2
- package/dist/esm/backend/index.d.ts +39 -15
- package/dist/esm/backend/index.js +10 -4
- package/dist/esm/bundle/index.js +28 -4
- package/dist/esm/check/index.js +57 -3
- package/dist/esm/cli.js +0 -0
- package/dist/esm/db/index.d.ts +2 -0
- package/dist/esm/db/index.js +1 -0
- package/dist/esm/dev/index.js +9 -0
- package/dist/esm/runtime/index.d.ts +57 -22
- package/dist/esm/sync/index.js +5 -0
- package/dist/esm/sync/lib.js +314 -74
- package/package.json +1 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCaller = void 0;
|
|
4
|
+
var index_js_1 = require("../caller/index.js");
|
|
5
|
+
Object.defineProperty(exports, "createCaller", { enumerable: true, get: function () { return index_js_1.createCaller; } });
|
package/dist/cjs/auth/index.d.ts
CHANGED
|
@@ -30,9 +30,17 @@ export declare const useSession: () => {
|
|
|
30
30
|
query?: import("better-auth/types").SessionQueryParams;
|
|
31
31
|
} | undefined) => Promise<void>;
|
|
32
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* `loginWithRedirect` and `logout` are returned as well as exported. The
|
|
35
|
+
* pre-monorepo `useAuth()` returned them, so app code that destructures them
|
|
36
|
+
* from the hook is common — and returning them here means the legacy compat
|
|
37
|
+
* shim is the only thing that has to know that, not every migrated app.
|
|
38
|
+
*/
|
|
33
39
|
export declare function useAuth(): {
|
|
34
40
|
user: User | null;
|
|
35
41
|
isLoading: boolean;
|
|
42
|
+
loginWithRedirect: typeof loginWithRedirect;
|
|
43
|
+
logout: typeof logout;
|
|
36
44
|
};
|
|
37
45
|
export declare const signIn: {
|
|
38
46
|
magicLink: <FetchOptions extends import("@better-auth/core").ClientFetchOption<Partial<{
|
|
@@ -239,17 +247,28 @@ export declare function updateProfile(data: {
|
|
|
239
247
|
statusText: string;
|
|
240
248
|
};
|
|
241
249
|
}>;
|
|
242
|
-
|
|
250
|
+
/**
|
|
251
|
+
* An `interface`, not a type alias, so a migrated app can widen it by
|
|
252
|
+
* declaration merging (`.zite/user-extensions.d.ts`). A legacy user-sync app's
|
|
253
|
+
* code reads arbitrary columns off the synced row; those can't be enumerated
|
|
254
|
+
* here, and a type alias can't be reopened to admit them.
|
|
255
|
+
*
|
|
256
|
+
* `firstName`/`lastName` are optional rather than `string | null`: the
|
|
257
|
+
* pre-monorepo User declared them optional, so `{ firstName?: string }` is the
|
|
258
|
+
* shape existing app code is written against. The producers normalize null to
|
|
259
|
+
* undefined — see `authTablesService` and the workflow-runner's sync branch.
|
|
260
|
+
*/
|
|
261
|
+
export interface User {
|
|
243
262
|
id: string;
|
|
244
263
|
name: string;
|
|
245
|
-
firstName
|
|
246
|
-
lastName
|
|
264
|
+
firstName?: string;
|
|
265
|
+
lastName?: string;
|
|
247
266
|
email: string;
|
|
248
267
|
emailVerified: boolean;
|
|
249
268
|
image: string | null;
|
|
250
269
|
createdAt: Date;
|
|
251
270
|
updatedAt: Date;
|
|
252
|
-
}
|
|
271
|
+
}
|
|
253
272
|
export interface ZiteAuthMethods {
|
|
254
273
|
emailPassword?: boolean;
|
|
255
274
|
magicLink?: boolean;
|
package/dist/cjs/auth/index.js
CHANGED
|
@@ -20,11 +20,19 @@ const authClient = (0, react_1.createAuthClient)({
|
|
|
20
20
|
],
|
|
21
21
|
});
|
|
22
22
|
exports.useSession = authClient.useSession;
|
|
23
|
+
/**
|
|
24
|
+
* `loginWithRedirect` and `logout` are returned as well as exported. The
|
|
25
|
+
* pre-monorepo `useAuth()` returned them, so app code that destructures them
|
|
26
|
+
* from the hook is common — and returning them here means the legacy compat
|
|
27
|
+
* shim is the only thing that has to know that, not every migrated app.
|
|
28
|
+
*/
|
|
23
29
|
function useAuth() {
|
|
24
30
|
const { data, isPending } = (0, exports.useSession)();
|
|
25
31
|
return {
|
|
26
32
|
user: data?.user ?? null,
|
|
27
33
|
isLoading: isPending,
|
|
34
|
+
loginWithRedirect,
|
|
35
|
+
logout,
|
|
28
36
|
};
|
|
29
37
|
}
|
|
30
38
|
exports.signIn = authClient.signIn;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
/** Must agree with `User` in `zitejs/auth` and `AuthUser` in `zitejs/runtime`. */
|
|
1
2
|
export interface ZiteAuthUser {
|
|
2
3
|
id: string;
|
|
3
4
|
email: string;
|
|
4
5
|
name: string;
|
|
5
|
-
firstName
|
|
6
|
-
lastName
|
|
6
|
+
firstName?: string;
|
|
7
|
+
lastName?: string;
|
|
7
8
|
}
|
|
8
9
|
import type { ZiteAuthMethods } from '../auth/index.js';
|
|
9
10
|
export type { ZiteAuthMethods };
|
|
@@ -11,38 +11,62 @@ export interface ZiteRequestContext {
|
|
|
11
11
|
};
|
|
12
12
|
userId?: string;
|
|
13
13
|
organizationId?: string;
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
}
|
|
16
|
-
export interface ZiteScheduledContext extends ZiteRequestContext {
|
|
17
|
-
scheduledAt: string;
|
|
18
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Context on a scheduled (cron-fired) run. There is no authenticated user —
|
|
17
|
+
* the workflow-runner sends `{ user: null }` literally, because a cron trigger
|
|
18
|
+
* is an internal call with no session. Only endpoints that declare a `schedule`
|
|
19
|
+
* see this in their context union, so plain endpoints keep a non-null user.
|
|
20
|
+
*/
|
|
21
|
+
export type ZiteScheduledContext = {
|
|
22
|
+
user: null;
|
|
23
|
+
};
|
|
24
|
+
export type ZiteErrorCode = "BAD_REQUEST" | "UNAUTHORIZED" | "FORBIDDEN" | "NOT_FOUND" | "CONFLICT" | "RATE_LIMITED" | "INTERNAL_ERROR";
|
|
25
|
+
/**
|
|
26
|
+
* Throw to fail an endpoint with a specific HTTP status. The worker maps `code`
|
|
27
|
+
* through a fixed table (BAD_REQUEST -> 400, and so on); it reads `code` and
|
|
28
|
+
* nothing else, so an error carrying only a numeric `statusCode` fell through
|
|
29
|
+
* to a generic 500.
|
|
30
|
+
*/
|
|
19
31
|
export declare class ZiteError extends Error {
|
|
20
|
-
|
|
21
|
-
constructor(
|
|
22
|
-
|
|
32
|
+
code: ZiteErrorCode;
|
|
33
|
+
constructor(options: {
|
|
34
|
+
code: ZiteErrorCode;
|
|
35
|
+
message: string;
|
|
23
36
|
});
|
|
24
37
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Structurally matches a zod schema. `TIn` is the schema's *input* type, which
|
|
40
|
+
* differs from its output wherever a field has a default or a transform —
|
|
41
|
+
* `z.number().default(10)` accepts `undefined` but produces `number`.
|
|
42
|
+
*/
|
|
43
|
+
type SchemaLike<TOut, TIn = TOut> = {
|
|
44
|
+
_output: TOut;
|
|
45
|
+
_input: TIn;
|
|
46
|
+
parse: (data: unknown) => TOut;
|
|
28
47
|
};
|
|
29
48
|
export type ZiteStreamInterface = {
|
|
30
49
|
write: (data: unknown) => Promise<void>;
|
|
31
50
|
forward: (asyncIterable: AsyncIterable<string>) => Promise<string>;
|
|
32
51
|
};
|
|
33
|
-
export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream extends boolean = false> {
|
|
52
|
+
export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream extends boolean = false, TSchedule extends ZiteSchedule | undefined = undefined, TRawInput = TInput> {
|
|
34
53
|
description?: string;
|
|
35
|
-
inputSchema?: SchemaLike<TInput>;
|
|
54
|
+
inputSchema?: SchemaLike<TInput, TRawInput>;
|
|
36
55
|
outputSchema?: SchemaLike<TOutput>;
|
|
37
56
|
stream?: TStream;
|
|
38
57
|
authenticated?: boolean;
|
|
39
|
-
|
|
58
|
+
/**
|
|
59
|
+
* When set, the endpoint also fires on this cron schedule. It stays
|
|
60
|
+
* request-callable — a schedule is an additional trigger, not a replacement.
|
|
61
|
+
* Declaring one widens `context` so `context.user` must be null-checked.
|
|
62
|
+
*/
|
|
63
|
+
schedule?: TSchedule;
|
|
40
64
|
webhook?: ZiteWebhook;
|
|
41
65
|
execute: (params: {
|
|
42
66
|
input: TInput;
|
|
43
|
-
context: ZiteRequestContext | ZiteScheduledContext;
|
|
67
|
+
context: TSchedule extends ZiteSchedule ? ZiteRequestContext | ZiteScheduledContext : ZiteRequestContext;
|
|
44
68
|
} & (TStream extends true ? {
|
|
45
69
|
stream: ZiteStreamInterface;
|
|
46
70
|
} : {})) => Promise<TOutput> | TOutput;
|
|
47
71
|
}
|
|
48
|
-
export declare function createEndpoint<TInput = unknown, TOutput = unknown, TStream extends boolean = false>(config: EndpointConfig<TInput, TOutput, TStream>): EndpointConfig<TInput, TOutput, TStream>;
|
|
72
|
+
export declare function createEndpoint<TInput = unknown, TOutput = unknown, TStream extends boolean = false, TSchedule extends ZiteSchedule | undefined = undefined, TRawInput = TInput>(config: EndpointConfig<TInput, TOutput, TStream, TSchedule, TRawInput>): EndpointConfig<TInput, TOutput, TStream, TSchedule, TRawInput>;
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZiteError = void 0;
|
|
4
4
|
exports.createEndpoint = createEndpoint;
|
|
5
|
+
/**
|
|
6
|
+
* Throw to fail an endpoint with a specific HTTP status. The worker maps `code`
|
|
7
|
+
* through a fixed table (BAD_REQUEST -> 400, and so on); it reads `code` and
|
|
8
|
+
* nothing else, so an error carrying only a numeric `statusCode` fell through
|
|
9
|
+
* to a generic 500.
|
|
10
|
+
*/
|
|
5
11
|
class ZiteError extends Error {
|
|
6
|
-
|
|
7
|
-
constructor(
|
|
8
|
-
super(message);
|
|
12
|
+
code;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super(options.message);
|
|
9
15
|
this.name = "ZiteError";
|
|
10
|
-
this.
|
|
16
|
+
this.code = options.code;
|
|
11
17
|
}
|
|
12
18
|
}
|
|
13
19
|
exports.ZiteError = ZiteError;
|
package/dist/cjs/bundle/index.js
CHANGED
|
@@ -210,6 +210,19 @@ function getSdkImportSource(baseDir) {
|
|
|
210
210
|
}
|
|
211
211
|
return 'zite-integrations-backend-sdk';
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* `zitejs/db`, `zitejs/api`, `zitejs/integrations` and `zitejs/email` are
|
|
215
|
+
* tsconfig aliases onto generated files, not real package subpaths — they are
|
|
216
|
+
* absent from the `exports` map, and `zitejs` isn't in PREBUNDLED_LIBS either.
|
|
217
|
+
* So marking one external doesn't defer resolution, it guarantees a module
|
|
218
|
+
* that fails to instantiate the first time the deployed endpoint is invoked,
|
|
219
|
+
* long after the build reported success. Fail here instead, where the message
|
|
220
|
+
* can name the file that's missing.
|
|
221
|
+
*/
|
|
222
|
+
const unresolvedAlias = (specifier, expectedPath) => {
|
|
223
|
+
throw new Error(`Cannot resolve '${specifier}': expected generated file at ${expectedPath}. ` +
|
|
224
|
+
`Run \`npx zitejs generate\` before bundling.`);
|
|
225
|
+
};
|
|
213
226
|
function createAliasPlugin(opts) {
|
|
214
227
|
return {
|
|
215
228
|
name: 'zite-alias',
|
|
@@ -234,7 +247,7 @@ function createAliasPlugin(opts) {
|
|
|
234
247
|
if (sdkPath)
|
|
235
248
|
return { path: sdkPath };
|
|
236
249
|
}
|
|
237
|
-
return
|
|
250
|
+
return unresolvedAlias(args.path, `${opts.baseDir}/.zite/backend.ts`);
|
|
238
251
|
});
|
|
239
252
|
}
|
|
240
253
|
// Resolve zitejs/db to .zite/db.ts — check app dir first, then
|
|
@@ -248,7 +261,18 @@ function createAliasPlugin(opts) {
|
|
|
248
261
|
if (fs.existsSync(rootDbPath))
|
|
249
262
|
return { path: rootDbPath };
|
|
250
263
|
}
|
|
251
|
-
return
|
|
264
|
+
return unresolvedAlias('zitejs/db', `${opts.baseDir}/.zite/db.ts or the project root's`);
|
|
265
|
+
});
|
|
266
|
+
// Resolve zitejs/api to the app's generated endpoint callers. Endpoints
|
|
267
|
+
// calling other endpoints is a supported shape — `createCaller` has a
|
|
268
|
+
// server-side branch that dials the runner directly.
|
|
269
|
+
build.onResolve({ filter: /^zitejs\/api$/ }, () => {
|
|
270
|
+
if (opts.baseDir) {
|
|
271
|
+
const apiPath = path.resolve(opts.baseDir, '.zite/api.ts');
|
|
272
|
+
if (fs.existsSync(apiPath))
|
|
273
|
+
return { path: apiPath };
|
|
274
|
+
}
|
|
275
|
+
return unresolvedAlias('zitejs/api', `${opts.baseDir}/.zite/api.ts`);
|
|
252
276
|
});
|
|
253
277
|
// Resolve zitejs/integrations to .zite/integrations/airtable.ts
|
|
254
278
|
build.onResolve({ filter: /^zitejs\/integrations$/ }, () => {
|
|
@@ -257,7 +281,7 @@ function createAliasPlugin(opts) {
|
|
|
257
281
|
if (fs.existsSync(intPath))
|
|
258
282
|
return { path: intPath };
|
|
259
283
|
}
|
|
260
|
-
return
|
|
284
|
+
return unresolvedAlias('zitejs/integrations', `${opts.baseDir}/.zite/integrations/airtable.ts`);
|
|
261
285
|
});
|
|
262
286
|
// Resolve zitejs/email to .zite/integrations/email.ts
|
|
263
287
|
build.onResolve({ filter: /^zitejs\/email$/ }, () => {
|
|
@@ -266,7 +290,7 @@ function createAliasPlugin(opts) {
|
|
|
266
290
|
if (fs.existsSync(intPath))
|
|
267
291
|
return { path: intPath };
|
|
268
292
|
}
|
|
269
|
-
return
|
|
293
|
+
return unresolvedAlias('zitejs/email', `${opts.baseDir}/.zite/integrations/email.ts`);
|
|
270
294
|
});
|
|
271
295
|
// zitejs/auth/server is types + an identity wrapper — inline a shim so
|
|
272
296
|
// zite.auth.ts bundles without resolving the installed package.
|
package/dist/cjs/check/index.js
CHANGED
|
@@ -26,6 +26,36 @@ function run(cmd, cwd) {
|
|
|
26
26
|
return { ok: false, output: (e.stderr ?? '') + (e.stdout ?? '') };
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* `zitejs bundle` reports per-endpoint failures inside its JSON payload and
|
|
31
|
+
* still exits 0, so a non-empty `endpointErrors` is the only signal there is.
|
|
32
|
+
*/
|
|
33
|
+
function bundleFailures(output) {
|
|
34
|
+
const line = output
|
|
35
|
+
.trim()
|
|
36
|
+
.split('\n')
|
|
37
|
+
.reverse()
|
|
38
|
+
.find(l => l.startsWith('{'));
|
|
39
|
+
if (!line)
|
|
40
|
+
return ['bundle produced no result'];
|
|
41
|
+
let result;
|
|
42
|
+
try {
|
|
43
|
+
result = JSON.parse(line);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return [`could not parse bundle output: ${line.slice(0, 200)}`];
|
|
47
|
+
}
|
|
48
|
+
const failures = [];
|
|
49
|
+
if (result.error)
|
|
50
|
+
failures.push(result.error);
|
|
51
|
+
for (const [name, err] of Object.entries(result.endpointErrors ?? {})) {
|
|
52
|
+
failures.push(`${name}: ${err}`);
|
|
53
|
+
}
|
|
54
|
+
if (result.authHooksError) {
|
|
55
|
+
failures.push(`zite.auth.ts: ${result.authHooksError}`);
|
|
56
|
+
}
|
|
57
|
+
return failures;
|
|
58
|
+
}
|
|
29
59
|
async function runCheck() {
|
|
30
60
|
const appDirs = findAppDirs();
|
|
31
61
|
if (appDirs.length === 0) {
|
|
@@ -36,11 +66,19 @@ async function runCheck() {
|
|
|
36
66
|
for (const app of appDirs) {
|
|
37
67
|
const appPath = (0, path_1.join)('apps', app);
|
|
38
68
|
console.log(`\n── ${app} ──`);
|
|
69
|
+
// Only tsconfig.app.json compiles anything. The app's tsconfig.json is a
|
|
70
|
+
// solution-style config — `"files": []` plus a reference — so
|
|
71
|
+
// `tsc --noEmit -p tsconfig.json` type-checks zero files and exits 0. It
|
|
72
|
+
// used to be the fallback, which meant an app missing tsconfig.app.json
|
|
73
|
+
// reported a passing typecheck it never ran.
|
|
39
74
|
const tsconfigAppPath = (0, path_1.join)(appPath, 'tsconfig.app.json');
|
|
40
|
-
|
|
41
|
-
|
|
75
|
+
if (!(0, fs_1.existsSync)(tsconfigAppPath)) {
|
|
76
|
+
console.log(` tsc --noEmit ... ✗ (no ${tsconfigAppPath})`);
|
|
77
|
+
allPassed = false;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
42
80
|
process.stdout.write(' tsc --noEmit ... ');
|
|
43
|
-
const tsc = run(`npx tsc --noEmit -p ${
|
|
81
|
+
const tsc = run(`npx tsc --noEmit -p ${tsconfigAppPath}`, '.');
|
|
44
82
|
if (tsc.ok) {
|
|
45
83
|
console.log('✓');
|
|
46
84
|
}
|
|
@@ -50,6 +88,22 @@ async function runCheck() {
|
|
|
50
88
|
allPassed = false;
|
|
51
89
|
}
|
|
52
90
|
}
|
|
91
|
+
// Endpoints never reach vite — they are bundled separately for the lambda,
|
|
92
|
+
// against a different resolver. tsc and vite both pass on an endpoint whose
|
|
93
|
+
// `zitejs/*` alias has no generated file behind it; only the bundler knows.
|
|
94
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(appPath, 'src', 'api'))) {
|
|
95
|
+
process.stdout.write(' bundle endpoints ... ');
|
|
96
|
+
const bundle = run(`npx zitejs bundle --app ${app}`, '.');
|
|
97
|
+
const failures = bundle.ok ? bundleFailures(bundle.output) : [bundle.output];
|
|
98
|
+
if (failures.length === 0) {
|
|
99
|
+
console.log('✓');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.log('✗');
|
|
103
|
+
console.log(failures.map(l => ` ${l}`).join('\n'));
|
|
104
|
+
allPassed = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
53
107
|
const viteConfig = (0, path_1.join)(appPath, 'vite.config.ts');
|
|
54
108
|
if ((0, fs_1.existsSync)(viteConfig)) {
|
|
55
109
|
process.stdout.write(' vite build ... ');
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTableClient = void 0;
|
|
4
|
+
var index_js_1 = require("../runtime/index.js");
|
|
5
|
+
Object.defineProperty(exports, "createTableClient", { enumerable: true, get: function () { return index_js_1.createTableClient; } });
|
package/dist/cjs/dev/index.js
CHANGED
|
@@ -83,8 +83,17 @@ function regenerateAppApiTs(appDir) {
|
|
|
83
83
|
const apiDir = (0, path_1.join)("apps", appDir, "src", "api");
|
|
84
84
|
if (!(0, fs_2.existsSync)(apiDir))
|
|
85
85
|
return;
|
|
86
|
+
// Sorted because `readdir` order is unspecified — it is whatever the
|
|
87
|
+
// filesystem returns. `generateApiTs` emits one import, one type block and
|
|
88
|
+
// one `api` key per endpoint IN THIS ORDER, and those declarations are
|
|
89
|
+
// order-independent, so a reshuffle produces a byte-different file that
|
|
90
|
+
// compiles to an identical program. Git cannot tell that apart from a real
|
|
91
|
+
// change: the app lands in the rebuild set and rebuilds for nothing, and a
|
|
92
|
+
// genuine one-endpoint addition shows up as a rewrite of the whole file
|
|
93
|
+
// instead of a few added lines.
|
|
86
94
|
const endpointFiles = (0, fs_2.readdirSync)(apiDir)
|
|
87
95
|
.filter((f) => f.endsWith(".ts") || f.endsWith(".js"))
|
|
96
|
+
.sort()
|
|
88
97
|
.map((f) => ({
|
|
89
98
|
fileName: f,
|
|
90
99
|
content: (0, fs_2.readFileSync)((0, path_1.join)(apiDir, f), "utf-8"),
|
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
import type { NotificationsCreateParams, NotificationsCreateResult } from "../notifications/index.js";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* A comparison against one field. Mirrors base-runner's operator set
|
|
4
|
+
* (`LegacyWhereConditionOperators`); anything else in the object is ignored.
|
|
5
|
+
*/
|
|
6
|
+
export type FilterCondition<V> = {
|
|
7
|
+
/** Substring match (text fields) or "has any of these" (linked records). */
|
|
8
|
+
contains?: V extends Array<infer E> ? E | E[] : V;
|
|
9
|
+
/** Not equal, or — against `null` — "is set". */
|
|
10
|
+
not?: V | null;
|
|
11
|
+
/** Empty array means "no filter", not "match nothing". */
|
|
12
|
+
in?: V extends Array<infer E> ? E[] : V[];
|
|
13
|
+
/** Empty array means "no filter", not "match everything". */
|
|
14
|
+
notIn?: V extends Array<infer E> ? E[] : V[];
|
|
15
|
+
lt?: V;
|
|
16
|
+
lte?: V;
|
|
17
|
+
gt?: V;
|
|
18
|
+
gte?: V;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Filters keyed by the record's own field names. Typed rather than `unknown`
|
|
22
|
+
* because an unrecognized key is not an error at runtime — it passes through
|
|
23
|
+
* the SDK-name-to-field-id transform verbatim, matches no column, and the query
|
|
24
|
+
* comes back **unfiltered**. A typo silently returns every row.
|
|
25
|
+
*/
|
|
26
|
+
export type RecordFilters<T> = {
|
|
27
|
+
[K in keyof T]?: T[K] | FilterCondition<T[K]>;
|
|
28
|
+
};
|
|
29
|
+
export interface TableFindAllOptions<T = Record<string, unknown>> {
|
|
3
30
|
limit?: number;
|
|
4
31
|
offset?: number;
|
|
5
32
|
sort?: unknown[];
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
fields?: string[];
|
|
33
|
+
filters?: RecordFilters<T>;
|
|
34
|
+
fields?: Array<Extract<keyof T, string>>;
|
|
9
35
|
}
|
|
10
36
|
export interface BulkCreateResult<T> {
|
|
11
37
|
success: boolean;
|
|
@@ -16,34 +42,40 @@ export interface UpdateResult<T> {
|
|
|
16
42
|
fields: Partial<T>;
|
|
17
43
|
}
|
|
18
44
|
export interface DeleteResult {
|
|
45
|
+
success: true;
|
|
19
46
|
id: string;
|
|
20
47
|
}
|
|
21
|
-
|
|
22
|
-
|
|
48
|
+
/**
|
|
49
|
+
* `TInput` is the record's *write* shape, which is not `T`: computed fields
|
|
50
|
+
* can't be written, and several field types accept looser input than they
|
|
51
|
+
* store. Defaults to `T` so a hand-written `TableClient<Foo>` still compiles.
|
|
52
|
+
*/
|
|
53
|
+
export interface TableClient<T, TInput = T> {
|
|
54
|
+
findAll(params?: TableFindAllOptions<T>): Promise<{
|
|
23
55
|
records: T[];
|
|
24
56
|
hasMore: boolean;
|
|
25
57
|
}>;
|
|
26
58
|
findOne(params: {
|
|
27
59
|
id?: string;
|
|
28
|
-
filters?:
|
|
29
|
-
fields?: string
|
|
60
|
+
filters?: RecordFilters<T>;
|
|
61
|
+
fields?: Array<Extract<keyof T, string>>;
|
|
30
62
|
}): Promise<T | undefined>;
|
|
31
63
|
create(params: {
|
|
32
|
-
record: Partial<
|
|
64
|
+
record: Partial<TInput>;
|
|
33
65
|
}): Promise<T>;
|
|
34
66
|
update(params: {
|
|
35
67
|
id: string;
|
|
36
|
-
record: Partial<
|
|
68
|
+
record: Partial<TInput>;
|
|
37
69
|
}): Promise<UpdateResult<T>>;
|
|
38
70
|
delete(params: {
|
|
39
71
|
id: string;
|
|
40
72
|
}): Promise<DeleteResult>;
|
|
41
73
|
bulkCreate(params: {
|
|
42
|
-
records: Partial<
|
|
74
|
+
records: Partial<TInput>[];
|
|
43
75
|
matchOn?: string[];
|
|
44
76
|
}): Promise<BulkCreateResult<T>>;
|
|
45
77
|
}
|
|
46
|
-
export declare function createTableClient<T>(className: string): TableClient<T>;
|
|
78
|
+
export declare function createTableClient<T, TInput = T>(className: string): TableClient<T, TInput>;
|
|
47
79
|
export interface SqlResult {
|
|
48
80
|
rows: Record<string, unknown>[];
|
|
49
81
|
columns: Array<{
|
|
@@ -57,15 +89,16 @@ export declare function createSqlClient(): (params: {
|
|
|
57
89
|
query: string;
|
|
58
90
|
params?: unknown[];
|
|
59
91
|
}) => Promise<SqlResult>;
|
|
92
|
+
/** Must agree with `User` in `zitejs/auth` and `ZiteAuthUser` in `zitejs/auth-server` — the three used to disagree on whether the name fields were nullable or optional. */
|
|
60
93
|
export interface AuthUser {
|
|
61
94
|
id: string;
|
|
62
95
|
name: string;
|
|
63
96
|
email: string;
|
|
64
|
-
firstName
|
|
65
|
-
lastName
|
|
97
|
+
firstName?: string;
|
|
98
|
+
lastName?: string;
|
|
66
99
|
image: string | null;
|
|
67
100
|
}
|
|
68
|
-
export type FindAllAuthUsersOptions = Omit<TableFindAllOptions
|
|
101
|
+
export type FindAllAuthUsersOptions = Omit<TableFindAllOptions<AuthUser>, "fields"> & {
|
|
69
102
|
/** Restrict results to users belonging to any of these apps. */
|
|
70
103
|
appIds?: string[];
|
|
71
104
|
};
|
|
@@ -80,11 +113,13 @@ export interface AuthClient<T extends AuthUser = AuthUser> {
|
|
|
80
113
|
updateUserProfile(userId: string, profile: UpdateAuthUserProfile): Promise<T>;
|
|
81
114
|
}
|
|
82
115
|
export declare function createAuthClient<T extends AuthUser = AuthUser>(): AuthClient<T>;
|
|
83
|
-
|
|
116
|
+
/** `TInput` is the record's write shape — see `TableClient` for why it isn't `T`. */
|
|
117
|
+
export interface AirtableTableClient<T, TInput = T> {
|
|
84
118
|
findAll(params?: {
|
|
119
|
+
/** An opaque cursor from a previous call — not a row count. */
|
|
85
120
|
offset?: string;
|
|
86
121
|
limit?: number;
|
|
87
|
-
filters?:
|
|
122
|
+
filters?: RecordFilters<T>;
|
|
88
123
|
}): Promise<{
|
|
89
124
|
records: T[];
|
|
90
125
|
offset: string | undefined;
|
|
@@ -92,17 +127,17 @@ export interface AirtableTableClient<T> {
|
|
|
92
127
|
}>;
|
|
93
128
|
findOne(params: {
|
|
94
129
|
id?: string;
|
|
95
|
-
filters?:
|
|
130
|
+
filters?: RecordFilters<T>;
|
|
96
131
|
}): Promise<T | undefined>;
|
|
97
132
|
create(params: {
|
|
98
|
-
record: Partial<
|
|
133
|
+
record: Partial<TInput>;
|
|
99
134
|
}): Promise<T>;
|
|
100
135
|
bulkCreate(params: {
|
|
101
|
-
records: Partial<
|
|
136
|
+
records: Partial<TInput>[];
|
|
102
137
|
}): Promise<T[]>;
|
|
103
138
|
update(params: {
|
|
104
139
|
id: string;
|
|
105
|
-
record: Partial<
|
|
140
|
+
record: Partial<TInput>;
|
|
106
141
|
}): Promise<{
|
|
107
142
|
id: string;
|
|
108
143
|
fields: Partial<T>;
|
|
@@ -111,7 +146,7 @@ export interface AirtableTableClient<T> {
|
|
|
111
146
|
id: string;
|
|
112
147
|
}): Promise<DeleteResult>;
|
|
113
148
|
}
|
|
114
|
-
export declare function createAirtableClient<T>(integrationId: string, className: string, implicitParams: Record<string, unknown>): AirtableTableClient<T>;
|
|
149
|
+
export declare function createAirtableClient<T, TInput = T>(integrationId: string, className: string, implicitParams: Record<string, unknown>): AirtableTableClient<T, TInput>;
|
|
115
150
|
/** A block of content in an email body. */
|
|
116
151
|
export type EmailBlock = {
|
|
117
152
|
type: "text";
|
package/dist/cjs/sync/index.js
CHANGED
|
@@ -86,8 +86,13 @@ function regenerateApiTs() {
|
|
|
86
86
|
const apiDir = (0, path_1.join)("src", "api");
|
|
87
87
|
if (!(0, fs_1.existsSync)(apiDir))
|
|
88
88
|
return;
|
|
89
|
+
// Sorted for the same reason as the `generate` path: `generateApiTs` emits
|
|
90
|
+
// per-endpoint declarations in list order, `readdir` order is unspecified,
|
|
91
|
+
// and a reshuffle rewrites the file without changing the program. Both
|
|
92
|
+
// writers must agree, or `sync` and `generate` reorder each other's output.
|
|
89
93
|
const endpointFiles = (0, fs_1.readdirSync)(apiDir)
|
|
90
94
|
.filter((f) => f.endsWith(".ts") || f.endsWith(".js"))
|
|
95
|
+
.sort()
|
|
91
96
|
.map((f) => ({
|
|
92
97
|
fileName: f,
|
|
93
98
|
content: (0, fs_1.readFileSync)((0, path_1.join)(apiDir, f), "utf-8"),
|