zitejs 0.9.34 → 0.9.35

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.
@@ -6,15 +6,15 @@ exports.createSqlClient = createSqlClient;
6
6
  function getSdkCall() {
7
7
  const fn = globalThis.__wrapSdkCall;
8
8
  if (!fn) {
9
- throw new Error('Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.');
9
+ throw new Error("Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.");
10
10
  }
11
11
  return fn;
12
12
  }
13
- const DB_INTEGRATION_ID = 'databases';
13
+ const DB_INTEGRATION_ID = "databases";
14
14
  function getBaseId() {
15
15
  try {
16
- return globalThis.__ZITE_EXECUTION_CONFIG__?.baseId
17
- ?? (typeof process !== 'undefined' ? process.env?.ZITE_BASE_ID : undefined);
16
+ return (globalThis.__ZITE_EXECUTION_CONFIG__?.baseId ??
17
+ (typeof process !== "undefined" ? process.env?.ZITE_BASE_ID : undefined));
18
18
  }
19
19
  catch {
20
20
  return undefined;
@@ -23,8 +23,8 @@ function getBaseId() {
23
23
  function resolveTableId(className) {
24
24
  try {
25
25
  const config = globalThis.__ZITE_EXECUTION_CONFIG__;
26
- const tables = config?.integrationSettings?.[DB_INTEGRATION_ID]
27
- ?.settings?.nameMappings?.tables;
26
+ const tables = config?.integrationSettings?.[DB_INTEGRATION_ID]?.settings?.nameMappings
27
+ ?.tables;
28
28
  if (!tables)
29
29
  return className;
30
30
  for (const [realId, entry] of Object.entries(tables)) {
@@ -37,33 +37,33 @@ function resolveTableId(className) {
37
37
  }
38
38
  function createTableClient(className) {
39
39
  return {
40
- findAll: (options) => getSdkCall()(DB_INTEGRATION_ID, className, 'findAll', {
40
+ findAll: (options) => getSdkCall()(DB_INTEGRATION_ID, className, "findAll", {
41
41
  baseId: getBaseId(),
42
42
  tableId: resolveTableId(className),
43
43
  ...options,
44
44
  }),
45
- findOne: (recordId) => getSdkCall()(DB_INTEGRATION_ID, className, 'findOne', {
45
+ findOne: (recordId) => getSdkCall()(DB_INTEGRATION_ID, className, "findOne", {
46
46
  baseId: getBaseId(),
47
47
  tableId: resolveTableId(className),
48
- ...(typeof recordId === 'string' ? { id: recordId } : recordId),
48
+ ...(typeof recordId === "string" ? { id: recordId } : recordId),
49
49
  }),
50
- create: (data) => getSdkCall()(DB_INTEGRATION_ID, className, 'create', {
50
+ create: (data) => getSdkCall()(DB_INTEGRATION_ID, className, "create", {
51
51
  baseId: getBaseId(),
52
52
  tableId: resolveTableId(className),
53
53
  record: data,
54
54
  }),
55
- update: (id, data) => getSdkCall()(DB_INTEGRATION_ID, className, 'update', {
55
+ update: (id, data) => getSdkCall()(DB_INTEGRATION_ID, className, "update", {
56
56
  baseId: getBaseId(),
57
57
  tableId: resolveTableId(className),
58
58
  id,
59
59
  record: data,
60
60
  }),
61
- delete: (id) => getSdkCall()(DB_INTEGRATION_ID, className, 'delete', {
61
+ delete: (id) => getSdkCall()(DB_INTEGRATION_ID, className, "delete", {
62
62
  baseId: getBaseId(),
63
63
  tableId: resolveTableId(className),
64
64
  id,
65
65
  }),
66
- bulkCreate: (records) => getSdkCall()(DB_INTEGRATION_ID, className, 'bulkCreate', {
66
+ bulkCreate: (records) => getSdkCall()(DB_INTEGRATION_ID, className, "bulkCreate", {
67
67
  baseId: getBaseId(),
68
68
  tableId: resolveTableId(className),
69
69
  records,
@@ -71,7 +71,10 @@ function createTableClient(className) {
71
71
  };
72
72
  }
73
73
  function createSqlClient() {
74
- return (params) => getSdkCall()(DB_INTEGRATION_ID, 'Db', 'executeSql', { baseId: getBaseId(), ...params });
74
+ return (params) => getSdkCall()(DB_INTEGRATION_ID, "Db", "executeSql", {
75
+ baseId: getBaseId(),
76
+ ...params,
77
+ });
75
78
  }
76
79
  var index_js_1 = require("../caller/index.js");
77
80
  Object.defineProperty(exports, "createCaller", { enumerable: true, get: function () { return index_js_1.createCaller; } });
@@ -7,13 +7,13 @@ const fs_1 = require("fs");
7
7
  const path_1 = require("path");
8
8
  const lib_js_1 = require("./lib.js");
9
9
  const DB_ENVIRONMENTS = {
10
- production: 'https://tables.fillout.com/api/v1',
11
- staging: 'https://tables.filloutstaging.com/api/v1',
12
- local: 'http://localhost:2507/api/v1',
10
+ production: "https://tables.fillout.com/api/v1",
11
+ staging: "https://tables.filloutstaging.com/api/v1",
12
+ local: "http://localhost:2507/api/v1",
13
13
  };
14
- const env = process.env.ZITE_ENV ?? 'production';
14
+ const env = process.env.ZITE_ENV ?? "production";
15
15
  const BASE_URL = process.env.ZITE_DB_URL ?? DB_ENVIRONMENTS[env] ?? DB_ENVIRONMENTS.production;
16
- const TOKEN = process.env.ZITE_DB_TOKEN ?? '';
16
+ const TOKEN = process.env.ZITE_DB_TOKEN ?? "";
17
17
  async function fetchBaseMetadata(baseId) {
18
18
  const url = `${BASE_URL}/bases/${encodeURIComponent(baseId)}`;
19
19
  const res = await fetch(url, {
@@ -28,7 +28,7 @@ function resolveBaseId() {
28
28
  if (process.env.ZITE_BASE_ID)
29
29
  return process.env.ZITE_BASE_ID;
30
30
  try {
31
- const config = JSON.parse((0, fs_1.readFileSync)('zite.config.json', 'utf-8'));
31
+ const config = JSON.parse((0, fs_1.readFileSync)("zite.config.json", "utf-8"));
32
32
  return config.project?.basePublicIdentifier;
33
33
  }
34
34
  catch {
@@ -37,43 +37,43 @@ function resolveBaseId() {
37
37
  }
38
38
  async function runSync() {
39
39
  if (!TOKEN) {
40
- throw new Error('ZITE_DB_TOKEN is required.');
40
+ throw new Error("ZITE_DB_TOKEN is required.");
41
41
  }
42
42
  const baseId = resolveBaseId();
43
43
  if (!baseId) {
44
- throw new Error('Could not determine base ID.');
44
+ throw new Error("Could not determine base ID.");
45
45
  }
46
46
  console.log(`Syncing database ${baseId}...`);
47
47
  const base = await fetchBaseMetadata(baseId);
48
48
  console.log(`Found ${base.tables?.length ?? 0} tables`);
49
49
  const schema = (0, lib_js_1.generateSchema)(base);
50
- (0, fs_1.writeFileSync)('zite.schema.json', JSON.stringify(schema, null, 2));
51
- console.log('Wrote zite.schema.json');
50
+ (0, fs_1.writeFileSync)("zite.schema.json", JSON.stringify(schema, null, 2));
51
+ console.log("Wrote zite.schema.json");
52
52
  const dbTs = (0, lib_js_1.generateDbTs)(base, schema);
53
- const dotZite = '.zite';
53
+ const dotZite = ".zite";
54
54
  (0, fs_1.mkdirSync)(dotZite, { recursive: true });
55
- (0, fs_1.writeFileSync)((0, path_1.join)(dotZite, 'db.ts'), dbTs);
56
- console.log('Wrote .zite/db.ts');
55
+ (0, fs_1.writeFileSync)((0, path_1.join)(dotZite, "db.ts"), dbTs);
56
+ console.log("Wrote .zite/db.ts");
57
57
  regenerateApiTs();
58
- console.log('Done!');
58
+ console.log("Done!");
59
59
  }
60
60
  function regenerateApiTs() {
61
- const apiDir = (0, path_1.join)('src', 'api');
61
+ const apiDir = (0, path_1.join)("src", "api");
62
62
  if (!(0, fs_1.existsSync)(apiDir))
63
63
  return;
64
- const endpointFiles = (0, fs_1.readdirSync)(apiDir).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));
64
+ const endpointFiles = (0, fs_1.readdirSync)(apiDir).filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
65
65
  const apiTs = (0, lib_js_1.generateApiTs)(endpointFiles);
66
66
  if (apiTs) {
67
- (0, fs_1.mkdirSync)('.zite', { recursive: true });
68
- (0, fs_1.writeFileSync)((0, path_1.join)('.zite', 'api.ts'), apiTs);
69
- console.log('Wrote .zite/api.ts');
67
+ (0, fs_1.mkdirSync)(".zite", { recursive: true });
68
+ (0, fs_1.writeFileSync)((0, path_1.join)(".zite", "api.ts"), apiTs);
69
+ console.log("Wrote .zite/api.ts");
70
70
  }
71
71
  }
72
72
  // Direct execution (npx zitejs sync)
73
- if (process.argv[1]?.endsWith('sync/index.js') ||
74
- process.argv[1]?.endsWith('sync/index.ts')) {
73
+ if (process.argv[1]?.endsWith("sync/index.js") ||
74
+ process.argv[1]?.endsWith("sync/index.ts")) {
75
75
  runSync().catch((err) => {
76
- console.error('Sync failed:', err.message);
76
+ console.error("Sync failed:", err.message);
77
77
  process.exit(1);
78
78
  });
79
79
  }
@@ -4,32 +4,31 @@ exports.toPascalCase = toPascalCase;
4
4
  exports.toCamelCase = toCamelCase;
5
5
  exports.generateSchema = generateSchema;
6
6
  exports.generateDbTs = generateDbTs;
7
- exports.generateDbDts = generateDbDts;
8
7
  exports.generateApiTs = generateApiTs;
9
8
  exports.generateUserTs = generateUserTs;
10
9
  exports.generateAuthWrapperTs = generateAuthWrapperTs;
11
10
  exports.generateBackendWrapperTs = generateBackendWrapperTs;
12
11
  const FIELD_TYPE_MAP = {
13
- single_line_text: 'string',
14
- long_text: 'string',
15
- email: 'string',
16
- url: 'string',
17
- phone_number: 'string',
18
- number: 'number',
19
- currency: 'number',
20
- percent: 'number',
21
- rating: 'number',
22
- duration: 'number',
23
- single_select: 'string',
24
- multiple_select: 'string[]',
25
- checkbox: 'boolean',
26
- date: 'string',
27
- datetime: 'string',
28
- attachments: 'Array<{ url: string; name?: string }>',
29
- linked_record: 'string | string[]',
30
- lookup: 'unknown',
31
- autonumber: 'number',
32
- source: 'string',
12
+ single_line_text: "string",
13
+ long_text: "string",
14
+ email: "string",
15
+ url: "string",
16
+ phone_number: "string",
17
+ number: "number",
18
+ currency: "number",
19
+ percent: "number",
20
+ rating: "number",
21
+ duration: "number",
22
+ single_select: "string",
23
+ multiple_select: "string[]",
24
+ checkbox: "boolean",
25
+ date: "string",
26
+ datetime: "string",
27
+ attachments: "Array<{ url: string; name?: string }>",
28
+ linked_record: "string | string[]",
29
+ lookup: "unknown",
30
+ autonumber: "number",
31
+ source: "string",
33
32
  };
34
33
  function toPascalCase(name) {
35
34
  return name
@@ -43,11 +42,14 @@ function toCamelCase(name) {
43
42
  function tsTypeForField(field) {
44
43
  if (FIELD_TYPE_MAP[field.type])
45
44
  return FIELD_TYPE_MAP[field.type];
46
- const lowerName = field.name?.toLowerCase() ?? '';
47
- if (lowerName === 'createdat' || lowerName === 'created_at' || lowerName === 'updatedat' || lowerName === 'updated_at') {
48
- return 'string';
45
+ const lowerName = field.name?.toLowerCase() ?? "";
46
+ if (lowerName === "createdat" ||
47
+ lowerName === "created_at" ||
48
+ lowerName === "updatedat" ||
49
+ lowerName === "updated_at") {
50
+ return "string";
49
51
  }
50
- return 'string';
52
+ return "string";
51
53
  }
52
54
  function generateSchema(base) {
53
55
  const schema = { tables: {} };
@@ -63,220 +65,191 @@ function generateSchema(base) {
63
65
  }
64
66
  function generateDbTs(base, schema) {
65
67
  const lines = [];
66
- lines.push('// Auto-generated by zitejs sync. Do not edit manually.');
67
- lines.push('//');
68
- lines.push('// Usage in endpoint files (src/api/*.ts):');
68
+ lines.push("// Auto-generated by zitejs sync. Do not edit manually.");
69
+ lines.push("//");
70
+ lines.push("// Usage in endpoint files (src/api/*.ts):");
69
71
  lines.push('// import { zite } from "zitejs/db";');
70
- lines.push('//');
72
+ lines.push("//");
71
73
  lines.push('// Always use "zitejs/db" — never use relative paths like "../../.zite/db".');
72
- lines.push('// The tsconfig aliases resolve zitejs/* imports to the correct .zite/ files.');
73
- lines.push('//');
74
- lines.push('// Table client methods:');
75
- lines.push('// .findAll(opts?) → { records: T[], total: number, hasMore: boolean }');
76
- lines.push('// .findOne(id) → T');
77
- lines.push('// .create(data) → T');
78
- lines.push('// .update(id, data) → T');
79
- lines.push('// .delete(id) → { deleted: true }');
80
- lines.push('// .bulkCreate(records) → T[]');
81
- lines.push('//');
82
- lines.push('// Raw SQL:');
83
- lines.push('// zite.sql({ query: "SELECT..." }) → { rows: Record<string, unknown>[] }');
74
+ lines.push("// The tsconfig aliases resolve zitejs/* imports to the correct .zite/ files.");
75
+ lines.push("//");
76
+ lines.push("// Table client methods:");
77
+ lines.push("// .findAll(opts?) → { records: T[], total: number, hasMore: boolean }");
78
+ lines.push("// opts: { limit?, offset?, sort?, filter?, filters? }");
79
+ lines.push("// .findOne(id | { filters }) → T");
80
+ lines.push("// .create({ record }) → T");
81
+ lines.push("// .update(id, { record }) → T");
82
+ lines.push("// .delete(id) → { deleted: true }");
83
+ lines.push("// .bulkCreate(records) → T[]");
84
+ lines.push("//");
85
+ lines.push("// Raw SQL (read-only SELECTs for aggregates, joins, multi-table queries):");
86
+ lines.push('// zite.sql({ query: "SELECT ...", params?: [...] })');
87
+ lines.push("// → { rows: Record<string, unknown>[], columns, rowCount, truncated }");
88
+ lines.push("//");
89
+ lines.push("// SQL guidelines:");
90
+ lines.push("// - Use SDK names for tables (PascalCase) and fields (camelCase)");
91
+ lines.push('// - ALWAYS double-quote every identifier: FROM "Orders", WHERE "status" = $1');
92
+ lines.push("// - Use params array for user input ($1, $2, ...): never interpolate into SQL");
93
+ lines.push('// - Link tables: alphabetical PascalCase concat (Items+Orders → "ItemsOrders")');
94
+ lines.push('// with id columns: "itemsId", "ordersId"');
95
+ lines.push("// - Soft-deleted rows are excluded automatically — no WHERE deleted_at IS NULL");
96
+ lines.push("// - SELECT only — use .create/.update/.delete for writes");
97
+ lines.push('// - Load the "zite:sql" skill for full SQL reference (formulas, lookups, etc.)');
84
98
  lines.push("import { createTableClient, createSqlClient } from 'zitejs/runtime';");
85
- lines.push('');
99
+ lines.push("");
86
100
  for (const table of base.tables ?? []) {
87
101
  const className = toPascalCase(table.name);
88
102
  const recordType = `${className}RecordType`;
89
103
  lines.push(`export type ${recordType} = {`);
90
- lines.push(' id: string;');
104
+ lines.push(" id: string;");
91
105
  for (const field of table.fields ?? []) {
92
106
  const fieldName = toCamelCase(field.name);
93
- if (fieldName === 'id')
107
+ if (fieldName === "id")
94
108
  continue;
95
109
  const tsType = tsTypeForField(field);
96
110
  lines.push(` ${fieldName}: ${tsType};`);
97
111
  }
98
- lines.push('};');
99
- lines.push('');
112
+ lines.push("};");
113
+ lines.push("");
100
114
  }
101
- lines.push('export const zite = {');
115
+ lines.push("export const zite = {");
102
116
  for (const table of base.tables ?? []) {
103
117
  const className = toPascalCase(table.name);
104
118
  const propName = toCamelCase(table.name);
105
119
  lines.push(` ${propName}: createTableClient<${className}RecordType>('${className}'),`);
106
120
  }
107
121
  lines.push(` sql: createSqlClient(),`);
108
- lines.push('};');
109
- lines.push('');
110
- return lines.join('\n');
111
- }
112
- function generateDbDts(base, schema) {
113
- const lines = [
114
- '// Auto-generated by zitejs sync. Do not edit manually.',
115
- '// Type declarations for IDE and LLM context. See db.ts for runtime.',
116
- '',
117
- 'interface TableClient<T> {',
118
- ' findAll(options?: { limit?: number; offset?: number; sort?: unknown[]; filter?: unknown; filters?: unknown }): Promise<{ records: T[]; total: number; hasMore: boolean }>;',
119
- ' findOne(recordId: string | { filters?: unknown; filter?: unknown }): Promise<T>;',
120
- ' create(data: Partial<T>): Promise<T>;',
121
- ' update(id: string, data: Partial<T>): Promise<T>;',
122
- ' delete(id: string): Promise<{ deleted: true }>;',
123
- ' bulkCreate(records: Partial<T>[]): Promise<T[]>;',
124
- '}',
125
- '',
126
- ];
127
- for (const table of base.tables ?? []) {
128
- const className = toPascalCase(table.name);
129
- const recordType = `${className}RecordType`;
130
- lines.push(`export type ${recordType} = {`);
131
- lines.push(' id: string;');
132
- for (const field of table.fields ?? []) {
133
- const fieldName = toCamelCase(field.name);
134
- if (fieldName === 'id')
135
- continue;
136
- const tsType = tsTypeForField(field);
137
- lines.push(` ${fieldName}: ${tsType};`);
138
- }
139
- lines.push('};');
140
- lines.push('');
141
- }
142
- lines.push('export declare const zite: {');
143
- for (const table of base.tables ?? []) {
144
- const className = toPascalCase(table.name);
145
- const propName = toCamelCase(table.name);
146
- lines.push(` ${propName}: TableClient<${className}RecordType>;`);
147
- }
148
- lines.push(' sql: (params: { query?: string; sql?: string; params?: unknown[] }) => Promise<{ rows: Record<string, unknown>[] }>;');
149
- lines.push('};');
150
- lines.push('');
151
- return lines.join('\n');
122
+ lines.push("};");
123
+ lines.push("");
124
+ return lines.join("\n");
152
125
  }
153
126
  function generateApiTs(endpointFiles) {
154
127
  if (!endpointFiles || endpointFiles.length === 0)
155
128
  return null;
156
129
  const lines = [
157
- '// Auto-generated by zitejs sync. Do not edit manually.',
158
- '',
130
+ "// Auto-generated by zitejs sync. Do not edit manually.",
131
+ "",
159
132
  "import { createCaller } from 'zitejs/caller';",
160
- '',
133
+ "",
161
134
  ];
162
135
  const endpointNames = [];
163
136
  for (const file of endpointFiles) {
164
- const name = file.replace(/\.(ts|js)$/, '');
137
+ const name = file.replace(/\.(ts|js)$/, "");
165
138
  const camelName = toCamelCase(name);
166
139
  lines.push(`import ${camelName}Endpoint from '../src/api/${name}';`);
167
140
  endpointNames.push(camelName);
168
141
  }
169
- lines.push('');
142
+ lines.push("");
170
143
  for (const name of endpointNames) {
171
144
  lines.push(`export const ${name} = createCaller(${name}Endpoint, '${name}');`);
172
145
  }
173
- lines.push('');
146
+ lines.push("");
174
147
  // Inferred input/output types per endpoint (e.g. GetDashboardInputType, GetDashboardOutputType)
175
148
  for (const name of endpointNames) {
176
149
  const pascal = toPascalCase(name);
177
150
  lines.push(`export type ${pascal}InputType = Parameters<typeof ${name}Endpoint.execute>[0]['input'];`);
178
151
  lines.push(`export type ${pascal}OutputType = Awaited<ReturnType<typeof ${name}Endpoint.execute>>;`);
179
152
  }
180
- lines.push('');
153
+ lines.push("");
181
154
  // Also export as a single api object
182
- lines.push('export const api = {');
155
+ lines.push("export const api = {");
183
156
  for (const name of endpointNames) {
184
157
  lines.push(` ${name},`);
185
158
  }
186
- lines.push('};');
187
- lines.push('');
188
- return lines.join('\n');
159
+ lines.push("};");
160
+ lines.push("");
161
+ return lines.join("\n");
189
162
  }
190
163
  function generateUserTs(usersTableFields) {
191
164
  const lines = [
192
- '// Auto-generated by zitejs sync. Do not edit manually.',
193
- '',
165
+ "// Auto-generated by zitejs sync. Do not edit manually.",
166
+ "",
194
167
  ];
195
168
  if (usersTableFields && usersTableFields.length > 0) {
196
- lines.push('export type User = {');
197
- lines.push(' id: string;');
198
- lines.push(' email: string;');
169
+ lines.push("export type User = {");
170
+ lines.push(" id: string;");
171
+ lines.push(" email: string;");
199
172
  for (const field of usersTableFields) {
200
173
  const lowerName = field.name.toLowerCase();
201
- if (lowerName === 'id' || lowerName === 'email')
174
+ if (lowerName === "id" || lowerName === "email")
202
175
  continue;
203
176
  const fieldName = toCamelCase(field.name);
204
177
  const tsType = tsTypeForField(field);
205
178
  lines.push(` ${fieldName}: ${tsType};`);
206
179
  }
207
- lines.push(' [key: string]: unknown;');
208
- lines.push('};');
180
+ lines.push(" [key: string]: unknown;");
181
+ lines.push("};");
209
182
  }
210
183
  else {
211
- lines.push('export type User = {');
212
- lines.push(' id: string;');
213
- lines.push(' email: string;');
214
- lines.push(' firstName?: string;');
215
- lines.push(' lastName?: string;');
216
- lines.push(' [key: string]: unknown;');
217
- lines.push('};');
184
+ lines.push("export type User = {");
185
+ lines.push(" id: string;");
186
+ lines.push(" email: string;");
187
+ lines.push(" firstName?: string;");
188
+ lines.push(" lastName?: string;");
189
+ lines.push(" [key: string]: unknown;");
190
+ lines.push("};");
218
191
  }
219
- lines.push('');
220
- return lines.join('\n');
192
+ lines.push("");
193
+ return lines.join("\n");
221
194
  }
222
195
  function generateAuthWrapperTs() {
223
196
  return [
224
- '// Auto-generated type-narrowing wrapper. Do not edit manually.',
225
- '// The real auth logic lives in the zitejs npm package (zitejs/auth).',
226
- '',
197
+ "// Auto-generated type-narrowing wrapper. Do not edit manually.",
198
+ "// The real auth logic lives in the zitejs npm package (zitejs/auth).",
199
+ "",
227
200
  "import { useAuth as _useAuth } from 'zitejs/auth/base';",
228
201
  "import type { User } from './user';",
229
- '',
230
- 'export type { User };',
231
- '',
232
- 'export function useAuth() {',
233
- ' return _useAuth() as ReturnType<typeof _useAuth> & { user: User | undefined };',
234
- '}',
235
- '',
236
- ].join('\n');
202
+ "",
203
+ "export type { User };",
204
+ "",
205
+ "export function useAuth() {",
206
+ " return _useAuth() as ReturnType<typeof _useAuth> & { user: User | undefined };",
207
+ "}",
208
+ "",
209
+ ].join("\n");
237
210
  }
238
211
  function generateBackendWrapperTs() {
239
212
  return [
240
- '// Auto-generated type-narrowing wrapper. Do not edit manually.',
241
- '// Re-exports createEndpoint with context.user typed to the app User.',
242
- '',
213
+ "// Auto-generated type-narrowing wrapper. Do not edit manually.",
214
+ "// Re-exports createEndpoint with context.user typed to the app User.",
215
+ "",
243
216
  "import type { ZiteRequestContext as _ZiteRequestContext, ZiteScheduledContext as _ZiteScheduledContext } from 'zitejs/backend/base';",
244
217
  "import type { User } from './user';",
245
- '',
246
- 'export class ZiteError extends Error {',
247
- ' statusCode: number;',
248
- ' constructor(message: string, options?: { statusCode?: number }) {',
249
- ' super(message);',
218
+ "",
219
+ "export class ZiteError extends Error {",
220
+ " statusCode: number;",
221
+ " constructor(message: string, options?: { statusCode?: number }) {",
222
+ " super(message);",
250
223
  " this.name = 'ZiteError';",
251
- ' this.statusCode = options?.statusCode ?? 500;',
252
- ' }',
253
- '}',
254
- '',
224
+ " this.statusCode = options?.statusCode ?? 500;",
225
+ " }",
226
+ "}",
227
+ "",
255
228
  'export interface ZiteRequestContext extends Omit<_ZiteRequestContext, "user"> {',
256
- ' user: User;',
257
- '}',
258
- '',
229
+ " user: User;",
230
+ "}",
231
+ "",
259
232
  'export interface ZiteScheduledContext extends Omit<_ZiteScheduledContext, "user"> {',
260
- ' user: User;',
261
- ' scheduledAt: string;',
262
- '}',
263
- '',
233
+ " user: User;",
234
+ " scheduledAt: string;",
235
+ "}",
236
+ "",
264
237
  "type SchemaLike<T> = { _output: T; parse: (data: unknown) => T };",
265
- '',
266
- 'export interface EndpointConfig<TInput = unknown, TOutput = unknown> {',
267
- ' description?: string;',
268
- ' inputSchema?: SchemaLike<TInput>;',
269
- ' outputSchema?: SchemaLike<TOutput>;',
270
- ' stream?: boolean;',
271
- ' authenticated?: boolean;',
272
- ' execute: (params: { input: TInput; context: ZiteRequestContext | ZiteScheduledContext }) => Promise<TOutput> | TOutput;',
273
- '}',
274
- '',
275
- 'export function createEndpoint<TInput = unknown, TOutput = unknown>(',
276
- ' config: EndpointConfig<TInput, TOutput>,',
277
- '): EndpointConfig<TInput, TOutput> {',
278
- ' return config;',
279
- '}',
280
- '',
281
- ].join('\n');
238
+ "",
239
+ "export interface EndpointConfig<TInput = unknown, TOutput = unknown> {",
240
+ " description?: string;",
241
+ " inputSchema?: SchemaLike<TInput>;",
242
+ " outputSchema?: SchemaLike<TOutput>;",
243
+ " stream?: boolean;",
244
+ " authenticated?: boolean;",
245
+ " execute: (params: { input: TInput; context: ZiteRequestContext | ZiteScheduledContext }) => Promise<TOutput> | TOutput;",
246
+ "}",
247
+ "",
248
+ "export function createEndpoint<TInput = unknown, TOutput = unknown>(",
249
+ " config: EndpointConfig<TInput, TOutput>,",
250
+ "): EndpointConfig<TInput, TOutput> {",
251
+ " return config;",
252
+ "}",
253
+ "",
254
+ ].join("\n");
282
255
  }
@@ -22,12 +22,18 @@ export interface TableClient<T> {
22
22
  bulkCreate(records: Partial<T>[]): Promise<T[]>;
23
23
  }
24
24
  export declare function createTableClient<T>(className: string): TableClient<T>;
25
+ export interface SqlResult {
26
+ rows: Record<string, unknown>[];
27
+ columns: Array<{
28
+ name: string;
29
+ originalName: string;
30
+ }>;
31
+ rowCount: number;
32
+ truncated: boolean;
33
+ }
25
34
  export declare function createSqlClient(): (params: {
26
- query?: string;
27
- sql?: string;
35
+ query: string;
28
36
  params?: unknown[];
29
- }) => Promise<{
30
- rows: Record<string, unknown>[];
31
- }>;
32
- export { createCaller } from '../caller/index.js';
33
- export type { EndpointConfig } from '../caller/index.js';
37
+ }) => Promise<SqlResult>;
38
+ export { createCaller } from "../caller/index.js";
39
+ export type { EndpointConfig } from "../caller/index.js";
@@ -1,15 +1,15 @@
1
1
  function getSdkCall() {
2
2
  const fn = globalThis.__wrapSdkCall;
3
3
  if (!fn) {
4
- throw new Error('Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.');
4
+ throw new Error("Zite SDK runtime not initialized. Endpoints must run inside the Zite worker.");
5
5
  }
6
6
  return fn;
7
7
  }
8
- const DB_INTEGRATION_ID = 'databases';
8
+ const DB_INTEGRATION_ID = "databases";
9
9
  function getBaseId() {
10
10
  try {
11
- return globalThis.__ZITE_EXECUTION_CONFIG__?.baseId
12
- ?? (typeof process !== 'undefined' ? process.env?.ZITE_BASE_ID : undefined);
11
+ return (globalThis.__ZITE_EXECUTION_CONFIG__?.baseId ??
12
+ (typeof process !== "undefined" ? process.env?.ZITE_BASE_ID : undefined));
13
13
  }
14
14
  catch {
15
15
  return undefined;
@@ -18,8 +18,8 @@ function getBaseId() {
18
18
  function resolveTableId(className) {
19
19
  try {
20
20
  const config = globalThis.__ZITE_EXECUTION_CONFIG__;
21
- const tables = config?.integrationSettings?.[DB_INTEGRATION_ID]
22
- ?.settings?.nameMappings?.tables;
21
+ const tables = config?.integrationSettings?.[DB_INTEGRATION_ID]?.settings?.nameMappings
22
+ ?.tables;
23
23
  if (!tables)
24
24
  return className;
25
25
  for (const [realId, entry] of Object.entries(tables)) {
@@ -32,33 +32,33 @@ function resolveTableId(className) {
32
32
  }
33
33
  export function createTableClient(className) {
34
34
  return {
35
- findAll: (options) => getSdkCall()(DB_INTEGRATION_ID, className, 'findAll', {
35
+ findAll: (options) => getSdkCall()(DB_INTEGRATION_ID, className, "findAll", {
36
36
  baseId: getBaseId(),
37
37
  tableId: resolveTableId(className),
38
38
  ...options,
39
39
  }),
40
- findOne: (recordId) => getSdkCall()(DB_INTEGRATION_ID, className, 'findOne', {
40
+ findOne: (recordId) => getSdkCall()(DB_INTEGRATION_ID, className, "findOne", {
41
41
  baseId: getBaseId(),
42
42
  tableId: resolveTableId(className),
43
- ...(typeof recordId === 'string' ? { id: recordId } : recordId),
43
+ ...(typeof recordId === "string" ? { id: recordId } : recordId),
44
44
  }),
45
- create: (data) => getSdkCall()(DB_INTEGRATION_ID, className, 'create', {
45
+ create: (data) => getSdkCall()(DB_INTEGRATION_ID, className, "create", {
46
46
  baseId: getBaseId(),
47
47
  tableId: resolveTableId(className),
48
48
  record: data,
49
49
  }),
50
- update: (id, data) => getSdkCall()(DB_INTEGRATION_ID, className, 'update', {
50
+ update: (id, data) => getSdkCall()(DB_INTEGRATION_ID, className, "update", {
51
51
  baseId: getBaseId(),
52
52
  tableId: resolveTableId(className),
53
53
  id,
54
54
  record: data,
55
55
  }),
56
- delete: (id) => getSdkCall()(DB_INTEGRATION_ID, className, 'delete', {
56
+ delete: (id) => getSdkCall()(DB_INTEGRATION_ID, className, "delete", {
57
57
  baseId: getBaseId(),
58
58
  tableId: resolveTableId(className),
59
59
  id,
60
60
  }),
61
- bulkCreate: (records) => getSdkCall()(DB_INTEGRATION_ID, className, 'bulkCreate', {
61
+ bulkCreate: (records) => getSdkCall()(DB_INTEGRATION_ID, className, "bulkCreate", {
62
62
  baseId: getBaseId(),
63
63
  tableId: resolveTableId(className),
64
64
  records,
@@ -66,6 +66,9 @@ export function createTableClient(className) {
66
66
  };
67
67
  }
68
68
  export function createSqlClient() {
69
- return (params) => getSdkCall()(DB_INTEGRATION_ID, 'Db', 'executeSql', { baseId: getBaseId(), ...params });
69
+ return (params) => getSdkCall()(DB_INTEGRATION_ID, "Db", "executeSql", {
70
+ baseId: getBaseId(),
71
+ ...params,
72
+ });
70
73
  }
71
- export { createCaller } from '../caller/index.js';
74
+ export { createCaller } from "../caller/index.js";
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, } from 'fs';
3
- import { join } from 'path';
4
- import { generateSchema, generateDbTs, generateApiTs, } from './lib.js';
2
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, } from "fs";
3
+ import { join } from "path";
4
+ import { generateSchema, generateDbTs, generateApiTs } from "./lib.js";
5
5
  const DB_ENVIRONMENTS = {
6
- production: 'https://tables.fillout.com/api/v1',
7
- staging: 'https://tables.filloutstaging.com/api/v1',
8
- local: 'http://localhost:2507/api/v1',
6
+ production: "https://tables.fillout.com/api/v1",
7
+ staging: "https://tables.filloutstaging.com/api/v1",
8
+ local: "http://localhost:2507/api/v1",
9
9
  };
10
- const env = process.env.ZITE_ENV ?? 'production';
10
+ const env = process.env.ZITE_ENV ?? "production";
11
11
  const BASE_URL = process.env.ZITE_DB_URL ?? DB_ENVIRONMENTS[env] ?? DB_ENVIRONMENTS.production;
12
- const TOKEN = process.env.ZITE_DB_TOKEN ?? '';
12
+ const TOKEN = process.env.ZITE_DB_TOKEN ?? "";
13
13
  async function fetchBaseMetadata(baseId) {
14
14
  const url = `${BASE_URL}/bases/${encodeURIComponent(baseId)}`;
15
15
  const res = await fetch(url, {
@@ -24,7 +24,7 @@ function resolveBaseId() {
24
24
  if (process.env.ZITE_BASE_ID)
25
25
  return process.env.ZITE_BASE_ID;
26
26
  try {
27
- const config = JSON.parse(readFileSync('zite.config.json', 'utf-8'));
27
+ const config = JSON.parse(readFileSync("zite.config.json", "utf-8"));
28
28
  return config.project?.basePublicIdentifier;
29
29
  }
30
30
  catch {
@@ -33,43 +33,43 @@ function resolveBaseId() {
33
33
  }
34
34
  export async function runSync() {
35
35
  if (!TOKEN) {
36
- throw new Error('ZITE_DB_TOKEN is required.');
36
+ throw new Error("ZITE_DB_TOKEN is required.");
37
37
  }
38
38
  const baseId = resolveBaseId();
39
39
  if (!baseId) {
40
- throw new Error('Could not determine base ID.');
40
+ throw new Error("Could not determine base ID.");
41
41
  }
42
42
  console.log(`Syncing database ${baseId}...`);
43
43
  const base = await fetchBaseMetadata(baseId);
44
44
  console.log(`Found ${base.tables?.length ?? 0} tables`);
45
45
  const schema = generateSchema(base);
46
- writeFileSync('zite.schema.json', JSON.stringify(schema, null, 2));
47
- console.log('Wrote zite.schema.json');
46
+ writeFileSync("zite.schema.json", JSON.stringify(schema, null, 2));
47
+ console.log("Wrote zite.schema.json");
48
48
  const dbTs = generateDbTs(base, schema);
49
- const dotZite = '.zite';
49
+ const dotZite = ".zite";
50
50
  mkdirSync(dotZite, { recursive: true });
51
- writeFileSync(join(dotZite, 'db.ts'), dbTs);
52
- console.log('Wrote .zite/db.ts');
51
+ writeFileSync(join(dotZite, "db.ts"), dbTs);
52
+ console.log("Wrote .zite/db.ts");
53
53
  regenerateApiTs();
54
- console.log('Done!');
54
+ console.log("Done!");
55
55
  }
56
56
  export function regenerateApiTs() {
57
- const apiDir = join('src', 'api');
57
+ const apiDir = join("src", "api");
58
58
  if (!existsSync(apiDir))
59
59
  return;
60
- const endpointFiles = readdirSync(apiDir).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));
60
+ const endpointFiles = readdirSync(apiDir).filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
61
61
  const apiTs = generateApiTs(endpointFiles);
62
62
  if (apiTs) {
63
- mkdirSync('.zite', { recursive: true });
64
- writeFileSync(join('.zite', 'api.ts'), apiTs);
65
- console.log('Wrote .zite/api.ts');
63
+ mkdirSync(".zite", { recursive: true });
64
+ writeFileSync(join(".zite", "api.ts"), apiTs);
65
+ console.log("Wrote .zite/api.ts");
66
66
  }
67
67
  }
68
68
  // Direct execution (npx zitejs sync)
69
- if (process.argv[1]?.endsWith('sync/index.js') ||
70
- process.argv[1]?.endsWith('sync/index.ts')) {
69
+ if (process.argv[1]?.endsWith("sync/index.js") ||
70
+ process.argv[1]?.endsWith("sync/index.ts")) {
71
71
  runSync().catch((err) => {
72
- console.error('Sync failed:', err.message);
72
+ console.error("Sync failed:", err.message);
73
73
  process.exit(1);
74
74
  });
75
75
  }
@@ -21,7 +21,6 @@ export declare function toPascalCase(name: string): string;
21
21
  export declare function toCamelCase(name: string): string;
22
22
  export declare function generateSchema(base: BaseMetadata): ZiteSchema;
23
23
  export declare function generateDbTs(base: BaseMetadata, schema: ZiteSchema): string;
24
- export declare function generateDbDts(base: BaseMetadata, schema: ZiteSchema): string;
25
24
  export declare function generateApiTs(endpointFiles: string[]): string | null;
26
25
  export declare function generateUserTs(usersTableFields?: Array<{
27
26
  name: string;
@@ -1,24 +1,24 @@
1
1
  const FIELD_TYPE_MAP = {
2
- single_line_text: 'string',
3
- long_text: 'string',
4
- email: 'string',
5
- url: 'string',
6
- phone_number: 'string',
7
- number: 'number',
8
- currency: 'number',
9
- percent: 'number',
10
- rating: 'number',
11
- duration: 'number',
12
- single_select: 'string',
13
- multiple_select: 'string[]',
14
- checkbox: 'boolean',
15
- date: 'string',
16
- datetime: 'string',
17
- attachments: 'Array<{ url: string; name?: string }>',
18
- linked_record: 'string | string[]',
19
- lookup: 'unknown',
20
- autonumber: 'number',
21
- source: 'string',
2
+ single_line_text: "string",
3
+ long_text: "string",
4
+ email: "string",
5
+ url: "string",
6
+ phone_number: "string",
7
+ number: "number",
8
+ currency: "number",
9
+ percent: "number",
10
+ rating: "number",
11
+ duration: "number",
12
+ single_select: "string",
13
+ multiple_select: "string[]",
14
+ checkbox: "boolean",
15
+ date: "string",
16
+ datetime: "string",
17
+ attachments: "Array<{ url: string; name?: string }>",
18
+ linked_record: "string | string[]",
19
+ lookup: "unknown",
20
+ autonumber: "number",
21
+ source: "string",
22
22
  };
23
23
  export function toPascalCase(name) {
24
24
  return name
@@ -32,11 +32,14 @@ export function toCamelCase(name) {
32
32
  function tsTypeForField(field) {
33
33
  if (FIELD_TYPE_MAP[field.type])
34
34
  return FIELD_TYPE_MAP[field.type];
35
- const lowerName = field.name?.toLowerCase() ?? '';
36
- if (lowerName === 'createdat' || lowerName === 'created_at' || lowerName === 'updatedat' || lowerName === 'updated_at') {
37
- return 'string';
35
+ const lowerName = field.name?.toLowerCase() ?? "";
36
+ if (lowerName === "createdat" ||
37
+ lowerName === "created_at" ||
38
+ lowerName === "updatedat" ||
39
+ lowerName === "updated_at") {
40
+ return "string";
38
41
  }
39
- return 'string';
42
+ return "string";
40
43
  }
41
44
  export function generateSchema(base) {
42
45
  const schema = { tables: {} };
@@ -52,220 +55,191 @@ export function generateSchema(base) {
52
55
  }
53
56
  export function generateDbTs(base, schema) {
54
57
  const lines = [];
55
- lines.push('// Auto-generated by zitejs sync. Do not edit manually.');
56
- lines.push('//');
57
- lines.push('// Usage in endpoint files (src/api/*.ts):');
58
+ lines.push("// Auto-generated by zitejs sync. Do not edit manually.");
59
+ lines.push("//");
60
+ lines.push("// Usage in endpoint files (src/api/*.ts):");
58
61
  lines.push('// import { zite } from "zitejs/db";');
59
- lines.push('//');
62
+ lines.push("//");
60
63
  lines.push('// Always use "zitejs/db" — never use relative paths like "../../.zite/db".');
61
- lines.push('// The tsconfig aliases resolve zitejs/* imports to the correct .zite/ files.');
62
- lines.push('//');
63
- lines.push('// Table client methods:');
64
- lines.push('// .findAll(opts?) → { records: T[], total: number, hasMore: boolean }');
65
- lines.push('// .findOne(id) → T');
66
- lines.push('// .create(data) → T');
67
- lines.push('// .update(id, data) → T');
68
- lines.push('// .delete(id) → { deleted: true }');
69
- lines.push('// .bulkCreate(records) → T[]');
70
- lines.push('//');
71
- lines.push('// Raw SQL:');
72
- lines.push('// zite.sql({ query: "SELECT..." }) → { rows: Record<string, unknown>[] }');
64
+ lines.push("// The tsconfig aliases resolve zitejs/* imports to the correct .zite/ files.");
65
+ lines.push("//");
66
+ lines.push("// Table client methods:");
67
+ lines.push("// .findAll(opts?) → { records: T[], total: number, hasMore: boolean }");
68
+ lines.push("// opts: { limit?, offset?, sort?, filter?, filters? }");
69
+ lines.push("// .findOne(id | { filters }) → T");
70
+ lines.push("// .create({ record }) → T");
71
+ lines.push("// .update(id, { record }) → T");
72
+ lines.push("// .delete(id) → { deleted: true }");
73
+ lines.push("// .bulkCreate(records) → T[]");
74
+ lines.push("//");
75
+ lines.push("// Raw SQL (read-only SELECTs for aggregates, joins, multi-table queries):");
76
+ lines.push('// zite.sql({ query: "SELECT ...", params?: [...] })');
77
+ lines.push("// → { rows: Record<string, unknown>[], columns, rowCount, truncated }");
78
+ lines.push("//");
79
+ lines.push("// SQL guidelines:");
80
+ lines.push("// - Use SDK names for tables (PascalCase) and fields (camelCase)");
81
+ lines.push('// - ALWAYS double-quote every identifier: FROM "Orders", WHERE "status" = $1');
82
+ lines.push("// - Use params array for user input ($1, $2, ...): never interpolate into SQL");
83
+ lines.push('// - Link tables: alphabetical PascalCase concat (Items+Orders → "ItemsOrders")');
84
+ lines.push('// with id columns: "itemsId", "ordersId"');
85
+ lines.push("// - Soft-deleted rows are excluded automatically — no WHERE deleted_at IS NULL");
86
+ lines.push("// - SELECT only — use .create/.update/.delete for writes");
87
+ lines.push('// - Load the "zite:sql" skill for full SQL reference (formulas, lookups, etc.)');
73
88
  lines.push("import { createTableClient, createSqlClient } from 'zitejs/runtime';");
74
- lines.push('');
89
+ lines.push("");
75
90
  for (const table of base.tables ?? []) {
76
91
  const className = toPascalCase(table.name);
77
92
  const recordType = `${className}RecordType`;
78
93
  lines.push(`export type ${recordType} = {`);
79
- lines.push(' id: string;');
94
+ lines.push(" id: string;");
80
95
  for (const field of table.fields ?? []) {
81
96
  const fieldName = toCamelCase(field.name);
82
- if (fieldName === 'id')
97
+ if (fieldName === "id")
83
98
  continue;
84
99
  const tsType = tsTypeForField(field);
85
100
  lines.push(` ${fieldName}: ${tsType};`);
86
101
  }
87
- lines.push('};');
88
- lines.push('');
102
+ lines.push("};");
103
+ lines.push("");
89
104
  }
90
- lines.push('export const zite = {');
105
+ lines.push("export const zite = {");
91
106
  for (const table of base.tables ?? []) {
92
107
  const className = toPascalCase(table.name);
93
108
  const propName = toCamelCase(table.name);
94
109
  lines.push(` ${propName}: createTableClient<${className}RecordType>('${className}'),`);
95
110
  }
96
111
  lines.push(` sql: createSqlClient(),`);
97
- lines.push('};');
98
- lines.push('');
99
- return lines.join('\n');
100
- }
101
- export function generateDbDts(base, schema) {
102
- const lines = [
103
- '// Auto-generated by zitejs sync. Do not edit manually.',
104
- '// Type declarations for IDE and LLM context. See db.ts for runtime.',
105
- '',
106
- 'interface TableClient<T> {',
107
- ' findAll(options?: { limit?: number; offset?: number; sort?: unknown[]; filter?: unknown; filters?: unknown }): Promise<{ records: T[]; total: number; hasMore: boolean }>;',
108
- ' findOne(recordId: string | { filters?: unknown; filter?: unknown }): Promise<T>;',
109
- ' create(data: Partial<T>): Promise<T>;',
110
- ' update(id: string, data: Partial<T>): Promise<T>;',
111
- ' delete(id: string): Promise<{ deleted: true }>;',
112
- ' bulkCreate(records: Partial<T>[]): Promise<T[]>;',
113
- '}',
114
- '',
115
- ];
116
- for (const table of base.tables ?? []) {
117
- const className = toPascalCase(table.name);
118
- const recordType = `${className}RecordType`;
119
- lines.push(`export type ${recordType} = {`);
120
- lines.push(' id: string;');
121
- for (const field of table.fields ?? []) {
122
- const fieldName = toCamelCase(field.name);
123
- if (fieldName === 'id')
124
- continue;
125
- const tsType = tsTypeForField(field);
126
- lines.push(` ${fieldName}: ${tsType};`);
127
- }
128
- lines.push('};');
129
- lines.push('');
130
- }
131
- lines.push('export declare const zite: {');
132
- for (const table of base.tables ?? []) {
133
- const className = toPascalCase(table.name);
134
- const propName = toCamelCase(table.name);
135
- lines.push(` ${propName}: TableClient<${className}RecordType>;`);
136
- }
137
- lines.push(' sql: (params: { query?: string; sql?: string; params?: unknown[] }) => Promise<{ rows: Record<string, unknown>[] }>;');
138
- lines.push('};');
139
- lines.push('');
140
- return lines.join('\n');
112
+ lines.push("};");
113
+ lines.push("");
114
+ return lines.join("\n");
141
115
  }
142
116
  export function generateApiTs(endpointFiles) {
143
117
  if (!endpointFiles || endpointFiles.length === 0)
144
118
  return null;
145
119
  const lines = [
146
- '// Auto-generated by zitejs sync. Do not edit manually.',
147
- '',
120
+ "// Auto-generated by zitejs sync. Do not edit manually.",
121
+ "",
148
122
  "import { createCaller } from 'zitejs/caller';",
149
- '',
123
+ "",
150
124
  ];
151
125
  const endpointNames = [];
152
126
  for (const file of endpointFiles) {
153
- const name = file.replace(/\.(ts|js)$/, '');
127
+ const name = file.replace(/\.(ts|js)$/, "");
154
128
  const camelName = toCamelCase(name);
155
129
  lines.push(`import ${camelName}Endpoint from '../src/api/${name}';`);
156
130
  endpointNames.push(camelName);
157
131
  }
158
- lines.push('');
132
+ lines.push("");
159
133
  for (const name of endpointNames) {
160
134
  lines.push(`export const ${name} = createCaller(${name}Endpoint, '${name}');`);
161
135
  }
162
- lines.push('');
136
+ lines.push("");
163
137
  // Inferred input/output types per endpoint (e.g. GetDashboardInputType, GetDashboardOutputType)
164
138
  for (const name of endpointNames) {
165
139
  const pascal = toPascalCase(name);
166
140
  lines.push(`export type ${pascal}InputType = Parameters<typeof ${name}Endpoint.execute>[0]['input'];`);
167
141
  lines.push(`export type ${pascal}OutputType = Awaited<ReturnType<typeof ${name}Endpoint.execute>>;`);
168
142
  }
169
- lines.push('');
143
+ lines.push("");
170
144
  // Also export as a single api object
171
- lines.push('export const api = {');
145
+ lines.push("export const api = {");
172
146
  for (const name of endpointNames) {
173
147
  lines.push(` ${name},`);
174
148
  }
175
- lines.push('};');
176
- lines.push('');
177
- return lines.join('\n');
149
+ lines.push("};");
150
+ lines.push("");
151
+ return lines.join("\n");
178
152
  }
179
153
  export function generateUserTs(usersTableFields) {
180
154
  const lines = [
181
- '// Auto-generated by zitejs sync. Do not edit manually.',
182
- '',
155
+ "// Auto-generated by zitejs sync. Do not edit manually.",
156
+ "",
183
157
  ];
184
158
  if (usersTableFields && usersTableFields.length > 0) {
185
- lines.push('export type User = {');
186
- lines.push(' id: string;');
187
- lines.push(' email: string;');
159
+ lines.push("export type User = {");
160
+ lines.push(" id: string;");
161
+ lines.push(" email: string;");
188
162
  for (const field of usersTableFields) {
189
163
  const lowerName = field.name.toLowerCase();
190
- if (lowerName === 'id' || lowerName === 'email')
164
+ if (lowerName === "id" || lowerName === "email")
191
165
  continue;
192
166
  const fieldName = toCamelCase(field.name);
193
167
  const tsType = tsTypeForField(field);
194
168
  lines.push(` ${fieldName}: ${tsType};`);
195
169
  }
196
- lines.push(' [key: string]: unknown;');
197
- lines.push('};');
170
+ lines.push(" [key: string]: unknown;");
171
+ lines.push("};");
198
172
  }
199
173
  else {
200
- lines.push('export type User = {');
201
- lines.push(' id: string;');
202
- lines.push(' email: string;');
203
- lines.push(' firstName?: string;');
204
- lines.push(' lastName?: string;');
205
- lines.push(' [key: string]: unknown;');
206
- lines.push('};');
174
+ lines.push("export type User = {");
175
+ lines.push(" id: string;");
176
+ lines.push(" email: string;");
177
+ lines.push(" firstName?: string;");
178
+ lines.push(" lastName?: string;");
179
+ lines.push(" [key: string]: unknown;");
180
+ lines.push("};");
207
181
  }
208
- lines.push('');
209
- return lines.join('\n');
182
+ lines.push("");
183
+ return lines.join("\n");
210
184
  }
211
185
  export function generateAuthWrapperTs() {
212
186
  return [
213
- '// Auto-generated type-narrowing wrapper. Do not edit manually.',
214
- '// The real auth logic lives in the zitejs npm package (zitejs/auth).',
215
- '',
187
+ "// Auto-generated type-narrowing wrapper. Do not edit manually.",
188
+ "// The real auth logic lives in the zitejs npm package (zitejs/auth).",
189
+ "",
216
190
  "import { useAuth as _useAuth } from 'zitejs/auth/base';",
217
191
  "import type { User } from './user';",
218
- '',
219
- 'export type { User };',
220
- '',
221
- 'export function useAuth() {',
222
- ' return _useAuth() as ReturnType<typeof _useAuth> & { user: User | undefined };',
223
- '}',
224
- '',
225
- ].join('\n');
192
+ "",
193
+ "export type { User };",
194
+ "",
195
+ "export function useAuth() {",
196
+ " return _useAuth() as ReturnType<typeof _useAuth> & { user: User | undefined };",
197
+ "}",
198
+ "",
199
+ ].join("\n");
226
200
  }
227
201
  export function generateBackendWrapperTs() {
228
202
  return [
229
- '// Auto-generated type-narrowing wrapper. Do not edit manually.',
230
- '// Re-exports createEndpoint with context.user typed to the app User.',
231
- '',
203
+ "// Auto-generated type-narrowing wrapper. Do not edit manually.",
204
+ "// Re-exports createEndpoint with context.user typed to the app User.",
205
+ "",
232
206
  "import type { ZiteRequestContext as _ZiteRequestContext, ZiteScheduledContext as _ZiteScheduledContext } from 'zitejs/backend/base';",
233
207
  "import type { User } from './user';",
234
- '',
235
- 'export class ZiteError extends Error {',
236
- ' statusCode: number;',
237
- ' constructor(message: string, options?: { statusCode?: number }) {',
238
- ' super(message);',
208
+ "",
209
+ "export class ZiteError extends Error {",
210
+ " statusCode: number;",
211
+ " constructor(message: string, options?: { statusCode?: number }) {",
212
+ " super(message);",
239
213
  " this.name = 'ZiteError';",
240
- ' this.statusCode = options?.statusCode ?? 500;',
241
- ' }',
242
- '}',
243
- '',
214
+ " this.statusCode = options?.statusCode ?? 500;",
215
+ " }",
216
+ "}",
217
+ "",
244
218
  'export interface ZiteRequestContext extends Omit<_ZiteRequestContext, "user"> {',
245
- ' user: User;',
246
- '}',
247
- '',
219
+ " user: User;",
220
+ "}",
221
+ "",
248
222
  'export interface ZiteScheduledContext extends Omit<_ZiteScheduledContext, "user"> {',
249
- ' user: User;',
250
- ' scheduledAt: string;',
251
- '}',
252
- '',
223
+ " user: User;",
224
+ " scheduledAt: string;",
225
+ "}",
226
+ "",
253
227
  "type SchemaLike<T> = { _output: T; parse: (data: unknown) => T };",
254
- '',
255
- 'export interface EndpointConfig<TInput = unknown, TOutput = unknown> {',
256
- ' description?: string;',
257
- ' inputSchema?: SchemaLike<TInput>;',
258
- ' outputSchema?: SchemaLike<TOutput>;',
259
- ' stream?: boolean;',
260
- ' authenticated?: boolean;',
261
- ' execute: (params: { input: TInput; context: ZiteRequestContext | ZiteScheduledContext }) => Promise<TOutput> | TOutput;',
262
- '}',
263
- '',
264
- 'export function createEndpoint<TInput = unknown, TOutput = unknown>(',
265
- ' config: EndpointConfig<TInput, TOutput>,',
266
- '): EndpointConfig<TInput, TOutput> {',
267
- ' return config;',
268
- '}',
269
- '',
270
- ].join('\n');
228
+ "",
229
+ "export interface EndpointConfig<TInput = unknown, TOutput = unknown> {",
230
+ " description?: string;",
231
+ " inputSchema?: SchemaLike<TInput>;",
232
+ " outputSchema?: SchemaLike<TOutput>;",
233
+ " stream?: boolean;",
234
+ " authenticated?: boolean;",
235
+ " execute: (params: { input: TInput; context: ZiteRequestContext | ZiteScheduledContext }) => Promise<TOutput> | TOutput;",
236
+ "}",
237
+ "",
238
+ "export function createEndpoint<TInput = unknown, TOutput = unknown>(",
239
+ " config: EndpointConfig<TInput, TOutput>,",
240
+ "): EndpointConfig<TInput, TOutput> {",
241
+ " return config;",
242
+ "}",
243
+ "",
244
+ ].join("\n");
271
245
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zitejs",
3
- "version": "0.9.34",
3
+ "version": "0.9.35",
4
4
  "description": "The Zite framework — build apps on Zite Database",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/runtime/index.js",