@tailor-platform/sdk 1.37.0 → 1.38.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 +56 -0
- package/dist/application-C1ipG5Q6.mjs +4 -0
- package/dist/{application-qRGMV8Tr.mjs → application-DhQrXEld.mjs} +13 -5
- package/dist/{application-qRGMV8Tr.mjs.map → application-DhQrXEld.mjs.map} +1 -1
- package/dist/cli/index.mjs +364 -123
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +6 -6
- package/dist/cli/lib.mjs +3 -3
- package/dist/{client-424n_3T9.mjs → client-BWAbbA1C.mjs} +1 -1
- package/dist/{client-DllDLYmZ.mjs → client-xzPXtc_e.mjs} +9 -3
- package/dist/{client-DllDLYmZ.mjs.map → client-xzPXtc_e.mjs.map} +1 -1
- package/dist/configure/index.d.mts +4 -5
- package/dist/configure/index.mjs +4 -1
- package/dist/configure/index.mjs.map +1 -1
- package/dist/{crash-report-aHnky_xH.mjs → crash-report-BEAiCSCl.mjs} +1 -1
- package/dist/{crash-report-CDQ2JvgR.mjs → crash-report-DXhPL8Ue.mjs} +3 -3
- package/dist/{crash-report-CDQ2JvgR.mjs.map → crash-report-DXhPL8Ue.mjs.map} +1 -1
- package/dist/errors-D9f2UJpT.mjs +43 -0
- package/dist/errors-D9f2UJpT.mjs.map +1 -0
- package/dist/{index-CeS4FA9o.d.mts → index-CHo73Aat.d.mts} +2 -2
- package/dist/{index-DnIg_LfT.d.mts → index-CIIXsk3E.d.mts} +2 -2
- package/dist/{index-BUT18Kak.d.mts → index-Cln_TTZn.d.mts} +2 -2
- package/dist/{index-BVJQLjyN.d.mts → index-Cs3fwmLu.d.mts} +22 -17
- package/dist/{index-C3kcXHXJ.d.mts → index-D_W9-Lvk.d.mts} +2 -2
- package/dist/{interceptor-dSNiQq71.mjs → interceptor-CzaH2Ur6.mjs} +1 -1
- package/dist/{interceptor-dSNiQq71.mjs.map → interceptor-CzaH2Ur6.mjs.map} +1 -1
- package/dist/{logger-C8qBDCKO.mjs → logger-5_JMzHmw.mjs} +42 -3
- package/dist/logger-5_JMzHmw.mjs.map +1 -0
- package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
- package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
- package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +1 -1
- package/dist/plugin/index.d.mts +1 -2
- package/dist/{plugin-D6P4g_2L.d.mts → plugin-D84blivd.d.mts} +54 -3
- package/dist/{runtime-D9ejnCm6.mjs → runtime-ChpwtPut.mjs} +26 -54
- package/dist/runtime-ChpwtPut.mjs.map +1 -0
- package/dist/service-Bcp6JB3w.mjs +132 -0
- package/dist/service-Bcp6JB3w.mjs.map +1 -0
- package/dist/utils/test/index.d.mts +2 -2
- package/dist/utils/test/index.mjs +6 -2
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/{workflow.generated-Bj_DVqGh.d.mts → workflow.generated-BRdcCWfC.d.mts} +2 -2
- package/docs/cli/function.md +42 -16
- package/docs/cli/upgrade.md +51 -0
- package/docs/cli/user.md +1 -1
- package/docs/cli/workflow.md +10 -10
- package/docs/cli-reference.md +23 -14
- package/docs/configuration.md +9 -7
- package/docs/services/executor.md +39 -0
- package/docs/services/tailordb.md +20 -0
- package/package.json +7 -7
- package/dist/application-ILhZq_oW.mjs +0 -4
- package/dist/env-04IQXqsl.d.mts +0 -30
- package/dist/logger-C8qBDCKO.mjs.map +0 -1
- package/dist/runtime-D9ejnCm6.mjs.map +0 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { I as AuthInvokerSchema, U as PATScope, i as fetchAll, k as FunctionExecution_Type, l as initOAuth2Client, m as userAgent, n as closeConnectionPool, o as fetchPlatformMachineUserToken, s as fetchUserInfo, u as initOperatorClient } from "../client-
|
|
4
|
-
import { n as logger, r as styles } from "../logger-
|
|
5
|
-
import {
|
|
3
|
+
import { I as AuthInvokerSchema, U as PATScope, i as fetchAll, k as FunctionExecution_Type, l as initOAuth2Client, m as userAgent, n as closeConnectionPool, o as fetchPlatformMachineUserToken, s as fetchUserInfo, u as initOperatorClient } from "../client-xzPXtc_e.mjs";
|
|
4
|
+
import { n as logger, r as styles } from "../logger-5_JMzHmw.mjs";
|
|
5
|
+
import { $ as deleteCommand$3, $t as isValidMigrationNumber, At as formatKeyValueTable, C as listCommand$12, E as resumeCommand, Et as executionsCommand, F as showCommand, G as getCommand$4, H as treeCommand, I as logBetaWarning, Lt as parseMigrationLabelNumber, N as generateCommand$1, Nt as apply, O as listCommand$11, Pt as executeScript, R as removeCommand$1, St as startCommand, T as healthCommand, U as listCommand$10, Xt as getMigrationFilePath, Y as listCommand$9, Z as getCommand$3, Zt as getMigrationFiles, _n as workspaceArgs, an as getNamespacesWithMigrations, at as getCommand$2, b as createCommand$4, c as listCommand$13, cn as trnPrefix, ct as tokenCommand, dn as apiCommand, dt as generate, en as loadDiff, f as restoreCommand, fn as defineAppCommand, g as getCommand$6, gn as isVerbose, gt as listCommand$6, hn as deploymentArgs, i as updateCommand$4, j as truncateCommand, jt as getCommand$1, kt as functionExecutionStatusToString, lt as listCommand$7, m as listCommand$14, mn as confirmationArgs, mt as triggerCommand, o as removeCommand, on as prompt, pn as commonArgs, pt as webhookCommand, q as updateCommand$2, qt as formatMigrationNumber, r as queryCommand, rt as listCommand$8, sn as sdkNameLabelKey, t as isNativeTypeScriptRuntime, tt as createCommand$3, u as inviteCommand, v as deleteCommand$4, wt as getCommand$5, yt as jobsCommand, z as updateCommand$3 } from "../runtime-ChpwtPut.mjs";
|
|
6
6
|
import { t as readPackageJson } from "../package-json-BHViVisJ.mjs";
|
|
7
|
-
import { C as resolveTokens, S as readPlatformConfig, T as writePlatformConfig, a as loadConfig, b as loadAccessToken, g as getDistDir, i as resolveInlineSourcemap, l as ExecutorSchema, o as WorkflowJobSchema, s as ResolverSchema, v as deleteUserTokens, w as saveUserTokens, x as loadWorkspaceId, y as fetchLatestToken } from "../application-
|
|
8
|
-
import { a as JSON_FOOTER_MARKER, i as CRASH_LOG_EXTENSION, o as parseCrashReportConfig, r as sendCrashReport, t as initCrashReporting } from "../crash-report-
|
|
7
|
+
import { C as resolveTokens, S as readPlatformConfig, T as writePlatformConfig, a as loadConfig, b as loadAccessToken, g as getDistDir, i as resolveInlineSourcemap, l as ExecutorSchema, o as WorkflowJobSchema, s as ResolverSchema, v as deleteUserTokens, w as saveUserTokens, x as loadWorkspaceId, y as fetchLatestToken } from "../application-DhQrXEld.mjs";
|
|
8
|
+
import { a as JSON_FOOTER_MARKER, i as CRASH_LOG_EXTENSION, o as parseCrashReportConfig, r as sendCrashReport, t as initCrashReporting } from "../crash-report-DXhPL8Ue.mjs";
|
|
9
|
+
import { n as isCLIError } from "../errors-D9f2UJpT.mjs";
|
|
9
10
|
import { createRequire } from "node:module";
|
|
10
11
|
import { arg, defineCommand, runCommand, runMain } from "politty";
|
|
11
12
|
import { withCompletionCommand } from "politty/completion";
|
|
@@ -404,125 +405,91 @@ const executorCommand = defineCommand({
|
|
|
404
405
|
});
|
|
405
406
|
|
|
406
407
|
//#endregion
|
|
407
|
-
//#region src/cli/
|
|
408
|
-
/**
|
|
409
|
-
* Convert function execution type enum to string.
|
|
410
|
-
* @param type - Function execution type enum value
|
|
411
|
-
* @returns Type string representation
|
|
412
|
-
*/
|
|
413
|
-
function functionExecutionTypeToString(type) {
|
|
414
|
-
switch (type) {
|
|
415
|
-
case FunctionExecution_Type.STANDARD: return "STANDARD";
|
|
416
|
-
case FunctionExecution_Type.JOB: return "JOB";
|
|
417
|
-
default: return "UNSPECIFIED";
|
|
418
|
-
}
|
|
419
|
-
}
|
|
408
|
+
//#region src/cli/shared/function-script-download.ts
|
|
420
409
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
410
|
+
* Download a deployed function script from the function registry.
|
|
411
|
+
*
|
|
412
|
+
* Wraps the server-streaming `downloadFunctionRegistryScript` RPC and
|
|
413
|
+
* concatenates content chunks into a single UTF-8 string.
|
|
424
414
|
*/
|
|
425
|
-
function toFunctionExecutionListInfo(execution) {
|
|
426
|
-
return {
|
|
427
|
-
id: execution.id,
|
|
428
|
-
scriptName: execution.scriptName,
|
|
429
|
-
status: functionExecutionStatusToString(execution.status),
|
|
430
|
-
type: functionExecutionTypeToString(execution.type),
|
|
431
|
-
startedAt: execution.startedAt ? timestampDate(execution.startedAt) : null,
|
|
432
|
-
finishedAt: execution.finishedAt ? timestampDate(execution.finishedAt) : null
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
415
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
416
|
+
* Translate a `FunctionExecution.scriptName` into the corresponding
|
|
417
|
+
* function registry name used by `downloadFunctionRegistryScript`.
|
|
418
|
+
*
|
|
419
|
+
* The platform records executions under a script-name format that
|
|
420
|
+
* differs from the registry name. The execution `type` is used as the
|
|
421
|
+
* primary discriminator because workflow job names are unconstrained
|
|
422
|
+
* strings (`WorkflowJobSchema.name: z.string()`) and may contain dots
|
|
423
|
+
* that collide with the resolver / executor / hook filename suffixes.
|
|
424
|
+
*
|
|
425
|
+
* JOB: `<jobName>` -> `workflow--<jobName>`
|
|
426
|
+
* STANDARD resolver: `<namespace>.<name>.body.js` -> `resolver--<namespace>--<name>`
|
|
427
|
+
* STANDARD executor: `<name>.operation.js` -> `executor--<name>`
|
|
428
|
+
* STANDARD auth hook: `<authName>.<hookPoint>.hook.js` -> `auth-hook--<authName>--<hookPoint>`
|
|
429
|
+
*
|
|
430
|
+
* For older servers that leave `type` as `UNSPECIFIED`, the same
|
|
431
|
+
* filename-suffix heuristic is applied, with a bare-name fallback to
|
|
432
|
+
* `workflow--<name>` for backward compatibility. Returns `null` for
|
|
433
|
+
* unrecognized formats (ad-hoc test-run scripts, seed scripts, etc.
|
|
434
|
+
* that are not stored in the registry).
|
|
435
|
+
* @param scriptName - The `scriptName` field from a `FunctionExecution`
|
|
436
|
+
* @param executionType - The `type` field from a `FunctionExecution`
|
|
437
|
+
* @returns The function registry name, or null when no mapping applies
|
|
438
|
+
*/
|
|
439
|
+
function scriptNameToRegistryName(scriptName, executionType) {
|
|
440
|
+
if (executionType === FunctionExecution_Type.JOB) return `workflow--${scriptName}`;
|
|
441
|
+
const resolverMatch = /^([^.]+)\.(.+)\.body\.js$/.exec(scriptName);
|
|
442
|
+
if (resolverMatch) {
|
|
443
|
+
const [, namespace, name] = resolverMatch;
|
|
444
|
+
return `resolver--${namespace}--${name}`;
|
|
445
|
+
}
|
|
446
|
+
const executorMatch = /^(.+)\.operation\.js$/.exec(scriptName);
|
|
447
|
+
if (executorMatch) {
|
|
448
|
+
const [, name] = executorMatch;
|
|
449
|
+
return `executor--${name}`;
|
|
450
|
+
}
|
|
451
|
+
const authHookMatch = /^([^.]+)\.([^.]+)\.hook\.js$/.exec(scriptName);
|
|
452
|
+
if (authHookMatch) {
|
|
453
|
+
const [, authName, hookPoint] = authHookMatch;
|
|
454
|
+
return `auth-hook--${authName}--${hookPoint}`;
|
|
455
|
+
}
|
|
456
|
+
if (executionType === FunctionExecution_Type.UNSPECIFIED && !scriptName.includes(".")) return `workflow--${scriptName}`;
|
|
457
|
+
return null;
|
|
451
458
|
}
|
|
452
459
|
/**
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
460
|
+
* Download a deployed function script.
|
|
461
|
+
*
|
|
462
|
+
* Returns the bundled script content together with the registry
|
|
463
|
+
* entry's `updatedAt` timestamp. Returns null when the download fails
|
|
464
|
+
* (script removed, network error, etc.) or when no content chunks are
|
|
465
|
+
* received; errors are swallowed so callers can fall back to a
|
|
466
|
+
* non-sourcemap display.
|
|
467
|
+
* @param options - Download options
|
|
468
|
+
* @returns Script content plus metadata, or null on failure / empty response
|
|
469
|
+
*/
|
|
470
|
+
async function downloadFunctionScript(options) {
|
|
471
|
+
const { client, workspaceId, name, contentHash } = options;
|
|
472
|
+
try {
|
|
473
|
+
const chunks = [];
|
|
474
|
+
let registryUpdatedAt = null;
|
|
475
|
+
for await (const response of client.downloadFunctionRegistryScript({
|
|
476
|
+
workspaceId,
|
|
477
|
+
name,
|
|
478
|
+
contentHash
|
|
479
|
+
})) if (response.payload.case === "metadata") {
|
|
480
|
+
const updatedAt = response.payload.value.function?.updatedAt;
|
|
481
|
+
if (updatedAt) registryUpdatedAt = timestampDate(updatedAt);
|
|
482
|
+
} else if (response.payload.case === "chunk") chunks.push(response.payload.value);
|
|
483
|
+
if (chunks.length === 0) return null;
|
|
484
|
+
return {
|
|
485
|
+
code: Buffer.concat(chunks).toString("utf-8"),
|
|
486
|
+
registryUpdatedAt
|
|
487
|
+
};
|
|
488
|
+
} catch (error) {
|
|
489
|
+
logger.debug(`Failed to download function script "${options.name}": ${error}`);
|
|
490
|
+
return null;
|
|
479
491
|
}
|
|
480
492
|
}
|
|
481
|
-
const logsCommand = defineAppCommand({
|
|
482
|
-
name: "logs",
|
|
483
|
-
description: "List or get function execution logs.",
|
|
484
|
-
args: z.object({
|
|
485
|
-
...workspaceArgs,
|
|
486
|
-
executionId: arg(z.string().optional(), {
|
|
487
|
-
positional: true,
|
|
488
|
-
description: "Execution ID (if provided, shows details with logs)"
|
|
489
|
-
})
|
|
490
|
-
}).strict(),
|
|
491
|
-
run: async (args) => {
|
|
492
|
-
const client = await initOperatorClient(await loadAccessToken({
|
|
493
|
-
useProfile: true,
|
|
494
|
-
profile: args.profile
|
|
495
|
-
}));
|
|
496
|
-
const workspaceId = await loadWorkspaceId({
|
|
497
|
-
workspaceId: args["workspace-id"],
|
|
498
|
-
profile: args.profile
|
|
499
|
-
});
|
|
500
|
-
if (args.executionId) {
|
|
501
|
-
const { execution } = await client.getFunctionExecution({
|
|
502
|
-
workspaceId,
|
|
503
|
-
executionId: args.executionId
|
|
504
|
-
});
|
|
505
|
-
if (!execution) throw new Error(`Function execution '${args.executionId}' not found.`);
|
|
506
|
-
const detail = toFunctionExecutionDetailInfo(execution);
|
|
507
|
-
if (args.json) logger.out(detail);
|
|
508
|
-
else printFunctionExecutionDetail(detail);
|
|
509
|
-
} else {
|
|
510
|
-
const logs = (await fetchAll(async (pageToken, maxPageSize) => {
|
|
511
|
-
const { executions, nextPageToken } = await client.listFunctionExecutions({
|
|
512
|
-
workspaceId,
|
|
513
|
-
pageToken,
|
|
514
|
-
pageSize: maxPageSize
|
|
515
|
-
});
|
|
516
|
-
return [executions, nextPageToken];
|
|
517
|
-
})).map(toFunctionExecutionListInfo);
|
|
518
|
-
if (logs.length === 0 && !args.json) {
|
|
519
|
-
logger.info("No function execution logs found.");
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
logger.out(logs);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
493
|
|
|
527
494
|
//#endregion
|
|
528
495
|
//#region src/cli/shared/stack-trace.ts
|
|
@@ -709,7 +676,7 @@ function formatMappedError(errorMessage, frames, traceMap, bundleDir) {
|
|
|
709
676
|
const { source, line, column, name } = frame.mapped;
|
|
710
677
|
const absolutePath = bundleDir ? path.resolve(bundleDir, source) : path.resolve(source);
|
|
711
678
|
const rel = path.relative(process.cwd(), absolutePath);
|
|
712
|
-
const displaySource = rel.startsWith("
|
|
679
|
+
const displaySource = rel.startsWith("..") ? rel : `./${rel}`;
|
|
713
680
|
const fnName = name ?? frame.original.functionName;
|
|
714
681
|
const link = buildSourceLink(displaySource, absolutePath, line, column);
|
|
715
682
|
parts.push(`\n at ${fnName} (${link})`);
|
|
@@ -756,6 +723,248 @@ function formatErrorWithSourcemap(error, bundledCode, bundleDir) {
|
|
|
756
723
|
}
|
|
757
724
|
}
|
|
758
725
|
|
|
726
|
+
//#endregion
|
|
727
|
+
//#region src/cli/commands/function/logs.ts
|
|
728
|
+
/**
|
|
729
|
+
* Convert function execution type enum to string.
|
|
730
|
+
* @param type - Function execution type enum value
|
|
731
|
+
* @returns Type string representation
|
|
732
|
+
*/
|
|
733
|
+
function functionExecutionTypeToString(type) {
|
|
734
|
+
switch (type) {
|
|
735
|
+
case FunctionExecution_Type.STANDARD: return "STANDARD";
|
|
736
|
+
case FunctionExecution_Type.JOB: return "JOB";
|
|
737
|
+
default: return "UNSPECIFIED";
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Transform FunctionExecution to FunctionExecutionListInfo for list display.
|
|
742
|
+
* @param execution - FunctionExecution from proto
|
|
743
|
+
* @returns Function execution list info
|
|
744
|
+
*/
|
|
745
|
+
function toFunctionExecutionListInfo(execution) {
|
|
746
|
+
return {
|
|
747
|
+
id: execution.id,
|
|
748
|
+
scriptName: execution.scriptName,
|
|
749
|
+
status: functionExecutionStatusToString(execution.status),
|
|
750
|
+
type: functionExecutionTypeToString(execution.type),
|
|
751
|
+
startedAt: execution.startedAt ? timestampDate(execution.startedAt) : null,
|
|
752
|
+
finishedAt: execution.finishedAt ? timestampDate(execution.finishedAt) : null
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Transform FunctionExecution to FunctionExecutionDetailInfo for detail display.
|
|
757
|
+
* @param execution - FunctionExecution from proto
|
|
758
|
+
* @returns Function execution detail info
|
|
759
|
+
*/
|
|
760
|
+
function toFunctionExecutionDetailInfo(execution) {
|
|
761
|
+
return {
|
|
762
|
+
...toFunctionExecutionListInfo(execution),
|
|
763
|
+
logs: execution.logs,
|
|
764
|
+
result: execution.result,
|
|
765
|
+
error: execution.error ? {
|
|
766
|
+
name: execution.error.name,
|
|
767
|
+
message: execution.error.message,
|
|
768
|
+
stackTrace: execution.error.stackTrace
|
|
769
|
+
} : null
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Compose a V8-style error string from a FunctionErrorInfo so that it
|
|
774
|
+
* can be parsed by `parseStackTrace`.
|
|
775
|
+
*
|
|
776
|
+
* `Error.prototype.stack` in V8 begins with `Name: message`, but the
|
|
777
|
+
* platform may store only the frame lines; in that case prepend the
|
|
778
|
+
* message line. When `stackTrace` is empty, return only `Name: message`.
|
|
779
|
+
* @param error - Function error info from FunctionExecution
|
|
780
|
+
* @returns Error string suitable for parseStackTrace
|
|
781
|
+
*/
|
|
782
|
+
function composeExecutionErrorString(error) {
|
|
783
|
+
const { name, message, stackTrace } = error;
|
|
784
|
+
if (!stackTrace) return `${name}: ${message}`;
|
|
785
|
+
const firstLine = stackTrace.split("\n", 1)[0] ?? "";
|
|
786
|
+
if (/^\s+at\s+/.test(firstLine)) return `${name}: ${message}\n${stackTrace}`;
|
|
787
|
+
return stackTrace;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Plain-text fallback used when sourcemap mapping is unavailable.
|
|
791
|
+
* Shows `Name: message` then the raw stack trace lines (dimmed).
|
|
792
|
+
*
|
|
793
|
+
* Uses `composeExecutionErrorString` to produce a canonical
|
|
794
|
+
* `Name: message\n<frames>` string first, so the header is never
|
|
795
|
+
* duplicated when `stackTrace` already begins with `Name: message`.
|
|
796
|
+
* @param error - Function error info from FunctionExecution
|
|
797
|
+
* @returns Formatted fallback string for display
|
|
798
|
+
*/
|
|
799
|
+
function formatExecutionErrorFallback(error) {
|
|
800
|
+
const [headerLine, ...frameLines] = composeExecutionErrorString(error).split("\n");
|
|
801
|
+
return [` ${styles.error(headerLine ?? "")}`, ...frameLines.map((line) => ` ${styles.dim(line)}`)].join("\n");
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Format an execution error for display, applying sourcemap mapping
|
|
805
|
+
* when bundled code is available.
|
|
806
|
+
* @param error - Function error info from FunctionExecution
|
|
807
|
+
* @param bundledCode - Downloaded bundled script content (may be null)
|
|
808
|
+
* @returns Formatted error string for display
|
|
809
|
+
*/
|
|
810
|
+
function formatExecutionError(error, bundledCode) {
|
|
811
|
+
if (bundledCode && error.stackTrace) {
|
|
812
|
+
const formatted = formatErrorWithSourcemap(composeExecutionErrorString(error), bundledCode, process.cwd());
|
|
813
|
+
if (formatted) return formatted;
|
|
814
|
+
}
|
|
815
|
+
return formatExecutionErrorFallback(error);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Print function execution detail in a human-readable format.
|
|
819
|
+
* @param options - Print options
|
|
820
|
+
* @param options.detail - Function execution detail info
|
|
821
|
+
* @param options.bundledCode - Downloaded bundled script content (used for sourcemap mapping)
|
|
822
|
+
*/
|
|
823
|
+
function printFunctionExecutionDetail(options) {
|
|
824
|
+
const { detail, bundledCode } = options;
|
|
825
|
+
const formatDate = (date) => date ? date.toISOString() : "N/A";
|
|
826
|
+
const summaryData = [
|
|
827
|
+
["id", detail.id],
|
|
828
|
+
["scriptName", detail.scriptName],
|
|
829
|
+
["status", detail.status],
|
|
830
|
+
["type", detail.type],
|
|
831
|
+
["startedAt", formatDate(detail.startedAt)],
|
|
832
|
+
["finishedAt", formatDate(detail.finishedAt)]
|
|
833
|
+
];
|
|
834
|
+
logger.out(formatKeyValueTable(summaryData));
|
|
835
|
+
if (detail.logs) {
|
|
836
|
+
logger.log(styles.bold("\nLogs:"));
|
|
837
|
+
for (const line of detail.logs.split("\n")) logger.log(` ${line}`);
|
|
838
|
+
}
|
|
839
|
+
if (detail.result) {
|
|
840
|
+
logger.log(styles.bold("\nResult:"));
|
|
841
|
+
try {
|
|
842
|
+
const parsed = JSON.parse(detail.result);
|
|
843
|
+
logger.log(` ${JSON.stringify(parsed, null, 2).split("\n").join("\n ")}`);
|
|
844
|
+
} catch {
|
|
845
|
+
logger.log(` ${detail.result}`);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
if (detail.error) {
|
|
849
|
+
logger.log(styles.bold("\nError:"));
|
|
850
|
+
logger.log(formatExecutionError(detail.error, bundledCode ?? null));
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Download a deployed function script for sourcemap mapping. Logs a
|
|
855
|
+
* debug message on failure but never throws. Error display falls back
|
|
856
|
+
* to a plain-text format when the script cannot be retrieved or when
|
|
857
|
+
* the current registry entry is stale relative to the execution.
|
|
858
|
+
*
|
|
859
|
+
* `FunctionExecution.scriptName` does not match the function registry
|
|
860
|
+
* name directly; `scriptNameToRegistryName` translates between the two
|
|
861
|
+
* formats.
|
|
862
|
+
* @param options - Lookup options
|
|
863
|
+
* @param options.client - Operator client instance
|
|
864
|
+
* @param options.workspaceId - Workspace ID
|
|
865
|
+
* @param options.scriptName - Script name (matches FunctionExecution.scriptName)
|
|
866
|
+
* @param options.executionType - Execution type used to discriminate registry name translation
|
|
867
|
+
* @param options.executionStartedAt - Execution start timestamp used for staleness check
|
|
868
|
+
* @returns Bundled script content, or null when unavailable / stale
|
|
869
|
+
*/
|
|
870
|
+
async function downloadScriptForMapping(options) {
|
|
871
|
+
const { client, workspaceId, scriptName, executionType, executionStartedAt } = options;
|
|
872
|
+
const registryName = scriptNameToRegistryName(scriptName, executionType);
|
|
873
|
+
if (registryName == null) {
|
|
874
|
+
logger.debug(`Script "${scriptName}" is not a deployed registry script (e.g. test-run or seed); skipping sourcemap mapping.`);
|
|
875
|
+
return null;
|
|
876
|
+
}
|
|
877
|
+
const result = await downloadFunctionScript({
|
|
878
|
+
client,
|
|
879
|
+
workspaceId,
|
|
880
|
+
name: registryName
|
|
881
|
+
});
|
|
882
|
+
if (result == null) {
|
|
883
|
+
logger.debug(`Could not download script "${scriptName}" (registry: "${registryName}") for stack trace mapping; showing raw stack trace.`);
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
if (executionStartedAt != null && result.registryUpdatedAt != null && result.registryUpdatedAt.getTime() > executionStartedAt.getTime()) {
|
|
887
|
+
logger.debug(`Registry script "${registryName}" was updated at ${result.registryUpdatedAt.toISOString()} after execution started at ${executionStartedAt.toISOString()}; skipping sourcemap mapping to avoid stale source locations.`);
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
return result.code;
|
|
891
|
+
}
|
|
892
|
+
const logsCommand = defineAppCommand({
|
|
893
|
+
name: "logs",
|
|
894
|
+
description: "List or get function execution logs.",
|
|
895
|
+
notes: `When viewing a specific execution that failed, the command displays error details with the stack trace mapped back to original source files via the inline sourcemap (clickable file links and code snippets, matching \`function test-run\` output).
|
|
896
|
+
|
|
897
|
+
When the deployed script cannot be downloaded or the function has been redeployed since the execution, the command falls back to a plain-text error display to avoid showing misleading source locations.`,
|
|
898
|
+
examples: [
|
|
899
|
+
{
|
|
900
|
+
cmd: "",
|
|
901
|
+
desc: "List all function execution logs"
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
cmd: "<execution-id>",
|
|
905
|
+
desc: "Get execution details with logs"
|
|
906
|
+
},
|
|
907
|
+
{
|
|
908
|
+
cmd: "--json",
|
|
909
|
+
desc: "Output as JSON"
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
cmd: "<execution-id> --json",
|
|
913
|
+
desc: "Get execution details as JSON"
|
|
914
|
+
}
|
|
915
|
+
],
|
|
916
|
+
args: z.object({
|
|
917
|
+
...workspaceArgs,
|
|
918
|
+
executionId: arg(z.string().optional(), {
|
|
919
|
+
positional: true,
|
|
920
|
+
description: "Execution ID (if provided, shows details with logs)"
|
|
921
|
+
})
|
|
922
|
+
}).strict(),
|
|
923
|
+
run: async (args) => {
|
|
924
|
+
const client = await initOperatorClient(await loadAccessToken({
|
|
925
|
+
useProfile: true,
|
|
926
|
+
profile: args.profile
|
|
927
|
+
}));
|
|
928
|
+
const workspaceId = await loadWorkspaceId({
|
|
929
|
+
workspaceId: args["workspace-id"],
|
|
930
|
+
profile: args.profile
|
|
931
|
+
});
|
|
932
|
+
if (args.executionId) {
|
|
933
|
+
const { execution } = await client.getFunctionExecution({
|
|
934
|
+
workspaceId,
|
|
935
|
+
executionId: args.executionId
|
|
936
|
+
});
|
|
937
|
+
if (!execution) throw new Error(`Function execution '${args.executionId}' not found.`);
|
|
938
|
+
const detail = toFunctionExecutionDetailInfo(execution);
|
|
939
|
+
if (args.json) logger.out(detail);
|
|
940
|
+
else printFunctionExecutionDetail({
|
|
941
|
+
detail,
|
|
942
|
+
bundledCode: detail.error ? await downloadScriptForMapping({
|
|
943
|
+
client,
|
|
944
|
+
workspaceId,
|
|
945
|
+
scriptName: detail.scriptName,
|
|
946
|
+
executionType: execution.type,
|
|
947
|
+
executionStartedAt: detail.startedAt
|
|
948
|
+
}) : null
|
|
949
|
+
});
|
|
950
|
+
} else {
|
|
951
|
+
const logs = (await fetchAll(async (pageToken, maxPageSize) => {
|
|
952
|
+
const { executions, nextPageToken } = await client.listFunctionExecutions({
|
|
953
|
+
workspaceId,
|
|
954
|
+
pageToken,
|
|
955
|
+
pageSize: maxPageSize
|
|
956
|
+
});
|
|
957
|
+
return [executions, nextPageToken];
|
|
958
|
+
})).map(toFunctionExecutionListInfo);
|
|
959
|
+
if (logs.length === 0 && !args.json) {
|
|
960
|
+
logger.info("No function execution logs found.");
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
logger.out(logs);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
|
|
759
968
|
//#endregion
|
|
760
969
|
//#region src/cli/commands/function/bundle.ts
|
|
761
970
|
/**
|
|
@@ -794,7 +1003,8 @@ async function bundleForTestRun(options) {
|
|
|
794
1003
|
format: "esm",
|
|
795
1004
|
sourcemap: inlineSourcemap ? "inline" : true,
|
|
796
1005
|
minify: inlineSourcemap ? { mangle: { keepNames: true } } : true,
|
|
797
|
-
codeSplitting: false
|
|
1006
|
+
codeSplitting: false,
|
|
1007
|
+
dir: process.cwd()
|
|
798
1008
|
},
|
|
799
1009
|
tsconfig,
|
|
800
1010
|
treeshake: {
|
|
@@ -1052,7 +1262,8 @@ const testRunCommand = defineAppCommand({
|
|
|
1052
1262
|
}),
|
|
1053
1263
|
"machine-user": arg(z.string().optional(), {
|
|
1054
1264
|
alias: "m",
|
|
1055
|
-
description: "Machine user name for authentication"
|
|
1265
|
+
description: "Machine user name for authentication",
|
|
1266
|
+
env: "TAILOR_PLATFORM_MACHINE_USER_NAME"
|
|
1056
1267
|
}),
|
|
1057
1268
|
config: arg(z.string().default("tailor.config.ts"), {
|
|
1058
1269
|
alias: "c",
|
|
@@ -1446,7 +1657,8 @@ const loginCommand = defineAppCommand({
|
|
|
1446
1657
|
name: "login",
|
|
1447
1658
|
description: "Login to Tailor Platform.",
|
|
1448
1659
|
args: z.xor([z.object({}).strict().describe("User Login"), z.object({
|
|
1449
|
-
|
|
1660
|
+
"machine-user": arg(z.literal(true), {
|
|
1661
|
+
hiddenAlias: "machineuser",
|
|
1450
1662
|
description: "Login as a platform machine user.",
|
|
1451
1663
|
required: true
|
|
1452
1664
|
}),
|
|
@@ -1461,7 +1673,7 @@ const loginCommand = defineAppCommand({
|
|
|
1461
1673
|
})
|
|
1462
1674
|
}).strict().describe("Machine User Login")]),
|
|
1463
1675
|
run: async (args) => {
|
|
1464
|
-
if ("
|
|
1676
|
+
if ("machine-user" in args && args["machine-user"]) await loginAsMachineUser({
|
|
1465
1677
|
clientId: args.clientId,
|
|
1466
1678
|
clientSecret: args.clientSecret
|
|
1467
1679
|
});
|
|
@@ -3371,6 +3583,34 @@ const tailordbCommand = defineCommand({
|
|
|
3371
3583
|
}
|
|
3372
3584
|
});
|
|
3373
3585
|
|
|
3586
|
+
//#endregion
|
|
3587
|
+
//#region src/cli/commands/upgrade/index.ts
|
|
3588
|
+
const upgradeCommand = defineAppCommand({
|
|
3589
|
+
name: "upgrade",
|
|
3590
|
+
description: "Run codemods to upgrade your project to a newer SDK version.",
|
|
3591
|
+
args: z.object({
|
|
3592
|
+
from: arg(z.string(), { description: "SDK version before the upgrade (e.g., 1.33.0)" }),
|
|
3593
|
+
"dry-run": arg(z.boolean().default(false), {
|
|
3594
|
+
alias: "d",
|
|
3595
|
+
description: "Preview changes without modifying files"
|
|
3596
|
+
}),
|
|
3597
|
+
path: arg(z.string().default("."), {
|
|
3598
|
+
description: "Project directory to upgrade",
|
|
3599
|
+
completion: { type: "directory" }
|
|
3600
|
+
})
|
|
3601
|
+
}).strict(),
|
|
3602
|
+
run: async (args) => {
|
|
3603
|
+
const { initTelemetry } = await import("../telemetry-4IOPW6wE.mjs");
|
|
3604
|
+
await initTelemetry();
|
|
3605
|
+
const { upgrade } = await import("../service-Bcp6JB3w.mjs");
|
|
3606
|
+
await upgrade({
|
|
3607
|
+
from: args.from,
|
|
3608
|
+
dryRun: args["dry-run"],
|
|
3609
|
+
path: path.resolve(args.path)
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
});
|
|
3613
|
+
|
|
3374
3614
|
//#endregion
|
|
3375
3615
|
//#region src/cli/commands/user/current.ts
|
|
3376
3616
|
const currentCommand = defineAppCommand({
|
|
@@ -3755,6 +3995,7 @@ const mainCommand = withCompletionCommand(defineCommand({
|
|
|
3755
3995
|
show: showCommand,
|
|
3756
3996
|
staticwebsite: staticwebsiteCommand,
|
|
3757
3997
|
tailordb: tailordbCommand,
|
|
3998
|
+
upgrade: upgradeCommand,
|
|
3758
3999
|
user: userCommand$1,
|
|
3759
4000
|
workflow: workflowCommand,
|
|
3760
4001
|
workspace: workspaceCommand
|
|
@@ -3774,7 +4015,7 @@ runMain(mainCommand, {
|
|
|
3774
4015
|
if (isVerbose() && error.stack) logger.debug(`\nStack trace:\n${error.stack}`);
|
|
3775
4016
|
} else logger.error(`Unknown error: ${error}`);
|
|
3776
4017
|
if (!isCLIError(error) && (!(error instanceof Error) || error instanceof TypeError || error instanceof RangeError)) {
|
|
3777
|
-
const { reportCrash } = await import("../crash-report-
|
|
4018
|
+
const { reportCrash } = await import("../crash-report-BEAiCSCl.mjs");
|
|
3778
4019
|
await reportCrash(error, "handledError");
|
|
3779
4020
|
}
|
|
3780
4021
|
}
|