@akanjs/devkit 3.0.0-beta.2 → 3.0.0-beta.20
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/README.md +1 -0
- 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 +1 -3
- package/akanApp/akanApp.host.ts +82 -254
- package/akanApp/devHostPolicy.test.ts +10 -34
- package/akanApp/devHostPolicy.ts +12 -98
- package/akanConfig/akanConfig.test.ts +85 -69
- package/akanConfig/akanConfig.ts +69 -153
- package/akanConfig/types.ts +1 -0
- package/akanContext.ts +106 -159
- package/akanMcpContract.ts +28 -73
- package/appSelectionMemory.ts +1 -4
- package/applicationBuildReporter.ts +37 -5
- package/applicationBuildRunner.test.ts +5 -3
- package/applicationBuildRunner.ts +54 -61
- package/applicationReleasePackager.ts +24 -44
- package/applicationTestPreload.ts +3 -12
- package/artifact/implicitRootLayout.test.ts +9 -30
- package/artifact/implicitRootLayout.ts +34 -106
- package/artifact/routeSeedIndex.test.ts +7 -6
- package/artifact/routeSeedIndex.ts +11 -44
- package/biome.base.json +6 -1
- package/biomeBase.ts +2 -5
- package/capacitorApp.test.ts +32 -16
- package/capacitorApp.ts +110 -238
- 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 +70 -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/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 +132 -106
- package/executors.ts +194 -484
- package/fileEditor.ts +9 -37
- package/{getDirname.test.ts → fileSys.test.ts} +5 -3
- package/fileSys.ts +6 -8
- 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 +62 -37
- package/frontendBuild/bundleDefine.ts +12 -0
- package/frontendBuild/clientBuildTypes.ts +5 -36
- package/frontendBuild/clientEntriesBundler.ts +9 -40
- package/frontendBuild/clientEntryDiscovery.ts +6 -41
- package/frontendBuild/csrArtifactBuilder.ts +6 -25
- package/frontendBuild/cssCandidateCache.test.ts +0 -6
- package/frontendBuild/cssCandidateCache.ts +6 -41
- package/frontendBuild/cssCompiler.ts +29 -78
- 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/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 +46 -69
- package/frontendBuild/hmrChangeClassifier.ts +2 -2
- package/frontendBuild/hmrWatcher.test.ts +8 -32
- package/frontendBuild/hmrWatcher.ts +14 -71
- package/frontendBuild/pagesBundleBuilder.ts +4 -29
- package/frontendBuild/precompressArtifacts.ts +5 -18
- package/frontendBuild/routeClientBuilder.ts +23 -46
- package/frontendBuild/routesManifestArtifactSerializer.ts +5 -36
- package/frontendBuild/sourceMtimeIndex.test.ts +41 -97
- package/frontendBuild/sourceMtimeIndex.ts +19 -130
- package/frontendBuild/ssrBaseArtifactBuilder.ts +2 -8
- 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 +22 -57
- package/incrementalBuilder/buildBatchProtocol.ts +8 -36
- package/incrementalBuilder/buildBatchRunner.test.ts +34 -0
- package/incrementalBuilder/buildBatchRunner.ts +10 -31
- 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/devWatchBatch.test.ts +21 -24
- package/incrementalBuilder/incrementalBuilder.host.test.ts +18 -55
- package/incrementalBuilder/incrementalBuilder.host.ts +18 -76
- package/incrementalBuilder/incrementalBuilder.proc.test.ts +81 -0
- package/incrementalBuilder/incrementalBuilder.proc.ts +49 -161
- package/index.ts +5 -17
- package/integration/devResourceProbe.ts +50 -56
- package/integration/devStability.integration.test.ts +47 -194
- 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/gritRules.test.ts +8 -24
- package/lint/no-deep-internal-import.grit +2 -2
- package/lint/no-redeclare-predefined-endpoint.grit +2 -1
- package/linter.test.ts +1 -2
- package/linter.ts +26 -116
- package/mobile/mobileTarget.ts +14 -13
- package/package.json +10 -5
- 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 +197 -285
- 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 +87 -216
- 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 +30 -25
- package/subspace.ts +81 -115
- package/subspaceConfig.ts +11 -9
- 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 +35 -20
- package/transforms/transforms.test.ts +153 -44
- package/transforms/tsconfigPackageResolver.test.ts +6 -24
- package/transforms/useClientBundlePlugin.ts +2 -22
- package/typeChecker.ts +7 -63
- package/types.ts +1 -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.ts +4 -19
- package/abstractCompactor.ts +0 -112
- package/aiEditor.test.ts +0 -60
- package/aiEditor.ts +0 -387
- 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
package/akanConfig/akanConfig.ts
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import type { AkanPlugin } from "akanjs";
|
|
5
|
-
import { normalizeRoutePrefix } from "akanjs/base";
|
|
5
|
+
import { DatabaseModes, normalizeRoutePrefix } from "akanjs/base";
|
|
6
6
|
import { type AkanI18nConfig, resolveAkanI18nConfig } from "akanjs/common";
|
|
7
7
|
import type { AkanImageConfig } from "akanjs/server";
|
|
8
8
|
import type { App, Lib } from "../commandDecorators";
|
|
@@ -11,6 +11,7 @@ import type { BaseDevEnv, PackageJson } from "../types";
|
|
|
11
11
|
import {
|
|
12
12
|
type AkanApiConfig,
|
|
13
13
|
type AkanAssetsConfig,
|
|
14
|
+
type AkanDatabaseConfig,
|
|
14
15
|
type AkanMobileConfig,
|
|
15
16
|
type AkanMobileTargetConfig,
|
|
16
17
|
type AkanRouteConfig,
|
|
@@ -31,40 +32,15 @@ import {
|
|
|
31
32
|
|
|
32
33
|
const DEFAULT_BARREL_IMPORTS = ["akanjs/webkit", "akanjs/common", "akanjs/ui", "akanjs/server"];
|
|
33
34
|
const DEFAULT_OPTIMIZE_IMPORTS = [
|
|
34
|
-
"lucide-react",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
"react-bootstrap",
|
|
40
|
-
"ahooks",
|
|
41
|
-
"@ant-design/icons",
|
|
42
|
-
"@headlessui/react",
|
|
43
|
-
"@headlessui-float/react",
|
|
44
|
-
"@heroicons/react/20/solid",
|
|
45
|
-
"@heroicons/react/24/solid",
|
|
46
|
-
"@heroicons/react/24/outline",
|
|
47
|
-
"@visx/visx",
|
|
48
|
-
"@tremor/react",
|
|
49
|
-
"rxjs",
|
|
50
|
-
"@mui/material",
|
|
51
|
-
"@mui/icons-material",
|
|
52
|
-
"recharts",
|
|
53
|
-
"react-use",
|
|
54
|
-
"@material-ui/core",
|
|
55
|
-
"@material-ui/icons",
|
|
56
|
-
"@tabler/icons-react",
|
|
57
|
-
"mui-core",
|
|
58
|
-
"react-icons/*",
|
|
59
|
-
];
|
|
35
|
+
"lucide-react date-fns lodash-es ramda antd react-bootstrap ahooks @ant-design/icons @headlessui/react",
|
|
36
|
+
"@headlessui-float/react @heroicons/react/20/solid @heroicons/react/24/solid @heroicons/react/24/outline",
|
|
37
|
+
"@visx/visx @tremor/react rxjs @mui/material @mui/icons-material recharts react-use @material-ui/core",
|
|
38
|
+
"@material-ui/icons @tabler/icons-react mui-core react-icons/*",
|
|
39
|
+
].flatMap((line) => line.split(" "));
|
|
60
40
|
const WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"] as const;
|
|
61
41
|
const DEFAULT_DOCKER_IMAGE = "oven/bun:1-slim";
|
|
62
42
|
const SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"] as const;
|
|
63
|
-
//
|
|
64
|
-
// `@capacitor/assets` (`npx @capacitor/assets`) plus the `@capacitor/core`/`ios`/`android` runtime
|
|
65
|
-
// and native-platform packages that `npx cap add`/`sync` resolve from the workspace node_modules.
|
|
66
|
-
// All are declared only as optional peers, so a fresh workspace never auto-installs them; the mobile
|
|
67
|
-
// preflight installs them (together with MOBILE_APP_CAPACITOR_PLUGINS) at the workspace root.
|
|
43
|
+
// Optional peers only, so a fresh workspace never installs them; the mobile preflight adds them at the root.
|
|
68
44
|
const MOBILE_RUNTIME_PACKAGES = [
|
|
69
45
|
"@capacitor/cli",
|
|
70
46
|
"@capacitor/core",
|
|
@@ -72,37 +48,14 @@ const MOBILE_RUNTIME_PACKAGES = [
|
|
|
72
48
|
"@capacitor/android",
|
|
73
49
|
"@capacitor/assets",
|
|
74
50
|
] as const;
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
// dependencies and registers their native code into the iOS/Android projects; packages present only
|
|
78
|
-
// at the workspace root are never registered, so the JS bridge throws
|
|
79
|
-
// `Capacitor plugin "Device" is not available.` at runtime. They are installed at the workspace root
|
|
80
|
-
// alongside MOBILE_RUNTIME_PACKAGES (pinned via optional peers) and declared in the app with a "*"
|
|
81
|
-
// range so bun dedupes them to that hoisted version instead of pinning a second source of truth.
|
|
51
|
+
// `npx cap sync` registers only plugins the app's own package.json declares (else the bridge throws `Capacitor plugin
|
|
52
|
+
// "Device" is not available.`), so they are declared there with "*" and deduped to the root-installed version.
|
|
82
53
|
const MOBILE_APP_CAPACITOR_PLUGINS = [
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
"@capacitor/core",
|
|
87
|
-
"@capacitor/device",
|
|
88
|
-
"@capacitor/geolocation",
|
|
89
|
-
"@capacitor/haptics",
|
|
90
|
-
"@capacitor/inappbrowser",
|
|
91
|
-
"@capacitor/keyboard",
|
|
92
|
-
"@capacitor/preferences",
|
|
93
|
-
"@capacitor/push-notifications",
|
|
54
|
+
..."app browser camera core device geolocation haptics inappbrowser keyboard preferences push-notifications"
|
|
55
|
+
.split(" ")
|
|
56
|
+
.map((name) => `@capacitor/${name}`),
|
|
94
57
|
"capacitor-plugin-safe-area",
|
|
95
|
-
]
|
|
96
|
-
const DATABASE_MODE_RUNTIME_PACKAGES = {
|
|
97
|
-
single: [],
|
|
98
|
-
multiple: ["@libsql/client", "bullmq", "ioredis", "protobufjs"],
|
|
99
|
-
cluster: ["bullmq", "ioredis", "postgres", "protobufjs"],
|
|
100
|
-
} satisfies Record<DatabaseMode, readonly string[]>;
|
|
101
|
-
const AKAN_RUNTIME_PACKAGES = new Set<string>([
|
|
102
|
-
...SSR_RUNTIME_PACKAGES,
|
|
103
|
-
...MOBILE_RUNTIME_PACKAGES,
|
|
104
|
-
...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat(),
|
|
105
|
-
]);
|
|
58
|
+
];
|
|
106
59
|
const DEFAULT_AKAN_IMAGE_CONFIG: AkanImageConfig = {
|
|
107
60
|
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
|
108
61
|
imageSizes: [32, 48, 64, 96, 128, 256, 384],
|
|
@@ -130,18 +83,14 @@ const normalizeStringList = (values: string[] | undefined) => {
|
|
|
130
83
|
return normalized.length > 0 ? [...new Set(normalized)] : undefined;
|
|
131
84
|
};
|
|
132
85
|
|
|
133
|
-
//
|
|
134
|
-
// only (hyphens/spaces dropped), never empty, never starting with a digit.
|
|
86
|
+
// A reverse-DNS / Android package segment: lowercase alphanumerics, never empty, never starting with a digit.
|
|
135
87
|
const sanitizeAppIdSegment = (value: string): string => {
|
|
136
88
|
const cleaned = value.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
137
89
|
if (!cleaned) return "app";
|
|
138
90
|
return /^[a-z]/.test(cleaned) ? cleaned : `app${cleaned}`;
|
|
139
91
|
};
|
|
140
92
|
|
|
141
|
-
// The
|
|
142
|
-
// (repo) name as the org segment so the default is far less collision-prone than a bare
|
|
143
|
-
// `com.<appName>.app`, which Apple's portal routinely already has claimed. Apps that ship pin an
|
|
144
|
-
// explicit appId, so this only affects unconfigured/dev apps.
|
|
93
|
+
// The repo name is the org segment: a bare `com.<appName>.app` is routinely already claimed on Apple's portal.
|
|
145
94
|
export const deriveDefaultAppId = (orgName: string, appName: string): string =>
|
|
146
95
|
`com.${sanitizeAppIdSegment(orgName)}.${sanitizeAppIdSegment(appName)}`;
|
|
147
96
|
|
|
@@ -174,13 +123,11 @@ const normalizeDeepLinks = (deepLinks: DeepPartial<AkanMobileTargetConfig["deepL
|
|
|
174
123
|
} satisfies AkanMobileTargetConfig["deepLinks"];
|
|
175
124
|
};
|
|
176
125
|
|
|
177
|
-
/** What `akan.config.ts` may write: the resolved shape made partial, with `docker` and `web` in their unions. */
|
|
178
126
|
type AppConfigDeclaration = Omit<DeepPartial<AppConfigResult>, "docker" | "web"> & {
|
|
179
127
|
docker?: DockerOption;
|
|
180
128
|
web?: AkanWebOption;
|
|
181
129
|
};
|
|
182
130
|
|
|
183
|
-
/** What the workspace's libs add to an app's build, read off each `libs/<lib>/akan.config.ts`. */
|
|
184
131
|
export interface LibContributions {
|
|
185
132
|
externalLibs: string[];
|
|
186
133
|
docker: LibDockerConfig;
|
|
@@ -211,7 +158,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
211
158
|
docker: DockerConfig;
|
|
212
159
|
/** The Dockerfile `akan build` writes: the declared string verbatim, or one assembled from the parts. */
|
|
213
160
|
dockerfile: string;
|
|
214
|
-
|
|
161
|
+
database: AkanDatabaseConfig;
|
|
215
162
|
web: AkanWebConfig;
|
|
216
163
|
externalLibs: string[];
|
|
217
164
|
barrelImports: string[];
|
|
@@ -225,7 +172,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
225
172
|
hasMobileConfig: boolean;
|
|
226
173
|
secrets: string[];
|
|
227
174
|
assets: AkanAssetsConfig;
|
|
228
|
-
/** Raw setting
|
|
175
|
+
/** Raw setting, resolved against the app's lib deps at sync time. */
|
|
229
176
|
syncPageLibs: string[] | boolean;
|
|
230
177
|
baseDevEnv: BaseDevEnv;
|
|
231
178
|
libs: string[];
|
|
@@ -250,7 +197,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
250
197
|
this.baseDevEnv = baseDevEnv;
|
|
251
198
|
this.plugins = plugins;
|
|
252
199
|
this.#applyRoutes(config?.routes);
|
|
253
|
-
this.
|
|
200
|
+
this.database = AkanAppConfig.#database(app, config);
|
|
254
201
|
this.externalLibs = [...new Set([...(config?.externalLibs ?? []), ...libContributions.externalLibs])];
|
|
255
202
|
this.barrelImports = [
|
|
256
203
|
...DEFAULT_BARREL_IMPORTS,
|
|
@@ -365,24 +312,12 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
365
312
|
}
|
|
366
313
|
#applyRoutes(routes: AkanRouteConfig[] = []) {
|
|
367
314
|
for (const route of routes) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
.flat()
|
|
375
|
-
.forEach((domain) => {
|
|
376
|
-
if (domain) domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
|
|
377
|
-
});
|
|
378
|
-
} else {
|
|
379
|
-
Object.keys(route.domains).forEach((branch) => void this.branches.add(branch));
|
|
380
|
-
Object.values(route.domains)
|
|
381
|
-
.flat()
|
|
382
|
-
.forEach((domain) => {
|
|
383
|
-
if (domain) this.domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
|
|
384
|
-
});
|
|
385
|
-
}
|
|
315
|
+
const basePath = route.basePath ? route.basePath.replace(/^\/+|\/+$/g, "") : null;
|
|
316
|
+
if (basePath !== null) this.basePaths.add(basePath);
|
|
317
|
+
const domains = basePath !== null ? this.subRoutes.getOrInsert(basePath, new Set()) : this.domains;
|
|
318
|
+
for (const branch of Object.keys(route.domains)) this.branches.add(branch);
|
|
319
|
+
for (const domain of Object.values(route.domains).flat())
|
|
320
|
+
if (domain) domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
|
|
386
321
|
}
|
|
387
322
|
const appName = this.app.name.toLowerCase();
|
|
388
323
|
const serveDomain = this.baseDevEnv.serveDomain.toLowerCase();
|
|
@@ -426,11 +361,8 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
426
361
|
const preRunScripts = this.#getDockerRunScripts(preRuns);
|
|
427
362
|
const postRunScripts = this.#getDockerRunScripts(postRuns);
|
|
428
363
|
const imageScript = this.#getDockerImageScript(image, DEFAULT_DOCKER_IMAGE);
|
|
429
|
-
// The
|
|
430
|
-
//
|
|
431
|
-
// File logging is off in the image: a container's writable layer is ephemeral and nothing collects a
|
|
432
|
-
// file from it, so the rotating files would only fill the node disk (50MB x 100 at `trace`). stdout is
|
|
433
|
-
// the collection path; a deployment that wants the files back sets `AKAN_LOG_TO_FILE=1`.
|
|
364
|
+
// The web env matches what was built (a deployment can only narrow it). File logging is off: a container's
|
|
365
|
+
// writable layer is ephemeral and stdout is the collection path.
|
|
434
366
|
const webEnvLines = [
|
|
435
367
|
...(this.web.ssr ? [] : ["ENV AKAN_SSR=false"]),
|
|
436
368
|
...(this.web.csr ? [] : ["ENV AKAN_CSR=false"]),
|
|
@@ -458,16 +390,13 @@ ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
|
|
|
458
390
|
ENV AKAN_PUBLIC_API_PREFIX=${this.api.prefix}
|
|
459
391
|
ENV AKAN_PUBLIC_WS_PREFIX=${this.api.websocketPrefix}
|
|
460
392
|
ENV AKAN_PUBLIC_OPERATION_MODE=cloud
|
|
393
|
+
ENV AKAN_DATABASE_MODES=${this.database.modes.join(",")}
|
|
461
394
|
ENV AKAN_LOG_TO_FILE=0
|
|
462
395
|
${webEnvLines}
|
|
463
396
|
CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
464
397
|
}
|
|
465
398
|
static #importGeneration = 0;
|
|
466
|
-
|
|
467
|
-
* Bun caches dynamic imports by path, so a plain re-import after the user edits the config file
|
|
468
|
-
* returns the stale module. `bustImportCache` appends a fresh query string to force re-evaluation
|
|
469
|
-
* of the config module itself; modules it imports keep their cached instances.
|
|
470
|
-
*/
|
|
399
|
+
// Bun caches dynamic imports by path; a fresh query string re-evaluates the config module (its imports stay cached).
|
|
471
400
|
static async importConfigModule<T = unknown>(
|
|
472
401
|
cwdPath: string,
|
|
473
402
|
{ bustImportCache = false }: { bustImportCache?: boolean } = {},
|
|
@@ -519,24 +448,40 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
519
448
|
#resolveProductionDependencyVersion(lib: string) {
|
|
520
449
|
const rootVersion = this.rootPackageJson.dependencies?.[lib] ?? this.rootPackageJson.devDependencies?.[lib];
|
|
521
450
|
if (rootVersion) return rootVersion;
|
|
522
|
-
//
|
|
523
|
-
// packages (e.g. firebase for the push plugin) resolve a version without the framework
|
|
524
|
-
// hardcoding a per-feature package list.
|
|
451
|
+
// The framework's own (peer)dependencies resolve plugin runtime packages without a hardcoded list.
|
|
525
452
|
const akanPackageJson = getAkanPackageJson();
|
|
526
|
-
|
|
453
|
+
const version = akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
|
|
454
|
+
if (!version) throw new Error(`Dependency ${lib} not found in package.json`);
|
|
455
|
+
return version;
|
|
527
456
|
}
|
|
528
457
|
#getProductionRuntimePackages() {
|
|
529
|
-
return [
|
|
458
|
+
return [
|
|
459
|
+
...this.externalLibs,
|
|
460
|
+
...SSR_RUNTIME_PACKAGES,
|
|
461
|
+
...this.database.modes.flatMap((mode) => this.getDatabaseModeRuntimePackages(mode)),
|
|
462
|
+
];
|
|
530
463
|
}
|
|
531
|
-
getDatabaseModeRuntimePackages(databaseMode: DatabaseMode
|
|
532
|
-
return [...
|
|
464
|
+
getDatabaseModeRuntimePackages(databaseMode: DatabaseMode) {
|
|
465
|
+
return [...DatabaseModes.drivers[databaseMode]];
|
|
533
466
|
}
|
|
534
|
-
getMissingDatabaseModeDependencySpecs(databaseMode: DatabaseMode
|
|
467
|
+
getMissingDatabaseModeDependencySpecs(databaseMode: DatabaseMode) {
|
|
535
468
|
return this.#getMissingDependencySpecs(this.getDatabaseModeRuntimePackages(databaseMode));
|
|
536
469
|
}
|
|
470
|
+
/** The mode a CLI command runs this app in: the shell's `AKAN_DATABASE_MODE` if the app declares it, else the first. */
|
|
471
|
+
resolveDatabaseMode() {
|
|
472
|
+
return DatabaseModes.resolve({
|
|
473
|
+
requested: process.env.AKAN_DATABASE_MODE,
|
|
474
|
+
declared: this.database.modes.join(","),
|
|
475
|
+
local: true,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
static #database(app: App, config: AppConfigDeclaration): AkanDatabaseConfig {
|
|
479
|
+
const declared = config?.database?.modes?.filter((mode): mode is DatabaseMode => !!mode);
|
|
480
|
+
const modes = declared?.length ? declared : ["single"];
|
|
481
|
+
return { modes: DatabaseModes.parseList(modes.join(","), `database.modes in apps/${app.name}/akan.config.ts`) };
|
|
482
|
+
}
|
|
537
483
|
getMobileRuntimePackages() {
|
|
538
|
-
//
|
|
539
|
-
// app's "*" declarations to a hoisted, peer-pinned version instead of fetching latest.
|
|
484
|
+
// Installed at the root too, so the app's "*" declarations resolve to the hoisted, peer-pinned version.
|
|
540
485
|
return [...new Set([...MOBILE_RUNTIME_PACKAGES, ...MOBILE_APP_CAPACITOR_PLUGINS])];
|
|
541
486
|
}
|
|
542
487
|
getMissingMobileDependencySpecs() {
|
|
@@ -552,11 +497,10 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
552
497
|
};
|
|
553
498
|
return libs
|
|
554
499
|
.filter((lib) => !rootDependencies[lib])
|
|
555
|
-
.map((lib) => {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
});
|
|
500
|
+
.map((lib) => `${lib}@${this.#resolveProductionDependencyVersion(lib)}`);
|
|
501
|
+
}
|
|
502
|
+
get akanVersion() {
|
|
503
|
+
return getAkanPackageJson().version;
|
|
560
504
|
}
|
|
561
505
|
getProductionPackageJson(data: Partial<PackageJson> = {}): PackageJson {
|
|
562
506
|
return {
|
|
@@ -565,11 +509,10 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
565
509
|
version: "1.0.0",
|
|
566
510
|
main: "./main.js",
|
|
567
511
|
dependencies: Object.fromEntries(
|
|
568
|
-
[...new Set(this.#getProductionRuntimePackages())].map((lib) =>
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}),
|
|
512
|
+
[...new Set(this.#getProductionRuntimePackages())].map((lib) => [
|
|
513
|
+
lib,
|
|
514
|
+
this.#resolveProductionDependencyVersion(lib),
|
|
515
|
+
]),
|
|
573
516
|
),
|
|
574
517
|
...data,
|
|
575
518
|
};
|
|
@@ -643,41 +586,14 @@ export class AkanLibConfig implements LibConfigResult {
|
|
|
643
586
|
}
|
|
644
587
|
}
|
|
645
588
|
|
|
646
|
-
// export const getCapacitorConfig = (configImp: AppConfig, appInfo: AppScanResult, tsconfig: TsConfigJson) => {
|
|
647
|
-
// const props: RunnerProps = {
|
|
648
|
-
// type: "app",
|
|
649
|
-
// name: appInfo.name,
|
|
650
|
-
// repoName: appInfo.repoName,
|
|
651
|
-
// serveDomain: appInfo.serveDomain,
|
|
652
|
-
// env: (process.env.AKAN_PUBLIC_ENV ?? "debug") as "testing" | "local" | "debug" | "develop" | "main",
|
|
653
|
-
// libs: appInfo.libDeps,
|
|
654
|
-
// tsconfig,
|
|
655
|
-
// };
|
|
656
|
-
// const config = typeof configImp === "function" ? configImp(props) : configImp;
|
|
657
|
-
// const akanConfig = makeAppConfig(config, props);
|
|
658
|
-
// return akanConfig;
|
|
659
|
-
// };
|
|
660
|
-
|
|
661
589
|
//! need to refactor
|
|
662
|
-
|
|
663
|
-
const
|
|
590
|
+
const shiftBuildNum = async (app: App, delta: number) => {
|
|
591
|
+
const { buildNum } = (await AkanAppConfig.from(app)).mobile;
|
|
664
592
|
const akanConfigPath = path.join(app.cwdPath, "akan.config.ts");
|
|
665
593
|
const akanConfig = fs.readFileSync(akanConfigPath, "utf8");
|
|
666
|
-
|
|
667
|
-
`buildNum: ${appConfig.mobile.buildNum}`,
|
|
668
|
-
`buildNum: ${appConfig.mobile.buildNum + 1}`,
|
|
669
|
-
);
|
|
670
|
-
//? 개선할 여지가 있는지 확인
|
|
671
|
-
fs.writeFileSync(akanConfigPath, akanConfigContent);
|
|
594
|
+
fs.writeFileSync(akanConfigPath, akanConfig.replace(`buildNum: ${buildNum}`, `buildNum: ${buildNum + delta}`));
|
|
672
595
|
};
|
|
673
596
|
|
|
674
|
-
export const
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
const akanConfig = fs.readFileSync(akanConfigPath, "utf8");
|
|
678
|
-
const akanConfigContent = akanConfig.replace(
|
|
679
|
-
`buildNum: ${appConfig.mobile.buildNum}`,
|
|
680
|
-
`buildNum: ${appConfig.mobile.buildNum - 1}`,
|
|
681
|
-
);
|
|
682
|
-
fs.writeFileSync(akanConfigPath, akanConfigContent);
|
|
683
|
-
};
|
|
597
|
+
export const increaseBuildNum = async (app: App) => await shiftBuildNum(app, 1);
|
|
598
|
+
|
|
599
|
+
export const decreaseBuildNum = async (app: App) => await shiftBuildNum(app, -1);
|