@akanjs/devkit 3.0.0-beta.9 → 3.0.0
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/DEV_RUNTIME_KNOBS.md +44 -26
- package/README.ko.md +21 -7
- package/README.md +17 -8
- package/abstractDoc.test.ts +6 -15
- package/abstractDoc.ts +6 -8
- package/agentsIndex.test.ts +4 -7
- package/agentsIndex.ts +6 -22
- package/akanApp/BackendImportGraph.test.ts +8 -22
- package/akanApp/BackendImportGraph.ts +1 -20
- package/akanApp/akanApp.host.test.ts +56 -3
- package/akanApp/akanApp.host.ts +218 -278
- package/akanApp/devBootLatch.test.ts +39 -0
- package/akanApp/devBootLatch.ts +39 -0
- package/akanApp/devHostPolicy.test.ts +81 -35
- package/akanApp/devHostPolicy.ts +41 -102
- package/akanConfig/akanBin.test.ts +62 -0
- package/akanConfig/akanBin.ts +78 -0
- package/akanConfig/akanConfig.test.ts +439 -141
- package/akanConfig/akanConfig.ts +359 -275
- package/akanConfig/index.ts +1 -0
- package/akanConfig/types.ts +22 -8
- package/akanContext.ts +110 -160
- package/akanMcpContract.ts +28 -73
- package/appSelectionMemory.ts +1 -4
- package/applicationBuildReporter.ts +37 -5
- package/applicationBuildRunner.test.ts +41 -5
- package/applicationBuildRunner.ts +71 -63
- package/applicationTestPreload.ts +3 -12
- package/artifact/implicitRootLayout.test.ts +32 -30
- package/artifact/implicitRootLayout.ts +58 -106
- package/artifact/routeSeedIndex.test.ts +7 -6
- package/artifact/routeSeedIndex.ts +11 -44
- package/biome.base.json +35 -2
- package/biomeBase.ts +2 -5
- package/cloud/cloudApi.test.ts +202 -0
- package/cloud/cloudApi.ts +77 -39
- package/cloud/configLock.test.ts +64 -0
- package/cloud/configLock.ts +96 -0
- package/cloud/constants.ts +26 -5
- package/cloud/globalConfig.ts +71 -32
- package/codeAgent/agent/AkanCodeServices.ts +97 -0
- package/codeAgent/agent/AkanContextFiles.ts +94 -0
- package/codeAgent/agent/CodeAgent.ts +551 -0
- package/codeAgent/agent/CodeAgentAsks.ts +66 -0
- package/codeAgent/agent/CodeAgentEventMapper.ts +225 -0
- package/codeAgent/agent/CodeAgentGate.ts +93 -0
- package/codeAgent/agent/CodeAgentProxy.ts +82 -0
- package/codeAgent/agent/CodeAgentRpcHost.ts +103 -0
- package/codeAgent/agent/CodeAgentRpcListener.ts +109 -0
- package/codeAgent/agent/CodeAgentStreamPrinter.ts +86 -0
- package/codeAgent/agent/CodeAgentSuspended.ts +85 -0
- package/codeAgent/agent/CodeAgentUi.ts +47 -0
- package/codeAgent/agent/CodeMailbox.ts +148 -0
- package/codeAgent/agent/CodeSessionFork.ts +56 -0
- package/codeAgent/agent/CodeSessionIndex.ts +78 -0
- package/codeAgent/agent/SubagentPool.ts +214 -0
- package/codeAgent/agent/akanCodeModel.ts +47 -0
- package/codeAgent/agent/akanCodePaths.ts +31 -0
- package/codeAgent/agent/akanContextFiles.test.ts +114 -0
- package/codeAgent/agent/akanSystemPrompt.ts +46 -0
- package/codeAgent/agent/codeAgent.test.ts +178 -0
- package/codeAgent/agent/codeAgentContract.test.ts +523 -0
- package/codeAgent/agent/codeAgentProxy.test.ts +74 -0
- package/codeAgent/agent/codeAgentRpcListener.test.ts +113 -0
- package/codeAgent/agent/codeAgentSuspended.test.ts +47 -0
- package/codeAgent/agent/codeMailbox.test.ts +76 -0
- package/codeAgent/agent/codeSessionFork.test.ts +58 -0
- package/codeAgent/agent/codeSessionIndex.test.ts +77 -0
- package/codeAgent/agent/consoleToStderr.ts +8 -0
- package/codeAgent/agent/jsonLines.ts +29 -0
- package/codeAgent/agent/stringArg.ts +5 -0
- package/codeAgent/feedback/DevLogFeedback.ts +82 -0
- package/codeAgent/feedback/PreviewChrome.ts +82 -0
- package/codeAgent/feedback/PreviewFeedback.ts +46 -0
- package/codeAgent/feedback/PreviewView.ts +95 -0
- package/codeAgent/feedback/TurnFeedback.ts +98 -0
- package/codeAgent/feedback/VerifyFeedback.ts +40 -0
- package/codeAgent/feedback/previewChrome.test.ts +73 -0
- package/codeAgent/index.ts +34 -0
- package/codeAgent/skills/akan-code/SKILL.md +130 -0
- package/codeAgent/skills/akan-debug/SKILL.md +42 -0
- package/codeAgent/skills/akan-deps/SKILL.md +50 -0
- package/codeAgent/skills/akan-err/SKILL.md +39 -0
- package/codeAgent/skills/akan-module/SKILL.md +45 -0
- package/codeAgent/skills/akan-scaffold/SKILL.md +76 -0
- package/codeAgent/skills/akan-scalar/SKILL.md +52 -0
- package/codeAgent/skills/akan-service/SKILL.md +34 -0
- package/codeAgent/skills/akan-store/SKILL.md +67 -0
- package/codeAgent/skills/akan-ui/SKILL.md +63 -0
- package/codeAgent/skills/akan-validate/SKILL.md +44 -0
- package/codeAgent/tools/AkanCli.ts +50 -0
- package/codeAgent/tools/AkanCodePlugins.ts +136 -0
- package/codeAgent/tools/AkanEditScope.ts +48 -0
- package/codeAgent/tools/AkanEnvKeys.ts +50 -0
- package/codeAgent/tools/AkanToolPack.ts +92 -0
- package/codeAgent/tools/AkanVerifier.ts +48 -0
- package/codeAgent/tools/AskToolPack.ts +99 -0
- package/codeAgent/tools/MailToolPack.ts +76 -0
- package/codeAgent/tools/McpClient.ts +187 -0
- package/codeAgent/tools/McpOAuth.ts +233 -0
- package/codeAgent/tools/McpOAuthLoopback.ts +64 -0
- package/codeAgent/tools/McpServerConfig.ts +129 -0
- package/codeAgent/tools/McpSignIn.ts +158 -0
- package/codeAgent/tools/McpTokenStore.ts +81 -0
- package/codeAgent/tools/McpToolPack.ts +199 -0
- package/codeAgent/tools/SessionToolPack.ts +91 -0
- package/codeAgent/tools/WebToolPack.ts +147 -0
- package/codeAgent/tools/akanCodePlugins.test.ts +677 -0
- package/codeAgent/tools/askToolPack.test.ts +116 -0
- package/codeAgent/tools/mcpOAuth.test.ts +612 -0
- package/codeAgent/tools/mcpServerConfig.test.ts +212 -0
- package/codegenLock.test.ts +4 -13
- package/codegenLock.ts +3 -17
- package/commandDecorators/argMeta.ts +1 -5
- package/commandDecorators/camelToKebabCase.ts +1 -0
- package/commandDecorators/command.ts +46 -102
- package/commandDecorators/commandBuilder.ts +30 -61
- package/commandDecorators/commandDecorators.test.ts +2 -10
- package/commandDecorators/dependencyBuilder.ts +10 -1
- package/commandDecorators/helpFormatter.ts +68 -145
- package/commandDecorators/index.ts +0 -2
- package/commandDecorators/targetMeta.ts +9 -7
- package/createTunnel.ts +7 -14
- package/csrE2e/csrE2eHarness.fixture.ts +505 -0
- package/csrE2e/csrFastRefresh.e2e.test.ts +233 -0
- package/csrE2e/csrPageStack.e2e.test.ts +252 -0
- package/csrE2e/csrPatchFirst.e2e.test.ts +87 -0
- package/csrE2e/csrRootLayout.e2e.test.ts +134 -0
- package/csrE2e/devHmrLatency.e2e.test.ts +391 -0
- package/csrE2e/registryVendor.e2e.test.ts +221 -0
- package/csrE2e/ssrRegistry.e2e.test.ts +644 -0
- package/dependencyScanner.test.ts +4 -16
- package/dependencyScanner.ts +31 -80
- package/devkitUtils.test.ts +48 -20
- package/executors.linkFallback.test.ts +103 -0
- package/executors.test.ts +176 -106
- package/executors.ts +212 -498
- package/fileEditor.ts +9 -37
- package/{getDirname.test.ts → fileSys.test.ts} +5 -3
- package/fileSys.ts +22 -9
- package/formSetterScanner.ts +3 -16
- package/frontendBuild/allRoutesBuilder.ts +7 -21
- package/frontendBuild/autoImportSync.test.ts +27 -38
- package/frontendBuild/autoImportSync.ts +31 -65
- package/frontendBuild/buildRouteClient.test.ts +123 -37
- package/frontendBuild/bundleDefine.test.ts +12 -0
- package/frontendBuild/bundleDefine.ts +16 -0
- package/frontendBuild/clientBuildTypes.ts +5 -36
- package/frontendBuild/clientEntriesBundler.ts +9 -40
- package/frontendBuild/clientEntryDiscovery.test.ts +112 -0
- package/frontendBuild/clientEntryDiscovery.ts +122 -110
- package/frontendBuild/csrArtifactBuilder.ts +9 -31
- package/frontendBuild/csrDevArtifactWriter.test.ts +151 -0
- package/frontendBuild/csrDevArtifactWriter.ts +307 -0
- package/frontendBuild/csrDevBundler.test.ts +66 -0
- package/frontendBuild/csrDevBundler.ts +95 -0
- package/frontendBuild/csrDevFactoryCheck.test.ts +33 -0
- package/frontendBuild/csrDevFactoryCheck.ts +39 -0
- package/frontendBuild/csrDevModuleCompiler.test.ts +293 -0
- package/frontendBuild/csrDevModuleCompiler.ts +422 -0
- package/frontendBuild/csrDevPatcher.test.ts +572 -0
- package/frontendBuild/csrDevPatcher.ts +548 -0
- package/frontendBuild/csrDevPaths.ts +145 -0
- package/frontendBuild/csrDevResolver.test.ts +239 -0
- package/frontendBuild/csrDevResolver.ts +363 -0
- package/frontendBuild/csrDevTypes.ts +61 -0
- package/frontendBuild/csrEntryFiles.ts +24 -0
- package/frontendBuild/cssCandidateCache.test.ts +0 -6
- package/frontendBuild/cssCandidateCache.ts +6 -41
- package/frontendBuild/cssCompiler.ts +31 -82
- package/frontendBuild/cssImportResolver.ts +6 -19
- package/frontendBuild/devChangePlanner.ts +7 -10
- package/frontendBuild/devGeneratedIndexSync.test.ts +12 -27
- package/frontendBuild/devGeneratedIndexSync.ts +1 -4
- package/frontendBuild/devRegistryBundler.ts +192 -0
- package/frontendBuild/fontOptimizer.test.ts +6 -14
- package/frontendBuild/fontOptimizer.ts +15 -72
- package/frontendBuild/fontPruner.test.ts +5 -10
- package/frontendBuild/fontPruner.ts +5 -20
- package/frontendBuild/frontendBuild.test.ts +57 -70
- package/frontendBuild/hmrChangeClassifier.ts +2 -2
- package/frontendBuild/hmrWatcher.test.ts +59 -32
- package/frontendBuild/hmrWatcher.ts +31 -74
- package/frontendBuild/index.ts +4 -0
- package/frontendBuild/pagesBundleBuilder.ts +28 -30
- package/frontendBuild/pagesEntrySourceGenerator.ts +56 -6
- package/frontendBuild/precompressArtifacts.ts +5 -18
- package/frontendBuild/registryMetadataFingerprint.test.ts +63 -0
- package/frontendBuild/registryMetadataFingerprint.ts +28 -0
- package/frontendBuild/routeClientBuilder.ts +100 -62
- package/frontendBuild/routesManifestArtifactSerializer.ts +5 -36
- package/frontendBuild/serverGraphFile.test.ts +77 -0
- package/frontendBuild/serverGraphFile.ts +93 -0
- package/frontendBuild/sourceMtimeIndex.test.ts +41 -97
- package/frontendBuild/sourceMtimeIndex.ts +19 -130
- package/frontendBuild/ssrBaseArtifactBuilder.ts +19 -13
- package/frontendBuild/ssrDevBundler.ts +85 -0
- package/frontendBuild/styleContract.ts +1 -8
- package/frontendBuild/themeValidator.ts +4 -26
- package/frontendBuild/watchRootResolver.test.ts +23 -42
- package/frontendBuild/watchRootResolver.ts +5 -27
- package/getRelatedCnsts.ts +12 -92
- package/incrementalBuilder/buildBatch.proc.ts +147 -63
- package/incrementalBuilder/buildBatchProtocol.ts +13 -38
- package/incrementalBuilder/buildBatchRunner.test.ts +65 -0
- package/incrementalBuilder/buildBatchRunner.ts +26 -38
- package/incrementalBuilder/builderChannel.test.ts +24 -49
- package/incrementalBuilder/builderChannel.ts +6 -37
- package/incrementalBuilder/builderRequestRouter.test.ts +0 -8
- package/incrementalBuilder/builderRequestRouter.ts +5 -24
- package/incrementalBuilder/builderWorkQueue.test.ts +94 -0
- package/incrementalBuilder/builderWorkQueue.ts +126 -0
- package/incrementalBuilder/devWatchBatch.test.ts +21 -24
- package/incrementalBuilder/incrementalBuilder.host.test.ts +53 -56
- package/incrementalBuilder/incrementalBuilder.host.ts +68 -81
- package/incrementalBuilder/incrementalBuilder.proc.test.ts +270 -0
- package/incrementalBuilder/incrementalBuilder.proc.ts +596 -208
- package/index.ts +5 -19
- package/integration/devResourceProbe.ts +50 -56
- package/integration/devStability.integration.test.ts +105 -199
- package/integration/devStabilityHarness.test.ts +13 -28
- package/integration/devStabilityHarness.ts +65 -330
- package/integration/ssrMemoryProbe.ts +41 -167
- package/libSource.test.ts +4 -15
- package/libSource.ts +19 -31
- package/lint/__fixtures__/no-document-cookie/bad.tsx +4 -0
- package/lint/__fixtures__/no-document-cookie/good.tsx +7 -0
- package/lint/__fixtures__/no-web-only-api-outside-webkit/bad.tsx +7 -0
- package/lint/__fixtures__/no-web-only-api-outside-webkit/good.tsx +11 -0
- package/lint/__fixtures__/no-web-storage/bad.tsx +6 -0
- package/lint/__fixtures__/no-web-storage/good.tsx +7 -0
- package/lint/gritRules.test.ts +8 -24
- package/lint/no-deep-internal-import.grit +2 -2
- package/lint/no-document-cookie.grit +29 -0
- package/lint/no-redeclare-predefined-endpoint.grit +2 -1
- package/lint/no-web-only-api-outside-webkit.grit +44 -0
- package/lint/no-web-storage.grit +30 -0
- package/linter.test.ts +1 -2
- package/linter.ts +26 -116
- package/mobile/desktopBin.test.ts +182 -0
- package/mobile/desktopBin.ts +144 -0
- package/mobile/desktopServerStage.test.ts +252 -0
- package/mobile/desktopServerStage.ts +178 -0
- package/mobile/index.ts +9 -0
- package/mobile/mobileTarget.test.ts +57 -8
- package/mobile/mobileTarget.ts +45 -26
- package/mobile/nativeApi.test.ts +30 -0
- package/mobile/nativeApi.ts +40 -0
- package/mobile/nativeApp.test.ts +184 -0
- package/mobile/nativeApp.ts +454 -0
- package/mobile/nativeAppLine.test.ts +69 -0
- package/mobile/nativeAppLine.ts +71 -0
- package/mobile/nativeConfig.test.ts +438 -0
- package/mobile/nativeConfig.ts +294 -0
- package/mobile/nativePluginFolders.test.ts +81 -0
- package/mobile/nativePluginFolders.ts +60 -0
- package/mobile/nativeWebDir.test.ts +80 -0
- package/mobile/nativeWebDir.ts +66 -0
- package/mobile/placeholderAppId.test.ts +13 -0
- package/mobile/placeholderAppId.ts +16 -0
- package/mobile/usageDescriptions.test.ts +27 -0
- package/mobile/usageDescriptions.ts +24 -0
- package/package.json +11 -11
- package/packageExports.test.ts +3 -18
- package/packageExportsMap.ts +3 -19
- package/piDependencyPins.test.ts +46 -0
- package/platformTest/BunTestReport.test.ts +60 -0
- package/platformTest/BunTestReport.ts +65 -0
- package/platformTest/IdleWatchedProcess.test.ts +56 -0
- package/platformTest/IdleWatchedProcess.ts +73 -0
- package/platformTest/LinuxDockerTarget.ts +105 -0
- package/platformTest/PlatformTestRun.test.ts +64 -0
- package/platformTest/PlatformTestRun.ts +141 -0
- package/platformTest/PlatformTestTarget.ts +142 -0
- package/platformTest/TestSnapshot.test.ts +72 -0
- package/platformTest/TestSnapshot.ts +103 -0
- package/platformTest/WindowsSshTarget.ts +151 -0
- package/prompter.ts +3 -13
- package/qualityScanner.test.ts +9 -26
- package/qualityScanner.ts +200 -286
- package/recipeScanner.test.ts +7 -12
- package/recipeScanner.ts +9 -38
- package/repoIdentity.ts +2 -9
- package/routeSourceValidator.test.ts +0 -1
- package/routeSourceValidator.ts +7 -42
- package/scanInfo.ts +91 -225
- package/selectModel.ts +1 -2
- package/semver.ts +3 -5
- package/slicePlanner.test.ts +6 -24
- package/slicePlanner.ts +11 -32
- package/spinner.test.ts +3 -8
- package/spinner.ts +4 -16
- package/sshTunnel.ts +1 -6
- package/ssrScanner.test.ts +1 -6
- package/ssrScanner.ts +103 -113
- package/stripAnsi.ts +3 -0
- package/subspace.test.ts +9 -25
- package/subspace.ts +48 -115
- package/subspaceConfig.ts +3 -11
- package/testHelpers.ts +194 -0
- package/transforms/asyncDefaultExportDetector.ts +3 -11
- package/transforms/barrelAnalyzer.ts +43 -135
- package/transforms/barrelImportsPlugin.ts +38 -175
- package/transforms/externalizeFrameworkPlugin.test.ts +39 -118
- package/transforms/externalizeFrameworkPlugin.ts +13 -87
- package/transforms/moduleSyntax.ts +32 -0
- package/transforms/rscUseClientTransform.ts +42 -20
- package/transforms/serverEnvPlugin.test.ts +103 -0
- package/transforms/serverEnvPlugin.ts +41 -0
- package/transforms/transforms.test.ts +166 -44
- package/transforms/tsconfigPackageResolver.test.ts +6 -24
- package/transforms/useClientBundlePlugin.ts +6 -23
- package/typeChecker.ts +7 -63
- package/types.ts +2 -0
- package/uploadRelease.ts +10 -25
- package/workflow/artifacts.ts +18 -0
- package/workflow/executor.test.ts +1 -12
- package/workflow/executor.ts +101 -110
- package/workflow/index.ts +0 -1
- package/workflow/moduleIndex.test.ts +4 -15
- package/workflow/moduleIndex.ts +9 -49
- package/workflow/plan.ts +18 -25
- package/workflow/render.ts +80 -96
- package/workflow/rolloutGate.test.ts +1 -1
- package/workflow/source.ts +52 -69
- package/workflow/sourceAst.ts +50 -0
- package/workspaceLayout.test.ts +18 -3
- package/workspaceLayout.ts +22 -23
- package/abstractCompactor.ts +0 -112
- package/aiEditor.test.ts +0 -60
- package/aiEditor.ts +0 -387
- package/applicationReleasePackager.ts +0 -209
- package/capacitorApp.test.ts +0 -372
- package/capacitorApp.ts +0 -1648
- package/commandDecorators/commandMeta.ts +0 -7
- package/commandDecorators/types.ts +0 -10
- package/getDirname.ts +0 -4
- package/guideline.ts +0 -19
- package/local/optimize-resource/ipcprobe/child.ts +0 -1
- package/local/optimize-resource/ipcprobe/parent.ts +0 -11
- package/workflow/primitive.ts +0 -59
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
App,
|
|
3
3
|
ArgMeta,
|
|
4
4
|
ArgsOption,
|
|
5
|
+
ArgType,
|
|
5
6
|
CommandContext,
|
|
6
7
|
Exec,
|
|
7
8
|
InternalArgMeta,
|
|
@@ -13,9 +14,14 @@ import type {
|
|
|
13
14
|
Sys,
|
|
14
15
|
} from "./argMeta";
|
|
15
16
|
import { normalizePrimitiveArgType } from "./argMeta";
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
assertUniqueDependencies,
|
|
19
|
+
type DependencyCls,
|
|
20
|
+
type DependencyInstanceMap,
|
|
21
|
+
type DependencyKey,
|
|
22
|
+
injectDependencies,
|
|
23
|
+
} from "./dependencyBuilder";
|
|
17
24
|
import { COMMAND_META, type CommandCls, type TargetMeta, type TargetOption } from "./targetMeta";
|
|
18
|
-
import type { DependencyCls, DependencyKey } from "./types";
|
|
19
25
|
|
|
20
26
|
type PrimitiveValue<T extends PrimitiveArgType> = T extends StringConstructor
|
|
21
27
|
? string
|
|
@@ -23,11 +29,7 @@ type PrimitiveValue<T extends PrimitiveArgType> = T extends StringConstructor
|
|
|
23
29
|
? number
|
|
24
30
|
: boolean;
|
|
25
31
|
type MaybeNullable<Value, Option> = Option extends { nullable: true } ? Value | null : Value;
|
|
26
|
-
|
|
27
|
-
* The literal union a static `enum` declares, or `never` for a `DynamicEnum` — a function does not extend
|
|
28
|
-
* a readonly array, so a runtime-resolved choice list falls back to the primitive type. `{ label, value }`
|
|
29
|
-
* choices contribute their `value`.
|
|
30
|
-
*/
|
|
32
|
+
// A DynamicEnum yields never (a function is no readonly array), so ArgValue falls back to the primitive type.
|
|
31
33
|
type EnumValue<Option> = Option extends { enum: infer Choices }
|
|
32
34
|
? Choices extends readonly (infer Choice)[]
|
|
33
35
|
? Choice extends { value: infer Value }
|
|
@@ -73,6 +75,14 @@ type CommandHandler<Deps extends readonly DependencyCls[], Params extends unknow
|
|
|
73
75
|
...args: Params
|
|
74
76
|
) => unknown | Promise<unknown>;
|
|
75
77
|
|
|
78
|
+
const argMetaOf = (
|
|
79
|
+
type: ArgType,
|
|
80
|
+
name: string,
|
|
81
|
+
primitive: PrimitiveArgType,
|
|
82
|
+
argsOption: object | undefined,
|
|
83
|
+
idx: number,
|
|
84
|
+
): ArgMeta => ({ name, argsOption: { ...argsOption, type: normalizePrimitiveArgType(primitive) }, key: "", idx, type });
|
|
85
|
+
|
|
76
86
|
class TargetBuilder<Deps extends readonly DependencyCls[], Params extends unknown[] = [], Context = object> {
|
|
77
87
|
readonly #args: (ArgMeta | InternalArgMeta)[];
|
|
78
88
|
|
|
@@ -83,56 +93,29 @@ class TargetBuilder<Deps extends readonly DependencyCls[], Params extends unknow
|
|
|
83
93
|
this.#args = args;
|
|
84
94
|
}
|
|
85
95
|
|
|
96
|
+
#add<NextParams extends unknown[], NextContext = Context>(...argMetas: (ArgMeta | InternalArgMeta)[]) {
|
|
97
|
+
return new TargetBuilder<Deps, NextParams, NextContext>(this.targetOption, [...this.#args, ...argMetas]);
|
|
98
|
+
}
|
|
99
|
+
|
|
86
100
|
arg<Type extends PrimitiveArgType, const Option extends ArgsOption<Context> = ArgsOption<Context>>(
|
|
87
101
|
name: string,
|
|
88
102
|
type: Type,
|
|
89
103
|
argsOption: Option = {} as Option,
|
|
90
|
-
)
|
|
91
|
-
return
|
|
92
|
-
...this.#args,
|
|
93
|
-
{
|
|
94
|
-
name,
|
|
95
|
-
argsOption: { ...argsOption, type: normalizePrimitiveArgType(type) },
|
|
96
|
-
key: "",
|
|
97
|
-
idx: this.#args.length,
|
|
98
|
-
type: "Argument",
|
|
99
|
-
} as ArgMeta<CommandContext>,
|
|
100
|
-
]);
|
|
104
|
+
) {
|
|
105
|
+
return this.#add<AddArg<Params, Type, Option>>(argMetaOf("Argument", name, type, argsOption, this.#args.length));
|
|
101
106
|
}
|
|
102
107
|
|
|
103
108
|
option<Type extends PrimitiveArgType, const Option extends ArgsOption<Context> = ArgsOption<Context>>(
|
|
104
109
|
name: string,
|
|
105
110
|
type: Type,
|
|
106
111
|
argsOption: Option = {} as Option,
|
|
107
|
-
)
|
|
108
|
-
return
|
|
109
|
-
...this.#args,
|
|
110
|
-
{
|
|
111
|
-
name,
|
|
112
|
-
argsOption: { ...argsOption, type: normalizePrimitiveArgType(type) },
|
|
113
|
-
key: "",
|
|
114
|
-
idx: this.#args.length,
|
|
115
|
-
type: "Option",
|
|
116
|
-
} as ArgMeta<CommandContext>,
|
|
117
|
-
]);
|
|
112
|
+
) {
|
|
113
|
+
return this.#add<AddArg<Params, Type, Option>>(argMetaOf("Option", name, type, argsOption, this.#args.length));
|
|
118
114
|
}
|
|
119
115
|
|
|
120
|
-
with<const Tokens extends readonly InternalArgToken[]>(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return new TargetBuilder<Deps, AddInternalArgs<Params, Tokens>, AddInternalContext<Context, Tokens>>(
|
|
124
|
-
this.targetOption,
|
|
125
|
-
[
|
|
126
|
-
...this.#args,
|
|
127
|
-
...tokens.map(
|
|
128
|
-
(token, offset) =>
|
|
129
|
-
({
|
|
130
|
-
key: "",
|
|
131
|
-
idx: this.#args.length + offset,
|
|
132
|
-
type: token.type,
|
|
133
|
-
}) satisfies InternalArgMeta,
|
|
134
|
-
),
|
|
135
|
-
],
|
|
116
|
+
with<const Tokens extends readonly InternalArgToken[]>(...tokens: Tokens) {
|
|
117
|
+
return this.#add<AddInternalArgs<Params, Tokens>, AddInternalContext<Context, Tokens>>(
|
|
118
|
+
...tokens.map((token, offset) => ({ key: "", idx: this.#args.length + offset, type: token.type })),
|
|
136
119
|
);
|
|
137
120
|
}
|
|
138
121
|
|
|
@@ -174,22 +157,8 @@ const createContext = <Deps extends readonly DependencyCls[]>(): CommandBuilderC
|
|
|
174
157
|
public: createTarget<Deps>("public"),
|
|
175
158
|
cloud: createTarget<Deps>("cloud"),
|
|
176
159
|
dev: createTarget<Deps>("dev"),
|
|
177
|
-
arg: (name, type, argsOption) =>
|
|
178
|
-
|
|
179
|
-
name,
|
|
180
|
-
argsOption: { ...(argsOption ?? {}), type: normalizePrimitiveArgType(type) },
|
|
181
|
-
key: "",
|
|
182
|
-
idx: -1,
|
|
183
|
-
type: "Argument",
|
|
184
|
-
}) as ArgMeta<CommandContext>,
|
|
185
|
-
option: (name, type, argsOption) =>
|
|
186
|
-
({
|
|
187
|
-
name,
|
|
188
|
-
argsOption: { ...(argsOption ?? {}), type: normalizePrimitiveArgType(type) },
|
|
189
|
-
key: "",
|
|
190
|
-
idx: -1,
|
|
191
|
-
type: "Option",
|
|
192
|
-
}) as ArgMeta<CommandContext>,
|
|
160
|
+
arg: (name, type, argsOption) => argMetaOf("Argument", name, type, argsOption, -1),
|
|
161
|
+
option: (name, type, argsOption) => argMetaOf("Option", name, type, argsOption, -1),
|
|
193
162
|
});
|
|
194
163
|
|
|
195
164
|
const buildCommandMeta = (definitions: Record<string, TargetDefinition>) => {
|
|
@@ -125,7 +125,7 @@ describe("command helper metadata", () => {
|
|
|
125
125
|
|
|
126
126
|
const commandHelp = stripAnsi(formatCommandHelp(HelpCommand, "buildApp"));
|
|
127
127
|
expect(commandHelp).toContain("akan build-app [app]");
|
|
128
|
-
expect(commandHelp).toContain("--write");
|
|
128
|
+
expect(commandHelp).toContain("--write, --no-write");
|
|
129
129
|
expect(commandHelp).toContain("[default: true]");
|
|
130
130
|
expect(commandHelp).toContain("Fast, Full");
|
|
131
131
|
});
|
|
@@ -243,8 +243,6 @@ describe("enum arg choices", () => {
|
|
|
243
243
|
expect(await getOptionValue(optionMeta(["text", "json"]), { format: "json" }, context)).toBe("json");
|
|
244
244
|
});
|
|
245
245
|
|
|
246
|
-
// Before this check `akan quality --format yaml` reached the script as "yaml" while the declaration
|
|
247
|
-
// claimed the parameter was "text" | "json".
|
|
248
246
|
test("rejects an undeclared value in commander's wording", async () => {
|
|
249
247
|
await expect(getOptionValue(optionMeta(["text", "json"]), { format: "yaml" }, context)).rejects.toThrow(
|
|
250
248
|
"option '--format' argument 'yaml' is invalid. Allowed choices are text, json.",
|
|
@@ -269,8 +267,6 @@ describe("enum arg choices", () => {
|
|
|
269
267
|
await expect(getOptionValue(labelled, { format: "JSON output" }, context)).rejects.toThrow("is invalid");
|
|
270
268
|
});
|
|
271
269
|
|
|
272
|
-
// A DynamicEnum resolves against a context that is not populated yet, and the interactive select is its
|
|
273
|
-
// only consumer, so an explicit value passes through unchecked rather than being rejected wrongly.
|
|
274
270
|
test("leaves a dynamic choice list unchecked", async () => {
|
|
275
271
|
expect(
|
|
276
272
|
await getOptionValue(
|
|
@@ -291,11 +287,7 @@ describe("enum arg type inference", () => {
|
|
|
291
287
|
CommandContainer.clear();
|
|
292
288
|
});
|
|
293
289
|
|
|
294
|
-
|
|
295
|
-
* Compile-time only. Nothing here can fail at runtime: if `enum` stops narrowing, the parameter widens
|
|
296
|
-
* to the primitive and these calls stop typechecking, so the regression surfaces in `akan typecheck`
|
|
297
|
-
* rather than in fifteen `as "a" | "b"` casts creeping back into the command files.
|
|
298
|
-
*/
|
|
290
|
+
//? Compile-time only: if `enum` stops narrowing, the parameter widens and these calls stop typechecking.
|
|
299
291
|
const expectLiteral = <Expected>(_value: Expected) => undefined;
|
|
300
292
|
|
|
301
293
|
test("a static enum narrows the exec parameter to its declared choices", () => {
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
export type Cls<T = unknown> = new (...args: unknown[]) => T;
|
|
2
|
+
|
|
3
|
+
export type DependencyKind = "command" | "script" | "runner";
|
|
4
|
+
export type DependencyKey<RefName extends string, Kind extends DependencyKind> = `${RefName}${Capitalize<Kind>}`;
|
|
5
|
+
|
|
6
|
+
export type DependencyCls<T = unknown, Key extends string = string> = (new () => T) & {
|
|
7
|
+
readonly dependencyKey: Key;
|
|
8
|
+
readonly dependencyKind: DependencyKind;
|
|
9
|
+
readonly refName: string;
|
|
10
|
+
};
|
|
2
11
|
|
|
3
12
|
type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends (
|
|
4
13
|
value: infer Intersection,
|
|
@@ -1,191 +1,119 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
|
|
3
3
|
import { type EnumChoice, getArgMetas } from "./argMeta";
|
|
4
|
+
import { camelToKebabCase } from "./camelToKebabCase";
|
|
4
5
|
import { type CommandCls, getTargetMetas } from "./targetMeta";
|
|
5
6
|
|
|
6
|
-
const camelToKebabCase = (str: string) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
7
7
|
const formatChoice = (choice: EnumChoice) => (typeof choice === "object" ? choice.label : choice.toString());
|
|
8
8
|
|
|
9
9
|
const groupCommands = (commands: CommandCls[]) => {
|
|
10
|
-
const groups = new Map<string, {
|
|
11
|
-
|
|
10
|
+
const groups = new Map<string, { key: string; args: string[]; desc?: string }[]>();
|
|
12
11
|
for (const command of commands) {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
if (!groups.has(groupName)) {
|
|
17
|
-
groups.set(groupName, { name: groupName, commands: [] });
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const targetMetas = getTargetMetas(command);
|
|
21
|
-
for (const targetMeta of targetMetas) {
|
|
22
|
-
// Skip devOnly commands in help
|
|
12
|
+
const group = groups.getOrInsert(command.name.replace("Command", ""), []);
|
|
13
|
+
for (const targetMeta of getTargetMetas(command)) {
|
|
23
14
|
if (targetMeta.targetOption.devOnly) continue;
|
|
24
|
-
|
|
25
15
|
const [allArgMetas] = getArgMetas(command, targetMeta.key);
|
|
26
16
|
const args = allArgMetas
|
|
27
17
|
.filter((arg) => arg.type !== "Option")
|
|
28
18
|
.map((arg) => {
|
|
29
19
|
if (arg.type === "Workspace") return "";
|
|
30
20
|
if (arg.type === "Module") return "[sys:module]";
|
|
31
|
-
if (arg.type === "Argument") {
|
|
32
|
-
return `[${arg.name}]`;
|
|
33
|
-
}
|
|
21
|
+
if (arg.type === "Argument") return `[${arg.name}]`;
|
|
34
22
|
return `[${arg.type.toLowerCase()}]`;
|
|
35
23
|
})
|
|
36
24
|
.filter(Boolean);
|
|
37
|
-
|
|
38
|
-
const group = groups.get(groupName);
|
|
39
|
-
if (group) {
|
|
40
|
-
group.commands.push({
|
|
41
|
-
key: camelToKebabCase(targetMeta.key),
|
|
42
|
-
args,
|
|
43
|
-
desc: targetMeta.targetOption.desc,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
25
|
+
group.push({ key: camelToKebabCase(targetMeta.key), args, desc: targetMeta.targetOption.desc });
|
|
46
26
|
}
|
|
47
27
|
}
|
|
48
|
-
|
|
49
28
|
return groups;
|
|
50
29
|
};
|
|
51
30
|
|
|
52
31
|
export const formatHelp = (commands: CommandCls[], version: string) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// Header
|
|
57
|
-
lines.push("");
|
|
58
|
-
lines.push(chalk.bold.cyan(" ╔═══════════════════════════════════════════════════╗"));
|
|
59
|
-
lines.push(
|
|
32
|
+
const lines = [
|
|
33
|
+
"",
|
|
34
|
+
chalk.bold.cyan(" ╔═══════════════════════════════════════════════════╗"),
|
|
60
35
|
chalk.bold.cyan(" ║") +
|
|
61
36
|
chalk.bold.white(" Akan.js Framework CLI ") +
|
|
62
37
|
chalk.bold.cyan(" ║"),
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
lines.push(chalk.bold.magenta(` ${groupName}`));
|
|
84
|
-
lines.push("");
|
|
85
|
-
|
|
86
|
-
for (const cmd of group.commands) {
|
|
87
|
-
const cmdName = chalk.green(cmd.key);
|
|
88
|
-
const cmdArgs = cmd.args.length > 0 ? chalk.gray(` ${cmd.args.join(" ")}`) : "";
|
|
89
|
-
|
|
90
|
-
// Format description: wrap if too long
|
|
91
|
-
if (cmd.desc) {
|
|
92
|
-
const maxLineLength = 70;
|
|
93
|
-
const cmdPrefix = ` ${cmdName}${cmdArgs}`;
|
|
94
|
-
const indent = " ";
|
|
95
|
-
|
|
96
|
-
if (cmdPrefix.length + cmd.desc.length + 3 < maxLineLength) {
|
|
97
|
-
// Single line
|
|
98
|
-
lines.push(`${cmdPrefix} ${chalk.gray(cmd.desc)}`);
|
|
99
|
-
} else {
|
|
100
|
-
// Multi-line
|
|
101
|
-
lines.push(cmdPrefix);
|
|
102
|
-
lines.push(`${indent}${chalk.gray(cmd.desc)}`);
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
lines.push(` ${cmdName}${cmdArgs}`);
|
|
106
|
-
}
|
|
38
|
+
chalk.bold.cyan(" ╚═══════════════════════════════════════════════════╝"),
|
|
39
|
+
"",
|
|
40
|
+
chalk.gray(` Version: ${version}`),
|
|
41
|
+
"",
|
|
42
|
+
chalk.bold.yellow(" USAGE"),
|
|
43
|
+
"",
|
|
44
|
+
chalk.gray(" $ ") + chalk.white("akan") + chalk.gray(" <command> [options]"),
|
|
45
|
+
"",
|
|
46
|
+
chalk.bold.yellow(" COMMANDS"),
|
|
47
|
+
"",
|
|
48
|
+
];
|
|
49
|
+
for (const [groupName, cmds] of groupCommands(commands)) {
|
|
50
|
+
if (cmds.length === 0) continue;
|
|
51
|
+
lines.push(chalk.bold.magenta(` ${groupName}`), "");
|
|
52
|
+
for (const cmd of cmds) {
|
|
53
|
+
const cmdPrefix = ` ${chalk.green(cmd.key)}${cmd.args.length > 0 ? chalk.gray(` ${cmd.args.join(" ")}`) : ""}`;
|
|
54
|
+
if (!cmd.desc) lines.push(cmdPrefix);
|
|
55
|
+
else if (cmdPrefix.length + cmd.desc.length + 3 < 70) lines.push(`${cmdPrefix} ${chalk.gray(cmd.desc)}`);
|
|
56
|
+
else lines.push(cmdPrefix, ` ${chalk.gray(cmd.desc)}`);
|
|
107
57
|
}
|
|
108
58
|
lines.push("");
|
|
109
59
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// Footer
|
|
133
|
-
lines.push(chalk.gray(" Documentation: ") + chalk.cyan("https://akanjs.com/docs"));
|
|
134
|
-
lines.push(chalk.gray(" Report issues: ") + chalk.cyan("https://github.com/akan-team/akanjs/issues"));
|
|
135
|
-
lines.push("");
|
|
136
|
-
|
|
60
|
+
lines.push(
|
|
61
|
+
chalk.bold.yellow(" OPTIONS"),
|
|
62
|
+
"",
|
|
63
|
+
` ${chalk.green("-v, --verbose")} ${chalk.gray("Enable verbose output")}`,
|
|
64
|
+
` ${chalk.green("-h, --help")} ${chalk.gray("Display this help message")}`,
|
|
65
|
+
` ${chalk.green("-V, --version")} ${chalk.gray("Output version number")}`,
|
|
66
|
+
"",
|
|
67
|
+
chalk.bold.yellow(" EXAMPLES"),
|
|
68
|
+
"",
|
|
69
|
+
chalk.gray(" # Create a new workspace"),
|
|
70
|
+
chalk.white(" $ akan create-workspace myproject"),
|
|
71
|
+
"",
|
|
72
|
+
chalk.gray(" # Start development server"),
|
|
73
|
+
chalk.white(" $ akan start myapp"),
|
|
74
|
+
"",
|
|
75
|
+
chalk.gray(" # Create a new module"),
|
|
76
|
+
chalk.white(" $ akan create-module userProfile"),
|
|
77
|
+
"",
|
|
78
|
+
chalk.gray(" Documentation: ") + chalk.cyan("https://akanjs.com/docs"),
|
|
79
|
+
chalk.gray(" Report issues: ") + chalk.cyan("https://github.com/akan-team/akanjs/issues"),
|
|
80
|
+
"",
|
|
81
|
+
);
|
|
137
82
|
return lines.join("\n");
|
|
138
83
|
};
|
|
139
84
|
|
|
140
85
|
export const formatCommandHelp = (command: CommandCls, key: string) => {
|
|
141
|
-
const [allArgMetas,
|
|
86
|
+
const [allArgMetas, optionArgs] = getArgMetas(command, key);
|
|
142
87
|
const kebabKey = camelToKebabCase(key);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
const targetMeta = targetMetas.find((t) => t.key === key);
|
|
147
|
-
const commandDesc = targetMeta?.targetOption.desc;
|
|
148
|
-
|
|
149
|
-
lines.push("");
|
|
150
|
-
lines.push(chalk.bold.cyan(` Command: ${kebabKey}`));
|
|
151
|
-
if (commandDesc) {
|
|
152
|
-
lines.push(chalk.gray(` ${commandDesc}`));
|
|
153
|
-
}
|
|
154
|
-
lines.push("");
|
|
155
|
-
|
|
156
|
-
// Usage
|
|
157
|
-
const args = allArgMetas
|
|
158
|
-
.filter((arg) => arg.type !== "Option")
|
|
88
|
+
const commandDesc = getTargetMetas(command).find((t) => t.key === key)?.targetOption.desc;
|
|
89
|
+
const nonOptionArgs = allArgMetas.filter((arg) => arg.type !== "Option");
|
|
90
|
+
const args = nonOptionArgs
|
|
159
91
|
.map((arg) => {
|
|
160
92
|
if (arg.type === "Workspace") return "";
|
|
161
93
|
if (arg.type === "Module") return "[sys:module]";
|
|
162
94
|
if (arg.type === "Apps") return "[apps...]";
|
|
163
|
-
if (arg.type === "Argument") {
|
|
164
|
-
return `[${camelToKebabCase(arg.name)}]`;
|
|
165
|
-
}
|
|
95
|
+
if (arg.type === "Argument") return `[${camelToKebabCase(arg.name)}]`;
|
|
166
96
|
return `[${arg.type.toLowerCase()}]`;
|
|
167
97
|
})
|
|
168
98
|
.filter(Boolean)
|
|
169
99
|
.join(" ");
|
|
170
100
|
|
|
171
|
-
lines
|
|
172
|
-
lines.push(
|
|
173
|
-
lines.push(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
101
|
+
const lines = ["", chalk.bold.cyan(` Command: ${kebabKey}`)];
|
|
102
|
+
if (commandDesc) lines.push(chalk.gray(` ${commandDesc}`));
|
|
103
|
+
lines.push(
|
|
104
|
+
"",
|
|
105
|
+
chalk.bold.yellow(" USAGE"),
|
|
106
|
+
"",
|
|
107
|
+
chalk.gray(" $ ") + chalk.white(`akan ${kebabKey}`) + (args ? chalk.gray(` ${args}`) : ""),
|
|
108
|
+
"",
|
|
109
|
+
);
|
|
178
110
|
if (nonOptionArgs.length > 0) {
|
|
179
|
-
lines.push(chalk.bold.yellow(" ARGUMENTS"));
|
|
180
|
-
lines.push("");
|
|
181
|
-
|
|
111
|
+
lines.push(chalk.bold.yellow(" ARGUMENTS"), "");
|
|
182
112
|
for (const arg of nonOptionArgs) {
|
|
183
113
|
if (arg.type === "Workspace") continue;
|
|
184
|
-
|
|
185
114
|
let argName: string;
|
|
186
115
|
let argDesc: string;
|
|
187
116
|
let example = "";
|
|
188
|
-
|
|
189
117
|
if (arg.type === "Argument") {
|
|
190
118
|
argName = camelToKebabCase(arg.name);
|
|
191
119
|
argDesc = arg.argsOption.desc ?? "";
|
|
@@ -200,24 +128,19 @@ export const formatCommandHelp = (command: CommandCls, key: string) => {
|
|
|
200
128
|
argName = arg.type.toLowerCase();
|
|
201
129
|
argDesc = `${arg.type} name in this workspace`;
|
|
202
130
|
}
|
|
203
|
-
|
|
204
131
|
lines.push(` ${chalk.green(argName)} ${chalk.gray(argDesc)}${example}`);
|
|
205
132
|
}
|
|
206
|
-
|
|
207
133
|
lines.push("");
|
|
208
134
|
}
|
|
209
135
|
|
|
210
|
-
// Options
|
|
211
|
-
const optionArgs = argMetas.filter((a) => a.type === "Option");
|
|
212
136
|
if (optionArgs.length > 0) {
|
|
213
|
-
lines.push(chalk.bold.yellow(" OPTIONS"));
|
|
214
|
-
lines.push("");
|
|
215
|
-
|
|
137
|
+
lines.push(chalk.bold.yellow(" OPTIONS"), "");
|
|
216
138
|
for (const arg of optionArgs) {
|
|
217
139
|
const opt = arg.argsOption;
|
|
218
140
|
const flag = opt.flag ? `-${opt.flag}, ` : "";
|
|
219
141
|
const kebabName = camelToKebabCase(arg.name);
|
|
220
|
-
const
|
|
142
|
+
const negation = opt.type === "boolean" && opt.default === true ? `, --no-${kebabName}` : "";
|
|
143
|
+
const optName = `${flag}--${kebabName}${negation}`;
|
|
221
144
|
const optDesc = opt.desc ?? "";
|
|
222
145
|
const defaultVal = opt.default !== undefined ? chalk.gray(` [default: ${String(opt.default)}]`) : "";
|
|
223
146
|
const choices = opt.enum
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ArgMeta, InternalArgMeta } from "./argMeta";
|
|
2
|
-
import
|
|
2
|
+
import { camelToKebabCase } from "./camelToKebabCase";
|
|
3
|
+
import type { Cls, DependencyCls } from "./dependencyBuilder";
|
|
3
4
|
|
|
4
5
|
export const COMMAND_META: unique symbol = Symbol("akan.command.meta");
|
|
5
6
|
|
|
@@ -22,12 +23,7 @@ export const getTargetMetas = (command: CommandCls): TargetMeta[] => {
|
|
|
22
23
|
return [...targetMetaMap.values()];
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* CLI names a target answers to. Shared with the command-manifest generator so a lazily-loaded CLI
|
|
29
|
-
* resolves `argv[2]` to the same module that `runCommands` would have registered it under.
|
|
30
|
-
*/
|
|
26
|
+
/** Shared with the command-manifest generator, so a lazily loaded CLI maps argv[2] to the module runCommands would. */
|
|
31
27
|
export const getTargetCommandNames = (targetMeta: TargetMeta): string[] => {
|
|
32
28
|
const kebabKey = camelToKebabCase(targetMeta.key);
|
|
33
29
|
if (targetMeta.targetOption.short !== true) return [kebabKey];
|
|
@@ -48,3 +44,9 @@ export interface TargetOption {
|
|
|
48
44
|
runsOnWorkspaceRoot?: boolean;
|
|
49
45
|
stdio?: boolean;
|
|
50
46
|
}
|
|
47
|
+
|
|
48
|
+
export const Commands = () => {
|
|
49
|
+
return (target: Cls) => {
|
|
50
|
+
// not implemented yet
|
|
51
|
+
};
|
|
52
|
+
};
|
package/createTunnel.ts
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import type { SshOptions } from "akanjs/base";
|
|
2
|
-
|
|
3
1
|
import { type AppExecutor, WorkspaceExecutor } from "./executors";
|
|
4
2
|
import { createSshTunnel } from "./sshTunnel";
|
|
5
3
|
|
|
6
|
-
const getSshTunnelOptions = (app: AppExecutor, environment: string): SshOptions => {
|
|
7
|
-
const { serveDomain, repoName } = WorkspaceExecutor.getBaseDevEnv();
|
|
8
|
-
return {
|
|
9
|
-
host: `${app.name}-${environment}.${serveDomain}`,
|
|
10
|
-
port: process.env.SSH_TUNNEL_PORT ? parseInt(process.env.SSH_TUNNEL_PORT) : 32767,
|
|
11
|
-
username: process.env.SSH_TUNNEL_USERNAME ?? "root",
|
|
12
|
-
password: process.env.SSH_TUNNEL_PASSWORD ?? repoName,
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
|
|
16
4
|
interface TunnelOption {
|
|
17
5
|
app: AppExecutor;
|
|
18
6
|
environment: string;
|
|
@@ -22,7 +10,7 @@ export const createTunnel = async (
|
|
|
22
10
|
service: "redis" | "postgres",
|
|
23
11
|
{ app, environment, port = service === "postgres" ? 5432 : 6379 }: TunnelOption,
|
|
24
12
|
) => {
|
|
25
|
-
const
|
|
13
|
+
const { serveDomain, repoName } = WorkspaceExecutor.getBaseDevEnv();
|
|
26
14
|
await createSshTunnel({
|
|
27
15
|
localHost: "0.0.0.0",
|
|
28
16
|
localPort: port,
|
|
@@ -30,7 +18,12 @@ export const createTunnel = async (
|
|
|
30
18
|
srcPort: port,
|
|
31
19
|
dstHost: `${service}-0.${service}-svc.${app.name}-${environment}.svc.cluster.local`,
|
|
32
20
|
dstPort: service === "postgres" ? 5432 : 6379,
|
|
33
|
-
sshOptions
|
|
21
|
+
sshOptions: {
|
|
22
|
+
host: `${app.name}-${environment}.${serveDomain}`,
|
|
23
|
+
port: process.env.SSH_TUNNEL_PORT ? parseInt(process.env.SSH_TUNNEL_PORT) : 32767,
|
|
24
|
+
username: process.env.SSH_TUNNEL_USERNAME ?? "root",
|
|
25
|
+
password: process.env.SSH_TUNNEL_PASSWORD ?? repoName,
|
|
26
|
+
},
|
|
34
27
|
});
|
|
35
28
|
return `localhost:${port}`;
|
|
36
29
|
};
|