@akanjs/devkit 3.0.0-beta.2 → 3.0.0-beta.21
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.ko.md +2 -2
- package/README.md +3 -2
- 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 +142 -106
- package/akanConfig/akanConfig.ts +147 -191
- package/akanConfig/types.ts +4 -3
- package/akanContext.ts +110 -160
- 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/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 +32 -1
- 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 +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 +195 -496
- 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 +29 -58
- 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 -19
- 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/__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/index.ts +6 -0
- package/mobile/mobileTarget.ts +16 -13
- package/mobile/nativeApi.test.ts +30 -0
- package/mobile/nativeApi.ts +40 -0
- package/mobile/nativeApp.test.ts +85 -0
- package/mobile/nativeApp.ts +210 -0
- package/mobile/nativeConfig.test.ts +199 -0
- package/mobile/nativeConfig.ts +184 -0
- package/mobile/nativeWebDir.test.ts +80 -0
- package/mobile/nativeWebDir.ts +62 -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 +10 -10
- 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 +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.test.ts +13 -3
- package/workspaceLayout.ts +20 -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
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,78 +32,14 @@ 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
|
-
// The firebase client (push tokens) and the Capacitor toolchain — `@capacitor/cli` (`npx cap`),
|
|
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.
|
|
68
|
-
const MOBILE_RUNTIME_PACKAGES = [
|
|
69
|
-
"@capacitor/cli",
|
|
70
|
-
"@capacitor/core",
|
|
71
|
-
"@capacitor/ios",
|
|
72
|
-
"@capacitor/android",
|
|
73
|
-
"@capacitor/assets",
|
|
74
|
-
] as const;
|
|
75
|
-
// Capacitor plugins that must additionally be declared in the *app's* package.json
|
|
76
|
-
// (apps/<app>/package.json): `npx cap sync` discovers plugins by scanning the app directory's
|
|
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.
|
|
82
|
-
const MOBILE_APP_CAPACITOR_PLUGINS = [
|
|
83
|
-
"@capacitor/app",
|
|
84
|
-
"@capacitor/browser",
|
|
85
|
-
"@capacitor/camera",
|
|
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",
|
|
94
|
-
"capacitor-plugin-safe-area",
|
|
95
|
-
] as const;
|
|
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
|
-
]);
|
|
106
43
|
const DEFAULT_AKAN_IMAGE_CONFIG: AkanImageConfig = {
|
|
107
44
|
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
|
108
45
|
imageSizes: [32, 48, 64, 96, 128, 256, 384],
|
|
@@ -130,18 +67,14 @@ const normalizeStringList = (values: string[] | undefined) => {
|
|
|
130
67
|
return normalized.length > 0 ? [...new Set(normalized)] : undefined;
|
|
131
68
|
};
|
|
132
69
|
|
|
133
|
-
//
|
|
134
|
-
// only (hyphens/spaces dropped), never empty, never starting with a digit.
|
|
70
|
+
// A reverse-DNS / Android package segment: lowercase alphanumerics, never empty, never starting with a digit.
|
|
135
71
|
const sanitizeAppIdSegment = (value: string): string => {
|
|
136
72
|
const cleaned = value.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
137
73
|
if (!cleaned) return "app";
|
|
138
74
|
return /^[a-z]/.test(cleaned) ? cleaned : `app${cleaned}`;
|
|
139
75
|
};
|
|
140
76
|
|
|
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.
|
|
77
|
+
// The repo name is the org segment: a bare `com.<appName>.app` is routinely already claimed on Apple's portal.
|
|
145
78
|
export const deriveDefaultAppId = (orgName: string, appName: string): string =>
|
|
146
79
|
`com.${sanitizeAppIdSegment(orgName)}.${sanitizeAppIdSegment(appName)}`;
|
|
147
80
|
|
|
@@ -174,13 +107,11 @@ const normalizeDeepLinks = (deepLinks: DeepPartial<AkanMobileTargetConfig["deepL
|
|
|
174
107
|
} satisfies AkanMobileTargetConfig["deepLinks"];
|
|
175
108
|
};
|
|
176
109
|
|
|
177
|
-
/** What `akan.config.ts` may write: the resolved shape made partial, with `docker` and `web` in their unions. */
|
|
178
110
|
type AppConfigDeclaration = Omit<DeepPartial<AppConfigResult>, "docker" | "web"> & {
|
|
179
111
|
docker?: DockerOption;
|
|
180
112
|
web?: AkanWebOption;
|
|
181
113
|
};
|
|
182
114
|
|
|
183
|
-
/** What the workspace's libs add to an app's build, read off each `libs/<lib>/akan.config.ts`. */
|
|
184
115
|
export interface LibContributions {
|
|
185
116
|
externalLibs: string[];
|
|
186
117
|
docker: LibDockerConfig;
|
|
@@ -211,7 +142,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
211
142
|
docker: DockerConfig;
|
|
212
143
|
/** The Dockerfile `akan build` writes: the declared string verbatim, or one assembled from the parts. */
|
|
213
144
|
dockerfile: string;
|
|
214
|
-
|
|
145
|
+
database: AkanDatabaseConfig;
|
|
215
146
|
web: AkanWebConfig;
|
|
216
147
|
externalLibs: string[];
|
|
217
148
|
barrelImports: string[];
|
|
@@ -225,7 +156,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
225
156
|
hasMobileConfig: boolean;
|
|
226
157
|
secrets: string[];
|
|
227
158
|
assets: AkanAssetsConfig;
|
|
228
|
-
/** Raw setting
|
|
159
|
+
/** Raw setting, resolved against the app's lib deps at sync time. */
|
|
229
160
|
syncPageLibs: string[] | boolean;
|
|
230
161
|
baseDevEnv: BaseDevEnv;
|
|
231
162
|
libs: string[];
|
|
@@ -250,7 +181,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
250
181
|
this.baseDevEnv = baseDevEnv;
|
|
251
182
|
this.plugins = plugins;
|
|
252
183
|
this.#applyRoutes(config?.routes);
|
|
253
|
-
this.
|
|
184
|
+
this.database = AkanAppConfig.#database(app, config);
|
|
254
185
|
this.externalLibs = [...new Set([...(config?.externalLibs ?? []), ...libContributions.externalLibs])];
|
|
255
186
|
this.barrelImports = [
|
|
256
187
|
...DEFAULT_BARREL_IMPORTS,
|
|
@@ -290,7 +221,7 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
290
221
|
// `akan build-ios` / `build-android` copy `dist/apps/<app>/csr/<target>.html` into the native project.
|
|
291
222
|
if (!resolved.csr && this.hasMobileConfig)
|
|
292
223
|
throw new Error(
|
|
293
|
-
`apps/${this.app.name}/akan.config.ts turns the CSR bundle off but declares mobile targets; the
|
|
224
|
+
`apps/${this.app.name}/akan.config.ts turns the CSR bundle off but declares mobile targets; the mobile apps ship that bundle. Drop the mobile section or leave CSR on.`,
|
|
294
225
|
);
|
|
295
226
|
return resolved;
|
|
296
227
|
}
|
|
@@ -300,10 +231,14 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
300
231
|
indexPath: _indexPath,
|
|
301
232
|
...rawMobile
|
|
302
233
|
} = (mobile ?? {}) as DeepPartial<AkanMobileConfig> & { indexPath?: unknown };
|
|
234
|
+
const configPath = `apps/${this.app.name}/akan.config.ts`;
|
|
235
|
+
AkanAppConfig.#assertMobileKeys(rawMobile, AkanAppConfig.#mobileKeys, "mobile", configPath);
|
|
303
236
|
const appName = rawMobile.appName ?? this.app.name;
|
|
304
237
|
const appId = rawMobile.appId ?? deriveDefaultAppId(this.baseDevEnv.repoName, this.app.name);
|
|
305
238
|
const version = rawMobile.version ?? "0.0.1";
|
|
306
239
|
const buildNum = rawMobile.buildNum ?? 1;
|
|
240
|
+
const files = AkanAppConfig.#resolveMobileFiles(rawMobile.files as AkanMobileConfig["files"], "mobile", configPath);
|
|
241
|
+
const native = rawMobile.native as AkanMobileConfig["native"];
|
|
307
242
|
const defaultTargetName = this.#defaultMobileTargetName(rawTargets);
|
|
308
243
|
const targetEntries = Object.entries(
|
|
309
244
|
rawTargets ?? {
|
|
@@ -312,52 +247,114 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
312
247
|
);
|
|
313
248
|
const targets = Object.fromEntries(
|
|
314
249
|
targetEntries.map(([name, rawTarget]) => {
|
|
315
|
-
const target = rawTarget as DeepPartial<AkanMobileTargetConfig>;
|
|
250
|
+
const target = (rawTarget ?? {}) as DeepPartial<AkanMobileTargetConfig>;
|
|
251
|
+
const where = `mobile.targets.${name}`;
|
|
252
|
+
AkanAppConfig.#assertMobileKeys(target, AkanAppConfig.#targetKeys, where, configPath);
|
|
316
253
|
const fallbackBasePath = !rawTargets && this.basePaths.has(name) ? name : undefined;
|
|
317
254
|
const basePath = (target.basePath ?? fallbackBasePath)?.replace(/^\/+|\/+$/g, "") || undefined;
|
|
318
255
|
const indexPath = normalizeIndexPath(target.indexPath as string | undefined);
|
|
319
256
|
const deepLinks = normalizeDeepLinks(target.deepLinks);
|
|
320
257
|
if (basePath && !this.basePaths.has(basePath)) {
|
|
321
|
-
throw new Error(
|
|
322
|
-
`Mobile target '${name}' uses unknown basePath '${basePath}' in apps/${this.app.name}/akan.config.ts`,
|
|
323
|
-
);
|
|
258
|
+
throw new Error(`Mobile target '${name}' uses unknown basePath '${basePath}' in ${configPath}`);
|
|
324
259
|
}
|
|
260
|
+
const targetFiles = AkanAppConfig.#resolveMobileFiles(
|
|
261
|
+
target.files as AkanMobileTargetConfig["files"],
|
|
262
|
+
where,
|
|
263
|
+
configPath,
|
|
264
|
+
);
|
|
265
|
+
const fileName = (target.fileName ?? rawMobile.fileName) as string | undefined;
|
|
325
266
|
const resolved = {
|
|
326
|
-
...rawMobile,
|
|
327
|
-
...target,
|
|
328
267
|
name,
|
|
329
268
|
basePath,
|
|
330
269
|
indexPath,
|
|
331
270
|
deepLinks,
|
|
332
271
|
appName: target.appName ?? appName,
|
|
333
272
|
appId: target.appId ?? appId,
|
|
273
|
+
...(fileName ? { fileName } : {}),
|
|
334
274
|
version: target.version ?? version,
|
|
335
275
|
buildNum: target.buildNum ?? buildNum,
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
...target.android,
|
|
343
|
-
},
|
|
344
|
-
ios: {
|
|
345
|
-
...rawMobile.ios,
|
|
346
|
-
...target.ios,
|
|
347
|
-
},
|
|
276
|
+
...(target.assets ? { assets: target.assets as AkanMobileTargetConfig["assets"] } : {}),
|
|
277
|
+
...(target.permissions ? { permissions: target.permissions as AkanMobileTargetConfig["permissions"] } : {}),
|
|
278
|
+
...(files || targetFiles ? { files: { ...files, ...targetFiles } } : {}),
|
|
279
|
+
...(native || target.native
|
|
280
|
+
? { native: AkanAppConfig.#mergeNative(native, target.native as AkanMobileTargetConfig["native"]) }
|
|
281
|
+
: {}),
|
|
348
282
|
} satisfies AkanMobileTargetConfig;
|
|
349
283
|
return [name, resolved];
|
|
350
284
|
}),
|
|
351
285
|
);
|
|
352
286
|
return {
|
|
353
|
-
...rawMobile,
|
|
354
287
|
appName,
|
|
355
288
|
appId,
|
|
289
|
+
...(rawMobile.fileName ? { fileName: rawMobile.fileName as string } : {}),
|
|
356
290
|
version,
|
|
357
291
|
buildNum,
|
|
292
|
+
...(files ? { files } : {}),
|
|
293
|
+
...(native ? { native } : {}),
|
|
358
294
|
targets,
|
|
359
|
-
|
|
360
|
-
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
static readonly #mobileKeys = ["appName", "appId", "fileName", "version", "buildNum", "files", "native"];
|
|
298
|
+
static readonly #targetKeys = [
|
|
299
|
+
"basePath",
|
|
300
|
+
"indexPath",
|
|
301
|
+
"appName",
|
|
302
|
+
"appId",
|
|
303
|
+
"fileName",
|
|
304
|
+
"version",
|
|
305
|
+
"buildNum",
|
|
306
|
+
"assets",
|
|
307
|
+
"permissions",
|
|
308
|
+
"deepLinks",
|
|
309
|
+
"files",
|
|
310
|
+
"native",
|
|
311
|
+
];
|
|
312
|
+
//* The Capacitor keys used to pass straight through; the native runtime takes typed ones, so a leftover is refused.
|
|
313
|
+
static #assertMobileKeys(section: object, known: string[], where: string, configPath: string) {
|
|
314
|
+
for (const key of Object.keys(section)) {
|
|
315
|
+
if (known.includes(key)) continue;
|
|
316
|
+
if (key === "plugins" || key === "ios" || key === "android")
|
|
317
|
+
throw new Error(
|
|
318
|
+
`${where}.${key} in ${configPath} is a Capacitor setting. The native runtime reads native.plugins, native.ios.{infoPlist,entitlements} and native.android.{manifest,application,activity,googleServices} instead.`,
|
|
319
|
+
);
|
|
320
|
+
throw new Error(`${where}.${key} in ${configPath} is not a mobile setting. Known: ${known.join(", ")}.`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
static readonly #fileTargetPattern = /^(?:ios\/.+|android\/res\/[^/]+\/[^/]+|android\/assets\/.+)$/;
|
|
324
|
+
static #resolveMobileFiles(files: AkanMobileTargetConfig["files"] | undefined, where: string, configPath: string) {
|
|
325
|
+
if (!files) return undefined;
|
|
326
|
+
for (const [to, from] of Object.entries(files)) {
|
|
327
|
+
if (typeof from !== "string")
|
|
328
|
+
throw new Error(
|
|
329
|
+
`${where}.files in ${configPath} maps where a file lands to its source now, e.g. { "android/res/raw/chime.mp3": "assets/chime.mp3" }. google-services.json goes to native.android.googleServices, and GoogleService-Info.plist is no longer needed.`,
|
|
330
|
+
);
|
|
331
|
+
if (!AkanAppConfig.#fileTargetPattern.test(to))
|
|
332
|
+
throw new Error(
|
|
333
|
+
`${where}.files["${to}"] in ${configPath} must land under ios/<path>, android/res/<type>/<file> or android/assets/<path>.`,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
return files;
|
|
337
|
+
}
|
|
338
|
+
static #mergeNative(
|
|
339
|
+
base: AkanMobileTargetConfig["native"],
|
|
340
|
+
override: AkanMobileTargetConfig["native"],
|
|
341
|
+
): NonNullable<AkanMobileTargetConfig["native"]> {
|
|
342
|
+
const plugins = [...new Set([...(base?.plugins ?? []), ...(override?.plugins ?? [])])];
|
|
343
|
+
const ios = { ...base?.ios, ...override?.ios };
|
|
344
|
+
const android: NonNullable<NonNullable<AkanMobileTargetConfig["native"]>["android"]> = {
|
|
345
|
+
...base?.android,
|
|
346
|
+
...override?.android,
|
|
347
|
+
};
|
|
348
|
+
for (const key of ["manifest", "application", "activity"] as const) {
|
|
349
|
+
const merged = [...(base?.android?.[key] ?? []), ...(override?.android?.[key] ?? [])];
|
|
350
|
+
if (merged.length) android[key] = merged;
|
|
351
|
+
else delete android[key];
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
...(plugins.length ? { plugins } : {}),
|
|
355
|
+
...(Object.keys(ios).length ? { ios } : {}),
|
|
356
|
+
...(Object.keys(android).length ? { android } : {}),
|
|
357
|
+
};
|
|
361
358
|
}
|
|
362
359
|
#defaultMobileTargetName(rawTargets: DeepPartial<AkanMobileConfig>["targets"] | undefined) {
|
|
363
360
|
if (rawTargets && Object.keys(rawTargets).length > 0) return Object.keys(rawTargets)[0] as string;
|
|
@@ -365,24 +362,12 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
365
362
|
}
|
|
366
363
|
#applyRoutes(routes: AkanRouteConfig[] = []) {
|
|
367
364
|
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
|
-
}
|
|
365
|
+
const basePath = route.basePath ? route.basePath.replace(/^\/+|\/+$/g, "") : null;
|
|
366
|
+
if (basePath !== null) this.basePaths.add(basePath);
|
|
367
|
+
const domains = basePath !== null ? this.subRoutes.getOrInsert(basePath, new Set()) : this.domains;
|
|
368
|
+
for (const branch of Object.keys(route.domains)) this.branches.add(branch);
|
|
369
|
+
for (const domain of Object.values(route.domains).flat())
|
|
370
|
+
if (domain) domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
|
|
386
371
|
}
|
|
387
372
|
const appName = this.app.name.toLowerCase();
|
|
388
373
|
const serveDomain = this.baseDevEnv.serveDomain.toLowerCase();
|
|
@@ -426,11 +411,8 @@ export class AkanAppConfig implements AppConfigResult {
|
|
|
426
411
|
const preRunScripts = this.#getDockerRunScripts(preRuns);
|
|
427
412
|
const postRunScripts = this.#getDockerRunScripts(postRuns);
|
|
428
413
|
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`.
|
|
414
|
+
// The web env matches what was built (a deployment can only narrow it). File logging is off: a container's
|
|
415
|
+
// writable layer is ephemeral and stdout is the collection path.
|
|
434
416
|
const webEnvLines = [
|
|
435
417
|
...(this.web.ssr ? [] : ["ENV AKAN_SSR=false"]),
|
|
436
418
|
...(this.web.csr ? [] : ["ENV AKAN_CSR=false"]),
|
|
@@ -458,16 +440,13 @@ ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
|
|
|
458
440
|
ENV AKAN_PUBLIC_API_PREFIX=${this.api.prefix}
|
|
459
441
|
ENV AKAN_PUBLIC_WS_PREFIX=${this.api.websocketPrefix}
|
|
460
442
|
ENV AKAN_PUBLIC_OPERATION_MODE=cloud
|
|
443
|
+
ENV AKAN_DATABASE_MODES=${this.database.modes.join(",")}
|
|
461
444
|
ENV AKAN_LOG_TO_FILE=0
|
|
462
445
|
${webEnvLines}
|
|
463
446
|
CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
464
447
|
}
|
|
465
448
|
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
|
-
*/
|
|
449
|
+
// Bun caches dynamic imports by path; a fresh query string re-evaluates the config module (its imports stay cached).
|
|
471
450
|
static async importConfigModule<T = unknown>(
|
|
472
451
|
cwdPath: string,
|
|
473
452
|
{ bustImportCache = false }: { bustImportCache?: boolean } = {},
|
|
@@ -519,31 +498,37 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
519
498
|
#resolveProductionDependencyVersion(lib: string) {
|
|
520
499
|
const rootVersion = this.rootPackageJson.dependencies?.[lib] ?? this.rootPackageJson.devDependencies?.[lib];
|
|
521
500
|
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.
|
|
501
|
+
// The framework's own (peer)dependencies resolve plugin runtime packages without a hardcoded list.
|
|
525
502
|
const akanPackageJson = getAkanPackageJson();
|
|
526
|
-
|
|
503
|
+
const version = akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
|
|
504
|
+
if (!version) throw new Error(`Dependency ${lib} not found in package.json`);
|
|
505
|
+
return version;
|
|
527
506
|
}
|
|
528
507
|
#getProductionRuntimePackages() {
|
|
529
|
-
return [
|
|
508
|
+
return [
|
|
509
|
+
...this.externalLibs,
|
|
510
|
+
...SSR_RUNTIME_PACKAGES,
|
|
511
|
+
...this.database.modes.flatMap((mode) => this.getDatabaseModeRuntimePackages(mode)),
|
|
512
|
+
];
|
|
530
513
|
}
|
|
531
|
-
getDatabaseModeRuntimePackages(databaseMode: DatabaseMode
|
|
532
|
-
return [...
|
|
514
|
+
getDatabaseModeRuntimePackages(databaseMode: DatabaseMode) {
|
|
515
|
+
return [...DatabaseModes.drivers[databaseMode]];
|
|
533
516
|
}
|
|
534
|
-
getMissingDatabaseModeDependencySpecs(databaseMode: DatabaseMode
|
|
517
|
+
getMissingDatabaseModeDependencySpecs(databaseMode: DatabaseMode) {
|
|
535
518
|
return this.#getMissingDependencySpecs(this.getDatabaseModeRuntimePackages(databaseMode));
|
|
536
519
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
520
|
+
/** The mode a CLI command runs this app in: the shell's `AKAN_DATABASE_MODE` if the app declares it, else the first. */
|
|
521
|
+
resolveDatabaseMode() {
|
|
522
|
+
return DatabaseModes.resolve({
|
|
523
|
+
requested: process.env.AKAN_DATABASE_MODE,
|
|
524
|
+
declared: this.database.modes.join(","),
|
|
525
|
+
local: true,
|
|
526
|
+
});
|
|
544
527
|
}
|
|
545
|
-
|
|
546
|
-
|
|
528
|
+
static #database(app: App, config: AppConfigDeclaration): AkanDatabaseConfig {
|
|
529
|
+
const declared = config?.database?.modes?.filter((mode): mode is DatabaseMode => !!mode);
|
|
530
|
+
const modes = declared?.length ? declared : ["single"];
|
|
531
|
+
return { modes: DatabaseModes.parseList(modes.join(","), `database.modes in apps/${app.name}/akan.config.ts`) };
|
|
547
532
|
}
|
|
548
533
|
#getMissingDependencySpecs(libs: readonly string[]) {
|
|
549
534
|
const rootDependencies = {
|
|
@@ -552,11 +537,10 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
552
537
|
};
|
|
553
538
|
return libs
|
|
554
539
|
.filter((lib) => !rootDependencies[lib])
|
|
555
|
-
.map((lib) => {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
});
|
|
540
|
+
.map((lib) => `${lib}@${this.#resolveProductionDependencyVersion(lib)}`);
|
|
541
|
+
}
|
|
542
|
+
get akanVersion() {
|
|
543
|
+
return getAkanPackageJson().version;
|
|
560
544
|
}
|
|
561
545
|
getProductionPackageJson(data: Partial<PackageJson> = {}): PackageJson {
|
|
562
546
|
return {
|
|
@@ -565,11 +549,10 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
565
549
|
version: "1.0.0",
|
|
566
550
|
main: "./main.js",
|
|
567
551
|
dependencies: Object.fromEntries(
|
|
568
|
-
[...new Set(this.#getProductionRuntimePackages())].map((lib) =>
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}),
|
|
552
|
+
[...new Set(this.#getProductionRuntimePackages())].map((lib) => [
|
|
553
|
+
lib,
|
|
554
|
+
this.#resolveProductionDependencyVersion(lib),
|
|
555
|
+
]),
|
|
573
556
|
),
|
|
574
557
|
...data,
|
|
575
558
|
};
|
|
@@ -643,41 +626,14 @@ export class AkanLibConfig implements LibConfigResult {
|
|
|
643
626
|
}
|
|
644
627
|
}
|
|
645
628
|
|
|
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
629
|
//! need to refactor
|
|
662
|
-
|
|
663
|
-
const
|
|
630
|
+
const shiftBuildNum = async (app: App, delta: number) => {
|
|
631
|
+
const { buildNum } = (await AkanAppConfig.from(app)).mobile;
|
|
664
632
|
const akanConfigPath = path.join(app.cwdPath, "akan.config.ts");
|
|
665
633
|
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);
|
|
634
|
+
fs.writeFileSync(akanConfigPath, akanConfig.replace(`buildNum: ${buildNum}`, `buildNum: ${buildNum + delta}`));
|
|
672
635
|
};
|
|
673
636
|
|
|
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
|
-
};
|
|
637
|
+
export const increaseBuildNum = async (app: App) => await shiftBuildNum(app, 1);
|
|
638
|
+
|
|
639
|
+
export const decreaseBuildNum = async (app: App) => await shiftBuildNum(app, -1);
|
package/akanConfig/types.ts
CHANGED
|
@@ -2,12 +2,14 @@ export type {
|
|
|
2
2
|
AkanApiConfig,
|
|
3
3
|
AkanAssetsConfig,
|
|
4
4
|
AkanConfigFile,
|
|
5
|
+
AkanDatabaseConfig,
|
|
5
6
|
AkanExecutor,
|
|
6
7
|
AkanMobileConfig,
|
|
8
|
+
AkanMobileNativeConfig,
|
|
7
9
|
AkanMobileTargetConfig,
|
|
8
|
-
|
|
10
|
+
AkanNativeValue,
|
|
9
11
|
AkanPlugin,
|
|
10
|
-
|
|
12
|
+
AkanPluginNativeConfig,
|
|
11
13
|
AkanRouteConfig,
|
|
12
14
|
AkanScanInfo,
|
|
13
15
|
AkanSyncContext,
|
|
@@ -34,7 +36,6 @@ export type {
|
|
|
34
36
|
MobileEnv,
|
|
35
37
|
MobilePermission,
|
|
36
38
|
PkgScanResult,
|
|
37
|
-
PluginRuntimeContext,
|
|
38
39
|
ScanResult,
|
|
39
40
|
WorkspaceScanResult,
|
|
40
41
|
} from "akanjs";
|