neon 3.0.0 → 3.1.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 +70 -5
- package/dist/_chunks/auth_selection-DGgq6ifc.js +83 -0
- package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
- package/dist/_chunks/credentials-MYdHdKah.js +188 -0
- package/dist/_chunks/env-NbA61JR3.js +585 -0
- package/dist/_chunks/env_services-Tz9G4JeT.js +531 -0
- package/dist/_chunks/paths-DMq0Lt7a.js +151 -0
- package/dist/_chunks/profiles-Ir29rqns.js +217 -0
- package/dist/_chunks/psql-DWH-kc69.js +2169 -0
- package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/_chunks/secure_file-BucZj4yQ.js +39 -0
- package/dist/analytics.js +163 -207
- package/dist/api.js +815 -758
- package/dist/auth.js +121 -141
- package/dist/auth_context.js +39 -53
- package/dist/cli.js +4 -7
- package/dist/commands/api.js +220 -250
- package/dist/commands/api_keys.js +251 -314
- package/dist/commands/auth.js +283 -328
- package/dist/commands/bootstrap.js +372 -437
- package/dist/commands/branches.js +304 -455
- package/dist/commands/bucket.js +374 -514
- package/dist/commands/checkout.js +213 -298
- package/dist/commands/config.js +573 -690
- package/dist/commands/connection_string.js +137 -165
- package/dist/commands/data_api.js +238 -260
- package/dist/commands/databases.js +67 -76
- package/dist/commands/deploy.js +31 -25
- package/dist/commands/dev.js +639 -719
- package/dist/commands/diff.js +156 -200
- package/dist/commands/env.js +255 -305
- package/dist/commands/functions.js +275 -355
- package/dist/commands/index.js +70 -65
- package/dist/commands/init.js +84 -119
- package/dist/commands/inspect.js +55 -55
- package/dist/commands/ip_allow.js +88 -120
- package/dist/commands/link.js +874 -1019
- package/dist/commands/logs.js +291 -0
- package/dist/commands/neon_auth.js +725 -933
- package/dist/commands/operations.js +34 -25
- package/dist/commands/orgs.js +28 -18
- package/dist/commands/profile.js +615 -846
- package/dist/commands/projects.js +313 -373
- package/dist/commands/psql.js +60 -58
- package/dist/commands/roles.js +55 -58
- package/dist/commands/schema_diff.js +87 -131
- package/dist/commands/set_context.js +34 -26
- package/dist/commands/snapshots.js +288 -413
- package/dist/commands/status.js +41 -37
- package/dist/commands/user.js +21 -10
- package/dist/commands/vpc_endpoints.js +85 -113
- package/dist/config.js +7 -6
- package/dist/config_format.js +50 -66
- package/dist/config_template.js +128 -157
- package/dist/context.js +183 -235
- package/dist/current_branch_fast_path.js +40 -49
- package/dist/dev/env.js +2 -446
- package/dist/dev/functions.js +54 -68
- package/dist/dev/inputs.js +46 -58
- package/dist/dev/runtime.js +135 -164
- package/dist/dev/websocket.js +766 -959
- package/dist/env.js +27 -33
- package/dist/env_file.js +118 -132
- package/dist/env_services.js +2 -51
- package/dist/errors.js +57 -68
- package/dist/functions_api.js +45 -43
- package/dist/help.js +189 -140
- package/dist/index.js +182 -257
- package/dist/init/agents.js +137 -118
- package/dist/init/auth.js +58 -68
- package/dist/init/bootstrap.js +325 -396
- package/dist/init/build_config.js +4 -2
- package/dist/init/detect_agent.js +56 -101
- package/dist/init/editors.js +35 -52
- package/dist/init/enrich_output.js +51 -66
- package/dist/init/extension.js +134 -171
- package/dist/init/inspect.js +179 -266
- package/dist/init/interactive.js +510 -622
- package/dist/init/neonctl.js +117 -168
- package/dist/init/orchestrate.js +157 -173
- package/dist/init/phases/auth.js +188 -202
- package/dist/init/phases/cleanup.js +23 -23
- package/dist/init/phases/db.js +251 -277
- package/dist/init/phases/getting_started.js +213 -223
- package/dist/init/phases/mcp.js +174 -224
- package/dist/init/phases/migrations.js +247 -248
- package/dist/init/phases/neon_auth.js +114 -133
- package/dist/init/phases/setup.js +546 -703
- package/dist/init/phases/skills.js +75 -86
- package/dist/init/phases/status.js +72 -67
- package/dist/init/resolve_context.js +102 -99
- package/dist/init/route_command.js +91 -98
- package/dist/init/skills.js +174 -218
- package/dist/init/vsix.js +77 -99
- package/dist/log.js +17 -16
- package/dist/neon_services.js +104 -129
- package/dist/parameters.gen.js +481 -471
- package/dist/pkg.js +17 -19
- package/dist/profile_keys.js +44 -47
- package/dist/psql/cli.js +44 -47
- package/dist/psql/command/cmd_cond.js +231 -406
- package/dist/psql/command/cmd_connect.js +557 -764
- package/dist/psql/command/cmd_copy.js +728 -984
- package/dist/psql/command/cmd_describe.js +1499 -1688
- package/dist/psql/command/cmd_format.js +733 -905
- package/dist/psql/command/cmd_io.js +2 -2193
- package/dist/psql/command/cmd_lo.js +297 -359
- package/dist/psql/command/cmd_meta.js +727 -878
- package/dist/psql/command/cmd_misc.js +138 -172
- package/dist/psql/command/cmd_pipeline.js +2 -1148
- package/dist/psql/command/cmd_restrict.js +119 -155
- package/dist/psql/command/cmd_show.js +529 -688
- package/dist/psql/command/dispatch.js +260 -325
- package/dist/psql/command/inputQueue.js +35 -33
- package/dist/psql/command/shared.js +49 -63
- package/dist/psql/complete/filenames.js +90 -133
- package/dist/psql/complete/index.js +59 -97
- package/dist/psql/complete/matcher.js +236 -300
- package/dist/psql/complete/psqlVars.js +218 -223
- package/dist/psql/complete/queries.js +159 -177
- package/dist/psql/complete/rules.js +1493 -2299
- package/dist/psql/core/common.js +2 -1253
- package/dist/psql/core/help.js +456 -546
- package/dist/psql/core/mainloop.js +692 -1303
- package/dist/psql/core/prompt.js +391 -408
- package/dist/psql/core/settings.js +429 -644
- package/dist/psql/core/sqlHelp.js +480 -554
- package/dist/psql/core/startup.js +2 -846
- package/dist/psql/core/syncVars.js +67 -110
- package/dist/psql/core/variables.js +156 -278
- package/dist/psql/describe/formatters.js +884 -1285
- package/dist/psql/describe/processNamePattern.js +173 -260
- package/dist/psql/describe/queries.js +1368 -2403
- package/dist/psql/describe/versionGate.js +32 -41
- package/dist/psql/index.js +2 -2030
- package/dist/psql/io/history.js +232 -271
- package/dist/psql/io/input.js +103 -108
- package/dist/psql/io/lineEditor/buffer.js +238 -319
- package/dist/psql/io/lineEditor/complete.js +135 -213
- package/dist/psql/io/lineEditor/filename.js +139 -148
- package/dist/psql/io/lineEditor/index.js +653 -870
- package/dist/psql/io/lineEditor/keymap.js +544 -702
- package/dist/psql/io/lineEditor/vt100.js +294 -341
- package/dist/psql/io/pgpass.js +158 -187
- package/dist/psql/io/pgservice.js +146 -183
- package/dist/psql/io/psqlrc.js +328 -403
- package/dist/psql/print/aligned.js +1020 -1683
- package/dist/psql/print/asciidoc.js +180 -214
- package/dist/psql/print/crosstab.js +281 -442
- package/dist/psql/print/csv.js +48 -70
- package/dist/psql/print/html.js +195 -226
- package/dist/psql/print/json.js +75 -88
- package/dist/psql/print/latex.js +291 -364
- package/dist/psql/print/pager.js +171 -242
- package/dist/psql/print/troff.js +194 -226
- package/dist/psql/print/unaligned.js +69 -95
- package/dist/psql/print/units.js +167 -169
- package/dist/psql/scanner/slash.js +428 -483
- package/dist/psql/scanner/sql.js +445 -889
- package/dist/psql/scanner/stringutils.js +309 -379
- package/dist/psql/types/index.js +8 -7
- package/dist/psql/types/scanner.js +25 -22
- package/dist/psql/wire/connection.js +2042 -2803
- package/dist/psql/wire/copy.js +84 -100
- package/dist/psql/wire/notify.js +39 -59
- package/dist/psql/wire/pipeline.js +305 -518
- package/dist/psql/wire/protocol.js +349 -417
- package/dist/psql/wire/sasl.js +180 -265
- package/dist/psql/wire/tls.js +400 -561
- package/dist/storage_api.js +115 -129
- package/dist/test_utils/fixtures.js +94 -113
- package/dist/test_utils/oauth_server.js +10 -7
- package/dist/test_utils/project_dir.js +33 -0
- package/dist/utils/ai_gateway_notice.js +131 -162
- package/dist/utils/api_enums.js +21 -28
- package/dist/utils/auth.js +10 -4
- package/dist/utils/branch_notice.js +20 -19
- package/dist/utils/branch_picker.js +83 -89
- package/dist/utils/cli_name.js +15 -12
- package/dist/utils/compute_units.js +20 -27
- package/dist/utils/config_diff.js +127 -158
- package/dist/utils/enrichers.js +95 -148
- package/dist/utils/esbuild.js +130 -189
- package/dist/utils/flags.js +35 -47
- package/dist/utils/formats.js +8 -15
- package/dist/utils/git_diff.js +69 -80
- package/dist/utils/inspect_db.js +101 -143
- package/dist/utils/inspect_queries.js +179 -142
- package/dist/utils/middlewares.js +39 -45
- package/dist/utils/openapi.js +87 -99
- package/dist/utils/package_manager.js +312 -110
- package/dist/utils/point_in_time.js +49 -53
- package/dist/utils/psql.js +89 -106
- package/dist/utils/service_picker.js +55 -58
- package/dist/utils/string.js +5 -5
- package/dist/utils/ui.js +38 -55
- package/dist/utils/write_sync.js +26 -35
- package/dist/utils/zip.js +4 -3
- package/dist/writer.js +67 -87
- package/package.json +11 -6
- package/dist/_shared/auth_selection.js +0 -86
- package/dist/_shared/credentials.js +0 -209
- package/dist/_shared/env-core/env.js +0 -558
- package/dist/_shared/env-core/reuse-secrets.js +0 -223
- package/dist/_shared/paths.js +0 -148
- package/dist/_shared/profiles.js +0 -276
- package/dist/_shared/secure_file.js +0 -43
package/dist/psql/print/units.js
CHANGED
|
@@ -1,188 +1,186 @@
|
|
|
1
|
+
//#region src/psql/print/units.ts
|
|
1
2
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
* Numeric, byte size, and duration formatting helpers.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors psql's `\pset numericlocale`, the server-side
|
|
6
|
+
* `pg_size_pretty()` output, and the `\timing` line format.
|
|
7
|
+
*/
|
|
7
8
|
const NUMERIC_RE = /^-?\d+(\.\d+)?$/;
|
|
8
9
|
/** PostgreSQL `bool` type OID. Cells of this column type honour the
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
* `\pset display_true` / `\pset display_false` strings (PG 19+). */
|
|
11
|
+
const BOOLOID = 16;
|
|
11
12
|
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
* Extract the `\pset display_true`/`display_false` pair from a print-table
|
|
14
|
+
* options object, defaulting to psql's `'t'`/`'f'`. Kept here so every
|
|
15
|
+
* printer derives `boolDisplay` the same way.
|
|
16
|
+
*/
|
|
17
|
+
const boolDisplayOf = (topt) => ({
|
|
18
|
+
true: topt.truePrint ?? "t",
|
|
19
|
+
false: topt.falsePrint ?? "f"
|
|
19
20
|
});
|
|
20
21
|
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (typeof cell === "boolean")
|
|
49
|
-
return cell ? trueStr : falseStr;
|
|
50
|
-
if (cell instanceof Date)
|
|
51
|
-
return cell.toISOString();
|
|
52
|
-
if (cell instanceof Uint8Array) {
|
|
53
|
-
// Bytea -> hex escape, matching libpq's `\x` form.
|
|
54
|
-
let hex = "\\x";
|
|
55
|
-
for (const b of cell)
|
|
56
|
-
hex += b.toString(16).padStart(2, "0");
|
|
57
|
-
return hex;
|
|
58
|
-
}
|
|
59
|
-
return JSON.stringify(cell);
|
|
22
|
+
* Render a single result cell to its display string, shared by every
|
|
23
|
+
* table-format printer (aligned/unaligned/csv/html/latex/troff/asciidoc).
|
|
24
|
+
*
|
|
25
|
+
* Boolean handling mirrors upstream print.c: a cell in a BOOLOID column
|
|
26
|
+
* arriving over the wire as the text `'t'`/`'f'` (or a JS boolean, for
|
|
27
|
+
* synthetic result sets) renders through `boolDisplay`, which carries the
|
|
28
|
+
* `\pset display_true`/`display_false` values. `dataTypeID`/`boolDisplay`
|
|
29
|
+
* are optional so existing callers that don't thread column type through
|
|
30
|
+
* keep the prior behaviour (`'t'`/`'f'`).
|
|
31
|
+
*/
|
|
32
|
+
const renderCellValue = (cell, nullPrint, numericLocale, dataTypeID, boolDisplay, locale) => {
|
|
33
|
+
if (cell === null || cell === void 0) return nullPrint;
|
|
34
|
+
const trueStr = boolDisplay?.true ?? "t";
|
|
35
|
+
const falseStr = boolDisplay?.false ?? "f";
|
|
36
|
+
if (dataTypeID === 16 && typeof cell === "string") {
|
|
37
|
+
if (cell === "t" || cell === "f") return cell === "t" ? trueStr : falseStr;
|
|
38
|
+
}
|
|
39
|
+
if (typeof cell === "string") return formatNumericLocale(cell, numericLocale, locale);
|
|
40
|
+
if (typeof cell === "number" || typeof cell === "bigint") return formatNumericLocale(cell.toString(), numericLocale, locale);
|
|
41
|
+
if (typeof cell === "boolean") return cell ? trueStr : falseStr;
|
|
42
|
+
if (cell instanceof Date) return cell.toISOString();
|
|
43
|
+
if (cell instanceof Uint8Array) {
|
|
44
|
+
let hex = "\\x";
|
|
45
|
+
for (const b of cell) hex += b.toString(16).padStart(2, "0");
|
|
46
|
+
return hex;
|
|
47
|
+
}
|
|
48
|
+
return JSON.stringify(cell);
|
|
60
49
|
};
|
|
61
50
|
/**
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
useGrouping: true,
|
|
87
|
-
maximumFractionDigits: 0,
|
|
88
|
-
}).format(BigInt(intPart));
|
|
89
|
-
if (fractionDigits === 0) {
|
|
90
|
-
return negative ? `-${intFormatted}` : intFormatted;
|
|
91
|
-
}
|
|
92
|
-
// Discover this locale's decimal separator.
|
|
93
|
-
const decimalSep = new Intl.NumberFormat(locale)
|
|
94
|
-
.formatToParts(1.1)
|
|
95
|
-
.find((p) => p.type === "decimal")?.value ?? ".";
|
|
96
|
-
const out = `${intFormatted}${decimalSep}${fracPart}`;
|
|
97
|
-
return negative ? `-${out}` : out;
|
|
51
|
+
* Format a numeric string using locale-aware thousand separators and
|
|
52
|
+
* decimal point. Equivalent to print.c `format_numeric_locale` but
|
|
53
|
+
* implemented through the host's `Intl.NumberFormat`.
|
|
54
|
+
*
|
|
55
|
+
* When `useLocale` is false (the psql default) the input is returned
|
|
56
|
+
* unchanged. Only operates on values whose stringified form matches
|
|
57
|
+
* `^-?\d+(\.\d+)?$`; anything else (NaN, scientific notation, etc.) is
|
|
58
|
+
* returned as-is so we never mangle non-numeric data passed via
|
|
59
|
+
* `numericlocale`.
|
|
60
|
+
*/
|
|
61
|
+
const formatNumericLocale = (value, useLocale, locale) => {
|
|
62
|
+
if (!useLocale) return value;
|
|
63
|
+
if (!NUMERIC_RE.test(value)) return value;
|
|
64
|
+
const dotIdx = value.indexOf(".");
|
|
65
|
+
const fractionDigits = dotIdx === -1 ? 0 : value.length - dotIdx - 1;
|
|
66
|
+
const negative = value.startsWith("-");
|
|
67
|
+
const [intPart, fracPart = ""] = (negative ? value.slice(1) : value).split(".");
|
|
68
|
+
const intFormatted = new Intl.NumberFormat(locale, {
|
|
69
|
+
useGrouping: true,
|
|
70
|
+
maximumFractionDigits: 0
|
|
71
|
+
}).format(BigInt(intPart));
|
|
72
|
+
if (fractionDigits === 0) return negative ? `-${intFormatted}` : intFormatted;
|
|
73
|
+
const out = `${intFormatted}${new Intl.NumberFormat(locale).formatToParts(1.1).find((p) => p.type === "decimal")?.value ?? "."}${fracPart}`;
|
|
74
|
+
return negative ? `-${out}` : out;
|
|
98
75
|
};
|
|
99
76
|
const BYTE_UNITS = [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
77
|
+
{
|
|
78
|
+
name: "bytes",
|
|
79
|
+
bits: 0
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "kB",
|
|
83
|
+
bits: 10
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "MB",
|
|
87
|
+
bits: 20
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "GB",
|
|
91
|
+
bits: 30
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "TB",
|
|
95
|
+
bits: 40
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "PB",
|
|
99
|
+
bits: 50
|
|
100
|
+
}
|
|
106
101
|
];
|
|
107
102
|
const SI_UNITS = [
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
103
|
+
{
|
|
104
|
+
name: "B",
|
|
105
|
+
bits: 0
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "kB",
|
|
109
|
+
bits: 10
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "MB",
|
|
113
|
+
bits: 20
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "GB",
|
|
117
|
+
bits: 30
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "TB",
|
|
121
|
+
bits: 40
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "PB",
|
|
125
|
+
bits: 50
|
|
126
|
+
}
|
|
114
127
|
];
|
|
115
128
|
/**
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
while (unitIndex < units.length - 1 && abs >= 20 * 1024) {
|
|
139
|
-
abs = abs / 1024;
|
|
140
|
-
unitIndex++;
|
|
141
|
-
}
|
|
142
|
-
// One decimal place once we leave the `bytes` regime, matching the
|
|
143
|
-
// `0 B`, `1.0 kB`, `1.5 MB` shape the WP spec calls out.
|
|
144
|
-
return `${sign}${abs.toFixed(1)} ${units[unitIndex].name}`;
|
|
129
|
+
* Pretty-print a byte count.
|
|
130
|
+
*
|
|
131
|
+
* Follows pg's `pg_size_pretty` ladder: values under 10 240 use the
|
|
132
|
+
* `bytes` unit, otherwise we promote until the magnitude is below
|
|
133
|
+
* 20 * 1024 in the next unit and emit one decimal place.
|
|
134
|
+
*
|
|
135
|
+
* `opts.si` swaps the smallest unit name from `bytes` to `B`. (psql
|
|
136
|
+
* itself does not have an SI flag, but we expose one because callers
|
|
137
|
+
* outside the print path want a shorter `0 B` rendering.)
|
|
138
|
+
*/
|
|
139
|
+
const formatByteSize = (bytes, opts) => {
|
|
140
|
+
const units = opts?.si ? SI_UNITS : BYTE_UNITS;
|
|
141
|
+
const sign = bytes < 0 ? "-" : "";
|
|
142
|
+
let abs = Math.abs(bytes);
|
|
143
|
+
if (abs < 10240) return `${sign}${abs.toString()} ${units[0].name}`;
|
|
144
|
+
let unitIndex = 1;
|
|
145
|
+
abs = abs / 1024;
|
|
146
|
+
while (unitIndex < units.length - 1 && abs >= 20480) {
|
|
147
|
+
abs = abs / 1024;
|
|
148
|
+
unitIndex++;
|
|
149
|
+
}
|
|
150
|
+
return `${sign}${abs.toFixed(1)} ${units[unitIndex].name}`;
|
|
145
151
|
};
|
|
146
152
|
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
153
|
+
* Render a duration in the upstream `\timing` style. psql scales the
|
|
154
|
+
* granularity to keep the line compact:
|
|
155
|
+
*
|
|
156
|
+
* - `< 1 ms` → `Time: 0.123 ms` (three decimal digits)
|
|
157
|
+
* - `< 1 s` → `Time: 123.456 ms`
|
|
158
|
+
* - `< 1 min` → `Time: 12.345 s`
|
|
159
|
+
* - `< 1 hour` → `Time: 12 m 34.567 s`
|
|
160
|
+
* - `>= 1 hour` → `Time: 1 h 23 m 45.678 s`
|
|
161
|
+
*
|
|
162
|
+
* Mirrors the `PrintTiming()` ladder in `src/bin/psql/common.c`. Negative
|
|
163
|
+
* or non-finite inputs fall through the ladder as `0`.
|
|
164
|
+
*/
|
|
165
|
+
const formatDurationMs = (ms) => {
|
|
166
|
+
return `Time: ${formatDurationBody(ms)}`;
|
|
161
167
|
};
|
|
162
168
|
/**
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// Under one hour: `M m SS.sss s`.
|
|
179
|
-
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
180
|
-
const remainingSeconds = totalSeconds - totalMinutes * 60;
|
|
181
|
-
if (totalMinutes < 60) {
|
|
182
|
-
return `${String(totalMinutes)} m ${remainingSeconds.toFixed(3)} s`;
|
|
183
|
-
}
|
|
184
|
-
// One hour or more: `H h MM m SS.sss s`.
|
|
185
|
-
const hours = Math.floor(totalMinutes / 60);
|
|
186
|
-
const minutes = totalMinutes - hours * 60;
|
|
187
|
-
return `${String(hours)} h ${String(minutes)} m ${remainingSeconds.toFixed(3)} s`;
|
|
169
|
+
* Format just the scaled-duration body (without the `Time: ` prefix) so
|
|
170
|
+
* callers like the `\watch` header can reuse the same ladder without
|
|
171
|
+
* dragging the prefix along.
|
|
172
|
+
*/
|
|
173
|
+
const formatDurationBody = (ms) => {
|
|
174
|
+
const safe = Number.isFinite(ms) && ms > 0 ? ms : 0;
|
|
175
|
+
if (safe < 1e3) return `${safe.toFixed(3)} ms`;
|
|
176
|
+
const totalSeconds = safe / 1e3;
|
|
177
|
+
if (totalSeconds < 60) return `${totalSeconds.toFixed(3)} s`;
|
|
178
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
179
|
+
const remainingSeconds = totalSeconds - totalMinutes * 60;
|
|
180
|
+
if (totalMinutes < 60) return `${String(totalMinutes)} m ${remainingSeconds.toFixed(3)} s`;
|
|
181
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
182
|
+
const minutes = totalMinutes - hours * 60;
|
|
183
|
+
return `${String(hours)} h ${String(minutes)} m ${remainingSeconds.toFixed(3)} s`;
|
|
188
184
|
};
|
|
185
|
+
//#endregion
|
|
186
|
+
export { BOOLOID, boolDisplayOf, formatByteSize, formatDurationBody, formatDurationMs, formatNumericLocale, renderCellValue };
|