@@ -5,20 +5,41 @@ import { readFileSync } from 'node:fs'
55import { dirname , join } from 'node:path'
66import { fileURLToPath } from 'node:url'
77import * as p from '@clack/prompts'
8+ // Commands that depend on @cipherstash /stack are lazy-loaded in the switch below.
89import {
910 authCommand ,
10- builderCommand ,
1111 initCommand ,
1212 installCommand ,
13- pushCommand ,
14- secretsCommand ,
1513 setupCommand ,
1614 statusCommand ,
1715 testConnectionCommand ,
1816 upgradeCommand ,
19- validateCommand ,
2017} from '../commands/index.js'
2118
19+ function isModuleNotFound ( err : unknown ) : boolean {
20+ return (
21+ err instanceof Error &&
22+ 'code' in err &&
23+ ( err as { code : string } ) . code === 'ERR_MODULE_NOT_FOUND'
24+ )
25+ }
26+
27+ async function requireStack < T > ( importFn : ( ) => Promise < T > ) : Promise < T > {
28+ try {
29+ return await importFn ( )
30+ } catch ( err : unknown ) {
31+ if ( isModuleNotFound ( err ) ) {
32+ p . log . error (
33+ '@cipherstash/stack is required for this command.\n' +
34+ ' Install it with: npm install @cipherstash/stack\n' +
35+ ' Or run: npx @cipherstash/cli init' ,
36+ )
37+ process . exit ( 1 ) as never
38+ }
39+ throw err
40+ }
41+ }
42+
2243const __dirname = dirname ( fileURLToPath ( import . meta. url ) )
2344const pkg = JSON . parse (
2445 readFileSync ( join ( __dirname , '../../package.json' ) , 'utf-8' ) ,
@@ -148,15 +169,19 @@ async function runDbCommand(
148169 out : values . out ,
149170 } )
150171 break
151- case 'push' :
172+ case 'push' : {
173+ const { pushCommand } = await requireStack ( ( ) => import ( '../commands/db/push.js' ) )
152174 await pushCommand ( { dryRun : flags [ 'dry-run' ] } )
153175 break
154- case 'validate' :
176+ }
177+ case 'validate' : {
178+ const { validateCommand } = await requireStack ( ( ) => import ( '../commands/db/validate.js' ) )
155179 await validateCommand ( {
156180 supabase : flags . supabase ,
157181 excludeOperatorFamily : flags [ 'exclude-operator-family' ] ,
158182 } )
159183 break
184+ }
160185 case 'status' :
161186 await statusCommand ( )
162187 break
@@ -179,9 +204,11 @@ async function runSchemaCommand(
179204 flags : Record < string , boolean > ,
180205) {
181206 switch ( sub ) {
182- case 'build' :
207+ case 'build' : {
208+ const { builderCommand } = await requireStack ( ( ) => import ( '../commands/schema/build.js' ) )
183209 await builderCommand ( { supabase : flags . supabase } )
184210 break
211+ }
185212 default :
186213 p . log . error ( `Unknown schema subcommand: ${ sub ?? '(none)' } ` )
187214 console . log ( )
@@ -215,6 +242,7 @@ async function main() {
215242 break
216243 }
217244 case 'secrets' : {
245+ const { secretsCommand } = await requireStack ( ( ) => import ( '../commands/secrets/index.js' ) )
218246 const secretsArgs = subcommand
219247 ? [ subcommand , ...commandArgs ]
220248 : commandArgs
0 commit comments