neonctl 2.37.1 → 2.38.1
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 +15 -700
- package/bin/cli.js +3 -0
- package/package.json +8 -75
- package/dist/analytics.js +0 -168
- package/dist/api.js +0 -720
- package/dist/auth.js +0 -125
- package/dist/callback.html +0 -60
- package/dist/cli.js +0 -9
- package/dist/commands/api.js +0 -278
- package/dist/commands/auth.js +0 -214
- package/dist/commands/bootstrap.js +0 -481
- package/dist/commands/branches.js +0 -488
- package/dist/commands/bucket.js +0 -549
- package/dist/commands/checkout.js +0 -321
- package/dist/commands/config.js +0 -626
- package/dist/commands/connection_string.js +0 -172
- package/dist/commands/data_api.js +0 -284
- package/dist/commands/databases.js +0 -82
- package/dist/commands/deploy.js +0 -26
- package/dist/commands/dev.js +0 -698
- package/dist/commands/diff.js +0 -222
- package/dist/commands/env.js +0 -189
- package/dist/commands/functions.js +0 -373
- package/dist/commands/index.js +0 -62
- package/dist/commands/init.js +0 -73
- package/dist/commands/inspect.js +0 -65
- package/dist/commands/ip_allow.js +0 -137
- package/dist/commands/link.js +0 -1121
- package/dist/commands/neon_auth.js +0 -1028
- package/dist/commands/operations.js +0 -28
- package/dist/commands/orgs.js +0 -24
- package/dist/commands/projects.js +0 -413
- package/dist/commands/psql.js +0 -62
- package/dist/commands/roles.js +0 -65
- package/dist/commands/schema_diff.js +0 -151
- package/dist/commands/set_context.js +0 -29
- package/dist/commands/snapshots.js +0 -455
- package/dist/commands/status.js +0 -40
- package/dist/commands/user.js +0 -15
- package/dist/commands/vpc_endpoints.js +0 -134
- package/dist/config.js +0 -11
- package/dist/config_format.js +0 -72
- package/dist/context.js +0 -231
- package/dist/current_branch_fast_path.js +0 -55
- package/dist/dev/env.js +0 -244
- package/dist/dev/functions.js +0 -70
- package/dist/dev/inputs.js +0 -63
- package/dist/dev/runtime.js +0 -146
- package/dist/env.js +0 -36
- package/dist/env_file.js +0 -159
- package/dist/errors.js +0 -80
- package/dist/functions_api.js +0 -48
- package/dist/help.js +0 -146
- package/dist/index.js +0 -240
- package/dist/log.js +0 -18
- package/dist/parameters.gen.js +0 -480
- package/dist/pkg.js +0 -25
- package/dist/psql/cli.js +0 -53
- package/dist/psql/command/cmd_cond.js +0 -437
- package/dist/psql/command/cmd_connect.js +0 -820
- package/dist/psql/command/cmd_copy.js +0 -1035
- package/dist/psql/command/cmd_describe.js +0 -1815
- package/dist/psql/command/cmd_format.js +0 -948
- package/dist/psql/command/cmd_io.js +0 -2193
- package/dist/psql/command/cmd_lo.js +0 -393
- package/dist/psql/command/cmd_meta.js +0 -969
- package/dist/psql/command/cmd_misc.js +0 -187
- package/dist/psql/command/cmd_pipeline.js +0 -1148
- package/dist/psql/command/cmd_restrict.js +0 -171
- package/dist/psql/command/cmd_show.js +0 -766
- package/dist/psql/command/dispatch.js +0 -343
- package/dist/psql/command/inputQueue.js +0 -42
- package/dist/psql/command/shared.js +0 -71
- package/dist/psql/complete/filenames.js +0 -139
- package/dist/psql/complete/index.js +0 -104
- package/dist/psql/complete/matcher.js +0 -315
- package/dist/psql/complete/psqlVars.js +0 -249
- package/dist/psql/complete/queries.js +0 -493
- package/dist/psql/complete/rules.js +0 -2424
- package/dist/psql/core/common.js +0 -1253
- package/dist/psql/core/help.js +0 -576
- package/dist/psql/core/mainloop.js +0 -1360
- package/dist/psql/core/prompt.js +0 -439
- package/dist/psql/core/settings.js +0 -686
- package/dist/psql/core/sqlHelp.js +0 -1066
- package/dist/psql/core/startup.js +0 -846
- package/dist/psql/core/syncVars.js +0 -116
- package/dist/psql/core/variables.js +0 -287
- package/dist/psql/describe/formatters.js +0 -1330
- package/dist/psql/describe/processNamePattern.js +0 -270
- package/dist/psql/describe/queries.js +0 -2452
- package/dist/psql/describe/versionGate.js +0 -44
- package/dist/psql/index.js +0 -2030
- package/dist/psql/io/history.js +0 -299
- package/dist/psql/io/input.js +0 -120
- package/dist/psql/io/lineEditor/buffer.js +0 -325
- package/dist/psql/io/lineEditor/complete.js +0 -227
- package/dist/psql/io/lineEditor/filename.js +0 -159
- package/dist/psql/io/lineEditor/index.js +0 -893
- package/dist/psql/io/lineEditor/keymap.js +0 -745
- package/dist/psql/io/lineEditor/vt100.js +0 -363
- package/dist/psql/io/pgpass.js +0 -202
- package/dist/psql/io/pgservice.js +0 -194
- package/dist/psql/io/psqlrc.js +0 -422
- package/dist/psql/print/aligned.js +0 -1748
- package/dist/psql/print/asciidoc.js +0 -230
- package/dist/psql/print/crosstab.js +0 -463
- package/dist/psql/print/csv.js +0 -76
- package/dist/psql/print/html.js +0 -240
- package/dist/psql/print/json.js +0 -96
- package/dist/psql/print/latex.js +0 -379
- package/dist/psql/print/pager.js +0 -267
- package/dist/psql/print/troff.js +0 -240
- package/dist/psql/print/unaligned.js +0 -99
- package/dist/psql/print/units.js +0 -188
- package/dist/psql/scanner/slash.js +0 -515
- package/dist/psql/scanner/sql.js +0 -914
- package/dist/psql/scanner/stringutils.js +0 -394
- package/dist/psql/types/backslash.js +0 -1
- package/dist/psql/types/connection.js +0 -1
- package/dist/psql/types/index.js +0 -7
- package/dist/psql/types/printer.js +0 -1
- package/dist/psql/types/repl.js +0 -1
- package/dist/psql/types/scanner.js +0 -24
- package/dist/psql/types/settings.js +0 -1
- package/dist/psql/types/variables.js +0 -1
- package/dist/psql/wire/connection.js +0 -2857
- package/dist/psql/wire/copy.js +0 -108
- package/dist/psql/wire/notify.js +0 -59
- package/dist/psql/wire/pipeline.js +0 -521
- package/dist/psql/wire/protocol.js +0 -466
- package/dist/psql/wire/sasl.js +0 -294
- package/dist/psql/wire/tls.js +0 -602
- package/dist/storage_api.js +0 -147
- package/dist/test_utils/fixtures.js +0 -121
- package/dist/test_utils/oauth_server.js +0 -9
- package/dist/types.js +0 -1
- package/dist/utils/ai_gateway_notice.js +0 -180
- package/dist/utils/api_enums.js +0 -33
- package/dist/utils/auth.js +0 -5
- package/dist/utils/branch_notice.js +0 -22
- package/dist/utils/branch_picker.js +0 -103
- package/dist/utils/compute_units.js +0 -28
- package/dist/utils/config_diff.js +0 -185
- package/dist/utils/enrichers.js +0 -161
- package/dist/utils/esbuild.js +0 -158
- package/dist/utils/formats.js +0 -18
- package/dist/utils/git_diff.js +0 -90
- package/dist/utils/inspect_db.js +0 -153
- package/dist/utils/inspect_queries.js +0 -372
- package/dist/utils/middlewares.js +0 -20
- package/dist/utils/openapi.js +0 -114
- package/dist/utils/package_manager.js +0 -68
- package/dist/utils/point_in_time.js +0 -56
- package/dist/utils/psql.js +0 -120
- package/dist/utils/string.js +0 -5
- package/dist/utils/ui.js +0 -59
- package/dist/utils/zip.js +0 -4
- package/dist/writer.js +0 -97
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import which from "which";
|
|
3
|
-
import { log } from "../log.js";
|
|
4
|
-
// npm first so it's the default/preselected choice; the rest follow in rough
|
|
5
|
-
// popularity order.
|
|
6
|
-
export const PACKAGE_MANAGERS = [
|
|
7
|
-
"npm",
|
|
8
|
-
"pnpm",
|
|
9
|
-
"yarn",
|
|
10
|
-
"bun",
|
|
11
|
-
];
|
|
12
|
-
/**
|
|
13
|
-
* The package manager the CLI was invoked through, read from the
|
|
14
|
-
* `npm_config_user_agent` npm sets for `npm exec`/`npx`, `pnpm dlx`, `yarn
|
|
15
|
-
* dlx`, and `bunx` (so `pnpm dlx neonctl …` installs with pnpm). Returns
|
|
16
|
-
* undefined when there's nothing to infer from — e.g. a globally-installed
|
|
17
|
-
* `neon`/`neonctl` — so the caller can ask (or fall back) instead of silently
|
|
18
|
-
* assuming npm.
|
|
19
|
-
*/
|
|
20
|
-
export const detectPackageManager = () => {
|
|
21
|
-
const ua = process.env.npm_config_user_agent ?? "";
|
|
22
|
-
if (ua.startsWith("pnpm"))
|
|
23
|
-
return "pnpm";
|
|
24
|
-
if (ua.startsWith("yarn"))
|
|
25
|
-
return "yarn";
|
|
26
|
-
if (ua.startsWith("bun"))
|
|
27
|
-
return "bun";
|
|
28
|
-
if (ua.startsWith("npm"))
|
|
29
|
-
return "npm";
|
|
30
|
-
return undefined;
|
|
31
|
-
};
|
|
32
|
-
/** The package managers actually on PATH, in {@link PACKAGE_MANAGERS} order. */
|
|
33
|
-
export const installedPackageManagers = () => PACKAGE_MANAGERS.filter((pm) => which.sync(pm, { nothrow: true }) !== null);
|
|
34
|
-
/**
|
|
35
|
-
* Pick a package manager without prompting: the one the CLI was invoked through,
|
|
36
|
-
* else the first one installed, else npm. Used by non-interactive flows (e.g.
|
|
37
|
-
* `config init`) where there's no scaffold prompt to hang a picker off.
|
|
38
|
-
*/
|
|
39
|
-
export const resolvePackageManager = () => detectPackageManager() ?? installedPackageManagers()[0] ?? "npm";
|
|
40
|
-
/**
|
|
41
|
-
* The argv that adds `packages` as runtime dependencies with `pm`. npm spells it
|
|
42
|
-
* `install`; pnpm/yarn/bun use `add`.
|
|
43
|
-
*/
|
|
44
|
-
export const addDependenciesArgs = (pm, packages) => (pm === "npm" ? ["install", ...packages] : ["add", ...packages]);
|
|
45
|
-
/**
|
|
46
|
-
* Run a command inheriting our stdio so the user sees install / link output
|
|
47
|
-
* live and can answer any prompts the child raises. Resolves to whether it
|
|
48
|
-
* exited cleanly; a non-zero exit is reported but never throws — the caller
|
|
49
|
-
* decides whether to treat it as fatal.
|
|
50
|
-
*/
|
|
51
|
-
export const runCommand = (cmd, args, cwd) => new Promise((resolvePromise) => {
|
|
52
|
-
// npm/pnpm/yarn ship as .cmd shims on Windows, which need a shell to run.
|
|
53
|
-
const child = spawn(cmd, args, {
|
|
54
|
-
cwd,
|
|
55
|
-
stdio: "inherit",
|
|
56
|
-
shell: process.platform === "win32",
|
|
57
|
-
});
|
|
58
|
-
child.on("error", (err) => {
|
|
59
|
-
log.warning("Could not run `%s %s`: %s", cmd, args.join(" "), err instanceof Error ? err.message : String(err));
|
|
60
|
-
resolvePromise(false);
|
|
61
|
-
});
|
|
62
|
-
child.on("close", (code) => {
|
|
63
|
-
if (code !== 0) {
|
|
64
|
-
log.warning("`%s %s` exited with code %d.", cmd, args.join(" "), code);
|
|
65
|
-
}
|
|
66
|
-
resolvePromise(code === 0);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { branchIdResolve } from "./enrichers.js";
|
|
2
|
-
import { looksLikeLSN, looksLikeTimestamp } from "./formats.js";
|
|
3
|
-
export class PointInTimeParseError extends Error {
|
|
4
|
-
constructor(message) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.name = "PointInTimeParseError";
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export const parsePITBranch = (input) => {
|
|
10
|
-
const splitIndex = input.lastIndexOf("@");
|
|
11
|
-
const sourceBranch = splitIndex === -1 ? input : input.slice(0, splitIndex);
|
|
12
|
-
const exactPIT = splitIndex === -1 ? null : input.slice(splitIndex + 1);
|
|
13
|
-
const result = {
|
|
14
|
-
branch: sourceBranch,
|
|
15
|
-
...(exactPIT === null
|
|
16
|
-
? { tag: "head" }
|
|
17
|
-
: looksLikeLSN(exactPIT)
|
|
18
|
-
? { tag: "lsn", lsn: exactPIT }
|
|
19
|
-
: { tag: "timestamp", timestamp: exactPIT }),
|
|
20
|
-
};
|
|
21
|
-
if (result.tag === "timestamp") {
|
|
22
|
-
const timestamp = result.timestamp;
|
|
23
|
-
if (!looksLikeTimestamp(timestamp)) {
|
|
24
|
-
throw new PointInTimeParseError(`Invalid source branch format - ${input}`);
|
|
25
|
-
}
|
|
26
|
-
if (Date.parse(timestamp) > Date.now()) {
|
|
27
|
-
throw new PointInTimeParseError(`Timestamp can not be in future - ${input}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
31
|
-
};
|
|
32
|
-
export const parsePointInTime = async ({ pointInTime, targetBranchId, projectId, api, }) => {
|
|
33
|
-
const parsedPIT = parsePITBranch(pointInTime);
|
|
34
|
-
let branchId = "";
|
|
35
|
-
if (parsedPIT.branch === "^self") {
|
|
36
|
-
branchId = targetBranchId;
|
|
37
|
-
}
|
|
38
|
-
else if (parsedPIT.branch === "^parent") {
|
|
39
|
-
const { data } = await api.getProjectBranch(projectId, targetBranchId);
|
|
40
|
-
const { parent_id: parentId } = data.branch;
|
|
41
|
-
if (parentId == null) {
|
|
42
|
-
throw new PointInTimeParseError("Branch has no parent");
|
|
43
|
-
}
|
|
44
|
-
branchId = parentId;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
branchId = await branchIdResolve({
|
|
48
|
-
branch: parsedPIT.branch,
|
|
49
|
-
projectId,
|
|
50
|
-
apiClient: api,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
// @ts-expect-error extracting pit from parsedPIT
|
|
54
|
-
delete parsedPIT.branch;
|
|
55
|
-
return { ...parsedPIT, branchId };
|
|
56
|
-
};
|
package/dist/utils/psql.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { spawn } from "child_process";
|
|
2
|
-
import which from "which";
|
|
3
|
-
import { closeAnalytics, trackEvent } from "../analytics.js";
|
|
4
|
-
import { log } from "../log.js";
|
|
5
|
-
const FALLBACK_ENV = "NEONCTL_PSQL_FALLBACK";
|
|
6
|
-
/** Max time we wait for the analytics flush before handing off to psql. */
|
|
7
|
-
const ANALYTICS_FLUSH_TIMEOUT_MS = 3000;
|
|
8
|
-
/**
|
|
9
|
-
* Decide which psql implementation will run, and why. The PATH probe is
|
|
10
|
-
* skipped when TS is forced (flag or env) — we don't need it and it'd be a
|
|
11
|
-
* wasted lookup — so `nativeAvailable` is `null` ("not checked") in those
|
|
12
|
-
* cases rather than a misleading `false`.
|
|
13
|
-
*/
|
|
14
|
-
const planPsql = async (opts) => {
|
|
15
|
-
if (opts.mode === "ts") {
|
|
16
|
-
return {
|
|
17
|
-
implementation: "ts",
|
|
18
|
-
reason: "forced_flag",
|
|
19
|
-
nativeAvailable: null,
|
|
20
|
-
nativePath: null,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
if (process.env[FALLBACK_ENV] === "1") {
|
|
24
|
-
return {
|
|
25
|
-
implementation: "ts",
|
|
26
|
-
reason: "forced_env",
|
|
27
|
-
nativeAvailable: null,
|
|
28
|
-
nativePath: null,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
const nativePath = await which("psql", { nothrow: true });
|
|
32
|
-
const nativeAvailable = nativePath !== null;
|
|
33
|
-
if (opts.mode === "native") {
|
|
34
|
-
return {
|
|
35
|
-
implementation: "native",
|
|
36
|
-
reason: "forced_native",
|
|
37
|
-
nativeAvailable,
|
|
38
|
-
nativePath,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
// 'auto' (or unset): strict fallback — prefer native, TS only if missing.
|
|
42
|
-
return nativeAvailable
|
|
43
|
-
? {
|
|
44
|
-
implementation: "native",
|
|
45
|
-
reason: "native_available",
|
|
46
|
-
nativeAvailable,
|
|
47
|
-
nativePath,
|
|
48
|
-
}
|
|
49
|
-
: {
|
|
50
|
-
implementation: "ts",
|
|
51
|
-
reason: "fallback_no_native",
|
|
52
|
-
nativeAvailable,
|
|
53
|
-
nativePath,
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Record which psql implementation is about to run, then flush analytics.
|
|
58
|
-
*
|
|
59
|
-
* Both exec paths below call `process.exit()`, which short-circuits the
|
|
60
|
-
* main loop's `closeAnalytics()` — so without flushing here the event (and
|
|
61
|
-
* any earlier queued events, e.g. `CLI Started`) would be dropped. The
|
|
62
|
-
* flush is bounded by {@link ANALYTICS_FLUSH_TIMEOUT_MS} so a slow or
|
|
63
|
-
* unreachable analytics endpoint can't stall the psql launch. No-ops when
|
|
64
|
-
* analytics is disabled (`--analytics false`), since the client is absent.
|
|
65
|
-
*/
|
|
66
|
-
const reportPsqlInvocation = async (plan) => {
|
|
67
|
-
trackEvent("psql_invoked", {
|
|
68
|
-
implementation: plan.implementation,
|
|
69
|
-
reason: plan.reason,
|
|
70
|
-
nativeAvailable: plan.nativeAvailable,
|
|
71
|
-
});
|
|
72
|
-
await closeAnalytics({ timeout: ANALYTICS_FLUSH_TIMEOUT_MS });
|
|
73
|
-
};
|
|
74
|
-
const execNative = async (binary, connection_uri, args) => {
|
|
75
|
-
log.info("Connecting to the database using psql...");
|
|
76
|
-
const child = spawn(binary, [connection_uri, ...args], {
|
|
77
|
-
stdio: "inherit",
|
|
78
|
-
});
|
|
79
|
-
for (const signame of ["SIGINT", "SIGTERM"]) {
|
|
80
|
-
process.on(signame, (code) => {
|
|
81
|
-
if (!child.killed && code !== null) {
|
|
82
|
-
child.kill(code);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
return new Promise((_, reject) => {
|
|
87
|
-
child.on("exit", (code) => {
|
|
88
|
-
process.exit(code === null ? 1 : code);
|
|
89
|
-
});
|
|
90
|
-
child.on("error", reject);
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
const execTs = async (connection_uri, args) => {
|
|
94
|
-
log.info("Connecting to the database using embedded psql (TypeScript)...");
|
|
95
|
-
const { runPsql } = await import("../psql/index.js");
|
|
96
|
-
const code = await runPsql([connection_uri, ...args], {
|
|
97
|
-
stdin: process.stdin,
|
|
98
|
-
stdout: process.stdout,
|
|
99
|
-
stderr: process.stderr,
|
|
100
|
-
});
|
|
101
|
-
process.exit(code);
|
|
102
|
-
};
|
|
103
|
-
export const psql = async (connection_uri, args = [], opts = {}) => {
|
|
104
|
-
const plan = await planPsql(opts);
|
|
105
|
-
await reportPsqlInvocation(plan);
|
|
106
|
-
if (plan.implementation === "ts") {
|
|
107
|
-
if (plan.reason === "fallback_no_native") {
|
|
108
|
-
log.info("psql binary not found on PATH; falling back to embedded TypeScript psql");
|
|
109
|
-
}
|
|
110
|
-
return execTs(connection_uri, args);
|
|
111
|
-
}
|
|
112
|
-
// implementation === 'native'
|
|
113
|
-
if (plan.nativePath === null) {
|
|
114
|
-
// Only reachable when native was explicitly requested (mode: 'native')
|
|
115
|
-
// but no binary is on PATH.
|
|
116
|
-
log.error(`psql is not available in the PATH`);
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
return execNative(plan.nativePath, connection_uri, args);
|
|
120
|
-
};
|
package/dist/utils/string.js
DELETED
package/dist/utils/ui.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// returns the next string if matches the given matcher,
|
|
2
|
-
// otherwise returns null
|
|
3
|
-
// consumes the line from the lines array
|
|
4
|
-
export const consumeNextMatching = (lines, matcher) => {
|
|
5
|
-
while (lines.length > 0) {
|
|
6
|
-
const line = lines.shift().trim();
|
|
7
|
-
if (line === "") {
|
|
8
|
-
continue;
|
|
9
|
-
}
|
|
10
|
-
if (matcher.test(line)) {
|
|
11
|
-
return line;
|
|
12
|
-
}
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
return null;
|
|
16
|
-
};
|
|
17
|
-
// returns strings if next non-empty line matches the given matcher,
|
|
18
|
-
// otherwise returns empty array
|
|
19
|
-
// consumes the lines from the lines array
|
|
20
|
-
export const consumeBlockIfMatches = (lines, matcher) => {
|
|
21
|
-
const result = [];
|
|
22
|
-
if (lines.length === 0) {
|
|
23
|
-
return result;
|
|
24
|
-
}
|
|
25
|
-
let line = lines.shift();
|
|
26
|
-
while (line.trim() === "") {
|
|
27
|
-
line = lines.shift();
|
|
28
|
-
}
|
|
29
|
-
if (!matcher.test(line)) {
|
|
30
|
-
lines.unshift(line);
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
result.push(line);
|
|
34
|
-
while (lines.length > 0) {
|
|
35
|
-
line = lines.shift();
|
|
36
|
-
if (line.trim() === "") {
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
result.push(line);
|
|
40
|
-
}
|
|
41
|
-
return result;
|
|
42
|
-
};
|
|
43
|
-
export const splitColumns = (line) => {
|
|
44
|
-
const result = line.trim().split(/\s{2,}/);
|
|
45
|
-
result[1] = result[1] ?? "";
|
|
46
|
-
if (result.length > 2) {
|
|
47
|
-
result[1] = result.slice(1).join(" ");
|
|
48
|
-
}
|
|
49
|
-
return result;
|
|
50
|
-
};
|
|
51
|
-
export const drawPointer = (width) => {
|
|
52
|
-
const result = [];
|
|
53
|
-
result.push("└");
|
|
54
|
-
for (let i = 0; i < width - 4; i++) {
|
|
55
|
-
result.push("─");
|
|
56
|
-
}
|
|
57
|
-
result.push(">");
|
|
58
|
-
return result.join("");
|
|
59
|
-
};
|
package/dist/utils/zip.js
DELETED
package/dist/writer.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import Table from "cli-table";
|
|
3
|
-
import YAML from "yaml";
|
|
4
|
-
import { isCi } from "./env.js";
|
|
5
|
-
import { isObject, toSnakeCase } from "./utils/string.js";
|
|
6
|
-
const writeYaml = (chunks) => {
|
|
7
|
-
return YAML.stringify(chunks.length === 1
|
|
8
|
-
? chunks[0].data
|
|
9
|
-
: Object.fromEntries(chunks.map(({ config, data }, idx) => [
|
|
10
|
-
config.title ? toSnakeCase(config.title) : idx,
|
|
11
|
-
data,
|
|
12
|
-
])), null, 2);
|
|
13
|
-
};
|
|
14
|
-
const writeJson = (chunks) => {
|
|
15
|
-
return JSON.stringify(chunks.length === 1
|
|
16
|
-
? chunks[0].data
|
|
17
|
-
: Object.fromEntries(chunks.map(({ config, data }, idx) => [
|
|
18
|
-
config.title ? toSnakeCase(config.title) : idx,
|
|
19
|
-
data,
|
|
20
|
-
])), null, 2);
|
|
21
|
-
};
|
|
22
|
-
const writeTable = (chunks, out) => {
|
|
23
|
-
chunks.forEach(({ data, config: { emptyMessage, fields, title, renderColumns = {} }, }) => {
|
|
24
|
-
const arrayData = Array.isArray(data) ? data : [data];
|
|
25
|
-
if (!arrayData.length && emptyMessage) {
|
|
26
|
-
out.write("\n" + emptyMessage + "\n");
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const fieldsFiltered = fields.filter((field) => arrayData.some((item) => item[field] !== undefined && item[field] !== ""));
|
|
30
|
-
const table = new Table({
|
|
31
|
-
style: {
|
|
32
|
-
head: ["green"],
|
|
33
|
-
},
|
|
34
|
-
head: fieldsFiltered.map((field) => field
|
|
35
|
-
.split("_")
|
|
36
|
-
.map((word) => word[0].toUpperCase() + word.slice(1))
|
|
37
|
-
.join(" ")),
|
|
38
|
-
});
|
|
39
|
-
arrayData.forEach((item) => {
|
|
40
|
-
table.push(fieldsFiltered.map((field) => {
|
|
41
|
-
const value = item[field];
|
|
42
|
-
if (renderColumns[field]) {
|
|
43
|
-
return renderColumns[field]?.(item);
|
|
44
|
-
}
|
|
45
|
-
return Array.isArray(value)
|
|
46
|
-
? value.join("\n")
|
|
47
|
-
: isObject(value)
|
|
48
|
-
? JSON.stringify(value, null, 2)
|
|
49
|
-
: (value ?? "");
|
|
50
|
-
}));
|
|
51
|
-
});
|
|
52
|
-
if (title) {
|
|
53
|
-
out.write((isCi() ? title : chalk.bold(title)) + "\n");
|
|
54
|
-
}
|
|
55
|
-
out.write(table.toString());
|
|
56
|
-
out.write("\n");
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
*
|
|
61
|
-
* Parses the output format, takes data and writes the output to stdout.
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* const { data } = await props.apiClient.listProjectBranches(props.project.id);
|
|
65
|
-
* // to output single data
|
|
66
|
-
* writer(props).end(data, { fields: ['id', 'name', 'created_at'] })
|
|
67
|
-
* // to output multiple data
|
|
68
|
-
* writer(props)
|
|
69
|
-
* .write(data, { fields: ['id', 'name', 'created_at'], title: 'branches' })
|
|
70
|
-
* .write(data, { fields: ['id', 'created_at'], title: 'endpoints' })
|
|
71
|
-
* .end()
|
|
72
|
-
*/
|
|
73
|
-
export const writer = (props) => {
|
|
74
|
-
const out = props.out ?? process.stdout;
|
|
75
|
-
const chunks = [];
|
|
76
|
-
return {
|
|
77
|
-
write(data, config) {
|
|
78
|
-
chunks.push({ data, config });
|
|
79
|
-
return this;
|
|
80
|
-
},
|
|
81
|
-
text(data) {
|
|
82
|
-
return out.write(data);
|
|
83
|
-
},
|
|
84
|
-
end: (...args) => {
|
|
85
|
-
if (args.length === 2) {
|
|
86
|
-
chunks.push({ data: args[0], config: args[1] });
|
|
87
|
-
}
|
|
88
|
-
if (props.output == "yaml") {
|
|
89
|
-
return out.write(writeYaml(chunks));
|
|
90
|
-
}
|
|
91
|
-
if (props.output == "json") {
|
|
92
|
-
return out.write(writeJson(chunks));
|
|
93
|
-
}
|
|
94
|
-
writeTable(chunks, out);
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
};
|