@tailor-platform/sdk 1.21.0 → 1.22.0
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/CHANGELOG.md +44 -0
- package/dist/application-CTQe2HSB.mjs +5723 -0
- package/dist/application-CTQe2HSB.mjs.map +1 -0
- package/dist/application-DdSu3baZ.mjs +8 -0
- package/dist/{brand-BZJCv6UY.mjs → brand-DyPrAzpM.mjs} +1 -1
- package/dist/{brand-BZJCv6UY.mjs.map → brand-DyPrAzpM.mjs.map} +1 -1
- package/dist/cli/index.mjs +544 -57
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +49 -8
- package/dist/cli/lib.mjs +15 -16
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/configure/index.d.mts +4 -4
- package/dist/configure/index.mjs +15 -4
- package/dist/configure/index.mjs.map +1 -1
- package/dist/{enum-constants-CGVvu3dd.mjs → enum-constants-B5Nl-yzx.mjs} +1 -1
- package/dist/{enum-constants-CGVvu3dd.mjs.map → enum-constants-B5Nl-yzx.mjs.map} +1 -1
- package/dist/{file-utils-GX_tGWl4.mjs → file-utils-sEOwAdJ4.mjs} +1 -1
- package/dist/{file-utils-GX_tGWl4.mjs.map → file-utils-sEOwAdJ4.mjs.map} +1 -1
- package/dist/{index-Dn61THJK.d.mts → index-BGPX26_D.d.mts} +2 -2
- package/dist/{index-CnHd6BNg.d.mts → index-BiutQT7m.d.mts} +4 -10
- package/dist/{index-DxlmLUag.d.mts → index-ClS0NClx.d.mts} +2 -2
- package/dist/{index-BWVAwea4.d.mts → index-Cwi86SUR.d.mts} +2 -2
- package/dist/{index-oZXVKyfX.d.mts → index-DPN_P0w3.d.mts} +2 -2
- package/dist/{interceptor-D8MeZOxX.mjs → interceptor-DiARwPfw.mjs} +1 -1
- package/dist/{interceptor-D8MeZOxX.mjs.map → interceptor-DiARwPfw.mjs.map} +1 -1
- package/dist/{job-2Q82qQ6N.mjs → job-CRavYLLk.mjs} +4 -24
- package/dist/job-CRavYLLk.mjs.map +1 -0
- package/dist/kysely/index.d.mts +2 -2
- package/dist/kysely/index.mjs +2 -2
- package/dist/kysely/index.mjs.map +1 -1
- package/dist/{kysely-type-Cpq5TNGY.mjs → kysely-type-CSlcwNFH.mjs} +1 -1
- package/dist/{kysely-type-Cpq5TNGY.mjs.map → kysely-type-CSlcwNFH.mjs.map} +1 -1
- package/dist/package-json-BI0ng3_5.mjs +3 -0
- package/dist/{package-json-3H5gfhA4.mjs → package-json-iVBhE5Ef.mjs} +1 -1
- package/dist/{package-json-3H5gfhA4.mjs.map → package-json-iVBhE5Ef.mjs.map} +1 -1
- package/dist/plugin/builtin/enum-constants/index.d.mts +2 -2
- package/dist/plugin/builtin/enum-constants/index.mjs +1 -1
- package/dist/plugin/builtin/file-utils/index.d.mts +2 -2
- package/dist/plugin/builtin/file-utils/index.mjs +1 -1
- package/dist/plugin/builtin/kysely-type/index.d.mts +2 -2
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +2 -2
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/plugin/index.d.mts +1 -1
- package/dist/plugin/index.mjs +3 -3
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/{update-9MTRN1UA.mjs → query-Bz2oDGhw.mjs} +915 -174
- package/dist/query-Bz2oDGhw.mjs.map +1 -0
- package/dist/{schema-D5Cpd8fQ.mjs → schema-Cjm-OvPF.mjs} +2 -2
- package/dist/{schema-D5Cpd8fQ.mjs.map → schema-Cjm-OvPF.mjs.map} +1 -1
- package/dist/{seed-D-rYCN5F.mjs → seed-CXvCW3Xc.mjs} +2 -2
- package/dist/{seed-D-rYCN5F.mjs.map → seed-CXvCW3Xc.mjs.map} +1 -1
- package/dist/telemetry-BAxP8-PR.mjs +3 -0
- package/dist/{telemetry-DuBhnd0X.mjs → telemetry-C46fds1l.mjs} +2 -2
- package/dist/{telemetry-DuBhnd0X.mjs.map → telemetry-C46fds1l.mjs.map} +1 -1
- package/dist/{types-ClK_HJ0G.mjs → types-CBTSg-LK.mjs} +1 -1
- package/dist/{types-ClK_HJ0G.mjs.map → types-CBTSg-LK.mjs.map} +1 -1
- package/dist/{types-C0o90Cmb.d.mts → types-DVMQNdTs.d.mts} +6 -2
- package/dist/{types-QKq1usl7.d.mts → types-bcuNRo1Y.d.mts} +8 -8
- package/dist/utils/test/index.d.mts +42 -4
- package/dist/utils/test/index.mjs +78 -3
- package/dist/utils/test/index.mjs.map +1 -1
- package/docs/cli/function.md +83 -3
- package/package.json +7 -5
- package/dist/application-CEv5c7TU.mjs +0 -102207
- package/dist/application-CEv5c7TU.mjs.map +0 -1
- package/dist/application-DiCzM9b0.mjs +0 -9
- package/dist/chunk-CqAI0b6X.mjs +0 -47
- package/dist/jiti-DfS9jItj.mjs +0 -4482
- package/dist/jiti-DfS9jItj.mjs.map +0 -1
- package/dist/job-2Q82qQ6N.mjs.map +0 -1
- package/dist/package-json-DTDAqRRJ.mjs +0 -3
- package/dist/src-Bb1UVstT.mjs +0 -1038
- package/dist/src-Bb1UVstT.mjs.map +0 -1
- package/dist/telemetry-Dhzj9Ncm.mjs +0 -3
- package/dist/update-9MTRN1UA.mjs.map +0 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "../
|
|
3
|
-
import "../
|
|
4
|
-
import "../
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import "../
|
|
9
|
-
import "../
|
|
10
|
-
import "../
|
|
11
|
-
import "../telemetry-DuBhnd0X.mjs";
|
|
2
|
+
import "../schema-Cjm-OvPF.mjs";
|
|
3
|
+
import "../brand-DyPrAzpM.mjs";
|
|
4
|
+
import { A as truncateCommand, B as getCommand$2, Bt as getNamespacesWithMigrations, D as listCommand$8, F as showCommand, Ft as loadDiff, Gt as commonArgs, J as webhookCommand, Jt as jsonArgs, K as generate, Kt as confirmationArgs, L as removeCommand$1, M as generateCommand$1, Mt as getMigrationFiles, N as logBetaWarning, Ot as formatMigrationNumber, Pt as isValidMigrationNumber, R as listCommand$7, S as listCommand$9, T as resumeCommand, U as tokenCommand, Vt as trnPrefix, W as listCommand$6, Wt as apiCommand, Xt as workspaceArgs, Y as triggerCommand, Yt as withCommonArgs, Z as listCommand$5, _ as deleteCommand$3, a as removeCommand, at as getCommand$3, d as restoreCommand, dt as formatKeyValueTable, et as jobsCommand, ft as getCommand$1, h as getCommand$4, ht as executeScript, jt as getMigrationFilePath, l as inviteCommand, mt as apply, n as queryCommand, p as listCommand$11, qt as deploymentArgs, r as updateCommand$2, rt as startCommand, s as listCommand$10, st as executionsCommand, ut as functionExecutionStatusToString, vt as parseMigrationLabelNumber, w as healthCommand, y as createCommand$3 } from "../query-Bz2oDGhw.mjs";
|
|
5
|
+
import { C as readPlatformConfig, D as fetchUserInfo, G as FunctionExecution_Type, O as initOAuth2Client, S as loadWorkspaceId, T as fetchAll, X as AuthInvokerSchema, a as loadConfig, c as ExecutorSchema, g as getDistDir, i as resolveInlineSourcemap, k as initOperatorClient, mt as styles, o as WorkflowJobSchema, pt as logger, rt as PATScope, u as ResolverSchema, v as fetchLatestToken, w as writePlatformConfig, y as loadAccessToken } from "../application-CTQe2HSB.mjs";
|
|
6
|
+
import { t as readPackageJson } from "../package-json-iVBhE5Ef.mjs";
|
|
7
|
+
import "../file-utils-sEOwAdJ4.mjs";
|
|
8
|
+
import "../kysely-type-CSlcwNFH.mjs";
|
|
9
|
+
import "../seed-CXvCW3Xc.mjs";
|
|
10
|
+
import "../telemetry-C46fds1l.mjs";
|
|
12
11
|
import { createRequire, register } from "node:module";
|
|
13
12
|
import { arg, defineCommand, runCommand, runMain } from "politty";
|
|
14
13
|
import { withCompletionCommand } from "politty/completion";
|
|
@@ -18,14 +17,18 @@ import * as path from "pathe";
|
|
|
18
17
|
import { generateCodeVerifier } from "@badgateway/oauth2-client";
|
|
19
18
|
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
20
19
|
import { Code, ConnectError } from "@connectrpc/connect";
|
|
20
|
+
import { resolveTSConfig } from "pkg-types";
|
|
21
21
|
import ml from "multiline-ts";
|
|
22
22
|
import * as crypto from "node:crypto";
|
|
23
|
-
import
|
|
24
|
-
import
|
|
23
|
+
import { pathToFileURL } from "node:url";
|
|
24
|
+
import * as rolldown from "rolldown";
|
|
25
|
+
import { create } from "@bufbuild/protobuf";
|
|
25
26
|
import { spawn, spawnSync } from "node:child_process";
|
|
26
27
|
import * as http from "node:http";
|
|
27
28
|
import open from "open";
|
|
29
|
+
import * as fs from "fs";
|
|
28
30
|
import { lookup } from "mime-types";
|
|
31
|
+
import pLimit from "p-limit";
|
|
29
32
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
30
33
|
|
|
31
34
|
//#region src/cli/commands/apply/index.ts
|
|
@@ -43,7 +46,7 @@ const applyCommand = defineCommand({
|
|
|
43
46
|
"no-schema-check": arg(z.boolean().optional(), { description: "Skip schema diff check against migration snapshots" }),
|
|
44
47
|
"no-cache": arg(z.boolean().optional(), { description: "Disable bundle caching for this run" }),
|
|
45
48
|
"clean-cache": arg(z.boolean().optional(), { description: "Clean the bundle cache before building" })
|
|
46
|
-
}),
|
|
49
|
+
}).strict(),
|
|
47
50
|
run: withCommonArgs(async (args) => {
|
|
48
51
|
await apply({
|
|
49
52
|
workspaceId: args["workspace-id"],
|
|
@@ -161,7 +164,7 @@ const logsCommand = defineCommand({
|
|
|
161
164
|
positional: true,
|
|
162
165
|
description: "Execution ID (if provided, shows details with logs)"
|
|
163
166
|
})
|
|
164
|
-
}),
|
|
167
|
+
}).strict(),
|
|
165
168
|
run: withCommonArgs(async (args) => {
|
|
166
169
|
const client = await initOperatorClient(await loadAccessToken({
|
|
167
170
|
useProfile: true,
|
|
@@ -198,12 +201,493 @@ const logsCommand = defineCommand({
|
|
|
198
201
|
})
|
|
199
202
|
});
|
|
200
203
|
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/cli/commands/function/bundle.ts
|
|
206
|
+
/**
|
|
207
|
+
* Bundler for function test-run command
|
|
208
|
+
*
|
|
209
|
+
* Bundles a single function file for execution via the TestExecScript API.
|
|
210
|
+
* Generates an entry file based on the detected function type and bundles
|
|
211
|
+
* with rolldown, following the same patterns as the existing bundlers.
|
|
212
|
+
*/
|
|
213
|
+
/**
|
|
214
|
+
* Bundle a function file for test-run execution via TestExecScript API.
|
|
215
|
+
* @param options - Bundle options
|
|
216
|
+
* @returns Bundled code and script name
|
|
217
|
+
*/
|
|
218
|
+
async function bundleForTestRun(options) {
|
|
219
|
+
const { detected, sourceFile, env = {}, machineUser, workspaceId } = options;
|
|
220
|
+
const inlineSourcemap = resolveInlineSourcemap(options.inlineSourcemap);
|
|
221
|
+
const outputDir = path.resolve(getDistDir(), "test-run");
|
|
222
|
+
fs$1.mkdirSync(outputDir, { recursive: true });
|
|
223
|
+
const baseName = `test-run--${detected.name}`;
|
|
224
|
+
const scriptName = `${baseName}.js`;
|
|
225
|
+
const entryPath = path.join(outputDir, `${baseName}.entry.js`);
|
|
226
|
+
const outputPath = path.join(outputDir, scriptName);
|
|
227
|
+
const entryContent = generateEntry(detected, sourceFile, env, machineUser, workspaceId);
|
|
228
|
+
fs$1.writeFileSync(entryPath, entryContent);
|
|
229
|
+
let tsconfig;
|
|
230
|
+
try {
|
|
231
|
+
tsconfig = await resolveTSConfig();
|
|
232
|
+
} catch {
|
|
233
|
+
tsconfig = void 0;
|
|
234
|
+
}
|
|
235
|
+
await rolldown.build(rolldown.defineConfig({
|
|
236
|
+
input: entryPath,
|
|
237
|
+
output: {
|
|
238
|
+
file: outputPath,
|
|
239
|
+
format: "esm",
|
|
240
|
+
sourcemap: inlineSourcemap ? "inline" : true,
|
|
241
|
+
minify: inlineSourcemap ? { mangle: { keepNames: true } } : true,
|
|
242
|
+
inlineDynamicImports: true
|
|
243
|
+
},
|
|
244
|
+
tsconfig,
|
|
245
|
+
treeshake: {
|
|
246
|
+
moduleSideEffects: false,
|
|
247
|
+
annotations: true,
|
|
248
|
+
unknownGlobalSideEffects: false
|
|
249
|
+
},
|
|
250
|
+
logLevel: "silent"
|
|
251
|
+
}));
|
|
252
|
+
return {
|
|
253
|
+
bundledCode: fs$1.readFileSync(outputPath, "utf-8"),
|
|
254
|
+
scriptName
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Generate entry file content based on the detected function type.
|
|
259
|
+
* @param detected - Detected function info
|
|
260
|
+
* @param sourceFile - Absolute path to the source file
|
|
261
|
+
* @param env - Environment variables for workflow job bundles
|
|
262
|
+
* @param machineUser - Resolved machine user info
|
|
263
|
+
* @param workspaceId - Workspace ID
|
|
264
|
+
* @returns Entry file content string
|
|
265
|
+
*/
|
|
266
|
+
function generateEntry(detected, sourceFile, env, machineUser, workspaceId) {
|
|
267
|
+
const absoluteSourcePath = path.resolve(sourceFile);
|
|
268
|
+
switch (detected.type) {
|
|
269
|
+
case "plain":
|
|
270
|
+
if (detected.namedMain) return ml`
|
|
271
|
+
export { main } from "${absoluteSourcePath}";
|
|
272
|
+
`;
|
|
273
|
+
return ml`
|
|
274
|
+
import _fn from "${absoluteSourcePath}";
|
|
275
|
+
export { _fn as main };
|
|
276
|
+
`;
|
|
277
|
+
case "resolver": {
|
|
278
|
+
const userExpr = buildMachineUserExpr(machineUser, workspaceId);
|
|
279
|
+
return ml`
|
|
280
|
+
import _internalResolver from "${absoluteSourcePath}";
|
|
281
|
+
import { t } from "@tailor-platform/sdk";
|
|
282
|
+
|
|
283
|
+
const _env = ${JSON.stringify(env)};
|
|
284
|
+
const _user = ${userExpr};
|
|
285
|
+
|
|
286
|
+
const $tailor_resolver_body = async (context) => {
|
|
287
|
+
const enrichedContext = { ...context, env: _env, user: _user };
|
|
288
|
+
|
|
289
|
+
if (_internalResolver.input) {
|
|
290
|
+
const result = t.object(_internalResolver.input).parse({
|
|
291
|
+
value: enrichedContext.input,
|
|
292
|
+
data: enrichedContext.input,
|
|
293
|
+
user: enrichedContext.user,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
if (result.issues) {
|
|
297
|
+
const errorMessages = result.issues
|
|
298
|
+
.map(issue => {
|
|
299
|
+
const path = issue.path ? issue.path.join('.') : '';
|
|
300
|
+
return path ? \` \${path}: \${issue.message}\` : issue.message;
|
|
301
|
+
})
|
|
302
|
+
.join('\\n');
|
|
303
|
+
throw new Error(\`Failed to input validation:\\n\${errorMessages}\`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return _internalResolver.body(enrichedContext);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
export { $tailor_resolver_body as main };
|
|
311
|
+
`;
|
|
312
|
+
}
|
|
313
|
+
case "executor": {
|
|
314
|
+
const actorExpr = buildMachineActorExpr(machineUser, workspaceId);
|
|
315
|
+
return ml`
|
|
316
|
+
import _internalExecutor from "${absoluteSourcePath}";
|
|
317
|
+
|
|
318
|
+
const _env = ${JSON.stringify(env)};
|
|
319
|
+
const _actor = ${actorExpr};
|
|
320
|
+
|
|
321
|
+
const __executor_function = async (args) => {
|
|
322
|
+
return _internalExecutor.operation.body({ ...args, env: _env, actor: _actor });
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
export { __executor_function as main };
|
|
326
|
+
`;
|
|
327
|
+
}
|
|
328
|
+
case "workflow-job": {
|
|
329
|
+
const exportName = detected.exportName;
|
|
330
|
+
return ml`
|
|
331
|
+
import { ${exportName} } from "${absoluteSourcePath}";
|
|
332
|
+
|
|
333
|
+
const env = ${JSON.stringify(env)};
|
|
334
|
+
|
|
335
|
+
export async function main(input) {
|
|
336
|
+
return await ${exportName}.body(input, { env });
|
|
337
|
+
}
|
|
338
|
+
`;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Build a JSON expression for a machine user TailorUser object.
|
|
344
|
+
* @param machineUser - Resolved machine user info
|
|
345
|
+
* @param workspaceId - Workspace ID
|
|
346
|
+
* @returns JSON string for the user expression
|
|
347
|
+
*/
|
|
348
|
+
function buildMachineUserExpr(machineUser, workspaceId) {
|
|
349
|
+
return JSON.stringify({
|
|
350
|
+
id: machineUser.id,
|
|
351
|
+
type: "machine_user",
|
|
352
|
+
workspaceId,
|
|
353
|
+
attributes: machineUser.attributes,
|
|
354
|
+
attributeList: machineUser.attributeList
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Build a JSON expression for a machine user TailorActor object.
|
|
359
|
+
* @param machineUser - Resolved machine user info
|
|
360
|
+
* @param workspaceId - Workspace ID
|
|
361
|
+
* @returns JSON string for the actor expression
|
|
362
|
+
*/
|
|
363
|
+
function buildMachineActorExpr(machineUser, workspaceId) {
|
|
364
|
+
return JSON.stringify({
|
|
365
|
+
workspaceId,
|
|
366
|
+
userId: machineUser.id,
|
|
367
|
+
attributes: machineUser.attributes,
|
|
368
|
+
attributeList: machineUser.attributeList,
|
|
369
|
+
userType: "USER_TYPE_MACHINE_USER"
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region src/cli/commands/function/detect.ts
|
|
375
|
+
/**
|
|
376
|
+
* Function type detection for test-run command
|
|
377
|
+
*
|
|
378
|
+
* Detects the function type (resolver, executor, workflow job, or plain function)
|
|
379
|
+
* by dynamically importing the module and checking against known schemas.
|
|
380
|
+
*/
|
|
381
|
+
/**
|
|
382
|
+
* Detect the function type from a file by importing it and checking against schemas.
|
|
383
|
+
* @param options - Detection options
|
|
384
|
+
* @returns Detected function information
|
|
385
|
+
*/
|
|
386
|
+
async function detectFunctionType(options) {
|
|
387
|
+
const { filePath, jobName } = options;
|
|
388
|
+
const module = await import(pathToFileURL(filePath).href);
|
|
389
|
+
const resolverResult = ResolverSchema.safeParse(module.default);
|
|
390
|
+
if (resolverResult.success) return {
|
|
391
|
+
type: "resolver",
|
|
392
|
+
name: resolverResult.data.name
|
|
393
|
+
};
|
|
394
|
+
const executorResult = ExecutorSchema.safeParse(module.default);
|
|
395
|
+
if (executorResult.success) {
|
|
396
|
+
const { operation } = executorResult.data;
|
|
397
|
+
if (operation.kind === "function" || operation.kind === "jobFunction") return {
|
|
398
|
+
type: "executor",
|
|
399
|
+
name: executorResult.data.name
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
const workflowJobResult = detectWorkflowJob(module, jobName);
|
|
403
|
+
if (workflowJobResult) return workflowJobResult;
|
|
404
|
+
if (typeof module.default === "function") return {
|
|
405
|
+
type: "plain",
|
|
406
|
+
name: deriveNameFromPath(filePath)
|
|
407
|
+
};
|
|
408
|
+
if (typeof module.main === "function") return {
|
|
409
|
+
type: "plain",
|
|
410
|
+
name: deriveNameFromPath(filePath),
|
|
411
|
+
namedMain: true
|
|
412
|
+
};
|
|
413
|
+
throw new Error(`Could not detect function type from ${filePath}.\nThe file must have one of:
|
|
414
|
+
- A default-exported resolver (createResolver)
|
|
415
|
+
- A default-exported executor (createExecutor) with function/jobFunction operation
|
|
416
|
+
- A named-exported workflow job (createWorkflowJob)
|
|
417
|
+
- A default-exported function
|
|
418
|
+
- A named-exported "main" function`);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Scan all named exports for workflow jobs.
|
|
422
|
+
* If jobName is specified, find the job whose `.name` matches.
|
|
423
|
+
* If not specified and exactly one job exists, use it.
|
|
424
|
+
* If multiple jobs exist, throw an error with the list.
|
|
425
|
+
* @param module - The imported module
|
|
426
|
+
* @param jobName - Workflow job name to select
|
|
427
|
+
* @returns Detected function or null if no workflow jobs found
|
|
428
|
+
*/
|
|
429
|
+
function detectWorkflowJob(module, jobName) {
|
|
430
|
+
const jobs = [];
|
|
431
|
+
for (const [exportName, exportValue] of Object.entries(module)) {
|
|
432
|
+
if (exportName === "default") continue;
|
|
433
|
+
const result = WorkflowJobSchema.safeParse(exportValue);
|
|
434
|
+
if (result.success) jobs.push({
|
|
435
|
+
name: result.data.name,
|
|
436
|
+
exportName
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
if (jobs.length === 0) return null;
|
|
440
|
+
if (jobName) {
|
|
441
|
+
const match = jobs.find((j) => j.name === jobName);
|
|
442
|
+
if (!match) {
|
|
443
|
+
const available$1 = jobs.map((j) => ` - "${j.name}" (export: ${j.exportName})`).join("\n");
|
|
444
|
+
throw new Error(`Workflow job "${jobName}" not found. Available jobs:\n${available$1}`);
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
type: "workflow-job",
|
|
448
|
+
name: match.name,
|
|
449
|
+
exportName: match.exportName
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
if (jobs.length === 1) return {
|
|
453
|
+
type: "workflow-job",
|
|
454
|
+
name: jobs[0].name,
|
|
455
|
+
exportName: jobs[0].exportName
|
|
456
|
+
};
|
|
457
|
+
const available = jobs.map((j) => ` - "${j.name}" (export: ${j.exportName})`).join("\n");
|
|
458
|
+
throw new Error(`Multiple workflow jobs found. Specify one with --name:\n${available}`);
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Derive a script name from a file path (filename without extension).
|
|
462
|
+
* @param filePath - Absolute path to the function file
|
|
463
|
+
* @returns Filename without extension
|
|
464
|
+
*/
|
|
465
|
+
function deriveNameFromPath(filePath) {
|
|
466
|
+
return path.basename(filePath, path.extname(filePath));
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region src/cli/commands/function/test-run.ts
|
|
471
|
+
/**
|
|
472
|
+
* `tailor-sdk function test-run` command
|
|
473
|
+
*
|
|
474
|
+
* Bundles and executes a function on the Tailor Platform server
|
|
475
|
+
* without deploying (applying) the application.
|
|
476
|
+
*/
|
|
477
|
+
const testRunCommand = defineCommand({
|
|
478
|
+
name: "test-run",
|
|
479
|
+
description: "Run a function on the Tailor Platform server without deploying.",
|
|
480
|
+
args: z.object({
|
|
481
|
+
...commonArgs,
|
|
482
|
+
...jsonArgs,
|
|
483
|
+
...workspaceArgs,
|
|
484
|
+
file: arg(z.string(), {
|
|
485
|
+
positional: true,
|
|
486
|
+
description: "Path to the function file"
|
|
487
|
+
}),
|
|
488
|
+
name: arg(z.string().optional(), {
|
|
489
|
+
alias: "n",
|
|
490
|
+
description: "Workflow job name to run (matches the `name` field of createWorkflowJob)"
|
|
491
|
+
}),
|
|
492
|
+
arg: arg(z.string().optional(), {
|
|
493
|
+
alias: "a",
|
|
494
|
+
description: "JSON argument to pass to the function"
|
|
495
|
+
}),
|
|
496
|
+
"machine-user": arg(z.string().optional(), {
|
|
497
|
+
alias: "m",
|
|
498
|
+
description: "Machine user name for authentication"
|
|
499
|
+
}),
|
|
500
|
+
config: arg(z.string().default("tailor.config.ts"), {
|
|
501
|
+
alias: "c",
|
|
502
|
+
description: "Path to SDK config file"
|
|
503
|
+
})
|
|
504
|
+
}),
|
|
505
|
+
notes: `You can pass either a source file (\`.ts\`) or a pre-bundled file (\`.js\`).
|
|
506
|
+
When a \`.js\` file is provided, detection and bundling are skipped and the file is executed as-is.
|
|
507
|
+
|
|
508
|
+
> [!WARNING]
|
|
509
|
+
> Workflow job \`.trigger()\` calls do not work in test-run mode.
|
|
510
|
+
> Triggered jobs are not executed; only the target job's \`body\` function runs in isolation.`,
|
|
511
|
+
examples: [
|
|
512
|
+
{
|
|
513
|
+
cmd: "resolvers/add.ts --arg '{\"input\":{\"a\":1,\"b\":2}}'",
|
|
514
|
+
desc: "Run a resolver with input arguments"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
cmd: "workflows/sample.ts --name validate-order",
|
|
518
|
+
desc: "Run a specific workflow job by name"
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
cmd: ".tailor-sdk/resolvers/add.js --arg '{\"input\":{\"a\":1,\"b\":2}}'",
|
|
522
|
+
desc: "Run a pre-bundled .js file directly"
|
|
523
|
+
}
|
|
524
|
+
],
|
|
525
|
+
run: withCommonArgs(async (args) => {
|
|
526
|
+
const filePath = path.resolve(args.file);
|
|
527
|
+
if (!fs$1.existsSync(filePath)) throw new Error(`File not found: ${filePath}`);
|
|
528
|
+
const { config } = await loadConfig(args.config);
|
|
529
|
+
const authNamespace = resolveAuthNamespace(config.auth);
|
|
530
|
+
const machineUserName = resolveMachineUserName(args["machine-user"], config.auth);
|
|
531
|
+
const client = await initOperatorClient(await loadAccessToken({
|
|
532
|
+
useProfile: true,
|
|
533
|
+
profile: args.profile
|
|
534
|
+
}));
|
|
535
|
+
const workspaceId = loadWorkspaceId({
|
|
536
|
+
workspaceId: args["workspace-id"],
|
|
537
|
+
profile: args.profile
|
|
538
|
+
});
|
|
539
|
+
const machineUser = await resolveMachineUser({
|
|
540
|
+
client,
|
|
541
|
+
workspaceId,
|
|
542
|
+
authNamespace,
|
|
543
|
+
machineUserName,
|
|
544
|
+
authConfig: config.auth
|
|
545
|
+
});
|
|
546
|
+
const relativePath = path.relative(process.cwd(), filePath);
|
|
547
|
+
const isPreBundled = filePath.endsWith(".js");
|
|
548
|
+
let bundledCode;
|
|
549
|
+
let scriptName;
|
|
550
|
+
let functionType;
|
|
551
|
+
let functionName;
|
|
552
|
+
if (isPreBundled) {
|
|
553
|
+
scriptName = path.basename(filePath);
|
|
554
|
+
bundledCode = fs$1.readFileSync(filePath, "utf-8");
|
|
555
|
+
logger.info(`Using pre-bundled script ${styles.bold(scriptName)}`);
|
|
556
|
+
} else {
|
|
557
|
+
logger.info(`Detecting function type from ${styles.path(relativePath)}`);
|
|
558
|
+
const detected = await detectFunctionType({
|
|
559
|
+
filePath,
|
|
560
|
+
jobName: args.name
|
|
561
|
+
});
|
|
562
|
+
functionType = detected.type;
|
|
563
|
+
functionName = detected.name;
|
|
564
|
+
logger.info(`Detected: ${styles.bold(detected.type)} ${styles.info(`"${detected.name}"`)}`);
|
|
565
|
+
logger.info("Bundling...");
|
|
566
|
+
({bundledCode, scriptName} = await bundleForTestRun({
|
|
567
|
+
detected,
|
|
568
|
+
sourceFile: filePath,
|
|
569
|
+
env: config.env ?? {},
|
|
570
|
+
inlineSourcemap: config.inlineSourcemap,
|
|
571
|
+
machineUser,
|
|
572
|
+
workspaceId
|
|
573
|
+
}));
|
|
574
|
+
logger.info(`Bundled as ${styles.bold(scriptName)}`);
|
|
575
|
+
}
|
|
576
|
+
const authInvoker = create(AuthInvokerSchema, {
|
|
577
|
+
namespace: authNamespace,
|
|
578
|
+
machineUserName: machineUser.name
|
|
579
|
+
});
|
|
580
|
+
logger.info(`Executing on workspace ${styles.dim(workspaceId)}...`);
|
|
581
|
+
const result = await executeScript({
|
|
582
|
+
client,
|
|
583
|
+
workspaceId,
|
|
584
|
+
name: scriptName,
|
|
585
|
+
code: bundledCode,
|
|
586
|
+
arg: args.arg,
|
|
587
|
+
invoker: authInvoker
|
|
588
|
+
});
|
|
589
|
+
if (args.json) logger.out({
|
|
590
|
+
success: result.success,
|
|
591
|
+
scriptName,
|
|
592
|
+
functionType,
|
|
593
|
+
functionName,
|
|
594
|
+
logs: result.logs,
|
|
595
|
+
result: result.result,
|
|
596
|
+
error: result.error
|
|
597
|
+
});
|
|
598
|
+
else {
|
|
599
|
+
if (result.success) logger.success("Execution succeeded");
|
|
600
|
+
else logger.error("Execution failed");
|
|
601
|
+
if (result.logs?.trim()) {
|
|
602
|
+
logger.log(styles.bold("\nLogs:"));
|
|
603
|
+
for (const line of result.logs.split("\n")) logger.log(` ${line}`);
|
|
604
|
+
}
|
|
605
|
+
if (result.result && result.success) {
|
|
606
|
+
logger.log(styles.bold("\nResult:"));
|
|
607
|
+
try {
|
|
608
|
+
const parsed = JSON.parse(result.result);
|
|
609
|
+
logger.log(` ${JSON.stringify(parsed, null, 2).split("\n").join("\n ")}`);
|
|
610
|
+
} catch {
|
|
611
|
+
logger.log(` ${result.result}`);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
if (result.error && !result.success) {
|
|
615
|
+
logger.log(styles.bold("\nError:"));
|
|
616
|
+
logger.log(` ${styles.error(result.error)}`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (!result.success) process.exit(1);
|
|
620
|
+
})
|
|
621
|
+
});
|
|
622
|
+
/**
|
|
623
|
+
* Resolve auth namespace from config.
|
|
624
|
+
* @param authConfig - Auth configuration from tailor.config.ts
|
|
625
|
+
* @returns Resolved auth namespace
|
|
626
|
+
*/
|
|
627
|
+
function resolveAuthNamespace(authConfig) {
|
|
628
|
+
if (authConfig?.name) return authConfig.name;
|
|
629
|
+
throw new Error("Auth namespace is required. Ensure tailor.config.ts has an auth config.");
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Resolve machine user name from CLI args or config. Priority: --machine-user > first key of config.auth.machineUsers
|
|
633
|
+
* @param cliMachineUser - CLI --machine-user value
|
|
634
|
+
* @param authConfig - Auth configuration from tailor.config.ts
|
|
635
|
+
* @returns Resolved machine user name
|
|
636
|
+
*/
|
|
637
|
+
function resolveMachineUserName(cliMachineUser, authConfig) {
|
|
638
|
+
if (cliMachineUser) return cliMachineUser;
|
|
639
|
+
if (authConfig && !("external" in authConfig && authConfig.external)) {
|
|
640
|
+
const machineUsers = authConfig.machineUsers;
|
|
641
|
+
if (machineUsers) {
|
|
642
|
+
const keys = Object.keys(machineUsers);
|
|
643
|
+
if (keys.length > 0) return keys[0];
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
throw new Error("Machine user is required. Provide --machine-user or ensure tailor.config.ts has machine users configured.");
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Resolve full machine user info: name, id (from API), and attributes (from config).
|
|
650
|
+
* @param options - Options for resolving machine user
|
|
651
|
+
* @returns Resolved machine user with id, attributes, and attributeList
|
|
652
|
+
*/
|
|
653
|
+
async function resolveMachineUser(options) {
|
|
654
|
+
const { client, workspaceId, authNamespace, machineUserName, authConfig } = options;
|
|
655
|
+
let id = "00000000-0000-0000-0000-000000000000";
|
|
656
|
+
try {
|
|
657
|
+
const { machineUser } = await client.getAuthMachineUser({
|
|
658
|
+
workspaceId,
|
|
659
|
+
authNamespace,
|
|
660
|
+
name: machineUserName
|
|
661
|
+
});
|
|
662
|
+
if (machineUser?.id) id = machineUser.id;
|
|
663
|
+
} catch {
|
|
664
|
+
logger.debug(`Could not fetch machine user "${machineUserName}" from server, using nil UUID`);
|
|
665
|
+
}
|
|
666
|
+
const machineUserConfig = authConfig?.machineUsers?.[machineUserName];
|
|
667
|
+
let attributes = null;
|
|
668
|
+
let attributeList = [];
|
|
669
|
+
if (machineUserConfig && typeof machineUserConfig === "object") {
|
|
670
|
+
const cfg = machineUserConfig;
|
|
671
|
+
attributes = cfg.attributes ?? null;
|
|
672
|
+
attributeList = cfg.attributeList ?? [];
|
|
673
|
+
}
|
|
674
|
+
return {
|
|
675
|
+
name: machineUserName,
|
|
676
|
+
id,
|
|
677
|
+
attributes,
|
|
678
|
+
attributeList
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
|
|
201
682
|
//#endregion
|
|
202
683
|
//#region src/cli/commands/function/index.ts
|
|
203
684
|
const functionCommand = defineCommand({
|
|
204
685
|
name: "function",
|
|
205
686
|
description: "Manage functions",
|
|
206
|
-
subCommands: {
|
|
687
|
+
subCommands: {
|
|
688
|
+
logs: logsCommand,
|
|
689
|
+
"test-run": testRunCommand
|
|
690
|
+
},
|
|
207
691
|
async run() {
|
|
208
692
|
await runCommand(logsCommand, []);
|
|
209
693
|
}
|
|
@@ -224,7 +708,7 @@ const generateCommand = defineCommand({
|
|
|
224
708
|
alias: "W",
|
|
225
709
|
description: "Watch for type/resolver changes and regenerate"
|
|
226
710
|
})
|
|
227
|
-
}),
|
|
711
|
+
}).strict(),
|
|
228
712
|
run: withCommonArgs(async (args) => {
|
|
229
713
|
await generate({
|
|
230
714
|
configPath: args.config,
|
|
@@ -260,7 +744,7 @@ const initCommand = defineCommand({
|
|
|
260
744
|
alias: "t",
|
|
261
745
|
description: "Template name"
|
|
262
746
|
})
|
|
263
|
-
}),
|
|
747
|
+
}).strict(),
|
|
264
748
|
run: withCommonArgs(async (args) => {
|
|
265
749
|
const packageJson$1 = await readPackageJson();
|
|
266
750
|
const version = packageJson$1.version && packageJson$1.version !== "0.0.0" ? packageJson$1.version : "latest";
|
|
@@ -292,7 +776,7 @@ const startAuthServer = async () => {
|
|
|
292
776
|
const client = initOAuth2Client();
|
|
293
777
|
const state = randomState();
|
|
294
778
|
const codeVerifier = await generateCodeVerifier();
|
|
295
|
-
return new Promise((resolve, reject) => {
|
|
779
|
+
return new Promise((resolve$1, reject) => {
|
|
296
780
|
const server = http.createServer(async (req, res) => {
|
|
297
781
|
try {
|
|
298
782
|
if (!req.url?.startsWith("/callback")) throw new Error("Invalid callback URL");
|
|
@@ -318,7 +802,7 @@ const startAuthServer = async () => {
|
|
|
318
802
|
status: "ok",
|
|
319
803
|
message: "Successfully authenticated. Please close this window."
|
|
320
804
|
}));
|
|
321
|
-
resolve();
|
|
805
|
+
resolve$1();
|
|
322
806
|
} catch (error) {
|
|
323
807
|
res.writeHead(401);
|
|
324
808
|
res.end("Authentication failed");
|
|
@@ -355,7 +839,7 @@ const startAuthServer = async () => {
|
|
|
355
839
|
const loginCommand = defineCommand({
|
|
356
840
|
name: "login",
|
|
357
841
|
description: "Login to Tailor Platform.",
|
|
358
|
-
args: z.object({ ...commonArgs }),
|
|
842
|
+
args: z.object({ ...commonArgs }).strict(),
|
|
359
843
|
run: withCommonArgs(async () => {
|
|
360
844
|
await startAuthServer();
|
|
361
845
|
logger.success("Successfully logged in to Tailor Platform.");
|
|
@@ -367,7 +851,7 @@ const loginCommand = defineCommand({
|
|
|
367
851
|
const logoutCommand = defineCommand({
|
|
368
852
|
name: "logout",
|
|
369
853
|
description: "Logout from Tailor Platform.",
|
|
370
|
-
args: z.object({ ...commonArgs }),
|
|
854
|
+
args: z.object({ ...commonArgs }).strict(),
|
|
371
855
|
run: withCommonArgs(async () => {
|
|
372
856
|
const pfConfig = readPlatformConfig();
|
|
373
857
|
const tokens = pfConfig.current_user ? pfConfig.users[pfConfig.current_user] : void 0;
|
|
@@ -424,7 +908,7 @@ const openCommand = defineCommand({
|
|
|
424
908
|
args: z.object({
|
|
425
909
|
...commonArgs,
|
|
426
910
|
...deploymentArgs
|
|
427
|
-
}),
|
|
911
|
+
}).strict(),
|
|
428
912
|
run: withCommonArgs(async (args) => {
|
|
429
913
|
const workspaceId = loadWorkspaceId({
|
|
430
914
|
workspaceId: args["workspace-id"],
|
|
@@ -466,7 +950,7 @@ const createCommand$2 = defineCommand({
|
|
|
466
950
|
alias: "w",
|
|
467
951
|
description: "Workspace ID"
|
|
468
952
|
})
|
|
469
|
-
}),
|
|
953
|
+
}).strict(),
|
|
470
954
|
run: withCommonArgs(async (args) => {
|
|
471
955
|
const config = readPlatformConfig();
|
|
472
956
|
if (config.profiles[args.name]) throw new Error(`Profile "${args.name}" already exists.`);
|
|
@@ -504,7 +988,7 @@ const deleteCommand$2 = defineCommand({
|
|
|
504
988
|
positional: true,
|
|
505
989
|
description: "Profile name"
|
|
506
990
|
})
|
|
507
|
-
}),
|
|
991
|
+
}).strict(),
|
|
508
992
|
run: withCommonArgs(async (args) => {
|
|
509
993
|
const config = readPlatformConfig();
|
|
510
994
|
if (!config.profiles[args.name]) throw new Error(`Profile "${args.name}" not found.`);
|
|
@@ -522,7 +1006,7 @@ const listCommand$4 = defineCommand({
|
|
|
522
1006
|
args: z.object({
|
|
523
1007
|
...commonArgs,
|
|
524
1008
|
...jsonArgs
|
|
525
|
-
}),
|
|
1009
|
+
}).strict(),
|
|
526
1010
|
run: withCommonArgs(async () => {
|
|
527
1011
|
const config = readPlatformConfig();
|
|
528
1012
|
const profiles = Object.entries(config.profiles);
|
|
@@ -562,7 +1046,7 @@ const updateCommand$1 = defineCommand({
|
|
|
562
1046
|
alias: "w",
|
|
563
1047
|
description: "New workspace ID"
|
|
564
1048
|
})
|
|
565
|
-
}),
|
|
1049
|
+
}).strict(),
|
|
566
1050
|
run: withCommonArgs(async (args) => {
|
|
567
1051
|
const config = readPlatformConfig();
|
|
568
1052
|
if (!config.profiles[args.name]) throw new Error(`Profile "${args.name}" not found.`);
|
|
@@ -648,7 +1132,7 @@ const createSecretCommand = defineCommand({
|
|
|
648
1132
|
...commonArgs,
|
|
649
1133
|
...workspaceArgs,
|
|
650
1134
|
...secretValueArgs
|
|
651
|
-
}),
|
|
1135
|
+
}).strict(),
|
|
652
1136
|
run: withCommonArgs(async (args) => {
|
|
653
1137
|
const client = await initOperatorClient(await loadAccessToken({
|
|
654
1138
|
useProfile: true,
|
|
@@ -686,7 +1170,7 @@ const deleteSecretCommand = defineCommand({
|
|
|
686
1170
|
...workspaceArgs,
|
|
687
1171
|
...secretIdentifyArgs,
|
|
688
1172
|
...confirmationArgs
|
|
689
|
-
}),
|
|
1173
|
+
}).strict(),
|
|
690
1174
|
run: withCommonArgs(async (args) => {
|
|
691
1175
|
const client = await initOperatorClient(await loadAccessToken({
|
|
692
1176
|
useProfile: true,
|
|
@@ -757,7 +1241,7 @@ const listSecretCommand = defineCommand({
|
|
|
757
1241
|
...jsonArgs,
|
|
758
1242
|
...workspaceArgs,
|
|
759
1243
|
...vaultArgs
|
|
760
|
-
}),
|
|
1244
|
+
}).strict(),
|
|
761
1245
|
run: withCommonArgs(async (args) => {
|
|
762
1246
|
try {
|
|
763
1247
|
const secrets = await secretList({
|
|
@@ -782,7 +1266,7 @@ const updateSecretCommand = defineCommand({
|
|
|
782
1266
|
...commonArgs,
|
|
783
1267
|
...workspaceArgs,
|
|
784
1268
|
...secretValueArgs
|
|
785
|
-
}),
|
|
1269
|
+
}).strict(),
|
|
786
1270
|
run: withCommonArgs(async (args) => {
|
|
787
1271
|
const client = await initOperatorClient(await loadAccessToken({
|
|
788
1272
|
useProfile: true,
|
|
@@ -823,7 +1307,7 @@ const createCommand$1 = defineCommand({
|
|
|
823
1307
|
...commonArgs,
|
|
824
1308
|
...workspaceArgs,
|
|
825
1309
|
...nameArgs
|
|
826
|
-
}),
|
|
1310
|
+
}).strict(),
|
|
827
1311
|
run: withCommonArgs(async (args) => {
|
|
828
1312
|
const client = await initOperatorClient(await loadAccessToken({
|
|
829
1313
|
useProfile: true,
|
|
@@ -856,7 +1340,7 @@ const deleteCommand$1 = defineCommand({
|
|
|
856
1340
|
...workspaceArgs,
|
|
857
1341
|
...nameArgs,
|
|
858
1342
|
...confirmationArgs
|
|
859
|
-
}),
|
|
1343
|
+
}).strict(),
|
|
860
1344
|
run: withCommonArgs(async (args) => {
|
|
861
1345
|
const client = await initOperatorClient(await loadAccessToken({
|
|
862
1346
|
useProfile: true,
|
|
@@ -924,7 +1408,7 @@ const listCommand$3 = defineCommand({
|
|
|
924
1408
|
...commonArgs,
|
|
925
1409
|
...jsonArgs,
|
|
926
1410
|
...workspaceArgs
|
|
927
|
-
}),
|
|
1411
|
+
}).strict(),
|
|
928
1412
|
run: withCommonArgs(async (args) => {
|
|
929
1413
|
const vaults = await vaultList({
|
|
930
1414
|
workspaceId: args["workspace-id"],
|
|
@@ -1066,7 +1550,7 @@ async function uploadDirectory(client, workspaceId, deploymentId, rootDir, showP
|
|
|
1066
1550
|
*/
|
|
1067
1551
|
async function collectFiles(rootDir, currentDir = "") {
|
|
1068
1552
|
const dirPath = path.join(rootDir, currentDir);
|
|
1069
|
-
const entries = await fs
|
|
1553
|
+
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
|
|
1070
1554
|
const files = [];
|
|
1071
1555
|
for (const entry of entries) {
|
|
1072
1556
|
const rel = path.join(currentDir, entry.name);
|
|
@@ -1085,7 +1569,7 @@ async function uploadSingleFile(client, workspaceId, deploymentId, rootDir, file
|
|
|
1085
1569
|
return;
|
|
1086
1570
|
}
|
|
1087
1571
|
const contentType = mime;
|
|
1088
|
-
const readStream = fs
|
|
1572
|
+
const readStream = fs.createReadStream(absPath, { highWaterMark: CHUNK_SIZE });
|
|
1089
1573
|
async function* requestStream() {
|
|
1090
1574
|
yield { payload: {
|
|
1091
1575
|
case: "initialMetadata",
|
|
@@ -1136,9 +1620,10 @@ const deployCommand = defineCommand({
|
|
|
1136
1620
|
}),
|
|
1137
1621
|
dir: arg(z.string(), {
|
|
1138
1622
|
alias: "d",
|
|
1139
|
-
description: "Path to the static website files"
|
|
1623
|
+
description: "Path to the static website files",
|
|
1624
|
+
completion: { type: "directory" }
|
|
1140
1625
|
})
|
|
1141
|
-
}),
|
|
1626
|
+
}).strict(),
|
|
1142
1627
|
run: withCommonArgs(async (args) => {
|
|
1143
1628
|
logger.info(`Deploying static website "${args.name}" from directory: ${args.dir}`);
|
|
1144
1629
|
const client = await initOperatorClient(await loadAccessToken({
|
|
@@ -1151,7 +1636,7 @@ const deployCommand = defineCommand({
|
|
|
1151
1636
|
workspaceId: args["workspace-id"],
|
|
1152
1637
|
profile: args.profile
|
|
1153
1638
|
});
|
|
1154
|
-
if (!fs
|
|
1639
|
+
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) throw new Error(`Directory not found or not a directory: ${dir}`);
|
|
1155
1640
|
const { url, skippedFiles } = await withTimeout(deployStaticWebsite(client, workspaceId, name, dir, !args.json), 10 * 6e4, "Deployment timed out after 10 minutes.");
|
|
1156
1641
|
if (args.json) logger.out({
|
|
1157
1642
|
name,
|
|
@@ -1179,7 +1664,7 @@ const getCommand = defineCommand({
|
|
|
1179
1664
|
positional: true,
|
|
1180
1665
|
description: "Static website name"
|
|
1181
1666
|
})
|
|
1182
|
-
}),
|
|
1667
|
+
}).strict(),
|
|
1183
1668
|
run: withCommonArgs(async (args) => {
|
|
1184
1669
|
const client = await initOperatorClient(await loadAccessToken({
|
|
1185
1670
|
useProfile: true,
|
|
@@ -1249,7 +1734,7 @@ const listCommand$2 = defineCommand({
|
|
|
1249
1734
|
...commonArgs,
|
|
1250
1735
|
...jsonArgs,
|
|
1251
1736
|
...workspaceArgs
|
|
1252
|
-
}),
|
|
1737
|
+
}).strict(),
|
|
1253
1738
|
run: withCommonArgs(async (args) => {
|
|
1254
1739
|
const websites = await listStaticWebsites({
|
|
1255
1740
|
workspaceId: args["workspace-id"],
|
|
@@ -1523,7 +2008,7 @@ function resolveAllNamespaces(config, options) {
|
|
|
1523
2008
|
*/
|
|
1524
2009
|
async function runLiamBuild(schemaPath, cwd) {
|
|
1525
2010
|
fs$1.mkdirSync(cwd, { recursive: true });
|
|
1526
|
-
return await new Promise((resolve, reject) => {
|
|
2011
|
+
return await new Promise((resolve$1, reject) => {
|
|
1527
2012
|
let liamBinPath;
|
|
1528
2013
|
try {
|
|
1529
2014
|
liamBinPath = resolveCliBinPath({
|
|
@@ -1560,7 +2045,7 @@ async function runLiamBuild(schemaPath, cwd) {
|
|
|
1560
2045
|
reject(error);
|
|
1561
2046
|
});
|
|
1562
2047
|
child.on("close", (code) => {
|
|
1563
|
-
if (code === 0) resolve();
|
|
2048
|
+
if (code === 0) resolve$1();
|
|
1564
2049
|
else {
|
|
1565
2050
|
if (stderrOutput) logger.error(stderrOutput);
|
|
1566
2051
|
logger.error("liam CLI exited with a non-zero code. Ensure `@liam-hq/cli erd build --format tbls --input schema.json` works in your project.");
|
|
@@ -1637,9 +2122,10 @@ const erdExportCommand = defineCommand({
|
|
|
1637
2122
|
}),
|
|
1638
2123
|
output: arg(z.string().default(DEFAULT_ERD_BASE_DIR), {
|
|
1639
2124
|
alias: "o",
|
|
1640
|
-
description: "Output directory path for tbls-compatible ERD JSON (writes to `<outputDir>/<namespace>/schema.json`)"
|
|
2125
|
+
description: "Output directory path for tbls-compatible ERD JSON (writes to `<outputDir>/<namespace>/schema.json`)",
|
|
2126
|
+
completion: { type: "directory" }
|
|
1641
2127
|
})
|
|
1642
|
-
}),
|
|
2128
|
+
}).strict(),
|
|
1643
2129
|
run: withCommonArgs(async (args) => {
|
|
1644
2130
|
const { client, workspaceId, config } = await initErdContext(args);
|
|
1645
2131
|
const outputDir = path.resolve(process.cwd(), String(args.output));
|
|
@@ -1677,7 +2163,7 @@ const erdDeployCommand = defineCommand({
|
|
|
1677
2163
|
alias: "n",
|
|
1678
2164
|
description: "TailorDB namespace name (optional - deploys all namespaces with erdSite if omitted)"
|
|
1679
2165
|
})
|
|
1680
|
-
}),
|
|
2166
|
+
}).strict(),
|
|
1681
2167
|
run: withCommonArgs(async (args) => {
|
|
1682
2168
|
const { client, workspaceId, config } = await initErdContext(args);
|
|
1683
2169
|
const buildResults = await prepareErdBuilds({
|
|
@@ -1723,7 +2209,7 @@ async function runServeDist(results) {
|
|
|
1723
2209
|
logger.warn(`Multiple namespaces found. To serve another namespace, run:\n${commands}`);
|
|
1724
2210
|
}
|
|
1725
2211
|
fs$1.mkdirSync(primary.erdDir, { recursive: true });
|
|
1726
|
-
return await new Promise((resolve, reject) => {
|
|
2212
|
+
return await new Promise((resolve$1, reject) => {
|
|
1727
2213
|
let serveBinPath;
|
|
1728
2214
|
try {
|
|
1729
2215
|
serveBinPath = resolveCliBinPath({
|
|
@@ -1744,7 +2230,7 @@ async function runServeDist(results) {
|
|
|
1744
2230
|
reject(error);
|
|
1745
2231
|
});
|
|
1746
2232
|
child.on("exit", (code) => {
|
|
1747
|
-
if (code === 0) resolve();
|
|
2233
|
+
if (code === 0) resolve$1();
|
|
1748
2234
|
else {
|
|
1749
2235
|
logger.error("serve CLI exited with a non-zero code. Ensure `serve dist` works in your project.");
|
|
1750
2236
|
reject(/* @__PURE__ */ new Error(`serve CLI exited with code ${code ?? 1}`));
|
|
@@ -1762,7 +2248,7 @@ const erdServeCommand = defineCommand({
|
|
|
1762
2248
|
alias: "n",
|
|
1763
2249
|
description: "TailorDB namespace name (uses first namespace in config if not specified)"
|
|
1764
2250
|
})
|
|
1765
|
-
}),
|
|
2251
|
+
}).strict(),
|
|
1766
2252
|
run: withCommonArgs(async (args) => {
|
|
1767
2253
|
const { client, workspaceId, config } = await initErdContext(args);
|
|
1768
2254
|
await runServeDist(await prepareErdBuilds({
|
|
@@ -1875,7 +2361,7 @@ const setCommand = defineCommand({
|
|
|
1875
2361
|
alias: "n",
|
|
1876
2362
|
description: "Target TailorDB namespace (required if multiple namespaces exist)"
|
|
1877
2363
|
})
|
|
1878
|
-
}),
|
|
2364
|
+
}).strict(),
|
|
1879
2365
|
run: withCommonArgs(async (args) => {
|
|
1880
2366
|
await set({
|
|
1881
2367
|
configPath: args.config,
|
|
@@ -1948,7 +2434,7 @@ const statusCommand = defineCommand({
|
|
|
1948
2434
|
alias: "n",
|
|
1949
2435
|
description: "Target TailorDB namespace (shows all namespaces if not specified)"
|
|
1950
2436
|
})
|
|
1951
|
-
}),
|
|
2437
|
+
}).strict(),
|
|
1952
2438
|
run: withCommonArgs(async (args) => {
|
|
1953
2439
|
await status({
|
|
1954
2440
|
configPath: args.config,
|
|
@@ -1996,7 +2482,7 @@ const tailordbCommand = defineCommand({
|
|
|
1996
2482
|
const currentCommand = defineCommand({
|
|
1997
2483
|
name: "current",
|
|
1998
2484
|
description: "Show current user.",
|
|
1999
|
-
args: z.object({ ...commonArgs }),
|
|
2485
|
+
args: z.object({ ...commonArgs }).strict(),
|
|
2000
2486
|
run: withCommonArgs(async () => {
|
|
2001
2487
|
const config = readPlatformConfig();
|
|
2002
2488
|
if (!config.current_user) throw new Error(ml`
|
|
@@ -2019,7 +2505,7 @@ const listCommand$1 = defineCommand({
|
|
|
2019
2505
|
args: z.object({
|
|
2020
2506
|
...commonArgs,
|
|
2021
2507
|
...jsonArgs
|
|
2022
|
-
}),
|
|
2508
|
+
}).strict(),
|
|
2023
2509
|
run: withCommonArgs(async (args) => {
|
|
2024
2510
|
const config = readPlatformConfig();
|
|
2025
2511
|
const users = Object.keys(config.users);
|
|
@@ -2113,7 +2599,7 @@ const createCommand = defineCommand({
|
|
|
2113
2599
|
alias: "W",
|
|
2114
2600
|
description: "Grant write permission (default: read-only)"
|
|
2115
2601
|
})
|
|
2116
|
-
}),
|
|
2602
|
+
}).strict(),
|
|
2117
2603
|
run: withCommonArgs(async (args) => {
|
|
2118
2604
|
const config = readPlatformConfig();
|
|
2119
2605
|
if (!config.current_user) throw new Error(ml`
|
|
@@ -2142,7 +2628,7 @@ const deleteCommand = defineCommand({
|
|
|
2142
2628
|
positional: true,
|
|
2143
2629
|
description: "Token name"
|
|
2144
2630
|
})
|
|
2145
|
-
}),
|
|
2631
|
+
}).strict(),
|
|
2146
2632
|
run: withCommonArgs(async (args) => {
|
|
2147
2633
|
const config = readPlatformConfig();
|
|
2148
2634
|
if (!config.current_user) throw new Error(ml`
|
|
@@ -2162,7 +2648,7 @@ const listCommand = defineCommand({
|
|
|
2162
2648
|
args: z.object({
|
|
2163
2649
|
...commonArgs,
|
|
2164
2650
|
...jsonArgs
|
|
2165
|
-
}),
|
|
2651
|
+
}).strict(),
|
|
2166
2652
|
run: withCommonArgs(async (args) => {
|
|
2167
2653
|
const config = readPlatformConfig();
|
|
2168
2654
|
if (!config.current_user) throw new Error(ml`
|
|
@@ -2215,7 +2701,7 @@ const updateCommand = defineCommand({
|
|
|
2215
2701
|
alias: "W",
|
|
2216
2702
|
description: "Grant write permission (if not specified, keeps read-only)"
|
|
2217
2703
|
})
|
|
2218
|
-
}),
|
|
2704
|
+
}).strict(),
|
|
2219
2705
|
run: withCommonArgs(async (args) => {
|
|
2220
2706
|
const config = readPlatformConfig();
|
|
2221
2707
|
if (!config.current_user) throw new Error(ml`
|
|
@@ -2262,7 +2748,7 @@ const switchCommand = defineCommand({
|
|
|
2262
2748
|
positional: true,
|
|
2263
2749
|
description: "User email"
|
|
2264
2750
|
})
|
|
2265
|
-
}),
|
|
2751
|
+
}).strict(),
|
|
2266
2752
|
run: withCommonArgs(async (args) => {
|
|
2267
2753
|
const config = readPlatformConfig();
|
|
2268
2754
|
if (!config.users[args.user]) throw new Error(ml`
|
|
@@ -2378,6 +2864,7 @@ const mainCommand = withCompletionCommand(defineCommand({
|
|
|
2378
2864
|
oauth2client: oauth2clientCommand,
|
|
2379
2865
|
open: openCommand,
|
|
2380
2866
|
profile: profileCommand,
|
|
2867
|
+
query: queryCommand,
|
|
2381
2868
|
remove: removeCommand$1,
|
|
2382
2869
|
secret: secretCommand,
|
|
2383
2870
|
show: showCommand,
|