primitive-admin 1.1.0-alpha.4 → 1.1.0-alpha.40
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/README.md +325 -31
- package/assets/skill/skills/primitive-platform/SKILL.md +281 -0
- package/dist/bin/primitive.d.ts +2 -0
- package/dist/bin/primitive.js +266 -16
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.d.ts +2 -0
- package/dist/src/commands/admins.js +123 -18
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.d.ts +2 -0
- package/dist/src/commands/analytics.js +464 -55
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.d.ts +2 -0
- package/dist/src/commands/apps.js +55 -13
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +177 -7
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/blob-buckets.d.ts +2 -0
- package/dist/src/commands/blob-buckets.js +422 -0
- package/dist/src/commands/blob-buckets.js.map +1 -0
- package/dist/src/commands/catalog.d.ts +2 -0
- package/dist/src/commands/catalog.js +34 -35
- package/dist/src/commands/catalog.js.map +1 -1
- package/dist/src/commands/collection-type-configs.d.ts +2 -0
- package/dist/src/commands/collection-type-configs.js +178 -0
- package/dist/src/commands/collection-type-configs.js.map +1 -0
- package/dist/src/commands/collections.d.ts +2 -0
- package/dist/src/commands/collections.js +515 -0
- package/dist/src/commands/collections.js.map +1 -0
- package/dist/src/commands/comparisons.d.ts +2 -0
- package/dist/src/commands/comparisons.js +6 -6
- package/dist/src/commands/comparisons.js.map +1 -1
- package/dist/src/commands/cron-triggers.d.ts +2 -0
- package/dist/src/commands/cron-triggers.js +357 -0
- package/dist/src/commands/cron-triggers.js.map +1 -0
- package/dist/src/commands/database-types.d.ts +2 -0
- package/dist/src/commands/database-types.js +471 -0
- package/dist/src/commands/database-types.js.map +1 -0
- package/dist/src/commands/databases.d.ts +2 -0
- package/dist/src/commands/databases.js +1462 -83
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +2 -0
- package/dist/src/commands/documents.js +518 -11
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.d.ts +2 -0
- package/dist/src/commands/email-templates.js +281 -0
- package/dist/src/commands/email-templates.js.map +1 -0
- package/dist/src/commands/env.d.ts +12 -0
- package/dist/src/commands/env.js +260 -0
- package/dist/src/commands/env.js.map +1 -0
- package/dist/src/commands/group-type-configs.d.ts +2 -0
- package/dist/src/commands/group-type-configs.js +181 -0
- package/dist/src/commands/group-type-configs.js.map +1 -0
- package/dist/src/commands/groups.d.ts +2 -0
- package/dist/src/commands/groups.js +45 -43
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/guides.d.ts +159 -0
- package/dist/src/commands/guides.js +449 -35
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.d.ts +17 -0
- package/dist/src/commands/init.js +811 -201
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.d.ts +2 -0
- package/dist/src/commands/integrations.js +533 -46
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/llm.d.ts +2 -0
- package/dist/src/commands/llm.js +4 -2
- package/dist/src/commands/llm.js.map +1 -1
- package/dist/src/commands/prompts.d.ts +2 -0
- package/dist/src/commands/prompts.js +50 -52
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +3 -0
- package/dist/src/commands/rule-sets.js +388 -0
- package/dist/src/commands/rule-sets.js.map +1 -0
- package/dist/src/commands/scripts.d.ts +2 -0
- package/dist/src/commands/scripts.js +667 -0
- package/dist/src/commands/scripts.js.map +1 -0
- package/dist/src/commands/secrets.d.ts +2 -0
- package/dist/src/commands/secrets.js +108 -0
- package/dist/src/commands/secrets.js.map +1 -0
- package/dist/src/commands/skill.d.ts +2 -0
- package/dist/src/commands/skill.js +29 -0
- package/dist/src/commands/skill.js.map +1 -0
- package/dist/src/commands/sync.d.ts +174 -0
- package/dist/src/commands/sync.js +4392 -235
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.d.ts +2 -0
- package/dist/src/commands/tokens.js +122 -19
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.d.ts +2 -0
- package/dist/src/commands/users.js +440 -22
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/waitlist.d.ts +2 -0
- package/dist/src/commands/waitlist.js +10 -10
- package/dist/src/commands/waitlist.js.map +1 -1
- package/dist/src/commands/webhooks.d.ts +2 -0
- package/dist/src/commands/webhooks.js +391 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/commands/workflows.d.ts +49 -0
- package/dist/src/commands/workflows.js +1009 -123
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +1272 -0
- package/dist/src/lib/api-client.js +1115 -83
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/auth-flow.d.ts +8 -0
- package/dist/src/lib/block-layout.d.ts +160 -0
- package/dist/src/lib/block-layout.js +451 -0
- package/dist/src/lib/block-layout.js.map +1 -0
- package/dist/src/lib/cli-manifest.d.ts +60 -0
- package/dist/src/lib/cli-manifest.js +70 -0
- package/dist/src/lib/cli-manifest.js.map +1 -0
- package/dist/src/lib/config.d.ts +53 -0
- package/dist/src/lib/config.js +92 -53
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/confirm-prompt.d.ts +83 -0
- package/dist/src/lib/confirm-prompt.js +110 -0
- package/dist/src/lib/confirm-prompt.js.map +1 -0
- package/dist/src/lib/constants.d.ts +2 -0
- package/dist/src/lib/constants.js +3 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/crash-handlers.d.ts +20 -0
- package/dist/src/lib/crash-handlers.js +49 -0
- package/dist/src/lib/crash-handlers.js.map +1 -0
- package/dist/src/lib/credentials-store.d.ts +79 -0
- package/dist/src/lib/credentials-store.js +307 -0
- package/dist/src/lib/credentials-store.js.map +1 -0
- package/dist/src/lib/csv.d.ts +48 -0
- package/dist/src/lib/csv.js +177 -0
- package/dist/src/lib/csv.js.map +1 -0
- package/dist/src/lib/db-codegen/dbFingerprint.d.ts +10 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js +17 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js.map +1 -0
- package/dist/src/lib/db-codegen/dbGenerator.d.ts +111 -0
- package/dist/src/lib/db-codegen/dbGenerator.js +371 -0
- package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/db-codegen/dbNaming.d.ts +45 -0
- package/dist/src/lib/db-codegen/dbNaming.js +104 -0
- package/dist/src/lib/db-codegen/dbNaming.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTemplates.d.ts +97 -0
- package/dist/src/lib/db-codegen/dbTemplates.js +159 -0
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTsTypes.d.ts +78 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js +112 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +62 -0
- package/dist/src/lib/env-resolver.js +121 -0
- package/dist/src/lib/env-resolver.js.map +1 -0
- package/dist/src/lib/fetch.d.ts +5 -0
- package/dist/src/lib/generated-allowlist.d.ts +28 -0
- package/dist/src/lib/generated-allowlist.js +213 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -0
- package/dist/src/lib/init-config.d.ts +59 -0
- package/dist/src/lib/init-config.js +113 -0
- package/dist/src/lib/init-config.js.map +1 -0
- package/dist/src/lib/migration-nag.d.ts +49 -0
- package/dist/src/lib/migration-nag.js +163 -0
- package/dist/src/lib/migration-nag.js.map +1 -0
- package/dist/src/lib/output.d.ts +86 -0
- package/dist/src/lib/output.js +150 -8
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/paginate.d.ts +33 -0
- package/dist/src/lib/paginate.js +42 -0
- package/dist/src/lib/paginate.js.map +1 -0
- package/dist/src/lib/project-config.d.ts +97 -0
- package/dist/src/lib/project-config.js +209 -0
- package/dist/src/lib/project-config.js.map +1 -0
- package/dist/src/lib/query-operators.d.ts +43 -0
- package/dist/src/lib/query-operators.js +80 -0
- package/dist/src/lib/query-operators.js.map +1 -0
- package/dist/src/lib/refresh-admin-credentials.d.ts +65 -0
- package/dist/src/lib/refresh-admin-credentials.js +103 -0
- package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
- package/dist/src/lib/resolve-platform.d.ts +45 -0
- package/dist/src/lib/resolve-platform.js +43 -0
- package/dist/src/lib/resolve-platform.js.map +1 -0
- package/dist/src/lib/skill-installer.d.ts +23 -0
- package/dist/src/lib/skill-installer.js +135 -0
- package/dist/src/lib/skill-installer.js.map +1 -0
- package/dist/src/lib/snapshots.d.ts +99 -0
- package/dist/src/lib/snapshots.js +357 -0
- package/dist/src/lib/snapshots.js.map +1 -0
- package/dist/src/lib/sync-paths.d.ts +72 -0
- package/dist/src/lib/sync-paths.js +130 -0
- package/dist/src/lib/sync-paths.js.map +1 -0
- package/dist/src/lib/template.d.ts +97 -0
- package/dist/src/lib/template.js +336 -62
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/token-inject.d.ts +56 -0
- package/dist/src/lib/token-inject.js +204 -0
- package/dist/src/lib/token-inject.js.map +1 -0
- package/dist/src/lib/toml-database-config.d.ts +152 -0
- package/dist/src/lib/toml-database-config.js +600 -0
- package/dist/src/lib/toml-database-config.js.map +1 -0
- package/dist/src/lib/toml-metadata-config.d.ts +108 -0
- package/dist/src/lib/toml-metadata-config.js +371 -0
- package/dist/src/lib/toml-metadata-config.js.map +1 -0
- package/dist/src/lib/toml-params-validator.d.ts +129 -0
- package/dist/src/lib/toml-params-validator.js +298 -0
- package/dist/src/lib/toml-params-validator.js.map +1 -0
- package/dist/src/lib/version-check.d.ts +10 -0
- package/dist/src/lib/version-check.js +172 -0
- package/dist/src/lib/version-check.js.map +1 -0
- package/dist/src/lib/workflow-apply.d.ts +66 -0
- package/dist/src/lib/workflow-apply.js +117 -0
- package/dist/src/lib/workflow-apply.js.map +1 -0
- package/dist/src/lib/workflow-fragments.d.ts +41 -0
- package/dist/src/lib/workflow-fragments.js +121 -0
- package/dist/src/lib/workflow-fragments.js.map +1 -0
- package/dist/src/lib/workflow-toml-validator.d.ts +95 -0
- package/dist/src/lib/workflow-toml-validator.js +323 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -0
- package/dist/src/types/index.d.ts +520 -0
- package/dist/src/validators.d.ts +64 -0
- package/dist/src/validators.js +63 -0
- package/dist/src/validators.js.map +1 -0
- package/package.json +18 -4
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export interface TableColumn {
|
|
2
|
+
header: string;
|
|
3
|
+
key: string;
|
|
4
|
+
width?: number;
|
|
5
|
+
/**
|
|
6
|
+
* Opt-in flexible sizing (#1065). When `true`, the column is sized from the
|
|
7
|
+
* remaining terminal width (`options.maxWidth ?? process.stdout.columns`)
|
|
8
|
+
* minus the sibling columns' widths and the inter-column padding, so the
|
|
9
|
+
* table shows as much of this column as fits **without wrapping**. Clamped to
|
|
10
|
+
* `[max(flexFloor, header length), flexMax]`. On a non-TTY (`maxWidth`
|
|
11
|
+
* undefined — piped/redirected) there is no width to wrap against, so the
|
|
12
|
+
* column is sized to `flexMax` (or its content width when `flexMax` is
|
|
13
|
+
* unset). Reading the terminal width is gated to flex columns: tables with no
|
|
14
|
+
* flex column never consult `process.stdout.columns` and stay byte-for-byte
|
|
15
|
+
* (and TTY-) unchanged.
|
|
16
|
+
*/
|
|
17
|
+
flex?: boolean;
|
|
18
|
+
/** Minimum width for a `flex` column. Default 0 (header length is always honored). */
|
|
19
|
+
flexFloor?: number;
|
|
20
|
+
/** Maximum width for a `flex` column. Default unbounded. */
|
|
21
|
+
flexMax?: number;
|
|
22
|
+
align?: "left" | "right" | "center";
|
|
23
|
+
format?: (value: any) => string;
|
|
24
|
+
/**
|
|
25
|
+
* Opt-in truncation. When `true` (and the column has a resolved width — a
|
|
26
|
+
* fixed `width` or a computed `flex` width), cell values longer than that
|
|
27
|
+
* width are ellipsized to fit the column so downstream columns stay aligned.
|
|
28
|
+
* Defaults to `false` so existing tables keep their current non-truncating
|
|
29
|
+
* behavior — only columns that explicitly opt in are clipped.
|
|
30
|
+
*/
|
|
31
|
+
truncate?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function formatTable(data: Record<string, any>[], columns: TableColumn[], options?: {
|
|
34
|
+
maxWidth?: number;
|
|
35
|
+
}): string;
|
|
36
|
+
export declare function success(message: string): void;
|
|
37
|
+
export declare function error(message: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Render an API error (or any Error) with its message plus the server's
|
|
40
|
+
* structured `details` payload, if present. Shared by `sync push`,
|
|
41
|
+
* `workflows create`/`update`, and any command that surfaces server-side
|
|
42
|
+
* validation failures (#1173).
|
|
43
|
+
*
|
|
44
|
+
* The server's error envelope can emit `details` as either:
|
|
45
|
+
* - an **array** of validation-issue strings/objects (e.g. the workflow
|
|
46
|
+
* identity validator's per-step reasons), or
|
|
47
|
+
* - an **object** (#666 schema gate — `{ code, ... }`).
|
|
48
|
+
*
|
|
49
|
+
* Both shapes are rendered without throwing; an absent/empty `details` prints
|
|
50
|
+
* just the message. Duck-typed (reads `.message`/`.details`) so it works on
|
|
51
|
+
* any `ApiError` instance without importing the class — keeping `output.ts`
|
|
52
|
+
* dependency-free.
|
|
53
|
+
*/
|
|
54
|
+
export declare function printApiError(err: unknown): void;
|
|
55
|
+
export declare function warn(message: string): void;
|
|
56
|
+
export declare function info(message: string): void;
|
|
57
|
+
export declare function dim(message: string): void;
|
|
58
|
+
export declare function heading(message: string): void;
|
|
59
|
+
export declare function json(data: any): void;
|
|
60
|
+
export declare function formatDate(date: string | Date | null | undefined): string;
|
|
61
|
+
export declare function formatStatus(status: string | undefined | null): string;
|
|
62
|
+
export declare function formatId(id: string): string;
|
|
63
|
+
export declare function formatBoolean(value: boolean | undefined | null): string;
|
|
64
|
+
export declare function formatNumber(value: number | undefined | null): string;
|
|
65
|
+
export declare function formatDuration(ms: number | undefined | null): string;
|
|
66
|
+
export declare function formatPercent(value: number | undefined | null): string;
|
|
67
|
+
export declare function keyValue(label: string, value: string | number | boolean | null | undefined): void;
|
|
68
|
+
/**
|
|
69
|
+
* Print a `label: value` line on **stdout** as part of a command's primary
|
|
70
|
+
* data output (e.g., `primitive integrations get <id>`,
|
|
71
|
+
* `primitive workflows get <id>`). Same visual rendering as `keyValue()`,
|
|
72
|
+
* but on the data stream so the value survives `> out.txt` redirection.
|
|
73
|
+
*
|
|
74
|
+
* Use `keyValue()` (stderr) for post-action diagnostic summaries; use
|
|
75
|
+
* `result()` (stdout) for fields the caller specifically requested.
|
|
76
|
+
*/
|
|
77
|
+
export declare function result(label: string, value: string | number | boolean | null | undefined): void;
|
|
78
|
+
export declare function divider(): void;
|
|
79
|
+
/**
|
|
80
|
+
* In-place progress indicator for long-running commands (e.g. polling a
|
|
81
|
+
* batch run). Writes to stderr so it can't corrupt JSON on stdout under
|
|
82
|
+
* `--json`. Callers should follow the final progress line with `progressEnd()`
|
|
83
|
+
* to print a trailing newline.
|
|
84
|
+
*/
|
|
85
|
+
export declare function progress(message: string): void;
|
|
86
|
+
export declare function progressEnd(): void;
|
package/dist/src/lib/output.js
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Ellipsize `str` (its visible, ANSI-stripped length) to at most `width`
|
|
4
|
+
* characters. Strings already within `width` are returned unchanged. Very
|
|
5
|
+
* narrow widths still keep a sensible result: width 1-3 returns leading dots.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: assumes the value carries no ANSI styling (the only opt-in caller —
|
|
8
|
+
* the guides DESCRIPTION column — passes plain strings). Truncating mid-escape
|
|
9
|
+
* would corrupt styling, so truncation is opt-in per column rather than global.
|
|
10
|
+
*/
|
|
11
|
+
function truncateToWidth(str, width) {
|
|
12
|
+
const stripped = stripAnsi(str);
|
|
13
|
+
if (stripped.length <= width)
|
|
14
|
+
return str;
|
|
15
|
+
if (width <= 0)
|
|
16
|
+
return "";
|
|
17
|
+
if (width <= 3)
|
|
18
|
+
return ".".repeat(width);
|
|
19
|
+
return stripped.slice(0, width - 1) + "…";
|
|
20
|
+
}
|
|
21
|
+
export function formatTable(data, columns, options) {
|
|
3
22
|
if (data.length === 0) {
|
|
4
23
|
return chalk.dim("No results found.");
|
|
5
24
|
}
|
|
@@ -12,6 +31,33 @@ export function formatTable(data, columns) {
|
|
|
12
31
|
}));
|
|
13
32
|
return col.width ?? Math.max(headerWidth, maxDataWidth);
|
|
14
33
|
});
|
|
34
|
+
// Flex pass (#1065): size the first column marked `flex` from the remaining
|
|
35
|
+
// terminal width so the table shows as much as fits without ever wrapping.
|
|
36
|
+
// The sibling widths above are already content-derived, so subtracting their
|
|
37
|
+
// ACTUAL widths plus the exact `2 * (N - 1)` inter-column padding makes the
|
|
38
|
+
// no-wrap guarantee structural rather than maintained by hand. Gated to flex
|
|
39
|
+
// columns so non-flex tables never read `process.stdout.columns`.
|
|
40
|
+
const flexIndex = columns.findIndex((col) => col.flex);
|
|
41
|
+
if (flexIndex !== -1) {
|
|
42
|
+
const col = columns[flexIndex];
|
|
43
|
+
const floor = Math.max(col.flexFloor ?? 0, col.header.length);
|
|
44
|
+
const cap = col.flexMax ?? Infinity;
|
|
45
|
+
const maxWidth = options?.maxWidth ?? process.stdout.columns;
|
|
46
|
+
if (typeof maxWidth === "number") {
|
|
47
|
+
const siblingWidth = widths.reduce((sum, w, i) => (i === flexIndex ? sum : sum + w), 0);
|
|
48
|
+
const padding = 2 * (columns.length - 1);
|
|
49
|
+
const avail = maxWidth - siblingWidth - padding;
|
|
50
|
+
// Clamp to [floor, cap]; never below the floor (so the header/min content
|
|
51
|
+
// stays readable) and never negative.
|
|
52
|
+
widths[flexIndex] = Math.min(cap, Math.max(floor, avail));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Non-TTY (piped/redirected): no terminal width to wrap against. Show as
|
|
56
|
+
// much as the cap allows — full content up to the contract max — falling
|
|
57
|
+
// back to the content-derived width when no cap is set.
|
|
58
|
+
widths[flexIndex] = cap === Infinity ? widths[flexIndex] : cap;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
15
61
|
// Format header
|
|
16
62
|
const header = columns
|
|
17
63
|
.map((col, i) => {
|
|
@@ -24,7 +70,13 @@ export function formatTable(data, columns) {
|
|
|
24
70
|
// Format rows
|
|
25
71
|
const rows = data.map((row) => columns
|
|
26
72
|
.map((col, i) => {
|
|
27
|
-
|
|
73
|
+
let value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? "");
|
|
74
|
+
// Opt-in: clip over-long cells to the column's resolved width (a fixed
|
|
75
|
+
// `width` or a computed `flex` width) so the columns that follow stay
|
|
76
|
+
// aligned (e.g. guides DESCRIPTION before LANGUAGES).
|
|
77
|
+
if (col.truncate && (col.width !== undefined || col.flex)) {
|
|
78
|
+
value = truncateToWidth(value, widths[i]);
|
|
79
|
+
}
|
|
28
80
|
return padString(value, widths[i], col.align ?? "left");
|
|
29
81
|
})
|
|
30
82
|
.join(" "));
|
|
@@ -47,23 +99,84 @@ function stripAnsi(str) {
|
|
|
47
99
|
// Simple ANSI escape code stripper
|
|
48
100
|
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
49
101
|
}
|
|
102
|
+
// Stream-routing convention (see issue #695):
|
|
103
|
+
// - data → stdout (`json`, `result`, plus the formatter helpers below
|
|
104
|
+
// that just return strings for callers to print themselves).
|
|
105
|
+
// - diagnostics → stderr (`success`, `warn`, `info`, `dim`, `heading`,
|
|
106
|
+
// `keyValue`, `divider`, `error`).
|
|
107
|
+
//
|
|
108
|
+
// This mirrors `git`/`kubectl`/`aws`/`gh` so that any command with a `--json`
|
|
109
|
+
// flag emits a single parseable JSON document on stdout, regardless of
|
|
110
|
+
// status, warning, or progress text the same command may print. Callers
|
|
111
|
+
// running interactively still see diagnostics by default because terminals
|
|
112
|
+
// display stderr; users redirecting `2>/dev/null` get a quiet pipe; users
|
|
113
|
+
// running `2>&1` get everything mixed.
|
|
114
|
+
//
|
|
115
|
+
// `result()` vs. `keyValue()` (data vs. diagnostic split):
|
|
116
|
+
// `keyValue()` is a *diagnostic* helper — use it for the `key: value`
|
|
117
|
+
// summary lines printed *after* a side-effecting command like `apps create`,
|
|
118
|
+
// `workflows update`, or `secrets set` (those summaries are nice context but
|
|
119
|
+
// are not what the caller asked the command to produce). `result()` is the
|
|
120
|
+
// *data* counterpart — use it for the primary fields a `get` / `show` /
|
|
121
|
+
// `describe` command emits, where the caller ran the command specifically
|
|
122
|
+
// to read those fields. Keeping the two on different streams means
|
|
123
|
+
// `primitive integrations get foo > out.txt` produces a non-empty `out.txt`
|
|
124
|
+
// even though the same command's status diagnostics still go to stderr.
|
|
50
125
|
export function success(message) {
|
|
51
|
-
console.
|
|
126
|
+
console.error(chalk.green("✓") + " " + message);
|
|
52
127
|
}
|
|
53
128
|
export function error(message) {
|
|
54
129
|
console.error(chalk.red("✗") + " " + message);
|
|
55
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Render an API error (or any Error) with its message plus the server's
|
|
133
|
+
* structured `details` payload, if present. Shared by `sync push`,
|
|
134
|
+
* `workflows create`/`update`, and any command that surfaces server-side
|
|
135
|
+
* validation failures (#1173).
|
|
136
|
+
*
|
|
137
|
+
* The server's error envelope can emit `details` as either:
|
|
138
|
+
* - an **array** of validation-issue strings/objects (e.g. the workflow
|
|
139
|
+
* identity validator's per-step reasons), or
|
|
140
|
+
* - an **object** (#666 schema gate — `{ code, ... }`).
|
|
141
|
+
*
|
|
142
|
+
* Both shapes are rendered without throwing; an absent/empty `details` prints
|
|
143
|
+
* just the message. Duck-typed (reads `.message`/`.details`) so it works on
|
|
144
|
+
* any `ApiError` instance without importing the class — keeping `output.ts`
|
|
145
|
+
* dependency-free.
|
|
146
|
+
*/
|
|
147
|
+
export function printApiError(err) {
|
|
148
|
+
const e = err;
|
|
149
|
+
const message = typeof e?.message === "string" && e.message.length > 0
|
|
150
|
+
? e.message
|
|
151
|
+
: String(err);
|
|
152
|
+
error(message);
|
|
153
|
+
const details = e?.details;
|
|
154
|
+
if (Array.isArray(details)) {
|
|
155
|
+
for (const detail of details) {
|
|
156
|
+
console.error(` - ${typeof detail === "string" ? detail : JSON.stringify(detail)}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else if (details && typeof details === "object") {
|
|
160
|
+
// Object form (#666 schema gate): render each key so the reason isn't
|
|
161
|
+
// hidden. Skip the redundant `code` (already implied by the message).
|
|
162
|
+
for (const [key, value] of Object.entries(details)) {
|
|
163
|
+
if (key === "code")
|
|
164
|
+
continue;
|
|
165
|
+
console.error(` ${key}: ${typeof value === "string" ? value : JSON.stringify(value)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
56
169
|
export function warn(message) {
|
|
57
|
-
console.
|
|
170
|
+
console.error(chalk.yellow("!") + " " + message);
|
|
58
171
|
}
|
|
59
172
|
export function info(message) {
|
|
60
|
-
console.
|
|
173
|
+
console.error(chalk.blue("i") + " " + message);
|
|
61
174
|
}
|
|
62
175
|
export function dim(message) {
|
|
63
|
-
console.
|
|
176
|
+
console.error(chalk.dim(message));
|
|
64
177
|
}
|
|
65
178
|
export function heading(message) {
|
|
66
|
-
console.
|
|
179
|
+
console.error(chalk.bold.underline(message));
|
|
67
180
|
}
|
|
68
181
|
export function json(data) {
|
|
69
182
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -130,6 +243,23 @@ export function formatPercent(value) {
|
|
|
130
243
|
return `${(value * 100).toFixed(1)}%`;
|
|
131
244
|
}
|
|
132
245
|
export function keyValue(label, value) {
|
|
246
|
+
const formattedValue = value === null || value === undefined
|
|
247
|
+
? chalk.dim("-")
|
|
248
|
+
: typeof value === "boolean"
|
|
249
|
+
? formatBoolean(value)
|
|
250
|
+
: String(value);
|
|
251
|
+
console.error(`${chalk.dim(label + ":")} ${formattedValue}`);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Print a `label: value` line on **stdout** as part of a command's primary
|
|
255
|
+
* data output (e.g., `primitive integrations get <id>`,
|
|
256
|
+
* `primitive workflows get <id>`). Same visual rendering as `keyValue()`,
|
|
257
|
+
* but on the data stream so the value survives `> out.txt` redirection.
|
|
258
|
+
*
|
|
259
|
+
* Use `keyValue()` (stderr) for post-action diagnostic summaries; use
|
|
260
|
+
* `result()` (stdout) for fields the caller specifically requested.
|
|
261
|
+
*/
|
|
262
|
+
export function result(label, value) {
|
|
133
263
|
const formattedValue = value === null || value === undefined
|
|
134
264
|
? chalk.dim("-")
|
|
135
265
|
: typeof value === "boolean"
|
|
@@ -138,6 +268,18 @@ export function keyValue(label, value) {
|
|
|
138
268
|
console.log(`${chalk.dim(label + ":")} ${formattedValue}`);
|
|
139
269
|
}
|
|
140
270
|
export function divider() {
|
|
141
|
-
console.
|
|
271
|
+
console.error(chalk.dim("-".repeat(60)));
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* In-place progress indicator for long-running commands (e.g. polling a
|
|
275
|
+
* batch run). Writes to stderr so it can't corrupt JSON on stdout under
|
|
276
|
+
* `--json`. Callers should follow the final progress line with `progressEnd()`
|
|
277
|
+
* to print a trailing newline.
|
|
278
|
+
*/
|
|
279
|
+
export function progress(message) {
|
|
280
|
+
process.stderr.write(`\r${message}`);
|
|
281
|
+
}
|
|
282
|
+
export function progressEnd() {
|
|
283
|
+
process.stderr.write("\n");
|
|
142
284
|
}
|
|
143
285
|
//# sourceMappingURL=output.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/lib/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/lib/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAmC1B;;;;;;;;GAQG;AACH,SAAS,eAAe,CAAC,GAAW,EAAE,KAAa;IACjD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,QAAQ,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,GAAG,CAAC;IACzC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1B,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,IAA2B,EAC3B,OAAsB,EACtB,OAA+B;IAE/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxC,CAAC;IAED,0BAA0B;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACjC,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;QACtC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC3B,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAClB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACjF,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC,CAAC,CACH,CAAC;QACF,OAAO,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,2EAA2E;IAC3E,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,kEAAkE;IAClE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QAC7D,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAChC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,EAChD,CAAC,CACF,CAAC;YACF,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;YAChD,0EAA0E;YAC1E,sCAAsC;YACtC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,yEAAyE;YACzE,yEAAyE;YACzE,wDAAwD;YACxD,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACjE,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,MAAM,MAAM,GAAG,OAAO;SACnB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QACxB,OAAO,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;IACzD,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,mBAAmB;IACnB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE9D,cAAc;IACd,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,OAAO;SACJ,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACd,IAAI,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/E,uEAAuE;QACvE,sEAAsE;QACtE,sDAAsD;QACtD,IAAI,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;IAC1D,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;IAEF,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,SAAS,CAAC,GAAW,EAAE,KAAa,EAAE,KAAkC;IAC/E,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAErD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC;IACnC,CAAC;SAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;QAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,mCAAmC;IACnC,OAAO,GAAG,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,8CAA8C;AAC9C,wEAAwE;AACxE,iEAAiE;AACjE,yEAAyE;AACzE,uCAAuC;AACvC,EAAE;AACF,8EAA8E;AAC9E,uEAAuE;AACvE,wEAAwE;AACxE,2EAA2E;AAC3E,0EAA0E;AAC1E,uCAAuC;AACvC,EAAE;AACF,2DAA2D;AAC3D,wEAAwE;AACxE,+EAA+E;AAC/E,+EAA+E;AAC/E,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,qEAAqE;AACrE,8EAA8E;AAC9E,0EAA0E;AAE1E,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,MAAM,CAAC,GAAG,GAA+C,CAAC;IAC1D,MAAM,OAAO,GACX,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QACpD,CAAC,CAAC,CAAC,CAAC,OAAO;QACX,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,CAAC,OAAO,CAAC,CAAC;IAEf,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CACX,SAAS,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CACxE,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAClD,sEAAsE;QACtE,sEAAsE;QACtE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAkC,CAAC,EAAE,CAAC;YAC9E,IAAI,GAAG,KAAK,MAAM;gBAAE,SAAS;YAC7B,OAAO,CAAC,KAAK,CACX,OAAO,GAAG,KAAK,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAS;IAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAsC;IAC/D,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAiC;IAC5D,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IACxB,QAAQ,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,KAAK,UAAU,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,KAAK,WAAW;YACd,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,gCAAgC;IAChC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAiC;IAC7D,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAgC;IAC3D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,cAAc,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAA6B;IAC1D,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,EAAE,IAAI,CAAC;IAChC,IAAI,EAAE,GAAG,KAAK;QAAE,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACpD,OAAO,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAgC;IAC5D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,KAAmD;IACzF,MAAM,cAAc,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAC1D,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAChB,CAAC,CAAC,OAAO,KAAK,KAAK,SAAS;YAC1B,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;YACtB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpB,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,KAAmD;IACvF,MAAM,cAAc,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAC1D,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAChB,CAAC,CAAC,OAAO,KAAK,KAAK,SAAS;YAC1B,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;YACtB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor-pagination helper used by the CLI's API client.
|
|
3
|
+
*
|
|
4
|
+
* The server exposes cursor-paginated endpoints (e.g. GET /admin/api/admins/me/apps)
|
|
5
|
+
* that return `{ items, nextCursor? }` pages. Callers historically only fetched
|
|
6
|
+
* the first page, silently truncating results (see issue #436). This helper
|
|
7
|
+
* walks every page and aggregates the items in order.
|
|
8
|
+
*
|
|
9
|
+
* Exported separately so the looping contract can be unit-tested without
|
|
10
|
+
* stubbing the full ApiClient.
|
|
11
|
+
*/
|
|
12
|
+
export interface PaginatedPage<T> {
|
|
13
|
+
items: T[];
|
|
14
|
+
nextCursor?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export type PageFetcher<T> = (cursor: string | undefined) => Promise<PaginatedPage<T>>;
|
|
17
|
+
export interface PaginateOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Safety net: if the server hands out a non-advancing cursor (same cursor
|
|
20
|
+
* returned repeatedly, or an implausibly long chain), stop after this many
|
|
21
|
+
* pages and throw. Default: 1000.
|
|
22
|
+
*/
|
|
23
|
+
maxPages?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Walk every cursor page from `fetchPage` and return the concatenated items.
|
|
27
|
+
*
|
|
28
|
+
* Detects two failure modes that would otherwise hang the CLI:
|
|
29
|
+
* - A cursor that repeats (server returned the same `nextCursor` twice).
|
|
30
|
+
* - A cursor chain longer than `maxPages` (default 1000).
|
|
31
|
+
* Both throw so the caller fails loudly rather than looping forever.
|
|
32
|
+
*/
|
|
33
|
+
export declare function paginateAll<T>(fetchPage: PageFetcher<T>, options?: PaginateOptions): Promise<T[]>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor-pagination helper used by the CLI's API client.
|
|
3
|
+
*
|
|
4
|
+
* The server exposes cursor-paginated endpoints (e.g. GET /admin/api/admins/me/apps)
|
|
5
|
+
* that return `{ items, nextCursor? }` pages. Callers historically only fetched
|
|
6
|
+
* the first page, silently truncating results (see issue #436). This helper
|
|
7
|
+
* walks every page and aggregates the items in order.
|
|
8
|
+
*
|
|
9
|
+
* Exported separately so the looping contract can be unit-tested without
|
|
10
|
+
* stubbing the full ApiClient.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Walk every cursor page from `fetchPage` and return the concatenated items.
|
|
14
|
+
*
|
|
15
|
+
* Detects two failure modes that would otherwise hang the CLI:
|
|
16
|
+
* - A cursor that repeats (server returned the same `nextCursor` twice).
|
|
17
|
+
* - A cursor chain longer than `maxPages` (default 1000).
|
|
18
|
+
* Both throw so the caller fails loudly rather than looping forever.
|
|
19
|
+
*/
|
|
20
|
+
export async function paginateAll(fetchPage, options = {}) {
|
|
21
|
+
const maxPages = options.maxPages ?? 1000;
|
|
22
|
+
const all = [];
|
|
23
|
+
const seenCursors = new Set();
|
|
24
|
+
let cursor;
|
|
25
|
+
for (let page = 0; page < maxPages; page++) {
|
|
26
|
+
const resp = await fetchPage(cursor);
|
|
27
|
+
if (Array.isArray(resp.items)) {
|
|
28
|
+
all.push(...resp.items);
|
|
29
|
+
}
|
|
30
|
+
const next = resp.nextCursor ?? undefined;
|
|
31
|
+
if (!next) {
|
|
32
|
+
return all;
|
|
33
|
+
}
|
|
34
|
+
if (seenCursors.has(next)) {
|
|
35
|
+
throw new Error(`Pagination cursor did not advance (cursor ${next} repeated); aborting to avoid an infinite loop.`);
|
|
36
|
+
}
|
|
37
|
+
seenCursors.add(next);
|
|
38
|
+
cursor = next;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Pagination exceeded ${maxPages} pages without terminating; server cursor may not be advancing.`);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=paginate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginate.js","sourceRoot":"","sources":["../../../src/lib/paginate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkBH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAyB,EACzB,UAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAC1C,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,IAAI,MAA0B,CAAC;IAE/B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,6CAA6C,IAAI,iDAAiD,CACnG,CAAC;QACJ,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,iEAAiE,CACjG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project-scoped configuration (.primitive/config.json).
|
|
3
|
+
*
|
|
4
|
+
* This module handles loading, validating, and saving the project config file
|
|
5
|
+
* that lives inside the .primitive/ directory at the project root. The config
|
|
6
|
+
* defines named environments (dev, prod, staging, etc.) with their API URLs
|
|
7
|
+
* and app IDs.
|
|
8
|
+
*
|
|
9
|
+
* Design:
|
|
10
|
+
* - Config file: .primitive/config.json (or any ancestor directory)
|
|
11
|
+
* - The .primitive/ directory groups the committable config and the
|
|
12
|
+
* gitignored local state (credentials, sync data) in one place.
|
|
13
|
+
* - Format: JSON
|
|
14
|
+
* - Schema is versioned (currently 1). Future versions use semver-ish
|
|
15
|
+
* caret range compatibility: we accept any config where major version
|
|
16
|
+
* matches CURRENT_CONFIG_VERSION.
|
|
17
|
+
* - Invalid configs throw — we do NOT silently ignore malformed files.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Current schema version. Increment the major version when making
|
|
21
|
+
* backward-incompatible changes. Older configs will be rejected.
|
|
22
|
+
*/
|
|
23
|
+
export declare const CURRENT_CONFIG_VERSION = 1;
|
|
24
|
+
/**
|
|
25
|
+
* The config file lives inside the .primitive/ directory, not at the
|
|
26
|
+
* project root. This keeps the project root clean and groups all
|
|
27
|
+
* Primitive state (config, credentials, sync data) under one directory.
|
|
28
|
+
*/
|
|
29
|
+
export declare const PROJECT_CONFIG_DIR = ".primitive";
|
|
30
|
+
export declare const PROJECT_CONFIG_FILENAME = "config.json";
|
|
31
|
+
/** Display name used in user-facing messages. */
|
|
32
|
+
export declare const PROJECT_CONFIG_DISPLAY_NAME = ".primitive/config.json";
|
|
33
|
+
export interface ProjectEnvironment {
|
|
34
|
+
apiUrl: string;
|
|
35
|
+
appId?: string;
|
|
36
|
+
appName?: string;
|
|
37
|
+
/** Optional notes about this environment. */
|
|
38
|
+
description?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface ProjectConfig {
|
|
41
|
+
/** Schema version (currently 1). */
|
|
42
|
+
version: number;
|
|
43
|
+
/**
|
|
44
|
+
* Default environment name to use when --env is not specified and
|
|
45
|
+
* PRIMITIVE_ENV is unset.
|
|
46
|
+
*/
|
|
47
|
+
defaultEnvironment?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Named environments keyed by short name (e.g. "dev", "prod", "staging").
|
|
50
|
+
*/
|
|
51
|
+
environments: Record<string, ProjectEnvironment>;
|
|
52
|
+
}
|
|
53
|
+
export declare class ProjectConfigError extends Error {
|
|
54
|
+
readonly path?: string;
|
|
55
|
+
constructor(message: string, path?: string);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Walks upward from `startDir` looking for a `.primitive/config.json` file.
|
|
59
|
+
* Returns the absolute path to the config file, or null if not found.
|
|
60
|
+
*
|
|
61
|
+
* Allows running `primitive` commands from subdirectories of a project,
|
|
62
|
+
* much like `git` walks up to find `.git`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function findProjectConfigPath(startDir?: string): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the project root directory (the parent of .primitive/ that contains
|
|
67
|
+
* .primitive/config.json), or null if no project config is found.
|
|
68
|
+
*
|
|
69
|
+
* When the PRIMITIVE_PROJECT_CONFIG env var override is active, the config
|
|
70
|
+
* file may not live inside a `.primitive/` directory (e.g. in tests), so
|
|
71
|
+
* we simply go up one level from the file.
|
|
72
|
+
*/
|
|
73
|
+
export declare function findProjectRoot(startDir?: string): string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Validates a raw parsed object against the ProjectConfig schema.
|
|
76
|
+
* Throws ProjectConfigError with a helpful message on any problem.
|
|
77
|
+
*/
|
|
78
|
+
export declare function validateProjectConfig(raw: unknown, sourcePath?: string): ProjectConfig;
|
|
79
|
+
/**
|
|
80
|
+
* Loads and validates the project config from a specific file path.
|
|
81
|
+
* Throws ProjectConfigError on I/O errors, JSON parse errors, or schema
|
|
82
|
+
* validation failures — we deliberately do NOT swallow these, because a
|
|
83
|
+
* broken config should be noisy so the user can fix it.
|
|
84
|
+
*/
|
|
85
|
+
export declare function loadProjectConfigFromPath(path: string): ProjectConfig;
|
|
86
|
+
/**
|
|
87
|
+
* Loads the project config by searching upward from the current directory.
|
|
88
|
+
* Returns null (not an error) if no .primitive/config.json is found anywhere.
|
|
89
|
+
* Still throws ProjectConfigError if a config IS found but is invalid.
|
|
90
|
+
*/
|
|
91
|
+
export declare function loadProjectConfig(startDir?: string): ProjectConfig | null;
|
|
92
|
+
/**
|
|
93
|
+
* Writes a project config to disk as pretty-printed JSON. Callers are
|
|
94
|
+
* responsible for ensuring the parent directory exists — this function
|
|
95
|
+
* does not try to be clever about location.
|
|
96
|
+
*/
|
|
97
|
+
export declare function saveProjectConfig(path: string, config: ProjectConfig): void;
|