@prisma-next/cli 0.3.0-dev.16 → 0.3.0-dev.163
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/LICENSE +201 -0
- package/README.md +381 -128
- package/dist/cli-errors-BDCYR5ap.mjs +4 -0
- package/dist/cli-errors-Dzs7Oxz7.d.mts +3 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.js +1 -2671
- package/dist/cli.mjs +238 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-yYtotiSX.mjs +1063 -0
- package/dist/client-yYtotiSX.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts +7 -0
- package/dist/commands/contract-emit.d.mts.map +1 -0
- package/dist/commands/contract-emit.mjs +4 -0
- package/dist/commands/contract-infer.d.mts +7 -0
- package/dist/commands/contract-infer.d.mts.map +1 -0
- package/dist/commands/contract-infer.mjs +4 -0
- package/dist/commands/db-init.d.mts +7 -0
- package/dist/commands/db-init.d.mts.map +1 -0
- package/dist/commands/db-init.mjs +124 -0
- package/dist/commands/db-init.mjs.map +1 -0
- package/dist/commands/db-schema.d.mts +7 -0
- package/dist/commands/db-schema.d.mts.map +1 -0
- package/dist/commands/db-schema.mjs +52 -0
- package/dist/commands/db-schema.mjs.map +1 -0
- package/dist/commands/db-sign.d.mts +7 -0
- package/dist/commands/db-sign.d.mts.map +1 -0
- package/dist/commands/db-sign.mjs +135 -0
- package/dist/commands/db-sign.mjs.map +1 -0
- package/dist/commands/db-update.d.mts +7 -0
- package/dist/commands/db-update.d.mts.map +1 -0
- package/dist/commands/db-update.mjs +121 -0
- package/dist/commands/db-update.mjs.map +1 -0
- package/dist/commands/db-verify.d.mts +7 -0
- package/dist/commands/db-verify.d.mts.map +1 -0
- package/dist/commands/db-verify.mjs +321 -0
- package/dist/commands/db-verify.mjs.map +1 -0
- package/dist/commands/migration-apply.d.mts +36 -0
- package/dist/commands/migration-apply.d.mts.map +1 -0
- package/dist/commands/migration-apply.mjs +243 -0
- package/dist/commands/migration-apply.mjs.map +1 -0
- package/dist/commands/migration-new.d.mts +8 -0
- package/dist/commands/migration-new.d.mts.map +1 -0
- package/dist/commands/migration-new.mjs +151 -0
- package/dist/commands/migration-new.mjs.map +1 -0
- package/dist/commands/migration-plan.d.mts +47 -0
- package/dist/commands/migration-plan.d.mts.map +1 -0
- package/dist/commands/migration-plan.mjs +312 -0
- package/dist/commands/migration-plan.mjs.map +1 -0
- package/dist/commands/migration-ref.d.mts +43 -0
- package/dist/commands/migration-ref.d.mts.map +1 -0
- package/dist/commands/migration-ref.mjs +194 -0
- package/dist/commands/migration-ref.mjs.map +1 -0
- package/dist/commands/migration-show.d.mts +28 -0
- package/dist/commands/migration-show.d.mts.map +1 -0
- package/dist/commands/migration-show.mjs +139 -0
- package/dist/commands/migration-show.mjs.map +1 -0
- package/dist/commands/migration-status.d.mts +86 -0
- package/dist/commands/migration-status.d.mts.map +1 -0
- package/dist/commands/migration-status.mjs +4 -0
- package/dist/commands/migration-verify.d.mts +16 -0
- package/dist/commands/migration-verify.d.mts.map +1 -0
- package/dist/commands/migration-verify.mjs +109 -0
- package/dist/commands/migration-verify.mjs.map +1 -0
- package/dist/config-loader-C4VXKl8f.mjs +43 -0
- package/dist/config-loader-C4VXKl8f.mjs.map +1 -0
- package/dist/{config-loader.d.ts → config-loader.d.mts} +8 -3
- package/dist/config-loader.d.mts.map +1 -0
- package/dist/config-loader.mjs +3 -0
- package/dist/contract-emit-Bk_eEDKu.mjs +187 -0
- package/dist/contract-emit-Bk_eEDKu.mjs.map +1 -0
- package/dist/contract-infer-suMDmFSG.mjs +89 -0
- package/dist/contract-infer-suMDmFSG.mjs.map +1 -0
- package/dist/exports/config-types.d.mts +2 -0
- package/dist/exports/config-types.mjs +3 -0
- package/dist/exports/control-api.d.mts +624 -0
- package/dist/exports/control-api.d.mts.map +1 -0
- package/dist/exports/control-api.mjs +109 -0
- package/dist/exports/control-api.mjs.map +1 -0
- package/dist/{load-ts-contract.d.ts → exports/index.d.mts} +12 -7
- package/dist/exports/index.d.mts.map +1 -0
- package/dist/exports/index.mjs +137 -0
- package/dist/exports/index.mjs.map +1 -0
- package/dist/extract-operation-statements-BVlb3jxp.mjs +13 -0
- package/dist/extract-operation-statements-BVlb3jxp.mjs.map +1 -0
- package/dist/extract-sql-ddl-6EVSOThm.mjs +26 -0
- package/dist/extract-sql-ddl-6EVSOThm.mjs.map +1 -0
- package/dist/framework-components-BAsliT4V.mjs +59 -0
- package/dist/framework-components-BAsliT4V.mjs.map +1 -0
- package/dist/inspect-live-schema-HMutsJYh.mjs +91 -0
- package/dist/inspect-live-schema-HMutsJYh.mjs.map +1 -0
- package/dist/migration-command-scaffold-Dg7CKKCg.mjs +105 -0
- package/dist/migration-command-scaffold-Dg7CKKCg.mjs.map +1 -0
- package/dist/migration-status-BqfVmC0w.mjs +1582 -0
- package/dist/migration-status-BqfVmC0w.mjs.map +1 -0
- package/dist/migrations-Bv8oeiY_.mjs +173 -0
- package/dist/migrations-Bv8oeiY_.mjs.map +1 -0
- package/dist/progress-adapter-D4x8SbJa.mjs +43 -0
- package/dist/progress-adapter-D4x8SbJa.mjs.map +1 -0
- package/dist/terminal-ui-N5tR-ob5.mjs +967 -0
- package/dist/terminal-ui-N5tR-ob5.mjs.map +1 -0
- package/dist/verify-WARh5TjK.mjs +385 -0
- package/dist/verify-WARh5TjK.mjs.map +1 -0
- package/package.json +88 -42
- package/src/cli.ts +113 -58
- package/src/commands/contract-emit.ts +237 -144
- package/src/commands/contract-infer-paths.ts +32 -0
- package/src/commands/contract-infer.ts +143 -0
- package/src/commands/db-init.ts +97 -219
- package/src/commands/db-schema.ts +77 -0
- package/src/commands/db-sign.ts +208 -229
- package/src/commands/db-update.ts +236 -0
- package/src/commands/db-verify.ts +504 -184
- package/src/commands/inspect-live-schema.ts +170 -0
- package/src/commands/migration-apply.ts +427 -0
- package/src/commands/migration-new.ts +260 -0
- package/src/commands/migration-plan.ts +519 -0
- package/src/commands/migration-ref.ts +305 -0
- package/src/commands/migration-show.ts +246 -0
- package/src/commands/migration-status.ts +864 -0
- package/src/commands/migration-verify.ts +180 -0
- package/src/config-loader.ts +13 -3
- package/src/control-api/client.ts +424 -72
- package/src/control-api/contract-enrichment.ts +119 -0
- package/src/control-api/errors.ts +9 -0
- package/src/control-api/operations/contract-emit.ts +174 -0
- package/src/control-api/operations/db-init.ts +53 -49
- package/src/control-api/operations/db-update.ts +220 -0
- package/src/control-api/operations/extract-operation-statements.ts +14 -0
- package/src/control-api/operations/extract-sql-ddl.ts +47 -0
- package/src/control-api/operations/migration-apply.ts +191 -0
- package/src/control-api/operations/migration-helpers.ts +49 -0
- package/src/control-api/types.ts +388 -18
- package/src/exports/config-types.ts +4 -3
- package/src/exports/control-api.ts +21 -2
- package/src/load-ts-contract.ts +30 -19
- package/src/utils/cli-errors.ts +14 -8
- package/src/utils/command-helpers.ts +302 -3
- package/src/utils/formatters/emit.ts +67 -0
- package/src/utils/formatters/errors.ts +82 -0
- package/src/utils/formatters/graph-migration-mapper.ts +240 -0
- package/src/utils/formatters/graph-render.ts +1323 -0
- package/src/utils/formatters/graph-types.ts +120 -0
- package/src/utils/formatters/help.ts +380 -0
- package/src/utils/formatters/helpers.ts +28 -0
- package/src/utils/formatters/migrations.ts +346 -0
- package/src/utils/formatters/styled.ts +212 -0
- package/src/utils/formatters/verify.ts +621 -0
- package/src/utils/framework-components.ts +13 -10
- package/src/utils/global-flags.ts +41 -23
- package/src/utils/migration-command-scaffold.ts +184 -0
- package/src/utils/migration-types.ts +12 -0
- package/src/utils/progress-adapter.ts +18 -29
- package/src/utils/result-handler.ts +12 -13
- package/src/utils/shutdown.ts +92 -0
- package/src/utils/suggest-command.ts +31 -0
- package/src/utils/terminal-ui.ts +276 -0
- package/dist/chunk-5MPKZYVI.js +0 -47
- package/dist/chunk-5MPKZYVI.js.map +0 -1
- package/dist/chunk-6EPKRATC.js +0 -91
- package/dist/chunk-6EPKRATC.js.map +0 -1
- package/dist/chunk-74IELXRA.js +0 -371
- package/dist/chunk-74IELXRA.js.map +0 -1
- package/dist/chunk-HWYQOCAJ.js +0 -47
- package/dist/chunk-HWYQOCAJ.js.map +0 -1
- package/dist/chunk-U6QI3AZ3.js +0 -133
- package/dist/chunk-U6QI3AZ3.js.map +0 -1
- package/dist/chunk-VI2YETW7.js +0 -38
- package/dist/chunk-VI2YETW7.js.map +0 -1
- package/dist/chunk-ZG5T6OB5.js +0 -923
- package/dist/chunk-ZG5T6OB5.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/contract-emit.d.ts +0 -3
- package/dist/commands/contract-emit.d.ts.map +0 -1
- package/dist/commands/contract-emit.js +0 -11
- package/dist/commands/contract-emit.js.map +0 -1
- package/dist/commands/db-init.d.ts +0 -3
- package/dist/commands/db-init.d.ts.map +0 -1
- package/dist/commands/db-init.js +0 -302
- package/dist/commands/db-init.js.map +0 -1
- package/dist/commands/db-introspect.d.ts +0 -3
- package/dist/commands/db-introspect.d.ts.map +0 -1
- package/dist/commands/db-introspect.js +0 -185
- package/dist/commands/db-introspect.js.map +0 -1
- package/dist/commands/db-schema-verify.d.ts +0 -3
- package/dist/commands/db-schema-verify.d.ts.map +0 -1
- package/dist/commands/db-schema-verify.js +0 -163
- package/dist/commands/db-schema-verify.js.map +0 -1
- package/dist/commands/db-sign.d.ts +0 -3
- package/dist/commands/db-sign.d.ts.map +0 -1
- package/dist/commands/db-sign.js +0 -198
- package/dist/commands/db-sign.js.map +0 -1
- package/dist/commands/db-verify.d.ts +0 -3
- package/dist/commands/db-verify.d.ts.map +0 -1
- package/dist/commands/db-verify.js +0 -172
- package/dist/commands/db-verify.js.map +0 -1
- package/dist/config-loader.d.ts.map +0 -1
- package/dist/config-loader.js +0 -7
- package/dist/config-loader.js.map +0 -1
- package/dist/control-api/client.d.ts +0 -13
- package/dist/control-api/client.d.ts.map +0 -1
- package/dist/control-api/operations/db-init.d.ts +0 -29
- package/dist/control-api/operations/db-init.d.ts.map +0 -1
- package/dist/control-api/types.d.ts +0 -256
- package/dist/control-api/types.d.ts.map +0 -1
- package/dist/exports/config-types.d.ts +0 -3
- package/dist/exports/config-types.d.ts.map +0 -1
- package/dist/exports/config-types.js +0 -6
- package/dist/exports/config-types.js.map +0 -1
- package/dist/exports/control-api.d.ts +0 -13
- package/dist/exports/control-api.d.ts.map +0 -1
- package/dist/exports/control-api.js +0 -9
- package/dist/exports/control-api.js.map +0 -1
- package/dist/exports/index.d.ts +0 -4
- package/dist/exports/index.d.ts.map +0 -1
- package/dist/exports/index.js +0 -177
- package/dist/exports/index.js.map +0 -1
- package/dist/load-ts-contract.d.ts.map +0 -1
- package/dist/utils/action.d.ts +0 -16
- package/dist/utils/action.d.ts.map +0 -1
- package/dist/utils/cli-errors.d.ts +0 -7
- package/dist/utils/cli-errors.d.ts.map +0 -1
- package/dist/utils/command-helpers.d.ts +0 -12
- package/dist/utils/command-helpers.d.ts.map +0 -1
- package/dist/utils/framework-components.d.ts +0 -70
- package/dist/utils/framework-components.d.ts.map +0 -1
- package/dist/utils/global-flags.d.ts +0 -25
- package/dist/utils/global-flags.d.ts.map +0 -1
- package/dist/utils/output.d.ts +0 -142
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/progress-adapter.d.ts +0 -26
- package/dist/utils/progress-adapter.d.ts.map +0 -1
- package/dist/utils/result-handler.d.ts +0 -15
- package/dist/utils/result-handler.d.ts.map +0 -1
- package/dist/utils/spinner.d.ts +0 -29
- package/dist/utils/spinner.d.ts.map +0 -1
- package/src/commands/db-introspect.ts +0 -254
- package/src/commands/db-schema-verify.ts +0 -231
- package/src/utils/action.ts +0 -43
- package/src/utils/output.ts +0 -1471
- package/src/utils/spinner.ts +0 -67
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import * as clack from '@clack/prompts';
|
|
2
|
+
import { bold, cyan, dim, green, red, yellow } from 'colorette';
|
|
3
|
+
import { shutdownSignal } from './shutdown';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Composable CLI output abstraction.
|
|
7
|
+
*
|
|
8
|
+
* Follows the Unix convention of separating data from decoration:
|
|
9
|
+
* - **stdout** — data output only (`ui.output()`). This is what scripts and pipes capture.
|
|
10
|
+
* - **stderr** — all decoration (spinners, logs, notes, intro/outro). Visible in terminal, invisible in pipes.
|
|
11
|
+
*
|
|
12
|
+
* Rules:
|
|
13
|
+
* 1. All methods except `output()` and `error()` write to stderr only in interactive mode.
|
|
14
|
+
* 2. `output(data)` always writes to stdout — if a command calls it, there is data to emit.
|
|
15
|
+
* 3. `error()` always writes to stderr — errors matter even when piped.
|
|
16
|
+
* 4. All other decoration is suppressed when piped — `isInteractive` gates every other decoration method.
|
|
17
|
+
* 5. Never write data to stderr — decoration methods are for human context only.
|
|
18
|
+
* 6. Never write decoration to stdout — it breaks pipes, `$(...)` captures, and `> file` redirects.
|
|
19
|
+
*/
|
|
20
|
+
export class TerminalUI {
|
|
21
|
+
/**
|
|
22
|
+
* True when stdout is a TTY (interactive terminal).
|
|
23
|
+
* False when piped (e.g., `prisma-next db verify | jq`).
|
|
24
|
+
*/
|
|
25
|
+
readonly isInteractive: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Whether color output is enabled.
|
|
29
|
+
*/
|
|
30
|
+
readonly useColor: boolean;
|
|
31
|
+
|
|
32
|
+
private static readonly stderrOpts = { output: process.stderr } as const;
|
|
33
|
+
|
|
34
|
+
constructor(options?: {
|
|
35
|
+
readonly color?: boolean | undefined;
|
|
36
|
+
readonly interactive?: boolean | undefined;
|
|
37
|
+
}) {
|
|
38
|
+
// --interactive/--no-interactive override TTY detection
|
|
39
|
+
this.isInteractive = options?.interactive ?? !!process.stdout.isTTY;
|
|
40
|
+
this.useColor = options?.color ?? this.isInteractive;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Decoration → stderr (only in interactive mode)
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Log a message line to stderr. No-op when piped.
|
|
49
|
+
*/
|
|
50
|
+
log(message: string): void {
|
|
51
|
+
if (!this.isInteractive) return;
|
|
52
|
+
clack.log.message(message, TerminalUI.stderrOpts);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Log a success message to stderr. No-op when piped.
|
|
57
|
+
*/
|
|
58
|
+
success(message: string): void {
|
|
59
|
+
if (!this.isInteractive) return;
|
|
60
|
+
clack.log.success(message, TerminalUI.stderrOpts);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Log a warning message to stderr. No-op when piped.
|
|
65
|
+
*/
|
|
66
|
+
warn(message: string): void {
|
|
67
|
+
if (!this.isInteractive) return;
|
|
68
|
+
clack.log.warn(message, TerminalUI.stderrOpts);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Log an error message to stderr. Always writes (errors matter even in pipes).
|
|
73
|
+
*/
|
|
74
|
+
error(message: string): void {
|
|
75
|
+
clack.log.error(message, TerminalUI.stderrOpts);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Log an info message to stderr. No-op when piped.
|
|
80
|
+
*/
|
|
81
|
+
info(message: string): void {
|
|
82
|
+
if (!this.isInteractive) return;
|
|
83
|
+
clack.log.info(message, TerminalUI.stderrOpts);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Log a step message to stderr. No-op when piped.
|
|
88
|
+
*/
|
|
89
|
+
step(message: string): void {
|
|
90
|
+
if (!this.isInteractive) return;
|
|
91
|
+
clack.log.step(message, TerminalUI.stderrOpts);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Display a note box on stderr. No-op when piped.
|
|
96
|
+
*/
|
|
97
|
+
note(message: string, title?: string): void {
|
|
98
|
+
if (!this.isInteractive) return;
|
|
99
|
+
clack.note(message, title, TerminalUI.stderrOpts);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Display intro banner on stderr. No-op when piped.
|
|
104
|
+
*/
|
|
105
|
+
intro(title?: string): void {
|
|
106
|
+
if (!this.isInteractive) return;
|
|
107
|
+
clack.intro(title, TerminalUI.stderrOpts);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Display outro banner on stderr. No-op when piped.
|
|
112
|
+
*/
|
|
113
|
+
outro(message?: string): void {
|
|
114
|
+
if (!this.isInteractive) return;
|
|
115
|
+
clack.outro(message, TerminalUI.stderrOpts);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Create a Clack spinner on stderr with a 100ms delay threshold.
|
|
120
|
+
* The spinner only appears if the operation takes longer than the threshold,
|
|
121
|
+
* avoiding flicker for fast operations. Returns a no-op spinner when not interactive.
|
|
122
|
+
*/
|
|
123
|
+
spinner(delayMs = 100): clack.SpinnerResult {
|
|
124
|
+
const noop: clack.SpinnerResult = {
|
|
125
|
+
start: () => {},
|
|
126
|
+
stop: () => {},
|
|
127
|
+
cancel: () => {},
|
|
128
|
+
error: () => {},
|
|
129
|
+
message: () => {},
|
|
130
|
+
clear: () => {},
|
|
131
|
+
get isCancelled() {
|
|
132
|
+
return false;
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
if (!this.isInteractive) {
|
|
137
|
+
return noop;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Wrap the real spinner with a delay: only show it after `delayMs`
|
|
141
|
+
let inner: clack.SpinnerResult | undefined;
|
|
142
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
143
|
+
let pendingMsg: string | undefined;
|
|
144
|
+
let settled = false;
|
|
145
|
+
|
|
146
|
+
const ensureCleared = () => {
|
|
147
|
+
if (timer !== undefined) {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
timer = undefined;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Cancel the spinner if a shutdown signal fires
|
|
154
|
+
const onAbort = () => {
|
|
155
|
+
if (!settled) {
|
|
156
|
+
settled = true;
|
|
157
|
+
ensureCleared();
|
|
158
|
+
if (inner) {
|
|
159
|
+
inner.cancel('Interrupted');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
if (!shutdownSignal.aborted) {
|
|
164
|
+
shutdownSignal.addEventListener('abort', onAbort, { once: true });
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
start(msg?: string) {
|
|
169
|
+
pendingMsg = msg;
|
|
170
|
+
timer = setTimeout(() => {
|
|
171
|
+
if (!settled) {
|
|
172
|
+
inner = clack.spinner(TerminalUI.stderrOpts);
|
|
173
|
+
inner.start(pendingMsg);
|
|
174
|
+
}
|
|
175
|
+
}, delayMs);
|
|
176
|
+
},
|
|
177
|
+
stop(msg?: string) {
|
|
178
|
+
settled = true;
|
|
179
|
+
ensureCleared();
|
|
180
|
+
if (inner) {
|
|
181
|
+
inner.stop(msg);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
cancel(msg?: string) {
|
|
185
|
+
settled = true;
|
|
186
|
+
ensureCleared();
|
|
187
|
+
if (inner) {
|
|
188
|
+
inner.cancel(msg);
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
error(msg?: string) {
|
|
192
|
+
settled = true;
|
|
193
|
+
ensureCleared();
|
|
194
|
+
if (inner) {
|
|
195
|
+
inner.error(msg);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
message(msg?: string) {
|
|
199
|
+
pendingMsg = msg;
|
|
200
|
+
if (inner) {
|
|
201
|
+
inner.message(msg);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
clear() {
|
|
205
|
+
settled = true;
|
|
206
|
+
ensureCleared();
|
|
207
|
+
if (inner) {
|
|
208
|
+
inner.clear();
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
get isCancelled() {
|
|
212
|
+
return inner?.isCancelled ?? false;
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Prompt for yes/no confirmation on stderr. Returns true if confirmed.
|
|
219
|
+
* In non-interactive mode or when cancelled (Ctrl-C), returns false.
|
|
220
|
+
*/
|
|
221
|
+
async confirm(message: string): Promise<boolean> {
|
|
222
|
+
if (!this.isInteractive) return false;
|
|
223
|
+
const result = await clack.confirm({
|
|
224
|
+
message,
|
|
225
|
+
...TerminalUI.stderrOpts,
|
|
226
|
+
});
|
|
227
|
+
if (clack.isCancel(result)) return false;
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Write a raw line to stderr. No-op when piped.
|
|
233
|
+
* Use for decoration that doesn't fit Clack's log format (e.g. styled headers).
|
|
234
|
+
*/
|
|
235
|
+
stderr(message: string): void {
|
|
236
|
+
if (!this.isInteractive) return;
|
|
237
|
+
process.stderr.write(`${message}\n`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ---------------------------------------------------------------------------
|
|
241
|
+
// Data → stdout (only when piped)
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Write machine-readable data to stdout.
|
|
246
|
+
* Always writes — if a command calls output(), there is data to emit.
|
|
247
|
+
*
|
|
248
|
+
* This is what scripts and pipes capture: `prisma-next db verify --json | jq .ok`
|
|
249
|
+
*/
|
|
250
|
+
output(data: string): void {
|
|
251
|
+
process.stdout.write(`${data}\n`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Color helpers
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
|
|
258
|
+
green(text: string): string {
|
|
259
|
+
return this.useColor ? green(text) : text;
|
|
260
|
+
}
|
|
261
|
+
red(text: string): string {
|
|
262
|
+
return this.useColor ? red(text) : text;
|
|
263
|
+
}
|
|
264
|
+
cyan(text: string): string {
|
|
265
|
+
return this.useColor ? cyan(text) : text;
|
|
266
|
+
}
|
|
267
|
+
dim(text: string): string {
|
|
268
|
+
return this.useColor ? dim(text) : text;
|
|
269
|
+
}
|
|
270
|
+
bold(text: string): string {
|
|
271
|
+
return this.useColor ? bold(text) : text;
|
|
272
|
+
}
|
|
273
|
+
yellow(text: string): string {
|
|
274
|
+
return this.useColor ? yellow(text) : text;
|
|
275
|
+
}
|
|
276
|
+
}
|
package/dist/chunk-5MPKZYVI.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CliStructuredError
|
|
3
|
-
} from "./chunk-VI2YETW7.js";
|
|
4
|
-
|
|
5
|
-
// src/utils/action.ts
|
|
6
|
-
import { notOk, ok } from "@prisma-next/utils/result";
|
|
7
|
-
async function performAction(fn) {
|
|
8
|
-
try {
|
|
9
|
-
const value = await fn();
|
|
10
|
-
return ok(value);
|
|
11
|
-
} catch (error) {
|
|
12
|
-
if (error instanceof CliStructuredError) {
|
|
13
|
-
return notOk(error);
|
|
14
|
-
}
|
|
15
|
-
throw error;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// src/utils/spinner.ts
|
|
20
|
-
import ora from "ora";
|
|
21
|
-
async function withSpinner(operation, options) {
|
|
22
|
-
const { message, flags } = options;
|
|
23
|
-
const shouldShowSpinner = !flags.quiet && flags.json !== "object" && process.stdout.isTTY;
|
|
24
|
-
if (!shouldShowSpinner) {
|
|
25
|
-
return operation();
|
|
26
|
-
}
|
|
27
|
-
const startTime = Date.now();
|
|
28
|
-
const spinner = ora({
|
|
29
|
-
text: message,
|
|
30
|
-
color: flags.color !== false ? "cyan" : false
|
|
31
|
-
}).start();
|
|
32
|
-
try {
|
|
33
|
-
const result = await operation();
|
|
34
|
-
const elapsed = Date.now() - startTime;
|
|
35
|
-
spinner.succeed(`${message} (${elapsed}ms)`);
|
|
36
|
-
return result;
|
|
37
|
-
} catch (error) {
|
|
38
|
-
spinner.fail(`${message} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export {
|
|
44
|
-
performAction,
|
|
45
|
-
withSpinner
|
|
46
|
-
};
|
|
47
|
-
//# sourceMappingURL=chunk-5MPKZYVI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/action.ts","../src/utils/spinner.ts"],"sourcesContent":["import type { Result } from '@prisma-next/utils/result';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { CliStructuredError } from './cli-errors';\n\nexport type CliResult<T> = Result<T, CliStructuredError>;\n\n/**\n * Performs an async action and catches structured errors, returning a Result.\n * Only catches CliStructuredError instances - other errors are allowed to propagate (fail fast).\n * If the function throws a CliStructuredError, it's caught and converted to a NotOk result.\n */\nexport async function performAction<T>(fn: () => Promise<T>): Promise<CliResult<T>> {\n try {\n const value = await fn();\n return ok(value);\n } catch (error) {\n // Only catch structured errors - let other errors propagate (fail fast)\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n // Re-throw non-structured errors to fail fast\n throw error;\n }\n}\n\n/**\n * Wraps a synchronous function to catch structured errors and return a Result.\n * Only catches CliStructuredError instances - other errors are allowed to propagate (fail fast).\n * If the function throws a CliStructuredError, it's caught and converted to a NotOk result.\n */\nexport function wrapSync<T>(fn: () => T): CliResult<T> {\n try {\n const value = fn();\n return ok(value);\n } catch (error) {\n // Only catch structured errors - let other errors propagate (fail fast)\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n // Re-throw non-structured errors to fail fast\n throw error;\n }\n}\n","import ora from 'ora';\nimport type { GlobalFlags } from './global-flags';\n\n/**\n * Options for the withSpinner helper function.\n */\ninterface WithSpinnerOptions {\n /**\n * The message to display in the spinner.\n */\n readonly message: string;\n /**\n * Global flags that control spinner behavior (quiet, json, color).\n */\n readonly flags: GlobalFlags;\n}\n\n/**\n * Wraps an async operation with a spinner.\n *\n * The spinner respects:\n * - `flags.quiet`: No spinner if quiet mode is enabled\n * - `flags.json === 'object'`: No spinner if JSON output is enabled\n * - Non-TTY environments: No spinner if stdout is not a TTY\n *\n * @param operation - The async operation to execute\n * @param options - Spinner configuration options\n * @returns The result of the operation\n */\nexport async function withSpinner<T>(\n operation: () => Promise<T>,\n options: WithSpinnerOptions,\n): Promise<T> {\n const { message, flags } = options;\n\n // Skip spinner if quiet, JSON output, or non-TTY\n const shouldShowSpinner = !flags.quiet && flags.json !== 'object' && process.stdout.isTTY;\n\n if (!shouldShowSpinner) {\n // Just execute the operation without spinner\n return operation();\n }\n\n // Start spinner immediately\n const startTime = Date.now();\n const spinner = ora({\n text: message,\n color: flags.color !== false ? 'cyan' : false,\n }).start();\n\n try {\n // Execute the operation\n const result = await operation();\n\n // Mark spinner as succeeded\n const elapsed = Date.now() - startTime;\n spinner.succeed(`${message} (${elapsed}ms)`);\n\n return result;\n } catch (error) {\n // Mark spinner as failed\n spinner.fail(`${message} failed: ${error instanceof Error ? error.message : String(error)}`);\n\n // Re-throw the error\n throw error;\n }\n}\n"],"mappings":";;;;;AACA,SAAS,OAAO,UAAU;AAU1B,eAAsB,cAAiB,IAA6C;AAClF,MAAI;AACF,UAAM,QAAQ,MAAM,GAAG;AACvB,WAAO,GAAG,KAAK;AAAA,EACjB,SAAS,OAAO;AAEd,QAAI,iBAAiB,oBAAoB;AACvC,aAAO,MAAM,KAAK;AAAA,IACpB;AAEA,UAAM;AAAA,EACR;AACF;;;ACvBA,OAAO,SAAS;AA6BhB,eAAsB,YACpB,WACA,SACY;AACZ,QAAM,EAAE,SAAS,MAAM,IAAI;AAG3B,QAAM,oBAAoB,CAAC,MAAM,SAAS,MAAM,SAAS,YAAY,QAAQ,OAAO;AAEpF,MAAI,CAAC,mBAAmB;AAEtB,WAAO,UAAU;AAAA,EACnB;AAGA,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,UAAU,IAAI;AAAA,IAClB,MAAM;AAAA,IACN,OAAO,MAAM,UAAU,QAAQ,SAAS;AAAA,EAC1C,CAAC,EAAE,MAAM;AAET,MAAI;AAEF,UAAM,SAAS,MAAM,UAAU;AAG/B,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,YAAQ,QAAQ,GAAG,OAAO,KAAK,OAAO,KAAK;AAE3C,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,YAAQ,KAAK,GAAG,OAAO,YAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAG3F,UAAM;AAAA,EACR;AACF;","names":[]}
|
package/dist/chunk-6EPKRATC.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
errorConfigValidation,
|
|
3
|
-
errorContractMissingExtensionPacks
|
|
4
|
-
} from "./chunk-VI2YETW7.js";
|
|
5
|
-
|
|
6
|
-
// src/utils/framework-components.ts
|
|
7
|
-
import {
|
|
8
|
-
checkContractComponentRequirements
|
|
9
|
-
} from "@prisma-next/contract/framework-components";
|
|
10
|
-
function assertFrameworkComponentsCompatible(expectedFamilyId, expectedTargetId, frameworkComponents) {
|
|
11
|
-
for (let i = 0; i < frameworkComponents.length; i++) {
|
|
12
|
-
const component = frameworkComponents[i];
|
|
13
|
-
if (typeof component !== "object" || component === null) {
|
|
14
|
-
throw errorConfigValidation("frameworkComponents[]", {
|
|
15
|
-
why: `Framework component at index ${i} must be an object`
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
const record = component;
|
|
19
|
-
if (!Object.hasOwn(record, "kind")) {
|
|
20
|
-
throw errorConfigValidation("frameworkComponents[].kind", {
|
|
21
|
-
why: `Framework component at index ${i} must have 'kind' property`
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
const kind = record["kind"];
|
|
25
|
-
if (kind !== "target" && kind !== "adapter" && kind !== "extension" && kind !== "driver") {
|
|
26
|
-
throw errorConfigValidation("frameworkComponents[].kind", {
|
|
27
|
-
why: `Framework component at index ${i} has invalid kind '${String(kind)}' (must be 'target', 'adapter', 'extension', or 'driver')`
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
if (!Object.hasOwn(record, "familyId")) {
|
|
31
|
-
throw errorConfigValidation("frameworkComponents[].familyId", {
|
|
32
|
-
why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'familyId' property`
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
const familyId = record["familyId"];
|
|
36
|
-
if (familyId !== expectedFamilyId) {
|
|
37
|
-
throw errorConfigValidation("frameworkComponents[].familyId", {
|
|
38
|
-
why: `Framework component at index ${i} (kind: ${String(kind)}) has familyId '${String(familyId)}' but expected '${expectedFamilyId}'`
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
if (!Object.hasOwn(record, "targetId")) {
|
|
42
|
-
throw errorConfigValidation("frameworkComponents[].targetId", {
|
|
43
|
-
why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'targetId' property`
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
const targetId = record["targetId"];
|
|
47
|
-
if (targetId !== expectedTargetId) {
|
|
48
|
-
throw errorConfigValidation("frameworkComponents[].targetId", {
|
|
49
|
-
why: `Framework component at index ${i} (kind: ${String(kind)}) has targetId '${String(targetId)}' but expected '${expectedTargetId}'`
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return frameworkComponents;
|
|
54
|
-
}
|
|
55
|
-
function assertContractRequirementsSatisfied({
|
|
56
|
-
contract,
|
|
57
|
-
stack
|
|
58
|
-
}) {
|
|
59
|
-
const providedComponentIds = /* @__PURE__ */ new Set([stack.target.id, stack.adapter.id]);
|
|
60
|
-
for (const extension of stack.extensionPacks) {
|
|
61
|
-
providedComponentIds.add(extension.id);
|
|
62
|
-
}
|
|
63
|
-
const result = checkContractComponentRequirements({
|
|
64
|
-
contract,
|
|
65
|
-
expectedTargetFamily: stack.target.familyId,
|
|
66
|
-
expectedTargetId: stack.target.targetId,
|
|
67
|
-
providedComponentIds
|
|
68
|
-
});
|
|
69
|
-
if (result.familyMismatch) {
|
|
70
|
-
throw errorConfigValidation("contract.targetFamily", {
|
|
71
|
-
why: `Contract was emitted for family '${result.familyMismatch.actual}' but CLI config is wired to '${result.familyMismatch.expected}'.`
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
if (result.targetMismatch) {
|
|
75
|
-
throw errorConfigValidation("contract.target", {
|
|
76
|
-
why: `Contract target '${result.targetMismatch.actual}' does not match CLI target '${result.targetMismatch.expected}'.`
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
if (result.missingExtensionPackIds.length > 0) {
|
|
80
|
-
throw errorContractMissingExtensionPacks({
|
|
81
|
-
missingExtensionPacks: result.missingExtensionPackIds,
|
|
82
|
-
providedComponentIds: [...providedComponentIds]
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export {
|
|
88
|
-
assertFrameworkComponentsCompatible,
|
|
89
|
-
assertContractRequirementsSatisfied
|
|
90
|
-
};
|
|
91
|
-
//# sourceMappingURL=chunk-6EPKRATC.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/framework-components.ts"],"sourcesContent":["import {\n checkContractComponentRequirements,\n type TargetBoundComponentDescriptor,\n} from '@prisma-next/contract/framework-components';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport type { ControlPlaneStack } from '@prisma-next/core-control-plane/types';\nimport { errorConfigValidation, errorContractMissingExtensionPacks } from './cli-errors';\n\n/**\n * Asserts that all framework components are compatible with the expected family and target.\n *\n * This function validates that each component in the framework components array:\n * - Has kind 'target', 'adapter', 'extension', or 'driver'\n * - Has familyId matching expectedFamilyId\n * - Has targetId matching expectedTargetId\n *\n * This validation happens at the CLI composition boundary, before passing components\n * to typed planner/runner instances. It fills the gap between runtime validation\n * (via `validateConfig()`) and compile-time type enforcement.\n *\n * @param expectedFamilyId - The expected family ID (e.g., 'sql')\n * @param expectedTargetId - The expected target ID (e.g., 'postgres')\n * @param frameworkComponents - Array of framework components to validate\n * @returns The same array typed as TargetBoundComponentDescriptor\n * @throws CliStructuredError if any component is incompatible\n *\n * @example\n * ```ts\n * const config = await loadConfig();\n * const frameworkComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];\n *\n * // Validate and type-narrow components before passing to planner\n * const typedComponents = assertFrameworkComponentsCompatible(\n * config.family.familyId,\n * config.target.targetId,\n * frameworkComponents\n * );\n *\n * const planner = target.migrations.createPlanner(familyInstance);\n * planner.plan({ contract, schema, policy, frameworkComponents: typedComponents });\n * ```\n */\nexport function assertFrameworkComponentsCompatible<\n TFamilyId extends string,\n TTargetId extends string,\n>(\n expectedFamilyId: TFamilyId,\n expectedTargetId: TTargetId,\n frameworkComponents: ReadonlyArray<unknown>,\n): ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>> {\n for (let i = 0; i < frameworkComponents.length; i++) {\n const component = frameworkComponents[i];\n\n // Check that component is an object\n if (typeof component !== 'object' || component === null) {\n throw errorConfigValidation('frameworkComponents[]', {\n why: `Framework component at index ${i} must be an object`,\n });\n }\n\n const record = component as Record<string, unknown>;\n\n // Check kind\n if (!Object.hasOwn(record, 'kind')) {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} must have 'kind' property`,\n });\n }\n\n const kind = record['kind'];\n if (kind !== 'target' && kind !== 'adapter' && kind !== 'extension' && kind !== 'driver') {\n throw errorConfigValidation('frameworkComponents[].kind', {\n why: `Framework component at index ${i} has invalid kind '${String(kind)}' (must be 'target', 'adapter', 'extension', or 'driver')`,\n });\n }\n\n // Check familyId\n if (!Object.hasOwn(record, 'familyId')) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'familyId' property`,\n });\n }\n\n const familyId = record['familyId'];\n if (familyId !== expectedFamilyId) {\n throw errorConfigValidation('frameworkComponents[].familyId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has familyId '${String(familyId)}' but expected '${expectedFamilyId}'`,\n });\n }\n\n // Check targetId\n if (!Object.hasOwn(record, 'targetId')) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) must have 'targetId' property`,\n });\n }\n\n const targetId = record['targetId'];\n if (targetId !== expectedTargetId) {\n throw errorConfigValidation('frameworkComponents[].targetId', {\n why: `Framework component at index ${i} (kind: ${String(kind)}) has targetId '${String(targetId)}' but expected '${expectedTargetId}'`,\n });\n }\n }\n\n // Type assertion is safe because we've validated all components above\n return frameworkComponents as ReadonlyArray<TargetBoundComponentDescriptor<TFamilyId, TTargetId>>;\n}\n\n/**\n * Validates that a contract is compatible with the configured target, adapter,\n * and extension packs. Throws on family/target mismatches or missing extension packs.\n *\n * This check ensures the emitted contract matches the CLI config before running\n * commands that depend on the contract (e.g., db verify, db sign).\n *\n * @param contract - The contract IR to validate (must include targetFamily, target, extensionPacks).\n * @param stack - The control plane stack (target, adapter, driver, extensionPacks).\n *\n * @throws {CliStructuredError} errorConfigValidation when contract.targetFamily or contract.target\n * doesn't match the configured family/target.\n * @throws {CliStructuredError} errorContractMissingExtensionPacks when the contract requires\n * extension packs that are not provided in the config (includes all missing packs in error.meta).\n *\n * @example\n * ```ts\n * import { assertContractRequirementsSatisfied } from './framework-components';\n *\n * const config = await loadConfig();\n * const contractIR = await loadContractJson(config.contract.output);\n * const stack = createControlPlaneStack({ target: config.target, adapter: config.adapter, ... });\n *\n * // Throws if contract is incompatible with config\n * assertContractRequirementsSatisfied({ contract: contractIR, stack });\n * ```\n */\nexport function assertContractRequirementsSatisfied<\n TFamilyId extends string,\n TTargetId extends string,\n>({\n contract,\n stack,\n}: {\n readonly contract: Pick<ContractIR, 'targetFamily' | 'target' | 'extensionPacks'>;\n readonly stack: ControlPlaneStack<TFamilyId, TTargetId>;\n}): void {\n const providedComponentIds = new Set<string>([stack.target.id, stack.adapter.id]);\n for (const extension of stack.extensionPacks) {\n providedComponentIds.add(extension.id);\n }\n\n const result = checkContractComponentRequirements({\n contract,\n expectedTargetFamily: stack.target.familyId,\n expectedTargetId: stack.target.targetId,\n providedComponentIds,\n });\n\n if (result.familyMismatch) {\n throw errorConfigValidation('contract.targetFamily', {\n why: `Contract was emitted for family '${result.familyMismatch.actual}' but CLI config is wired to '${result.familyMismatch.expected}'.`,\n });\n }\n\n if (result.targetMismatch) {\n throw errorConfigValidation('contract.target', {\n why: `Contract target '${result.targetMismatch.actual}' does not match CLI target '${result.targetMismatch.expected}'.`,\n });\n }\n\n if (result.missingExtensionPackIds.length > 0) {\n throw errorContractMissingExtensionPacks({\n missingExtensionPacks: result.missingExtensionPackIds,\n providedComponentIds: [...providedComponentIds],\n });\n }\n}\n"],"mappings":";;;;;;AAAA;AAAA,EACE;AAAA,OAEK;AAuCA,SAAS,oCAId,kBACA,kBACA,qBACqE;AACrE,WAAS,IAAI,GAAG,IAAI,oBAAoB,QAAQ,KAAK;AACnD,UAAM,YAAY,oBAAoB,CAAC;AAGvC,QAAI,OAAO,cAAc,YAAY,cAAc,MAAM;AACvD,YAAM,sBAAsB,yBAAyB;AAAA,QACnD,KAAK,gCAAgC,CAAC;AAAA,MACxC,CAAC;AAAA,IACH;AAEA,UAAM,SAAS;AAGf,QAAI,CAAC,OAAO,OAAO,QAAQ,MAAM,GAAG;AAClC,YAAM,sBAAsB,8BAA8B;AAAA,QACxD,KAAK,gCAAgC,CAAC;AAAA,MACxC,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,OAAO,MAAM;AAC1B,QAAI,SAAS,YAAY,SAAS,aAAa,SAAS,eAAe,SAAS,UAAU;AACxF,YAAM,sBAAsB,8BAA8B;AAAA,QACxD,KAAK,gCAAgC,CAAC,sBAAsB,OAAO,IAAI,CAAC;AAAA,MAC1E,CAAC;AAAA,IACH;AAGA,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,GAAG;AACtC,YAAM,sBAAsB,kCAAkC;AAAA,QAC5D,KAAK,gCAAgC,CAAC,WAAW,OAAO,IAAI,CAAC;AAAA,MAC/D,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,OAAO,UAAU;AAClC,QAAI,aAAa,kBAAkB;AACjC,YAAM,sBAAsB,kCAAkC;AAAA,QAC5D,KAAK,gCAAgC,CAAC,WAAW,OAAO,IAAI,CAAC,mBAAmB,OAAO,QAAQ,CAAC,mBAAmB,gBAAgB;AAAA,MACrI,CAAC;AAAA,IACH;AAGA,QAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,GAAG;AACtC,YAAM,sBAAsB,kCAAkC;AAAA,QAC5D,KAAK,gCAAgC,CAAC,WAAW,OAAO,IAAI,CAAC;AAAA,MAC/D,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,OAAO,UAAU;AAClC,QAAI,aAAa,kBAAkB;AACjC,YAAM,sBAAsB,kCAAkC;AAAA,QAC5D,KAAK,gCAAgC,CAAC,WAAW,OAAO,IAAI,CAAC,mBAAmB,OAAO,QAAQ,CAAC,mBAAmB,gBAAgB;AAAA,MACrI,CAAC;AAAA,IACH;AAAA,EACF;AAGA,SAAO;AACT;AA6BO,SAAS,oCAGd;AAAA,EACA;AAAA,EACA;AACF,GAGS;AACP,QAAM,uBAAuB,oBAAI,IAAY,CAAC,MAAM,OAAO,IAAI,MAAM,QAAQ,EAAE,CAAC;AAChF,aAAW,aAAa,MAAM,gBAAgB;AAC5C,yBAAqB,IAAI,UAAU,EAAE;AAAA,EACvC;AAEA,QAAM,SAAS,mCAAmC;AAAA,IAChD;AAAA,IACA,sBAAsB,MAAM,OAAO;AAAA,IACnC,kBAAkB,MAAM,OAAO;AAAA,IAC/B;AAAA,EACF,CAAC;AAED,MAAI,OAAO,gBAAgB;AACzB,UAAM,sBAAsB,yBAAyB;AAAA,MACnD,KAAK,oCAAoC,OAAO,eAAe,MAAM,iCAAiC,OAAO,eAAe,QAAQ;AAAA,IACtI,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,gBAAgB;AACzB,UAAM,sBAAsB,mBAAmB;AAAA,MAC7C,KAAK,oBAAoB,OAAO,eAAe,MAAM,gCAAgC,OAAO,eAAe,QAAQ;AAAA,IACrH,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,wBAAwB,SAAS,GAAG;AAC7C,UAAM,mCAAmC;AAAA,MACvC,uBAAuB,OAAO;AAAA,MAC9B,sBAAsB,CAAC,GAAG,oBAAoB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;","names":[]}
|