@supatype/cli 0.1.0 → 0.1.2
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +121 -86
- package/.turbo/turbo-typecheck.log +2 -2
- package/dist/binary-cache.d.ts +2 -0
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +36 -0
- package/dist/binary-cache.js.map +1 -1
- package/dist/binary-download-lock.d.ts +12 -0
- package/dist/binary-download-lock.d.ts.map +1 -0
- package/dist/binary-download-lock.js +106 -0
- package/dist/binary-download-lock.js.map +1 -0
- package/dist/cli-package-version.d.ts +3 -0
- package/dist/cli-package-version.d.ts.map +1 -0
- package/dist/cli-package-version.js +15 -0
- package/dist/cli-package-version.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.js +25 -19
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/admin.d.ts +28 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +290 -112
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/cache.d.ts +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +98 -5
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +28 -22
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts +8 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +278 -139
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link-helpers.d.ts.map +1 -1
- package/dist/commands/link-helpers.js +26 -25
- package/dist/commands/link-helpers.js.map +1 -1
- package/dist/commands/push.js +3 -3
- package/dist/commands/push.js.map +1 -1
- package/dist/compose-local-server-image.d.ts +13 -0
- package/dist/compose-local-server-image.d.ts.map +1 -0
- package/dist/compose-local-server-image.js +57 -0
- package/dist/compose-local-server-image.js.map +1 -0
- package/dist/compose-rename.d.ts +10 -0
- package/dist/compose-rename.d.ts.map +1 -0
- package/dist/compose-rename.js +64 -0
- package/dist/compose-rename.js.map +1 -0
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +138 -97
- package/dist/dev-compose.js.map +1 -1
- package/dist/dev-log-bus.d.ts +5 -0
- package/dist/dev-log-bus.d.ts.map +1 -1
- package/dist/dev-log-bus.js +14 -0
- package/dist/dev-log-bus.js.map +1 -1
- package/dist/dev-log-filter.d.ts +4 -0
- package/dist/dev-log-filter.d.ts.map +1 -1
- package/dist/dev-log-filter.js +52 -0
- package/dist/dev-log-filter.js.map +1 -1
- package/dist/dev-ports.d.ts +27 -0
- package/dist/dev-ports.d.ts.map +1 -0
- package/dist/dev-ports.js +178 -0
- package/dist/dev-ports.js.map +1 -0
- package/dist/dev-ready-panel.d.ts +19 -0
- package/dist/dev-ready-panel.d.ts.map +1 -0
- package/dist/dev-ready-panel.js +49 -0
- package/dist/dev-ready-panel.js.map +1 -0
- package/dist/dev-session-lock.d.ts +25 -0
- package/dist/dev-session-lock.d.ts.map +1 -0
- package/dist/dev-session-lock.js +78 -0
- package/dist/dev-session-lock.js.map +1 -0
- package/dist/dev-session.d.ts +18 -5
- package/dist/dev-session.d.ts.map +1 -1
- package/dist/dev-session.js +91 -18
- package/dist/dev-session.js.map +1 -1
- package/dist/dev-shutdown.d.ts +20 -2
- package/dist/dev-shutdown.d.ts.map +1 -1
- package/dist/dev-shutdown.js +88 -10
- package/dist/dev-shutdown.js.map +1 -1
- package/dist/dev-task-colors.d.ts +3 -1
- package/dist/dev-task-colors.d.ts.map +1 -1
- package/dist/dev-task-colors.js +23 -3
- package/dist/dev-task-colors.js.map +1 -1
- package/dist/docker-runtime.js +1 -1
- package/dist/docker-runtime.js.map +1 -1
- package/dist/engine-push-output.d.ts +1 -0
- package/dist/engine-push-output.d.ts.map +1 -1
- package/dist/engine-push-output.js +4 -1
- package/dist/engine-push-output.js.map +1 -1
- package/dist/ensure-binary.d.ts.map +1 -1
- package/dist/ensure-binary.js +14 -2
- package/dist/ensure-binary.js.map +1 -1
- package/dist/ensure-component-binaries.d.ts +17 -0
- package/dist/ensure-component-binaries.d.ts.map +1 -0
- package/dist/ensure-component-binaries.js +45 -0
- package/dist/ensure-component-binaries.js.map +1 -0
- package/dist/ensure-dev-api-config.d.ts +3 -0
- package/dist/ensure-dev-api-config.d.ts.map +1 -0
- package/dist/ensure-dev-api-config.js +17 -0
- package/dist/ensure-dev-api-config.js.map +1 -0
- package/dist/env-file.d.ts +5 -0
- package/dist/env-file.d.ts.map +1 -0
- package/dist/env-file.js +33 -0
- package/dist/env-file.js.map +1 -0
- package/dist/init-dependency-versions.d.ts +13 -0
- package/dist/init-dependency-versions.d.ts.map +1 -0
- package/dist/init-dependency-versions.js +53 -0
- package/dist/init-dependency-versions.js.map +1 -0
- package/dist/init-package-json.d.ts +21 -0
- package/dist/init-package-json.d.ts.map +1 -0
- package/dist/init-package-json.js +46 -0
- package/dist/init-package-json.js.map +1 -0
- package/dist/postgres-ctl.d.ts.map +1 -1
- package/dist/postgres-ctl.js +2 -1
- package/dist/postgres-ctl.js.map +1 -1
- package/dist/required-host-components.d.ts +11 -0
- package/dist/required-host-components.d.ts.map +1 -0
- package/dist/required-host-components.js +25 -0
- package/dist/required-host-components.js.map +1 -0
- package/dist/resolve-api-url.d.ts +6 -0
- package/dist/resolve-api-url.d.ts.map +1 -0
- package/dist/resolve-api-url.js +39 -0
- package/dist/resolve-api-url.js.map +1 -0
- package/dist/rest-cache-admin.d.ts +33 -0
- package/dist/rest-cache-admin.d.ts.map +1 -0
- package/dist/rest-cache-admin.js +96 -0
- package/dist/rest-cache-admin.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +4 -6
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +8 -41
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +24 -13
- package/dist/self-host-compose.js.map +1 -1
- package/dist/studio-dev-server.d.ts +4 -2
- package/dist/studio-dev-server.d.ts.map +1 -1
- package/dist/studio-dev-server.js +3 -2
- package/dist/studio-dev-server.js.map +1 -1
- package/dist/ui/brand.d.ts +2 -5
- package/dist/ui/brand.d.ts.map +1 -1
- package/dist/ui/brand.js +2 -7
- package/dist/ui/brand.js.map +1 -1
- package/dist/ui/clack-api.d.ts +44 -0
- package/dist/ui/clack-api.d.ts.map +1 -0
- package/dist/ui/clack-api.js +76 -0
- package/dist/ui/clack-api.js.map +1 -0
- package/dist/ui/clack.d.ts +14 -0
- package/dist/ui/clack.d.ts.map +1 -0
- package/dist/ui/clack.js +147 -0
- package/dist/ui/clack.js.map +1 -0
- package/dist/ui/components/FlowSpinner.d.ts +5 -0
- package/dist/ui/components/FlowSpinner.d.ts.map +1 -0
- package/dist/ui/components/FlowSpinner.js +8 -0
- package/dist/ui/components/FlowSpinner.js.map +1 -0
- package/dist/ui/components/LogoWordmark.d.ts +9 -0
- package/dist/ui/components/LogoWordmark.d.ts.map +1 -0
- package/dist/ui/components/LogoWordmark.js +17 -0
- package/dist/ui/components/LogoWordmark.js.map +1 -0
- package/dist/ui/components/PromptPanel.d.ts +5 -0
- package/dist/ui/components/PromptPanel.d.ts.map +1 -0
- package/dist/ui/components/PromptPanel.js +7 -0
- package/dist/ui/components/PromptPanel.js.map +1 -0
- package/dist/ui/components/SelectField.d.ts +11 -0
- package/dist/ui/components/SelectField.d.ts.map +1 -0
- package/dist/ui/components/SelectField.js +19 -0
- package/dist/ui/components/SelectField.js.map +1 -0
- package/dist/ui/confirm.d.ts +2 -1
- package/dist/ui/confirm.d.ts.map +1 -1
- package/dist/ui/confirm.js +4 -4
- package/dist/ui/confirm.js.map +1 -1
- package/dist/ui/dev/DevDashboard.d.ts +8 -0
- package/dist/ui/dev/DevDashboard.d.ts.map +1 -0
- package/dist/ui/dev/DevDashboard.js +151 -0
- package/dist/ui/dev/DevDashboard.js.map +1 -0
- package/dist/ui/dev/DevReadyPanelView.d.ts +7 -0
- package/dist/ui/dev/DevReadyPanelView.d.ts.map +1 -0
- package/dist/ui/dev/DevReadyPanelView.js +29 -0
- package/dist/ui/dev/DevReadyPanelView.js.map +1 -0
- package/dist/ui/fatal.d.ts.map +1 -1
- package/dist/ui/fatal.js +5 -11
- package/dist/ui/fatal.js.map +1 -1
- package/dist/ui/flows/FlowApp.d.ts +8 -0
- package/dist/ui/flows/FlowApp.d.ts.map +1 -0
- package/dist/ui/flows/FlowApp.js +42 -0
- package/dist/ui/flows/FlowApp.js.map +1 -0
- package/dist/ui/flows/prompt-fields.d.ts +48 -0
- package/dist/ui/flows/prompt-fields.d.ts.map +1 -0
- package/dist/ui/flows/prompt-fields.js +88 -0
- package/dist/ui/flows/prompt-fields.js.map +1 -0
- package/dist/ui/flows/types.d.ts +41 -0
- package/dist/ui/flows/types.d.ts.map +1 -0
- package/dist/ui/flows/types.js +2 -0
- package/dist/ui/flows/types.js.map +1 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/messages.d.ts +1 -0
- package/dist/ui/messages.d.ts.map +1 -1
- package/dist/ui/messages.js +48 -8
- package/dist/ui/messages.js.map +1 -1
- package/dist/ui/progress.d.ts +5 -1
- package/dist/ui/progress.d.ts.map +1 -1
- package/dist/ui/progress.js +12 -3
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/prompts.d.ts +7 -5
- package/dist/ui/prompts.d.ts.map +1 -1
- package/dist/ui/prompts.js +15 -8
- package/dist/ui/prompts.js.map +1 -1
- package/dist/ui/runtime/cancel.d.ts +4 -0
- package/dist/ui/runtime/cancel.d.ts.map +1 -0
- package/dist/ui/runtime/cancel.js +6 -0
- package/dist/ui/runtime/cancel.js.map +1 -0
- package/dist/ui/runtime/command-chrome.d.ts +17 -0
- package/dist/ui/runtime/command-chrome.d.ts.map +1 -0
- package/dist/ui/runtime/command-chrome.js +123 -0
- package/dist/ui/runtime/command-chrome.js.map +1 -0
- package/dist/ui/runtime/dev-prompt-queue.d.ts +30 -0
- package/dist/ui/runtime/dev-prompt-queue.d.ts.map +1 -0
- package/dist/ui/runtime/dev-prompt-queue.js +57 -0
- package/dist/ui/runtime/dev-prompt-queue.js.map +1 -0
- package/dist/ui/runtime/flow-session.d.ts +4 -0
- package/dist/ui/runtime/flow-session.d.ts.map +1 -0
- package/dist/ui/runtime/flow-session.js +8 -0
- package/dist/ui/runtime/flow-session.js.map +1 -0
- package/dist/ui/runtime/run-clack-flow.d.ts +5 -0
- package/dist/ui/runtime/run-clack-flow.d.ts.map +1 -0
- package/dist/ui/runtime/run-clack-flow.js +34 -0
- package/dist/ui/runtime/run-clack-flow.js.map +1 -0
- package/dist/ui/theme.d.ts +24 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +34 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/valkey-sidecar.d.ts +17 -0
- package/dist/valkey-sidecar.d.ts.map +1 -0
- package/dist/valkey-sidecar.js +94 -0
- package/dist/valkey-sidecar.js.map +1 -0
- package/package.json +11 -3
- package/src/binary-cache.ts +61 -0
- package/src/binary-download-lock.ts +124 -0
- package/src/cli-package-version.ts +15 -0
- package/src/cli.ts +6 -2
- package/src/commands/add.ts +26 -19
- package/src/commands/admin.ts +380 -137
- package/src/commands/cache.ts +105 -5
- package/src/commands/dev.ts +29 -21
- package/src/commands/init.ts +217 -46
- package/src/commands/link-helpers.ts +30 -29
- package/src/commands/push.ts +3 -3
- package/src/compose-local-server-image.ts +68 -0
- package/src/compose-rename.ts +73 -0
- package/src/dev-compose.ts +175 -96
- package/src/dev-log-bus.ts +18 -0
- package/src/dev-log-filter.ts +42 -0
- package/src/dev-ports.ts +223 -0
- package/src/dev-ready-panel.ts +63 -0
- package/src/dev-session-lock.ts +98 -0
- package/src/dev-session.ts +98 -18
- package/src/dev-shutdown.ts +114 -9
- package/src/dev-task-colors.ts +22 -3
- package/src/docker-runtime.ts +1 -1
- package/src/engine-push-output.ts +5 -1
- package/src/ensure-binary.ts +21 -1
- package/src/ensure-component-binaries.ts +71 -0
- package/src/ensure-dev-api-config.ts +18 -0
- package/src/env-file.ts +37 -0
- package/src/init-dependency-versions.ts +69 -0
- package/src/init-package-json.ts +63 -0
- package/src/postgres-ctl.ts +2 -1
- package/src/required-host-components.ts +37 -0
- package/src/resolve-api-url.ts +43 -0
- package/src/rest-cache-admin.ts +135 -0
- package/src/scripts/postinstall.ts +9 -46
- package/src/self-host-compose.ts +23 -12
- package/src/studio-dev-server.ts +5 -4
- package/src/ui/README.md +13 -9
- package/src/ui/brand.ts +2 -8
- package/src/ui/clack-api.ts +123 -0
- package/src/ui/clack.ts +153 -0
- package/src/ui/components/FlowSpinner.tsx +15 -0
- package/src/ui/components/LogoWordmark.tsx +36 -0
- package/src/ui/components/PromptPanel.tsx +17 -0
- package/src/ui/components/SelectField.tsx +58 -0
- package/src/ui/confirm.ts +5 -4
- package/src/ui/dev/DevDashboard.tsx +213 -0
- package/src/ui/dev/DevReadyPanelView.tsx +67 -0
- package/src/ui/fatal.ts +5 -10
- package/src/ui/flows/FlowApp.tsx +67 -0
- package/src/ui/flows/prompt-fields.tsx +192 -0
- package/src/ui/flows/types.ts +50 -0
- package/src/ui/index.ts +1 -1
- package/src/ui/messages.ts +50 -8
- package/src/ui/progress.ts +14 -3
- package/src/ui/prompts.ts +17 -9
- package/src/ui/runtime/cancel.ts +6 -0
- package/src/ui/runtime/command-chrome.ts +147 -0
- package/src/ui/runtime/dev-prompt-queue.ts +84 -0
- package/src/ui/runtime/flow-session.ts +11 -0
- package/src/ui/runtime/run-clack-flow.tsx +52 -0
- package/src/ui/theme.ts +41 -0
- package/src/valkey-sidecar.ts +126 -0
- package/tests/admin-ensure.test.ts +59 -0
- package/tests/binary-cache-cloud-overrides.test.ts +2 -2
- package/tests/binary-download-lock.test.ts +41 -0
- package/tests/cli-help.test.ts +7 -4
- package/tests/cli-package-version.test.ts +15 -0
- package/tests/command-chrome-coverage.test.ts +149 -0
- package/tests/command-chrome-wrap.test.ts +51 -0
- package/tests/config.test.ts +8 -4
- package/tests/dev-ports.test.ts +41 -0
- package/tests/dev-ready-panel.test.ts +20 -0
- package/tests/dev-session-lock.test.ts +54 -0
- package/tests/dev-ui.test.ts +66 -3
- package/tests/docker-runtime.test.ts +9 -20
- package/tests/ensure-dev-api-config.test.ts +22 -0
- package/tests/init-dependency-versions.test.ts +62 -0
- package/tests/init-package-json.test.ts +18 -0
- package/tests/init.test.ts +30 -3
- package/tests/required-host-components.test.ts +51 -0
- package/tests/resolve-api-url.test.ts +23 -0
- package/tests/rest-cache-admin.test.ts +28 -0
- package/tests/runtime-contract.test.ts +12 -3
- package/tests/tsconfig.json +8 -2
- package/tests/ui-confirm.test.ts +13 -9
- package/tests/ui-messages.test.ts +4 -18
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +3 -0
- package/dist/dev-tui.d.ts +0 -24
- package/dist/dev-tui.d.ts.map +0 -1
- package/dist/dev-tui.js +0 -188
- package/dist/dev-tui.js.map +0 -1
- package/src/dev-tui.ts +0 -232
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { render } from "ink";
|
|
4
|
+
import { isInteractive } from "../interactive.js";
|
|
5
|
+
import { createClackApi } from "../clack-api.js";
|
|
6
|
+
import { FlowApp } from "../flows/FlowApp.js";
|
|
7
|
+
function RunClackFlowRoot({ run, onComplete, onError }) {
|
|
8
|
+
const started = useRef(false);
|
|
9
|
+
return (_jsx(FlowApp, { bind: (controller) => {
|
|
10
|
+
if (started.current)
|
|
11
|
+
return;
|
|
12
|
+
started.current = true;
|
|
13
|
+
void run(createClackApi(controller))
|
|
14
|
+
.then(onComplete)
|
|
15
|
+
.catch(onError);
|
|
16
|
+
} }));
|
|
17
|
+
}
|
|
18
|
+
/** Mount a single Ink flow session (init wizard, standalone confirm, etc.). */
|
|
19
|
+
export async function runClackFlow(run) {
|
|
20
|
+
if (!isInteractive()) {
|
|
21
|
+
throw new Error("Interactive Ink flow requires a TTY.");
|
|
22
|
+
}
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const instance = render(_jsx(RunClackFlowRoot, { run: run, onComplete: (value) => {
|
|
25
|
+
instance.unmount();
|
|
26
|
+
resolve(value);
|
|
27
|
+
}, onError: (err) => {
|
|
28
|
+
instance.unmount();
|
|
29
|
+
reject(err);
|
|
30
|
+
} }));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export { CLACK_CANCEL } from "./cancel.js";
|
|
34
|
+
//# sourceMappingURL=run-clack-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-clack-flow.js","sourceRoot":"","sources":["../../../src/ui/runtime/run-clack-flow.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAQ7C,SAAS,gBAAgB,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAyB;IAC3E,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAE7B,OAAO,CACL,KAAC,OAAO,IACN,IAAI,EAAE,CAAC,UAAU,EAAE,EAAE;YACnB,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAM;YAC3B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;YACtB,KAAK,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;iBACjC,IAAI,CAAC,UAAU,CAAC;iBAChB,KAAK,CAAC,OAAO,CAAC,CAAA;QACnB,CAAC,GACD,CACH,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,GAAkC;IACtE,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,MAAM,CACrB,KAAC,gBAAgB,IACf,GAAG,EAAE,GAA0C,EAC/C,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBACpB,QAAQ,CAAC,OAAO,EAAE,CAAA;gBAClB,OAAO,CAAC,KAAU,CAAC,CAAA;YACrB,CAAC,EACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACf,QAAQ,CAAC,OAAO,EAAE,CAAA;gBAClB,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,GACD,CACH,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supatype terminal design tokens — shared by Ink components and plain CI output.
|
|
3
|
+
*/
|
|
4
|
+
export declare const RESET = "\u001B[0m";
|
|
5
|
+
export declare const DIM = "\u001B[2m";
|
|
6
|
+
export declare const BOLD = "\u001B[1m";
|
|
7
|
+
export declare const theme: {
|
|
8
|
+
readonly brand: "magenta";
|
|
9
|
+
readonly brandHex: "#c084fc";
|
|
10
|
+
readonly info: "cyan";
|
|
11
|
+
readonly warn: "yellow";
|
|
12
|
+
readonly error: "red";
|
|
13
|
+
readonly success: "green";
|
|
14
|
+
readonly dim: "gray";
|
|
15
|
+
readonly muted: "gray";
|
|
16
|
+
};
|
|
17
|
+
/** Legacy ANSI exports used by dev-logo / dev-task-colors. */
|
|
18
|
+
export declare const BRAND_COLOR = "\u001B[35m";
|
|
19
|
+
export declare function brandStyle(text: string): string;
|
|
20
|
+
export declare function plainInfo(message: string): string;
|
|
21
|
+
export declare function plainWarn(message: string): string;
|
|
22
|
+
export declare function plainError(message: string): string;
|
|
23
|
+
export declare function plainSuccess(message: string): string;
|
|
24
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,KAAK,cAAY,CAAA;AAC9B,eAAO,MAAM,GAAG,cAAY,CAAA;AAC5B,eAAO,MAAM,IAAI,cAAY,CAAA;AAE7B,eAAO,MAAM,KAAK;;;;;;;;;CASR,CAAA;AAEV,8DAA8D;AAC9D,eAAO,MAAM,WAAW,eAAa,CAAA;AAErC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD"}
|
package/dist/ui/theme.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supatype terminal design tokens — shared by Ink components and plain CI output.
|
|
3
|
+
*/
|
|
4
|
+
export const RESET = "\x1b[0m";
|
|
5
|
+
export const DIM = "\x1b[2m";
|
|
6
|
+
export const BOLD = "\x1b[1m";
|
|
7
|
+
export const theme = {
|
|
8
|
+
brand: "magenta",
|
|
9
|
+
brandHex: "#c084fc",
|
|
10
|
+
info: "cyan",
|
|
11
|
+
warn: "yellow",
|
|
12
|
+
error: "red",
|
|
13
|
+
success: "green",
|
|
14
|
+
dim: "gray",
|
|
15
|
+
muted: "gray",
|
|
16
|
+
};
|
|
17
|
+
/** Legacy ANSI exports used by dev-logo / dev-task-colors. */
|
|
18
|
+
export const BRAND_COLOR = "\x1b[35m";
|
|
19
|
+
export function brandStyle(text) {
|
|
20
|
+
return `${BRAND_COLOR}${BOLD}${text}${RESET}`;
|
|
21
|
+
}
|
|
22
|
+
export function plainInfo(message) {
|
|
23
|
+
return `${theme.info === "cyan" ? "\x1b[36m" : ""}ℹ ${message}${RESET}`;
|
|
24
|
+
}
|
|
25
|
+
export function plainWarn(message) {
|
|
26
|
+
return `\x1b[33m⚠ ${message}${RESET}`;
|
|
27
|
+
}
|
|
28
|
+
export function plainError(message) {
|
|
29
|
+
return `\x1b[31m✗ ${message}${RESET}`;
|
|
30
|
+
}
|
|
31
|
+
export function plainSuccess(message) {
|
|
32
|
+
return `\x1b[32m✓ ${message}${RESET}`;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAA;AAC9B,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAA;AAC5B,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAA;AAE7B,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,KAAK,EAAE,SAAkB;IACzB,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,MAAe;IACrB,IAAI,EAAE,QAAiB;IACvB,KAAK,EAAE,KAAc;IACrB,OAAO,EAAE,OAAgB;IACzB,GAAG,EAAE,MAAe;IACpB,KAAK,EAAE,MAAe;CACd,CAAA;AAEV,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAA;AAErC,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,GAAG,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,GAAG,KAAK,EAAE,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,aAAa,OAAO,GAAG,KAAK,EAAE,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,aAAa,OAAO,GAAG,KAAK,EAAE,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,aAAa,OAAO,GAAG,KAAK,EAAE,CAAA;AACvC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight Valkey container for native `supatype dev` (REST response cache).
|
|
3
|
+
*/
|
|
4
|
+
export interface ValkeySidecarResult {
|
|
5
|
+
addr: string;
|
|
6
|
+
containerName: string | null;
|
|
7
|
+
started: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Ensure Valkey is reachable at 127.0.0.1:6379 for native dev.
|
|
11
|
+
* Starts a named Docker container when Docker is available and nothing is listening.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ensureValkeySidecar(projectName: string): ValkeySidecarResult;
|
|
14
|
+
export declare function stopValkeySidecar(containerName: string | null): void;
|
|
15
|
+
/** @internal Test helper — probe without subprocess. */
|
|
16
|
+
export declare function probeTcp(host: string, port: number): Promise<boolean>;
|
|
17
|
+
//# sourceMappingURL=valkey-sidecar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valkey-sidecar.d.ts","sourceRoot":"","sources":["../src/valkey-sidecar.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4CH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAgD5E;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGpE;AAED,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAarE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight Valkey container for native `supatype dev` (REST response cache).
|
|
3
|
+
*/
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { createConnection } from "node:net";
|
|
6
|
+
const DEFAULT_HOST = "127.0.0.1";
|
|
7
|
+
const DEFAULT_PORT = 6379;
|
|
8
|
+
const IMAGE = "valkey/valkey:8-alpine";
|
|
9
|
+
function containerName(projectName) {
|
|
10
|
+
const safe = projectName.replace(/[^a-zA-Z0-9_-]/g, "-").slice(0, 48);
|
|
11
|
+
return `supatype-valkey-dev-${safe}`;
|
|
12
|
+
}
|
|
13
|
+
function dockerAvailable() {
|
|
14
|
+
const r = spawnSync("docker", ["info"], { stdio: "ignore" });
|
|
15
|
+
return r.status === 0;
|
|
16
|
+
}
|
|
17
|
+
function isAddrReachable(host, port, timeoutMs = 800) {
|
|
18
|
+
try {
|
|
19
|
+
const r = spawnSync(process.execPath, [
|
|
20
|
+
"-e",
|
|
21
|
+
`const n=require('net');const s=n.createConnection({host:${JSON.stringify(host)},port:${port}});` +
|
|
22
|
+
`s.on('connect',()=>{s.end();process.exit(0)});s.on('error',()=>process.exit(1));` +
|
|
23
|
+
`setTimeout(()=>process.exit(1),${timeoutMs})`,
|
|
24
|
+
], { stdio: "ignore" });
|
|
25
|
+
return r.status === 0;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function sleepMs(ms) {
|
|
32
|
+
const end = Date.now() + ms;
|
|
33
|
+
while (Date.now() < end) {
|
|
34
|
+
/* spin */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Ensure Valkey is reachable at 127.0.0.1:6379 for native dev.
|
|
39
|
+
* Starts a named Docker container when Docker is available and nothing is listening.
|
|
40
|
+
*/
|
|
41
|
+
export function ensureValkeySidecar(projectName) {
|
|
42
|
+
const envAddr = process.env["SUPATYPE_VALKEY_ADDR"]?.trim();
|
|
43
|
+
if (envAddr) {
|
|
44
|
+
return { addr: envAddr, containerName: null, started: false };
|
|
45
|
+
}
|
|
46
|
+
const addr = `${DEFAULT_HOST}:${DEFAULT_PORT}`;
|
|
47
|
+
if (isAddrReachable(DEFAULT_HOST, DEFAULT_PORT)) {
|
|
48
|
+
return { addr, containerName: null, started: false };
|
|
49
|
+
}
|
|
50
|
+
if (!dockerAvailable()) {
|
|
51
|
+
console.warn("[supatype] ⚠ Valkey not available (Docker not running). " +
|
|
52
|
+
"REST server cache (`cache({ server: true })`) will bypass until Valkey is reachable.");
|
|
53
|
+
return { addr: "", containerName: null, started: false };
|
|
54
|
+
}
|
|
55
|
+
const name = containerName(projectName);
|
|
56
|
+
spawnSync("docker", ["rm", "-f", name], { stdio: "ignore" });
|
|
57
|
+
const run = spawnSync("docker", ["run", "-d", "--name", name, "-p", `${DEFAULT_PORT}:6379`, IMAGE], { encoding: "utf8" });
|
|
58
|
+
if (run.status !== 0) {
|
|
59
|
+
const detail = (run.stderr || run.stdout || "").trim();
|
|
60
|
+
console.warn(`[supatype] ⚠ Could not start Valkey sidecar: ${detail || `exit ${run.status}`}\n` +
|
|
61
|
+
" REST server cache will bypass until Valkey is available.");
|
|
62
|
+
return { addr: "", containerName: null, started: false };
|
|
63
|
+
}
|
|
64
|
+
for (let i = 0; i < 30; i++) {
|
|
65
|
+
if (isAddrReachable(DEFAULT_HOST, DEFAULT_PORT)) {
|
|
66
|
+
console.log(`[supatype] Valkey sidecar running (${addr})`);
|
|
67
|
+
return { addr, containerName: name, started: true };
|
|
68
|
+
}
|
|
69
|
+
sleepMs(100);
|
|
70
|
+
}
|
|
71
|
+
console.warn("[supatype] ⚠ Valkey sidecar started but not reachable yet — cache may bypass initially.");
|
|
72
|
+
return { addr, containerName: name, started: true };
|
|
73
|
+
}
|
|
74
|
+
export function stopValkeySidecar(containerName) {
|
|
75
|
+
if (!containerName)
|
|
76
|
+
return;
|
|
77
|
+
spawnSync("docker", ["rm", "-f", containerName], { stdio: "ignore" });
|
|
78
|
+
}
|
|
79
|
+
/** @internal Test helper — probe without subprocess. */
|
|
80
|
+
export function probeTcp(host, port) {
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
const s = createConnection({ host, port });
|
|
83
|
+
s.once("connect", () => {
|
|
84
|
+
s.destroy();
|
|
85
|
+
resolve(true);
|
|
86
|
+
});
|
|
87
|
+
s.once("error", () => resolve(false));
|
|
88
|
+
setTimeout(() => {
|
|
89
|
+
s.destroy();
|
|
90
|
+
resolve(false);
|
|
91
|
+
}, 800);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=valkey-sidecar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valkey-sidecar.js","sourceRoot":"","sources":["../src/valkey-sidecar.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supatype/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Supatype CLI — schema push, introspect, generate",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,12 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"
|
|
22
|
+
"bcryptjs": "^3.0.2",
|
|
23
|
+
"ink": "^5.2.1",
|
|
24
|
+
"ink-select-input": "^6.2.0",
|
|
25
|
+
"ink-spinner": "^5.0.0",
|
|
26
|
+
"ink-text-input": "^6.0.0",
|
|
27
|
+
"react": "^18.3.1",
|
|
23
28
|
"commander": "^12.1.0",
|
|
24
29
|
"pg": "^8.13.0",
|
|
25
30
|
"ts-morph": "^28.0.0",
|
|
@@ -27,6 +32,8 @@
|
|
|
27
32
|
"typescript": "^5"
|
|
28
33
|
},
|
|
29
34
|
"devDependencies": {
|
|
35
|
+
"@types/bcryptjs": "^2.4.6",
|
|
36
|
+
"@types/react": "^18.3.18",
|
|
30
37
|
"@types/node": "^22",
|
|
31
38
|
"@types/pg": "^8",
|
|
32
39
|
"vitest": "^4.0.18"
|
|
@@ -34,7 +41,8 @@
|
|
|
34
41
|
"scripts": {
|
|
35
42
|
"build": "tsc --project tsconfig.json && node --input-type=module -e \"import{cpSync,mkdirSync}from'node:fs';const a='dist/assets';mkdirSync(a,{recursive:true});cpSync('assets/supatype-logo-wordmark.ascii.txt',a+'/supatype-logo-wordmark.ascii.txt')\"",
|
|
36
43
|
"dev": "tsc --project tsconfig.json --watch",
|
|
37
|
-
"typecheck": "tsc --project tsconfig.json --noEmit",
|
|
44
|
+
"typecheck": "tsc --project tsconfig.json --noEmit && tsc --project tests/tsconfig.json --noEmit",
|
|
45
|
+
"typecheck:tests": "tsc --project tests/tsconfig.json --noEmit",
|
|
38
46
|
"postinstall": "node --input-type=module --eval \"import{existsSync}from'node:fs';import{resolve}from'node:path';import{pathToFileURL}from'node:url';const f=resolve(process.cwd(),'dist/scripts/postinstall.js');if(existsSync(f))await import(pathToFileURL(f).href)\"",
|
|
39
47
|
"test": "vitest run",
|
|
40
48
|
"clean": "rm -rf dist *.tsbuildinfo"
|
package/src/binary-cache.ts
CHANGED
|
@@ -37,6 +37,12 @@ import { basename, join, resolve, isAbsolute } from "node:path"
|
|
|
37
37
|
import type { SupatypeProjectConfig } from "./project-config.js"
|
|
38
38
|
import { loadProjectLink, migrateLegacyLinkFiles } from "./link.js"
|
|
39
39
|
import { releasePublicKey } from "./release-public-key.js"
|
|
40
|
+
import {
|
|
41
|
+
isDownloadInProgress,
|
|
42
|
+
releaseDownloadLock,
|
|
43
|
+
tryAcquireDownloadLock,
|
|
44
|
+
waitForComponentDownload,
|
|
45
|
+
} from "./binary-download-lock.js"
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
48
|
* Set `versions.{engine|server|postgres|deno}: VERSION_PIN_LOCAL` to mean “use `overrides.*` only”
|
|
@@ -167,6 +173,16 @@ export function cachedBinaryPath(component: Component, version: string, platform
|
|
|
167
173
|
return join(cachePath(component, version), binaryName(component, version, platform))
|
|
168
174
|
}
|
|
169
175
|
|
|
176
|
+
/** True when the platform binary for `version` is present and passes format checks. */
|
|
177
|
+
export function isCachedBinaryReady(
|
|
178
|
+
component: Component,
|
|
179
|
+
version: string,
|
|
180
|
+
platform: PlatformId = currentPlatform(),
|
|
181
|
+
): boolean {
|
|
182
|
+
const destPath = cachedBinaryPath(component, version, platform)
|
|
183
|
+
return existsSync(destPath) && cachedArtifactLooksValid(component, destPath)
|
|
184
|
+
}
|
|
185
|
+
|
|
170
186
|
function binaryName(component: Component, version: string, platform: PlatformId): string {
|
|
171
187
|
const win = platform.os === "windows"
|
|
172
188
|
switch (component) {
|
|
@@ -299,6 +315,45 @@ export async function ensureCachedBinary(
|
|
|
299
315
|
return download(component, version, platform)
|
|
300
316
|
}
|
|
301
317
|
|
|
318
|
+
async function acquireDownloadSlot(
|
|
319
|
+
component: Component,
|
|
320
|
+
version: string,
|
|
321
|
+
platform: PlatformId,
|
|
322
|
+
): Promise<void> {
|
|
323
|
+
const isReady = () => isCachedBinaryReady(component, version, platform)
|
|
324
|
+
|
|
325
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
326
|
+
if (isReady()) return
|
|
327
|
+
|
|
328
|
+
if (tryAcquireDownloadLock(component, version)) return
|
|
329
|
+
|
|
330
|
+
if (isDownloadInProgress(component, version)) {
|
|
331
|
+
console.log(
|
|
332
|
+
`[supatype] ${component} v${version} is downloading in another process — waiting...`,
|
|
333
|
+
)
|
|
334
|
+
const outcome = await waitForComponentDownload(component, version, isReady, (c) => {
|
|
335
|
+
console.log(`[supatype] Still waiting for ${c} download...`)
|
|
336
|
+
})
|
|
337
|
+
if (outcome === "ready") return
|
|
338
|
+
if (outcome === "timeout") {
|
|
339
|
+
throw new Error(
|
|
340
|
+
`Timed out waiting for ${component} v${version} download. Run: supatype update`,
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
console.warn(
|
|
344
|
+
`[supatype] ${component} v${version} download did not finish in the other process — retrying.`,
|
|
345
|
+
)
|
|
346
|
+
continue
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (tryAcquireDownloadLock(component, version)) return
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
throw new Error(
|
|
353
|
+
`Could not acquire download lock for ${component} v${version}. Run: supatype update`,
|
|
354
|
+
)
|
|
355
|
+
}
|
|
356
|
+
|
|
302
357
|
export async function download(
|
|
303
358
|
component: Component,
|
|
304
359
|
version: string,
|
|
@@ -327,6 +382,11 @@ export async function download(
|
|
|
327
382
|
unlinkSync(destPath)
|
|
328
383
|
}
|
|
329
384
|
|
|
385
|
+
await acquireDownloadSlot(component, version, platform)
|
|
386
|
+
if (isCachedBinaryReady(component, version, platform)) {
|
|
387
|
+
return destPath
|
|
388
|
+
}
|
|
389
|
+
|
|
330
390
|
const binaryUrl = `${CDN_BASE}${CDN_PATHS[component](version, platform)}`
|
|
331
391
|
const checksumsUrl = `${CDN_BASE}${checksumsDirPath(component, version)}`
|
|
332
392
|
const minisigUrl = `${checksumsUrl}.minisig`
|
|
@@ -361,6 +421,7 @@ export async function download(
|
|
|
361
421
|
`Failed to download ${component} v${version} from ${CDN_BASE}: ${(err as Error).message}`,
|
|
362
422
|
)
|
|
363
423
|
} finally {
|
|
424
|
+
releaseDownloadLock(component, version)
|
|
364
425
|
if (existsSync(tmpPath)) {
|
|
365
426
|
try { unlinkSync(tmpPath) } catch { /* ignore */ }
|
|
366
427
|
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordinates concurrent component-binary downloads (postinstall, init, dev).
|
|
3
|
+
* A second CLI process waits for an in-flight download instead of racing the CDN.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs"
|
|
7
|
+
import { join } from "node:path"
|
|
8
|
+
import { cachePath, type Component } from "./binary-cache.js"
|
|
9
|
+
|
|
10
|
+
const LOCK_VERSION = 1 as const
|
|
11
|
+
const STALE_MS = 30 * 60 * 1000
|
|
12
|
+
const POLL_MS = 500
|
|
13
|
+
const WAIT_NOTICE_MS = 3000
|
|
14
|
+
|
|
15
|
+
interface DownloadLockPayload {
|
|
16
|
+
version: typeof LOCK_VERSION
|
|
17
|
+
pid: number
|
|
18
|
+
component: Component
|
|
19
|
+
semver: string
|
|
20
|
+
startedAt: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function lockPath(component: Component, version: string): string {
|
|
24
|
+
return join(cachePath(component, version), ".downloading")
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function sleep(ms: number): Promise<void> {
|
|
28
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isPidAlive(pid: number): boolean {
|
|
32
|
+
try {
|
|
33
|
+
process.kill(pid, 0)
|
|
34
|
+
return true
|
|
35
|
+
} catch {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function readLock(component: Component, version: string): DownloadLockPayload | null {
|
|
41
|
+
const path = lockPath(component, version)
|
|
42
|
+
if (!existsSync(path)) return null
|
|
43
|
+
try {
|
|
44
|
+
const data = JSON.parse(readFileSync(path, "utf8")) as DownloadLockPayload
|
|
45
|
+
if (data.version !== LOCK_VERSION) return null
|
|
46
|
+
return data
|
|
47
|
+
} catch {
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isLockStale(lock: DownloadLockPayload): boolean {
|
|
53
|
+
if (!isPidAlive(lock.pid)) return true
|
|
54
|
+
const age = Date.now() - Date.parse(lock.startedAt)
|
|
55
|
+
return Number.isNaN(age) || age > STALE_MS
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function clearDownloadLock(component: Component, version: string): void {
|
|
59
|
+
const path = lockPath(component, version)
|
|
60
|
+
if (existsSync(path)) unlinkSync(path)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Atomically claim the download lock for this process, or return false if another live holder exists. */
|
|
64
|
+
export function tryAcquireDownloadLock(component: Component, version: string): boolean {
|
|
65
|
+
mkdirSync(cachePath(component, version), { recursive: true })
|
|
66
|
+
const existing = readLock(component, version)
|
|
67
|
+
if (existing && !isLockStale(existing)) return false
|
|
68
|
+
if (existing) clearDownloadLock(component, version)
|
|
69
|
+
|
|
70
|
+
const payload: DownloadLockPayload = {
|
|
71
|
+
version: LOCK_VERSION,
|
|
72
|
+
pid: process.pid,
|
|
73
|
+
component,
|
|
74
|
+
semver: version,
|
|
75
|
+
startedAt: new Date().toISOString(),
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
writeFileSync(lockPath(component, version), JSON.stringify(payload), { flag: "wx" })
|
|
79
|
+
return true
|
|
80
|
+
} catch {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function releaseDownloadLock(component: Component, version: string): void {
|
|
86
|
+
const lock = readLock(component, version)
|
|
87
|
+
if (!lock || lock.pid !== process.pid) return
|
|
88
|
+
clearDownloadLock(component, version)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function isDownloadInProgress(component: Component, version: string): boolean {
|
|
92
|
+
const lock = readLock(component, version)
|
|
93
|
+
return lock !== null && !isLockStale(lock)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function waitForComponentDownload(
|
|
97
|
+
component: Component,
|
|
98
|
+
version: string,
|
|
99
|
+
isReady: () => boolean,
|
|
100
|
+
onWait?: (component: Component) => void,
|
|
101
|
+
): Promise<"ready" | "failed" | "timeout"> {
|
|
102
|
+
const deadline = Date.now() + STALE_MS
|
|
103
|
+
let lastNotice = 0
|
|
104
|
+
|
|
105
|
+
while (Date.now() < deadline) {
|
|
106
|
+
if (isReady()) return "ready"
|
|
107
|
+
|
|
108
|
+
const lock = readLock(component, version)
|
|
109
|
+
if (!lock || isLockStale(lock)) {
|
|
110
|
+
if (isReady()) return "ready"
|
|
111
|
+
return "failed"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const now = Date.now()
|
|
115
|
+
if (onWait && now - lastNotice >= WAIT_NOTICE_MS) {
|
|
116
|
+
onWait(component)
|
|
117
|
+
lastNotice = now
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
await sleep(POLL_MS)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return isReady() ? "ready" : "timeout"
|
|
124
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs"
|
|
2
|
+
import { dirname, join } from "node:path"
|
|
3
|
+
import { fileURLToPath } from "node:url"
|
|
4
|
+
|
|
5
|
+
const CLI_PACKAGE_JSON = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json")
|
|
6
|
+
|
|
7
|
+
/** Installed @supatype/cli version from package.json (used by --version and init scaffolding). */
|
|
8
|
+
export function cliPackageVersion(): string {
|
|
9
|
+
try {
|
|
10
|
+
const pkg = JSON.parse(readFileSync(CLI_PACKAGE_JSON, "utf8")) as { version?: string }
|
|
11
|
+
return pkg.version ?? "0.0.0"
|
|
12
|
+
} catch {
|
|
13
|
+
return "0.0.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -29,13 +29,15 @@ import { registerPlugins } from "./commands/plugins.js"
|
|
|
29
29
|
import { registerTypes } from "./commands/types.js"
|
|
30
30
|
import { registerMigrateFromV1 } from "./commands/migrate-from-v1.js"
|
|
31
31
|
import { registerSelfUpdate } from "./commands/self-update.js"
|
|
32
|
+
import { cliPackageVersion } from "./cli-package-version.js"
|
|
32
33
|
import { reportCliFatal } from "./ui/fatal.js"
|
|
34
|
+
import { wrapProgramActionsWithChrome } from "./ui/runtime/command-chrome.js"
|
|
33
35
|
|
|
34
36
|
export async function run(): Promise<void> {
|
|
35
37
|
const program = new Command()
|
|
36
38
|
.name("supatype")
|
|
37
|
-
.description("Supatype —
|
|
38
|
-
.version(
|
|
39
|
+
.description("Supatype — type-first platform for PostgreSQL")
|
|
40
|
+
.version(cliPackageVersion())
|
|
39
41
|
|
|
40
42
|
registerInit(program)
|
|
41
43
|
registerDev(program)
|
|
@@ -68,6 +70,8 @@ export async function run(): Promise<void> {
|
|
|
68
70
|
registerTypes(program)
|
|
69
71
|
registerMigrateFromV1(program)
|
|
70
72
|
|
|
73
|
+
wrapProgramActionsWithChrome(program)
|
|
74
|
+
|
|
71
75
|
try {
|
|
72
76
|
await program.parseAsync(process.argv)
|
|
73
77
|
} catch (err) {
|
package/src/commands/add.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Command } from "commander"
|
|
2
|
-
import
|
|
2
|
+
import { p, runClackFlow } from "../ui/clack.js"
|
|
3
3
|
import { loadConfig } from "../config.js"
|
|
4
4
|
import { selfHostTlsEnabled } from "../project-config.js"
|
|
5
5
|
import { updateServerConfigInProject } from "../app-config.js"
|
|
6
|
-
import { ensureNotCancelled
|
|
6
|
+
import { ensureNotCancelled } from "../ui/prompts.js"
|
|
7
7
|
import { file, error, info, plain } from "../ui/messages.js"
|
|
8
8
|
import { nextSteps } from "../ui/next-steps.js"
|
|
9
9
|
|
|
@@ -49,26 +49,33 @@ async function addDomain(domainArg?: string, emailArg?: string): Promise<void> {
|
|
|
49
49
|
const cwd = process.cwd()
|
|
50
50
|
const interactive = !domainArg?.trim() || !emailArg?.trim()
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const domain = await promptDomain(domainArg)
|
|
58
|
-
const email = await promptEmail(emailArg)
|
|
52
|
+
const run = async (): Promise<void> => {
|
|
53
|
+
const domain = await promptDomain(domainArg)
|
|
54
|
+
const email = await promptEmail(emailArg)
|
|
59
55
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
try {
|
|
57
|
+
const configPath = updateServerConfigInProject(cwd, { domain, tlsEmail: email })
|
|
58
|
+
if (interactive) {
|
|
59
|
+
p.outro(`Updated ${configPath}`)
|
|
60
|
+
} else {
|
|
61
|
+
file("updated", configPath)
|
|
62
|
+
}
|
|
63
|
+
printDomainNextSteps(cwd, domain)
|
|
64
|
+
} catch (err) {
|
|
65
|
+
error((err as Error).message)
|
|
66
|
+
process.exit(1)
|
|
66
67
|
}
|
|
67
|
-
printDomainNextSteps(cwd, domain)
|
|
68
|
-
} catch (err) {
|
|
69
|
-
error((err as Error).message)
|
|
70
|
-
process.exit(1)
|
|
71
68
|
}
|
|
69
|
+
|
|
70
|
+
if (interactive) {
|
|
71
|
+
await runClackFlow(async () => {
|
|
72
|
+
p.intro("Add a custom domain")
|
|
73
|
+
await run()
|
|
74
|
+
})
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await run()
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
function printDomainNextSteps(cwd: string, domain: string): void {
|