@beignet/cli 0.0.1 → 0.0.3
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/CHANGELOG.md +26 -0
- package/README.md +144 -55
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/create.d.ts +9 -0
- package/dist/create.d.ts.map +1 -1
- package/dist/create.js +5 -0
- package/dist/create.js.map +1 -1
- package/dist/db.d.ts +36 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +111 -0
- package/dist/db.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +243 -2
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +24 -0
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +288 -4
- package/dist/inspect.js.map +1 -1
- package/dist/lint.d.ts +12 -0
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +30 -5
- package/dist/lint.js.map +1 -1
- package/dist/make.d.ts +91 -0
- package/dist/make.d.ts.map +1 -1
- package/dist/make.js +602 -72
- package/dist/make.js.map +1 -1
- package/dist/templates.d.ts +33 -0
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +1396 -112
- package/dist/templates.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +31 -0
- package/src/create.ts +11 -0
- package/src/db.ts +166 -0
- package/src/index.ts +320 -0
- package/src/inspect.ts +497 -3
- package/src/lint.ts +43 -9
- package/src/make.ts +917 -80
- package/src/templates.ts +1425 -111
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "@stricli/core";
|
|
15
15
|
import type { CreateOptions } from "./create.js";
|
|
16
16
|
import { createProject } from "./create.js";
|
|
17
|
+
import { type DatabaseCommand, runDatabaseCommand } from "./db.js";
|
|
17
18
|
import {
|
|
18
19
|
applyDoctorFixes,
|
|
19
20
|
formatDoctor,
|
|
@@ -25,15 +26,24 @@ import {
|
|
|
25
26
|
makeAdapter,
|
|
26
27
|
makeContract,
|
|
27
28
|
makeEvent,
|
|
29
|
+
makeFactory,
|
|
30
|
+
makeFeature,
|
|
31
|
+
makeFeatureAddonChoices,
|
|
28
32
|
makeJob,
|
|
29
33
|
makeListener,
|
|
34
|
+
makeNotification,
|
|
30
35
|
makePolicy,
|
|
31
36
|
makePort,
|
|
32
37
|
makeResource,
|
|
33
38
|
makeSchedule,
|
|
39
|
+
makeSeed,
|
|
34
40
|
makeTest,
|
|
41
|
+
makeUpload,
|
|
35
42
|
makeUseCase,
|
|
36
43
|
} from "./make.js";
|
|
44
|
+
|
|
45
|
+
export type { MakeFeatureAddon } from "./make.js";
|
|
46
|
+
|
|
37
47
|
import {
|
|
38
48
|
type FeatureName,
|
|
39
49
|
featureChoices,
|
|
@@ -58,14 +68,21 @@ export {
|
|
|
58
68
|
makeAdapter,
|
|
59
69
|
makeContract,
|
|
60
70
|
makeEvent,
|
|
71
|
+
makeFactory,
|
|
72
|
+
makeFeature,
|
|
73
|
+
makeFeatureAddonChoices,
|
|
61
74
|
makeJob,
|
|
62
75
|
makeListener,
|
|
76
|
+
makeNotification,
|
|
63
77
|
makePolicy,
|
|
64
78
|
makePort,
|
|
65
79
|
makeResource,
|
|
66
80
|
makeSchedule,
|
|
81
|
+
makeSeed,
|
|
67
82
|
makeTest,
|
|
83
|
+
makeUpload,
|
|
68
84
|
makeUseCase,
|
|
85
|
+
runDatabaseCommand,
|
|
69
86
|
};
|
|
70
87
|
|
|
71
88
|
type CliContext = CommandContext & {
|
|
@@ -89,6 +106,10 @@ type MakeFlags = {
|
|
|
89
106
|
json?: boolean;
|
|
90
107
|
};
|
|
91
108
|
|
|
109
|
+
type MakeFeatureFlags = MakeFlags & {
|
|
110
|
+
with?: readonly (typeof makeFeatureAddonChoices)[number][];
|
|
111
|
+
};
|
|
112
|
+
|
|
92
113
|
type MakeListenerFlags = MakeFlags & {
|
|
93
114
|
event?: string;
|
|
94
115
|
};
|
|
@@ -103,6 +124,11 @@ type JsonFlags = {
|
|
|
103
124
|
json?: boolean;
|
|
104
125
|
};
|
|
105
126
|
|
|
127
|
+
type DbFlags = {
|
|
128
|
+
json?: boolean;
|
|
129
|
+
dryRun?: boolean;
|
|
130
|
+
};
|
|
131
|
+
|
|
106
132
|
type DoctorFlags = {
|
|
107
133
|
json?: boolean;
|
|
108
134
|
strict?: boolean;
|
|
@@ -158,6 +184,11 @@ const jsonFlagParameters = {
|
|
|
158
184
|
json: jsonFlag,
|
|
159
185
|
} satisfies FlagParametersForType<JsonFlags, CliContext>;
|
|
160
186
|
|
|
187
|
+
const dbFlagParameters = {
|
|
188
|
+
json: jsonFlag,
|
|
189
|
+
dryRun: dryRunFlag,
|
|
190
|
+
} satisfies FlagParametersForType<DbFlags, CliContext>;
|
|
191
|
+
|
|
161
192
|
const namePositional = {
|
|
162
193
|
kind: "tuple",
|
|
163
194
|
parameters: [
|
|
@@ -337,6 +368,46 @@ const lintCommand = buildCommand<JsonFlags, [], CliContext>({
|
|
|
337
368
|
},
|
|
338
369
|
});
|
|
339
370
|
|
|
371
|
+
function databaseCommand(command: DatabaseCommand) {
|
|
372
|
+
return buildCommand<DbFlags, [], CliContext>({
|
|
373
|
+
docs: {
|
|
374
|
+
brief: `Run the app's db:${command} script.`,
|
|
375
|
+
},
|
|
376
|
+
parameters: {
|
|
377
|
+
flags: dbFlagParameters,
|
|
378
|
+
},
|
|
379
|
+
async func(flags) {
|
|
380
|
+
const result = await runDatabaseCommand({
|
|
381
|
+
command,
|
|
382
|
+
captureOutput: Boolean(flags.json),
|
|
383
|
+
dryRun: Boolean(flags.dryRun),
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
writeOutput(
|
|
387
|
+
this,
|
|
388
|
+
flags.json
|
|
389
|
+
? JSON.stringify(result, null, 2)
|
|
390
|
+
: databaseCommandNextSteps(result),
|
|
391
|
+
);
|
|
392
|
+
if (result.exitCode !== 0) {
|
|
393
|
+
this.process.exitCode = result.exitCode;
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const dbRoutes = buildRouteMap({
|
|
400
|
+
docs: {
|
|
401
|
+
brief: "Run Beignet database lifecycle commands.",
|
|
402
|
+
},
|
|
403
|
+
routes: {
|
|
404
|
+
generate: databaseCommand("generate"),
|
|
405
|
+
migrate: databaseCommand("migrate"),
|
|
406
|
+
reset: databaseCommand("reset"),
|
|
407
|
+
seed: databaseCommand("seed"),
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
|
|
340
411
|
const makeResourceCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
341
412
|
docs: {
|
|
342
413
|
brief: "Generate a feature resource.",
|
|
@@ -360,6 +431,42 @@ const makeResourceCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
|
360
431
|
},
|
|
361
432
|
});
|
|
362
433
|
|
|
434
|
+
const makeFeatureCommand = buildCommand<MakeFeatureFlags, [string], CliContext>(
|
|
435
|
+
{
|
|
436
|
+
docs: {
|
|
437
|
+
brief: "Generate a contract-first feature slice.",
|
|
438
|
+
},
|
|
439
|
+
parameters: {
|
|
440
|
+
flags: {
|
|
441
|
+
...makeFlagParameters,
|
|
442
|
+
with: {
|
|
443
|
+
kind: "enum",
|
|
444
|
+
values: makeFeatureAddonChoices,
|
|
445
|
+
optional: true,
|
|
446
|
+
variadic: ",",
|
|
447
|
+
brief:
|
|
448
|
+
"Add feature-owned artifacts. Supports policy, event/events, job/jobs, and upload/uploads.",
|
|
449
|
+
},
|
|
450
|
+
} satisfies FlagParametersForType<MakeFeatureFlags, CliContext>,
|
|
451
|
+
positional: namePositional,
|
|
452
|
+
},
|
|
453
|
+
async func(flags, name) {
|
|
454
|
+
const result = await makeFeature({
|
|
455
|
+
name,
|
|
456
|
+
with: flags.with,
|
|
457
|
+
force: Boolean(flags.force),
|
|
458
|
+
dryRun: Boolean(flags.dryRun),
|
|
459
|
+
});
|
|
460
|
+
writeOutput(
|
|
461
|
+
this,
|
|
462
|
+
flags.json
|
|
463
|
+
? JSON.stringify(result, null, 2)
|
|
464
|
+
: makeFeatureNextSteps(result),
|
|
465
|
+
);
|
|
466
|
+
},
|
|
467
|
+
},
|
|
468
|
+
);
|
|
469
|
+
|
|
363
470
|
const makeContractCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
364
471
|
docs: {
|
|
365
472
|
brief: "Generate a contract group.",
|
|
@@ -536,6 +643,73 @@ const makeJobCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
|
536
643
|
},
|
|
537
644
|
});
|
|
538
645
|
|
|
646
|
+
const makeFactoryCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
647
|
+
docs: {
|
|
648
|
+
brief: "Generate a feature test data factory.",
|
|
649
|
+
},
|
|
650
|
+
parameters: {
|
|
651
|
+
flags: makeFlagParameters,
|
|
652
|
+
positional: namePositional,
|
|
653
|
+
},
|
|
654
|
+
async func(flags, name) {
|
|
655
|
+
const result = await makeFactory({
|
|
656
|
+
name,
|
|
657
|
+
force: Boolean(flags.force),
|
|
658
|
+
dryRun: Boolean(flags.dryRun),
|
|
659
|
+
});
|
|
660
|
+
writeOutput(
|
|
661
|
+
this,
|
|
662
|
+
flags.json
|
|
663
|
+
? JSON.stringify(result, null, 2)
|
|
664
|
+
: makeFactoryNextSteps(result),
|
|
665
|
+
);
|
|
666
|
+
},
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
const makeSeedCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
670
|
+
docs: {
|
|
671
|
+
brief: "Generate a feature seed.",
|
|
672
|
+
},
|
|
673
|
+
parameters: {
|
|
674
|
+
flags: makeFlagParameters,
|
|
675
|
+
positional: namePositional,
|
|
676
|
+
},
|
|
677
|
+
async func(flags, name) {
|
|
678
|
+
const result = await makeSeed({
|
|
679
|
+
name,
|
|
680
|
+
force: Boolean(flags.force),
|
|
681
|
+
dryRun: Boolean(flags.dryRun),
|
|
682
|
+
});
|
|
683
|
+
writeOutput(
|
|
684
|
+
this,
|
|
685
|
+
flags.json ? JSON.stringify(result, null, 2) : makeSeedNextSteps(result),
|
|
686
|
+
);
|
|
687
|
+
},
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
const makeNotificationCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
691
|
+
docs: {
|
|
692
|
+
brief: "Generate a feature notification.",
|
|
693
|
+
},
|
|
694
|
+
parameters: {
|
|
695
|
+
flags: makeFlagParameters,
|
|
696
|
+
positional: namePositional,
|
|
697
|
+
},
|
|
698
|
+
async func(flags, name) {
|
|
699
|
+
const result = await makeNotification({
|
|
700
|
+
name,
|
|
701
|
+
force: Boolean(flags.force),
|
|
702
|
+
dryRun: Boolean(flags.dryRun),
|
|
703
|
+
});
|
|
704
|
+
writeOutput(
|
|
705
|
+
this,
|
|
706
|
+
flags.json
|
|
707
|
+
? JSON.stringify(result, null, 2)
|
|
708
|
+
: makeNotificationNextSteps(result),
|
|
709
|
+
);
|
|
710
|
+
},
|
|
711
|
+
});
|
|
712
|
+
|
|
539
713
|
const makeListenerFlagParameters = {
|
|
540
714
|
...makeFlagParameters,
|
|
541
715
|
event: parsedStringFlag("Event to listen to, for example posts/published."),
|
|
@@ -617,6 +791,29 @@ const makeScheduleCommand = buildCommand<
|
|
|
617
791
|
},
|
|
618
792
|
});
|
|
619
793
|
|
|
794
|
+
const makeUploadCommand = buildCommand<MakeFlags, [string], CliContext>({
|
|
795
|
+
docs: {
|
|
796
|
+
brief: "Generate a feature upload.",
|
|
797
|
+
},
|
|
798
|
+
parameters: {
|
|
799
|
+
flags: makeFlagParameters,
|
|
800
|
+
positional: namePositional,
|
|
801
|
+
},
|
|
802
|
+
async func(flags, name) {
|
|
803
|
+
const result = await makeUpload({
|
|
804
|
+
name,
|
|
805
|
+
force: Boolean(flags.force),
|
|
806
|
+
dryRun: Boolean(flags.dryRun),
|
|
807
|
+
});
|
|
808
|
+
writeOutput(
|
|
809
|
+
this,
|
|
810
|
+
flags.json
|
|
811
|
+
? JSON.stringify(result, null, 2)
|
|
812
|
+
: makeUploadNextSteps(result),
|
|
813
|
+
);
|
|
814
|
+
},
|
|
815
|
+
});
|
|
816
|
+
|
|
620
817
|
const makeRoutes = buildRouteMap({
|
|
621
818
|
docs: {
|
|
622
819
|
brief: "Generate Beignet app files.",
|
|
@@ -625,13 +822,18 @@ const makeRoutes = buildRouteMap({
|
|
|
625
822
|
adapter: makeAdapterCommand,
|
|
626
823
|
contract: makeContractCommand,
|
|
627
824
|
event: makeEventCommand,
|
|
825
|
+
factory: makeFactoryCommand,
|
|
826
|
+
feature: makeFeatureCommand,
|
|
628
827
|
job: makeJobCommand,
|
|
828
|
+
notification: makeNotificationCommand,
|
|
629
829
|
listener: makeListenerCommand,
|
|
630
830
|
policy: makePolicyCommand,
|
|
631
831
|
port: makePortCommand,
|
|
632
832
|
resource: makeResourceCommand,
|
|
633
833
|
schedule: makeScheduleCommand,
|
|
834
|
+
seed: makeSeedCommand,
|
|
634
835
|
test: makeTestCommand,
|
|
836
|
+
upload: makeUploadCommand,
|
|
635
837
|
useCase: makeUseCaseCommand,
|
|
636
838
|
},
|
|
637
839
|
});
|
|
@@ -645,6 +847,7 @@ create-beignet <directory> is equivalent to beignet create <directory>.`,
|
|
|
645
847
|
},
|
|
646
848
|
routes: {
|
|
647
849
|
create: createCommand,
|
|
850
|
+
db: dbRoutes,
|
|
648
851
|
doctor: doctorCommand,
|
|
649
852
|
lint: lintCommand,
|
|
650
853
|
make: makeRoutes,
|
|
@@ -738,6 +941,39 @@ Next steps:
|
|
|
738
941
|
Run your app's typecheck and test commands.`;
|
|
739
942
|
}
|
|
740
943
|
|
|
944
|
+
function databaseCommandNextSteps(
|
|
945
|
+
result: Awaited<ReturnType<typeof runDatabaseCommand>>,
|
|
946
|
+
): string {
|
|
947
|
+
const command = [result.runner, ...result.args].join(" ");
|
|
948
|
+
const prefix = result.dryRun ? "Would run" : "Ran";
|
|
949
|
+
|
|
950
|
+
return `${prefix} ${result.script} in ${result.cwd}
|
|
951
|
+
|
|
952
|
+
Command:
|
|
953
|
+
${command}`;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
function makeFeatureNextSteps(
|
|
957
|
+
result: Awaited<ReturnType<typeof makeFeature>>,
|
|
958
|
+
): string {
|
|
959
|
+
const changedFiles = [...result.createdFiles, ...result.updatedFiles]
|
|
960
|
+
.map((file) => ` ${file}`)
|
|
961
|
+
.join("\n");
|
|
962
|
+
const skippedFiles = result.skippedFiles
|
|
963
|
+
.map((file) => ` ${file}`)
|
|
964
|
+
.join("\n");
|
|
965
|
+
|
|
966
|
+
return `${result.dryRun ? "Would create" : "Created"} ${result.name} feature slice in ${result.targetDir}
|
|
967
|
+
|
|
968
|
+
Changed files:
|
|
969
|
+
${changedFiles || " none"}
|
|
970
|
+
${skippedFiles ? `\nSkipped identical files:\n${skippedFiles}` : ""}
|
|
971
|
+
|
|
972
|
+
Next steps:
|
|
973
|
+
Treat the generated name field as a placeholder and shape the contracts, use cases, and repository around the feature's real workflow.
|
|
974
|
+
Run your app's typecheck, test, beignet lint, and beignet doctor commands.`;
|
|
975
|
+
}
|
|
976
|
+
|
|
741
977
|
function makeContractNextSteps(
|
|
742
978
|
result: Awaited<ReturnType<typeof makeContract>>,
|
|
743
979
|
): string {
|
|
@@ -904,6 +1140,69 @@ Next steps:
|
|
|
904
1140
|
Dispatch the job through ctx.ports.jobs from a use case, listener, or schedule.`;
|
|
905
1141
|
}
|
|
906
1142
|
|
|
1143
|
+
function makeFactoryNextSteps(
|
|
1144
|
+
result: Awaited<ReturnType<typeof makeFactory>>,
|
|
1145
|
+
): string {
|
|
1146
|
+
const changedFiles = [...result.createdFiles, ...result.updatedFiles]
|
|
1147
|
+
.map((file) => ` ${file}`)
|
|
1148
|
+
.join("\n");
|
|
1149
|
+
const skippedFiles = result.skippedFiles
|
|
1150
|
+
.map((file) => ` ${file}`)
|
|
1151
|
+
.join("\n");
|
|
1152
|
+
|
|
1153
|
+
return `${result.dryRun ? "Would create" : "Created"} ${result.name} factory in ${result.targetDir}
|
|
1154
|
+
|
|
1155
|
+
Changed files:
|
|
1156
|
+
${changedFiles || " none"}
|
|
1157
|
+
${skippedFiles ? `\nSkipped identical files:\n${skippedFiles}` : ""}
|
|
1158
|
+
|
|
1159
|
+
Next steps:
|
|
1160
|
+
Replace the starter defaults with realistic test data for this feature.
|
|
1161
|
+
Persist through app-owned repository ports so tests avoid raw database clients.`;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
function makeSeedNextSteps(
|
|
1165
|
+
result: Awaited<ReturnType<typeof makeSeed>>,
|
|
1166
|
+
): string {
|
|
1167
|
+
const changedFiles = [...result.createdFiles, ...result.updatedFiles]
|
|
1168
|
+
.map((file) => ` ${file}`)
|
|
1169
|
+
.join("\n");
|
|
1170
|
+
const skippedFiles = result.skippedFiles
|
|
1171
|
+
.map((file) => ` ${file}`)
|
|
1172
|
+
.join("\n");
|
|
1173
|
+
|
|
1174
|
+
return `${result.dryRun ? "Would create" : "Created"} ${result.name} seed in ${result.targetDir}
|
|
1175
|
+
|
|
1176
|
+
Changed files:
|
|
1177
|
+
${changedFiles || " none"}
|
|
1178
|
+
${skippedFiles ? `\nSkipped identical files:\n${skippedFiles}` : ""}
|
|
1179
|
+
|
|
1180
|
+
Next steps:
|
|
1181
|
+
Replace the starter record with idempotent local or demo data.
|
|
1182
|
+
Import the feature seed from your app-owned database seed entrypoint and run it with runSeeds(...).`;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
function makeNotificationNextSteps(
|
|
1186
|
+
result: Awaited<ReturnType<typeof makeNotification>>,
|
|
1187
|
+
): string {
|
|
1188
|
+
const changedFiles = [...result.createdFiles, ...result.updatedFiles]
|
|
1189
|
+
.map((file) => ` ${file}`)
|
|
1190
|
+
.join("\n");
|
|
1191
|
+
const skippedFiles = result.skippedFiles
|
|
1192
|
+
.map((file) => ` ${file}`)
|
|
1193
|
+
.join("\n");
|
|
1194
|
+
|
|
1195
|
+
return `${result.dryRun ? "Would create" : "Created"} ${result.name} notification in ${result.targetDir}
|
|
1196
|
+
|
|
1197
|
+
Changed files:
|
|
1198
|
+
${changedFiles || " none"}
|
|
1199
|
+
${skippedFiles ? `\nSkipped identical files:\n${skippedFiles}` : ""}
|
|
1200
|
+
|
|
1201
|
+
Next steps:
|
|
1202
|
+
Replace the starter payload and channels with the real user-facing message.
|
|
1203
|
+
Send the notification through ctx.ports.notifications so delivery can run inline in tests and through jobs in production.`;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
907
1206
|
function makeListenerNextSteps(
|
|
908
1207
|
result: Awaited<ReturnType<typeof makeListener>>,
|
|
909
1208
|
): string {
|
|
@@ -946,6 +1245,27 @@ Next steps:
|
|
|
946
1245
|
Trigger it from a cron route, worker, or provider adapter.`;
|
|
947
1246
|
}
|
|
948
1247
|
|
|
1248
|
+
function makeUploadNextSteps(
|
|
1249
|
+
result: Awaited<ReturnType<typeof makeUpload>>,
|
|
1250
|
+
): string {
|
|
1251
|
+
const changedFiles = [...result.createdFiles, ...result.updatedFiles]
|
|
1252
|
+
.map((file) => ` ${file}`)
|
|
1253
|
+
.join("\n");
|
|
1254
|
+
const skippedFiles = result.skippedFiles
|
|
1255
|
+
.map((file) => ` ${file}`)
|
|
1256
|
+
.join("\n");
|
|
1257
|
+
|
|
1258
|
+
return `${result.dryRun ? "Would create" : "Created"} ${result.name} upload in ${result.targetDir}
|
|
1259
|
+
|
|
1260
|
+
Changed files:
|
|
1261
|
+
${changedFiles || " none"}
|
|
1262
|
+
${skippedFiles ? `\nSkipped identical files:\n${skippedFiles}` : ""}
|
|
1263
|
+
|
|
1264
|
+
Next steps:
|
|
1265
|
+
Replace the starter metadata, constraints, key, authorization, and onComplete behavior.
|
|
1266
|
+
Register the upload in createUploadRouter(...) and expose it with createUploadRoute(...).`;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
949
1269
|
export async function main(
|
|
950
1270
|
inputs = process.argv.slice(2),
|
|
951
1271
|
context: StricliDynamicCommandContext<CliContext> = { process },
|