@akanjs/cli 3.0.0-beta.29 → 3.0.0-beta.30
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/.build-stamp +1 -1
- package/{CodeAgent-86q8d13j.js → CodeAgent-xnfyyz8h.js} +2 -2
- package/{CodeTui-r8tgxsyb.js → CodeTui-h66xb1fh.js} +1 -1
- package/README.ko.md +72 -0
- package/README.md +88 -0
- package/{agent.command-q9bmqrag.js → agent.command-c4v7kjff.js} +5 -5
- package/akanCode.js +2 -2
- package/{application.command-712jd2z8.js → application.command-yzsswrz6.js} +9 -9
- package/{applicationBuildRunner-ez37p161.js → applicationBuildRunner-qkt6spd5.js} +3 -3
- package/buildBatch.proc.js +3 -3
- package/{cloud.command-8eegwcsc.js → cloud.command-v8h688jc.js} +9 -9
- package/cloud.script-yct1sk4k.js +20 -0
- package/{code.command-n0c2tyzx.js → code.command-jff3tw7y.js} +6 -6
- package/{context.command-vxf6d7q2.js → context.command-y5sevk3c.js} +14 -14
- package/context.runner-90hsmacr.js +21 -0
- package/{guideline.command-ene55fkr.js → guideline.command-11cndccb.js} +2 -2
- package/guidelines/conventions/conventions.instruction.md +27 -14
- package/guidelines/runtimeRule/runtimeRule.instruction.md +90 -17
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
- package/incrementalBuilder.proc.js +2 -2
- package/{index-2z30v4k5.js → index-0ncc0mbk.js} +3 -3
- package/{index-2yvy9ztj.js → index-167c77aq.js} +4 -4
- package/{index-nbg9bfnr.js → index-35mmm9ca.js} +1 -1
- package/{index-fy42hyb9.js → index-376gpdds.js} +5 -5
- package/{index-n9gxx7bp.js → index-3rh7thcx.js} +13 -13
- package/{index-rrt9pnb4.js → index-5rp0h6na.js} +2 -2
- package/{index-ttn00pr3.js → index-6x9p8dpb.js} +1 -1
- package/{index-8ej6r02m.js → index-8tv7356t.js} +1 -1
- package/{index-k7809wmg.js → index-a4s954kq.js} +2 -2
- package/{index-rbeahw6j.js → index-bxmejydw.js} +3 -3
- package/{index-qtz88kh0.js → index-gxamdf18.js} +2 -2
- package/{index-20r2g1t3.js → index-hf6f4xnb.js} +4 -4
- package/{index-2s2e5qnd.js → index-hmdq5pqm.js} +1 -1
- package/{index-16k7m3cs.js → index-hqd0h1pb.js} +10 -10
- package/{index-1hs6jrys.js → index-kb16nzyt.js} +36 -33
- package/{index-krwz9ek9.js → index-mk3b9rk1.js} +3 -3
- package/{index-r8gp8zk3.js → index-n3jk2501.js} +155 -152
- package/{index-g44da4r2.js → index-qcejqgts.js} +5 -5
- package/{index-h9ed99ax.js → index-rtwhw4aq.js} +7 -7
- package/{index-ss828r32.js → index-se643zvp.js} +1 -1
- package/{index-2ctqegdm.js → index-tsb0f8ya.js} +2 -2
- package/{index-0pqzrbpr.js → index-tzc1gtrg.js} +2 -2
- package/{index-genegfnt.js → index-wfwgcnyc.js} +4 -4
- package/{index-b68zfsvz.js → index-xb7qhxa8.js} +1 -1
- package/index.js +21 -21
- package/{library.command-tz7vnwea.js → library.command-n9kp7yms.js} +3 -3
- package/{localRegistry.command-7dd85czz.js → localRegistry.command-jx6kxt2x.js} +8 -8
- package/{module.command-qhc9ns0s.js → module.command-q2xjf6cx.js} +5 -5
- package/{package.command-z3epnvas.js → package.command-q5a3nsw5.js} +3 -3
- package/package.json +3 -3
- package/{page.command-exd2vakz.js → page.command-ppenrxjn.js} +3 -3
- package/{primitive.command-0w6cha4j.js → primitive.command-dvgg8nem.js} +6 -6
- package/{quality.command-je4kc9yv.js → quality.command-pz7kg3pc.js} +2 -2
- package/{repair.command-knvwfgtg.js → repair.command-a6py9xvz.js} +5 -5
- package/{scalar.command-60nxfchc.js → scalar.command-7f3xfpen.js} +4 -4
- package/{subspace.command-683qxcw9.js → subspace.command-z7nqs508.js} +4 -4
- package/{tunnel.command-7m2kxtat.js → tunnel.command-zy4wbcgt.js} +2 -2
- package/{workflow.command-j5tk13ds.js → workflow.command-f142t17s.js} +10 -10
- package/{workspace.command-jxdm0wrb.js → workspace.command-gpk1149x.js} +20 -20
- package/cloud.script-55s1cmz9.js +0 -20
- package/context.runner-70r2fmty.js +0 -21
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
binPlatforms,
|
|
4
4
|
Executor
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-n3jk2501.js";
|
|
6
6
|
|
|
7
7
|
// pkgs/@akanjs/devkit/mobile/mobileTarget.ts
|
|
8
8
|
var trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
|
|
9
9
|
var getMobileTargets = async (app) => {
|
|
10
10
|
const config = await app.getConfig();
|
|
11
|
-
return Object.entries(config.
|
|
11
|
+
return Object.entries(config.native.targets).map(([name, target]) => ({ name, config: target }));
|
|
12
12
|
};
|
|
13
|
-
var isTemplateOnly = ({ basePaths,
|
|
13
|
+
var isTemplateOnly = ({ basePaths, native }) => basePaths.size > 0 && Object.values(native.targets).every((target) => !target.basePath);
|
|
14
14
|
var getMobileTargetChoices = async (app) => {
|
|
15
15
|
const config = await app.getConfig();
|
|
16
|
-
const targetNames = Object.keys(config.
|
|
16
|
+
const targetNames = Object.keys(config.native.targets);
|
|
17
17
|
if (targetNames.length > 0 && !isTemplateOnly(config))
|
|
18
18
|
return targetNames;
|
|
19
19
|
return [...config.basePaths];
|
|
@@ -35,17 +35,17 @@ var resolveMobileTargets = async (app, selection) => {
|
|
|
35
35
|
const config = await app.getConfig();
|
|
36
36
|
const targets = await getMobileTargets(app);
|
|
37
37
|
if (targets.length === 0)
|
|
38
|
-
throw new Error(`No
|
|
38
|
+
throw new Error(`No native targets configured for ${app.name}`);
|
|
39
39
|
if (!selection && targets.length === 1 && !isTemplateOnly(config))
|
|
40
40
|
return targets;
|
|
41
41
|
if (!selection) {
|
|
42
42
|
const choices = await getMobileTargetChoices(app);
|
|
43
43
|
if (choices.length === 1)
|
|
44
44
|
return resolveMobileTargets(app, choices[0]);
|
|
45
|
-
throw new Error(`Multiple
|
|
45
|
+
throw new Error(`Multiple native targets found for ${app.name}. Pass --target <${choices.join("|")}|all>.`);
|
|
46
46
|
}
|
|
47
47
|
if (selection === "all") {
|
|
48
|
-
if (Object.keys(config.
|
|
48
|
+
if (Object.keys(config.native.targets).length > 1)
|
|
49
49
|
return targets;
|
|
50
50
|
const basePaths = [...config.basePaths];
|
|
51
51
|
if (basePaths.length > 1 || isTemplateOnly(config)) {
|
|
@@ -63,14 +63,14 @@ var resolveMobileTargets = async (app, selection) => {
|
|
|
63
63
|
if (basePathTarget && config.basePaths.has(trimSlashes(selection)))
|
|
64
64
|
return [basePathTarget];
|
|
65
65
|
const choices = await getMobileTargetChoices(app);
|
|
66
|
-
throw new Error(`
|
|
66
|
+
throw new Error(`Native target '${selection}' was not found. Available: ${choices.join(", ")}`);
|
|
67
67
|
};
|
|
68
68
|
var resolveAppId = (appId, platform) => {
|
|
69
69
|
if (typeof appId === "string")
|
|
70
70
|
return appId;
|
|
71
71
|
const id = appId[platform] ?? appId.default;
|
|
72
72
|
if (!id)
|
|
73
|
-
throw new Error(`
|
|
73
|
+
throw new Error(`native.appId names no id for ${platform}; give it ${platform} or default.`);
|
|
74
74
|
return id;
|
|
75
75
|
};
|
|
76
76
|
var appIdsOf = (appId) => typeof appId === "string" ? [appId] : Object.values(appId).filter((id) => !!id);
|
|
@@ -378,7 +378,7 @@ class NativeConfig {
|
|
|
378
378
|
const updates = NativeConfig.#updates(target, env);
|
|
379
379
|
const folders = new Set(nativePlugins.map((plugin) => path3.resolve(plugin.dir)));
|
|
380
380
|
const folderIds = new Set(nativePlugins.map((plugin) => plugin.id));
|
|
381
|
-
const listed = (target.
|
|
381
|
+
const listed = (target.plugins ?? []).filter((spec) => NativeConfig.#isId(spec) ? !folderIds.has(spec) : !folders.has(path3.resolve(appPath, spec)));
|
|
382
382
|
const plugins = [
|
|
383
383
|
...new Set([
|
|
384
384
|
...NativeConfig.basePlugins,
|
|
@@ -393,27 +393,30 @@ class NativeConfig {
|
|
|
393
393
|
const pluginIds = plugins.map((spec) => nativePlugins.find((plugin) => plugin.dir === spec)?.id ?? NativeConfig.#pluginId(appPath, spec));
|
|
394
394
|
const usageDescriptions = Object.fromEntries(Object.entries(toIosInfoPlistUsageDescriptions(Object.assign({}, ...applied.map((contribution) => contribution.usageDescriptions ?? {})))).map(([key, text]) => [key, text.replaceAll("$(PRODUCT_NAME)", target.appName)]));
|
|
395
395
|
const ios = NativeConfig.#compact({
|
|
396
|
-
infoPlist: NativeConfig.#merged(applied.map((c) => c.infoPlist), target.
|
|
397
|
-
entitlements: NativeConfig.#merged(applied.map((c) => c.entitlements), target.
|
|
396
|
+
infoPlist: NativeConfig.#merged(applied.map((c) => c.infoPlist), target.ios?.infoPlist),
|
|
397
|
+
entitlements: NativeConfig.#merged(applied.map((c) => c.entitlements), target.ios?.entitlements)
|
|
398
398
|
});
|
|
399
399
|
const manifest = [
|
|
400
400
|
...[...new Set(applied.flatMap((c) => c.androidPermissions ?? []))].map((name) => `<uses-permission android:name="android.permission.${name}" />`),
|
|
401
401
|
...[...new Set(applied.flatMap((c) => c.androidFeatures ?? []))].map((name) => `<uses-feature android:name="${name}" android:required="false" />`),
|
|
402
|
-
...target.
|
|
402
|
+
...target.android?.manifest ?? []
|
|
403
403
|
];
|
|
404
404
|
const android = NativeConfig.#compact({
|
|
405
405
|
manifest,
|
|
406
|
-
application: target.
|
|
407
|
-
activity: target.
|
|
406
|
+
application: target.android?.application ?? [],
|
|
407
|
+
activity: target.android?.activity ?? []
|
|
408
408
|
});
|
|
409
|
-
const resources =
|
|
409
|
+
const resources = [
|
|
410
|
+
...Object.entries(target.ios?.files ?? {}).map(([to, from]) => ({ from: abs(from), to: `ios/${to}` })),
|
|
411
|
+
...Object.entries(target.android?.files ?? {}).map(([to, from]) => ({ from: abs(from), to: `android/${to}` }))
|
|
412
|
+
];
|
|
410
413
|
const native = NativeConfig.#compact({ ios, android, resources });
|
|
411
|
-
const googleServices = target.
|
|
412
|
-
const pushAndroid = target.
|
|
414
|
+
const googleServices = target.android?.googleServices;
|
|
415
|
+
const pushAndroid = target.android?.push;
|
|
413
416
|
const desktop = NativeConfig.#compact({
|
|
414
|
-
recovery: target.
|
|
415
|
-
screenCapture: target.
|
|
416
|
-
window: NativeConfig.#compact({ ...target.
|
|
417
|
+
recovery: target.desktop?.recovery,
|
|
418
|
+
screenCapture: target.desktop?.screenCapture,
|
|
419
|
+
window: NativeConfig.#compact({ ...target.desktop?.window }),
|
|
417
420
|
server: desktopServer,
|
|
418
421
|
bin: desktopBin
|
|
419
422
|
});
|
|
@@ -443,16 +446,16 @@ class NativeConfig {
|
|
|
443
446
|
android: { ...pushAndroid, ...pushAndroid.smallIcon ? { smallIcon: abs(pushAndroid.smallIcon) } : {} }
|
|
444
447
|
}
|
|
445
448
|
} : {},
|
|
446
|
-
...target.
|
|
449
|
+
...target.ios?.privacy ? { privacy: target.ios.privacy } : {},
|
|
447
450
|
android: {
|
|
448
451
|
debugAppIdSuffix: ".debug",
|
|
449
452
|
...googleServices ? { googleServices: abs(googleServices) } : {},
|
|
450
|
-
...target.
|
|
453
|
+
...target.android?.autoplay ? { autoplay: true } : {}
|
|
451
454
|
},
|
|
452
455
|
keyboard: { resize: "none" },
|
|
453
456
|
...desktop ? { desktop } : {},
|
|
454
|
-
...target.
|
|
455
|
-
...target.
|
|
457
|
+
...target.icon ? { icon: NativeConfig.#icon(target.icon, abs) } : {},
|
|
458
|
+
...target.splash ? { splash: NativeConfig.#splash(target.splash, abs) } : {}
|
|
456
459
|
};
|
|
457
460
|
return { config, warnings };
|
|
458
461
|
}
|
|
@@ -578,7 +581,7 @@ ${script}${html.slice(at)}`;
|
|
|
578
581
|
}
|
|
579
582
|
async assemble(target, { html, publicDir, fontsDir }) {
|
|
580
583
|
if (!await Bun.file(html).exists())
|
|
581
|
-
throw new Error(`CSR html for
|
|
584
|
+
throw new Error(`CSR html for native target '${target.name}' not found: ${html}`);
|
|
582
585
|
await this.clear();
|
|
583
586
|
if (publicDir && await NativeWebDir.#isDir(publicDir))
|
|
584
587
|
await cp(publicDir, this.dir, { recursive: true });
|
|
@@ -611,11 +614,11 @@ class NativeApp {
|
|
|
611
614
|
this.app = app;
|
|
612
615
|
this.target = target;
|
|
613
616
|
this.env = env;
|
|
614
|
-
this.targetRoot = path6.join(app.cwdPath, ".akan", "
|
|
617
|
+
this.targetRoot = path6.join(app.cwdPath, ".akan", "native", target.name);
|
|
615
618
|
this.web = new NativeWebDir(path6.join(this.targetRoot, "web"));
|
|
616
619
|
}
|
|
617
620
|
outDir(platform) {
|
|
618
|
-
return path6.join(this.targetRoot, "
|
|
621
|
+
return path6.join(this.targetRoot, "build", platform);
|
|
619
622
|
}
|
|
620
623
|
devOutDir(platform) {
|
|
621
624
|
return path6.join(this.targetRoot, "dev", platform);
|
|
@@ -669,7 +672,7 @@ class NativeApp {
|
|
|
669
672
|
#assertValid(api, config) {
|
|
670
673
|
const problems = api.validateConfig(config, { appDir: this.app.cwdPath });
|
|
671
674
|
if (problems.length)
|
|
672
|
-
throw new Error(`
|
|
675
|
+
throw new Error(`Native target '${this.target.name}' makes an invalid native config:
|
|
673
676
|
- ${problems.join(`
|
|
674
677
|
- `)}`);
|
|
675
678
|
}
|
|
@@ -807,14 +810,14 @@ class NativeApp {
|
|
|
807
810
|
...channel ? { channel } : {}
|
|
808
811
|
});
|
|
809
812
|
} catch (error) {
|
|
810
|
-
throw new Error(`
|
|
813
|
+
throw new Error(`Native target '${this.target.name}': ${error instanceof Error ? error.message : String(error)}`, {
|
|
811
814
|
cause: error
|
|
812
815
|
});
|
|
813
816
|
}
|
|
814
817
|
}
|
|
815
818
|
#assertUpdates() {
|
|
816
819
|
if (!this.target.config.updates)
|
|
817
|
-
throw new Error(`
|
|
820
|
+
throw new Error(`Native target '${this.target.name}' has no updates: add native.updates: { url, publicKey } to akan.config.ts; \`akan update-keygen ${this.app.name}\` prints the key.`);
|
|
818
821
|
}
|
|
819
822
|
async updateKeygen(platform) {
|
|
820
823
|
const [api, { config }] = await Promise.all([
|
|
@@ -833,7 +836,7 @@ class NativeApp {
|
|
|
833
836
|
await this.assembleWeb();
|
|
834
837
|
const { api, config } = await this.prepare(platform);
|
|
835
838
|
if (!config.updates)
|
|
836
|
-
throw new Error(`
|
|
839
|
+
throw new Error(`Native target '${this.target.name}' takes no updates: add native.updates: { url, publicKey } to akan.config.ts first.`);
|
|
837
840
|
const packed = await api.packUpdate({
|
|
838
841
|
...this.#task(platform, config),
|
|
839
842
|
platform,
|
|
@@ -929,7 +932,7 @@ class DesktopServerStage {
|
|
|
929
932
|
}
|
|
930
933
|
static assertCarriable(config) {
|
|
931
934
|
if (!config.database.modes.includes("single"))
|
|
932
|
-
throw new Error(`
|
|
935
|
+
throw new Error(`desktop.server in native puts the server in the app, where only database mode single runs (no Redis or Postgres); apps/${config.app.name}/akan.config.ts declares ${config.database.modes.join(", ")}.`);
|
|
933
936
|
}
|
|
934
937
|
static env(config, environment) {
|
|
935
938
|
const { PORT: _port, AKAN_LOG_TO_FILE: _fileLog, ...image } = config.getProductionEnv(environment);
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
akanCodePaths2,
|
|
5
5
|
McpServerConfig,
|
|
6
6
|
McpSignIn
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-8tv7356t.js";
|
|
8
8
|
import {
|
|
9
9
|
stripAnsi
|
|
10
10
|
} from "./index-7md2g9vw.js";
|
|
@@ -511,7 +511,7 @@ class AkanToolPack2 {
|
|
|
511
511
|
return { name: "akan-tools", factory: async (pi) => await this.#register(pi) };
|
|
512
512
|
}
|
|
513
513
|
async names() {
|
|
514
|
-
const { ContextRunner } = await import("./context.runner-
|
|
514
|
+
const { ContextRunner } = await import("./context.runner-90hsmacr.js");
|
|
515
515
|
return [
|
|
516
516
|
...new ContextRunner().listMcpTools(this.#options.mode).map((tool) => tool.name),
|
|
517
517
|
AkanToolPack2.verifyToolName
|
|
@@ -519,7 +519,7 @@ class AkanToolPack2 {
|
|
|
519
519
|
}
|
|
520
520
|
static verifyToolName = "akan_verify";
|
|
521
521
|
async#register(pi) {
|
|
522
|
-
const { ContextRunner } = await import("./context.runner-
|
|
522
|
+
const { ContextRunner } = await import("./context.runner-90hsmacr.js");
|
|
523
523
|
const runner = new ContextRunner;
|
|
524
524
|
const guidelineNames = await AkanToolPack2.#guidelineNames();
|
|
525
525
|
for (const tool of runner.listMcpTools(this.#options.mode, { guidelineNames })) {
|
|
@@ -799,20 +799,11 @@ var normalizeDeepLinkDomain = (domain) => {
|
|
|
799
799
|
}
|
|
800
800
|
};
|
|
801
801
|
var normalizeDeepLinks = (deepLinks) => {
|
|
802
|
-
|
|
802
|
+
const schemes = normalizeStringList(deepLinks?.schemes);
|
|
803
|
+
const domains = normalizeStringList(deepLinks?.domains?.map(normalizeDeepLinkDomain));
|
|
804
|
+
if (!schemes && !domains)
|
|
803
805
|
return;
|
|
804
|
-
|
|
805
|
-
const domains = normalizeStringList(deepLinks.domains?.map(normalizeDeepLinkDomain));
|
|
806
|
-
const teamId = deepLinks.ios?.teamId?.trim();
|
|
807
|
-
const sha256CertFingerprints = normalizeStringList(deepLinks.android?.sha256CertFingerprints);
|
|
808
|
-
if (!schemes && !domains && !teamId && !sha256CertFingerprints)
|
|
809
|
-
return;
|
|
810
|
-
return {
|
|
811
|
-
...schemes ? { schemes } : {},
|
|
812
|
-
...domains ? { domains } : {},
|
|
813
|
-
...teamId ? { ios: { teamId } } : {},
|
|
814
|
-
...sha256CertFingerprints ? { android: { sha256CertFingerprints } } : {}
|
|
815
|
-
};
|
|
806
|
+
return { ...schemes ? { schemes } : {}, ...domains ? { domains } : {} };
|
|
816
807
|
};
|
|
817
808
|
var emptyLibContributions = () => ({
|
|
818
809
|
externalLibs: [],
|
|
@@ -855,8 +846,8 @@ class AkanAppConfig {
|
|
|
855
846
|
i18n;
|
|
856
847
|
api;
|
|
857
848
|
publicEnv;
|
|
858
|
-
|
|
859
|
-
|
|
849
|
+
native;
|
|
850
|
+
hasNativeConfig;
|
|
860
851
|
secrets;
|
|
861
852
|
assets;
|
|
862
853
|
syncPageLibs;
|
|
@@ -912,155 +903,167 @@ class AkanAppConfig {
|
|
|
912
903
|
]
|
|
913
904
|
};
|
|
914
905
|
this.syncPageLibs = config?.syncPageLibs ?? false;
|
|
915
|
-
|
|
916
|
-
|
|
906
|
+
if (config.mobile !== undefined)
|
|
907
|
+
throw new Error(`apps/${this.app.name}/akan.config.ts declares \`mobile\`, which is now \`native\`: the platform settings sit in native.ios, native.android and native.desktop, and a target overrides them under native.targets.<name>.`);
|
|
908
|
+
this.hasNativeConfig = Boolean(config.native);
|
|
909
|
+
this.native = this.#resolveNativeConfig(config.native);
|
|
917
910
|
this.web = this.#resolveWebConfig(config.web);
|
|
918
911
|
this.docker = AkanAppConfig.#resolveDocker(config.docker, libContributions.docker);
|
|
919
912
|
this.dockerfile = this.#makeDockerfile();
|
|
920
913
|
}
|
|
921
914
|
#resolveWebConfig(web) {
|
|
922
915
|
const resolved = typeof web === "object" ? { ssr: true, csr: web.csr } : { ssr: web ?? true, csr: web ?? true };
|
|
923
|
-
if (!resolved.csr && this.
|
|
924
|
-
throw new Error(`apps/${this.app.name}/akan.config.ts turns the CSR bundle off but declares
|
|
916
|
+
if (!resolved.csr && this.hasNativeConfig)
|
|
917
|
+
throw new Error(`apps/${this.app.name}/akan.config.ts turns the CSR bundle off but declares a native section; the native apps ship that bundle. Drop the native section or leave CSR on.`);
|
|
925
918
|
return resolved;
|
|
926
919
|
}
|
|
927
|
-
#
|
|
928
|
-
const {
|
|
929
|
-
targets: rawTargets,
|
|
930
|
-
indexPath: _indexPath,
|
|
931
|
-
...rawMobile
|
|
932
|
-
} = mobile ?? {};
|
|
920
|
+
#resolveNativeConfig(native) {
|
|
933
921
|
const configPath = `apps/${this.app.name}/akan.config.ts`;
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
const
|
|
938
|
-
const
|
|
939
|
-
const
|
|
940
|
-
const
|
|
941
|
-
const
|
|
942
|
-
const
|
|
943
|
-
const
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
const
|
|
948
|
-
const
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
const
|
|
922
|
+
const { targets: rawTargets, ...root } = native ?? {};
|
|
923
|
+
AkanAppConfig.#assertNativeKeys(root, "native", configPath);
|
|
924
|
+
AkanAppConfig.#assertFiles(root, "native", configPath);
|
|
925
|
+
const appName = root.appName ?? this.app.name;
|
|
926
|
+
const appId = root.appId ?? deriveDefaultAppId(this.baseDevEnv.repoName, this.app.name);
|
|
927
|
+
const version = root.version ?? "0.0.1";
|
|
928
|
+
const buildNum = root.buildNum ?? 1;
|
|
929
|
+
const named = rawTargets !== undefined && Object.keys(rawTargets).length > 0;
|
|
930
|
+
const entries = named ? Object.entries(rawTargets) : [[this.basePaths.has(this.app.name) ? this.app.name : "default", {}]];
|
|
931
|
+
const targets = Object.fromEntries(entries.map(([name, own]) => {
|
|
932
|
+
const where = named ? `native.targets.${name}` : "native";
|
|
933
|
+
AkanAppConfig.#assertNativeKeys(own ?? {}, where, configPath);
|
|
934
|
+
const merged = AkanAppConfig.#overlay(root, own ?? {});
|
|
935
|
+
const fallbackBasePath = !named && this.basePaths.has(name) ? name : undefined;
|
|
936
|
+
const basePath = (merged.basePath ?? fallbackBasePath)?.replace(/^\/+|\/+$/g, "") || undefined;
|
|
937
|
+
if (basePath && !this.basePaths.has(basePath))
|
|
938
|
+
throw new Error(`Native target '${name}' uses unknown basePath '${basePath}' in ${configPath}`);
|
|
939
|
+
const { updates } = merged;
|
|
940
|
+
if (updates && (!updates.url || !updates.publicKey))
|
|
941
|
+
throw new Error(`${where}.updates in ${configPath} has no url or publicKey${named ? "; give them in native.updates or the target's own" : ""}.`);
|
|
942
|
+
AkanAppConfig.#assertFiles(own ?? {}, where, configPath);
|
|
943
|
+
const {
|
|
944
|
+
basePath: _basePath,
|
|
945
|
+
indexPath: rawIndexPath,
|
|
946
|
+
deepLinks: rawDeepLinks,
|
|
947
|
+
updates: _updates,
|
|
948
|
+
...rest
|
|
949
|
+
} = merged;
|
|
950
|
+
const indexPath = normalizeIndexPath(rawIndexPath);
|
|
951
|
+
const deepLinks = normalizeDeepLinks(rawDeepLinks);
|
|
952
|
+
const { teamId: rawTeamId, ...iosRest } = merged.ios ?? {};
|
|
953
|
+
const teamId = rawTeamId?.trim();
|
|
954
|
+
const { sha256CertFingerprints: rawFingerprints, ...androidRest } = merged.android ?? {};
|
|
955
|
+
const fingerprints = normalizeStringList(rawFingerprints);
|
|
956
|
+
const target = {
|
|
957
|
+
...rest,
|
|
963
958
|
name,
|
|
964
|
-
basePath,
|
|
965
|
-
indexPath,
|
|
966
|
-
deepLinks,
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
...
|
|
974
|
-
...files || targetFiles ? { files: { ...files, ...targetFiles } } : {},
|
|
975
|
-
...native || target.native ? { native: AkanAppConfig.#mergeNative(native, target.native) } : {},
|
|
976
|
-
...targetUpdates ? { updates: targetUpdates } : {}
|
|
959
|
+
...basePath ? { basePath } : {},
|
|
960
|
+
...indexPath ? { indexPath } : {},
|
|
961
|
+
...deepLinks ? { deepLinks } : {},
|
|
962
|
+
...merged.ios ? { ios: { ...iosRest, ...teamId ? { teamId } : {} } } : {},
|
|
963
|
+
...merged.android ? { android: { ...androidRest, ...fingerprints ? { sha256CertFingerprints: fingerprints } : {} } } : {},
|
|
964
|
+
appName: merged.appName ?? this.app.name,
|
|
965
|
+
appId: merged.appId ?? appId,
|
|
966
|
+
version: merged.version ?? version,
|
|
967
|
+
buildNum: merged.buildNum ?? buildNum,
|
|
968
|
+
...updates ? { updates } : {}
|
|
977
969
|
};
|
|
978
|
-
return [name,
|
|
970
|
+
return [name, target];
|
|
979
971
|
}));
|
|
980
|
-
return {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
static #targetKeys = [
|
|
994
|
-
"basePath",
|
|
995
|
-
"indexPath",
|
|
996
|
-
"appName",
|
|
997
|
-
"appId",
|
|
998
|
-
"fileName",
|
|
999
|
-
"version",
|
|
1000
|
-
"buildNum",
|
|
1001
|
-
"assets",
|
|
1002
|
-
"permissions",
|
|
1003
|
-
"deepLinks",
|
|
1004
|
-
"files",
|
|
1005
|
-
"native",
|
|
1006
|
-
"updates"
|
|
1007
|
-
];
|
|
1008
|
-
static #assertMobileKeys(section, known, where, configPath) {
|
|
1009
|
-
for (const key of Object.keys(section)) {
|
|
1010
|
-
if (known.includes(key))
|
|
1011
|
-
continue;
|
|
1012
|
-
if (key === "plugins" || key === "ios" || key === "android")
|
|
1013
|
-
throw new Error(`${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.`);
|
|
1014
|
-
throw new Error(`${where}.${key} in ${configPath} is not a mobile setting. Known: ${known.join(", ")}.`);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
static #fileTargetPattern = /^(?:ios\/.+|android\/res\/[^/]+\/[^/]+|android\/assets\/.+)$/;
|
|
1018
|
-
static #resolveMobileFiles(files, where, configPath) {
|
|
1019
|
-
if (!files)
|
|
1020
|
-
return;
|
|
1021
|
-
for (const [to, from] of Object.entries(files)) {
|
|
1022
|
-
if (typeof from !== "string")
|
|
1023
|
-
throw new Error(`${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.`);
|
|
1024
|
-
if (!AkanAppConfig.#fileTargetPattern.test(to))
|
|
1025
|
-
throw new Error(`${where}.files["${to}"] in ${configPath} must land under ios/<path>, android/res/<type>/<file> or android/assets/<path>.`);
|
|
1026
|
-
}
|
|
1027
|
-
return files;
|
|
1028
|
-
}
|
|
1029
|
-
static #mergeNative(base, override) {
|
|
1030
|
-
const plugins = [...new Set([...base?.plugins ?? [], ...override?.plugins ?? []])];
|
|
1031
|
-
const ios = { ...base?.ios, ...override?.ios };
|
|
1032
|
-
const android = {
|
|
1033
|
-
...base?.android,
|
|
1034
|
-
...override?.android
|
|
972
|
+
return { appName, appId, ...root.fileName ? { fileName: root.fileName } : {}, version, buildNum, targets };
|
|
973
|
+
}
|
|
974
|
+
static #overlay(base, own) {
|
|
975
|
+
const merge = (kept, value, top, key) => {
|
|
976
|
+
if (!AkanAppConfig.#isPlainObject(kept) || !AkanAppConfig.#isPlainObject(value))
|
|
977
|
+
return value;
|
|
978
|
+
if (top && (key === "icon" || key === "splash"))
|
|
979
|
+
return value;
|
|
980
|
+
const out = { ...kept };
|
|
981
|
+
for (const [inner, next] of Object.entries(value))
|
|
982
|
+
if (next !== undefined)
|
|
983
|
+
out[inner] = merge(out[inner], next, false, inner);
|
|
984
|
+
return out;
|
|
1035
985
|
};
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
if (
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
986
|
+
const out = { ...base };
|
|
987
|
+
for (const [key, value] of Object.entries(own))
|
|
988
|
+
if (value !== undefined)
|
|
989
|
+
out[key] = merge(out[key], value, true, key);
|
|
990
|
+
return out;
|
|
991
|
+
}
|
|
992
|
+
static #isPlainObject(value) {
|
|
993
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
994
|
+
}
|
|
995
|
+
static #nativeKeys = {
|
|
996
|
+
native: [
|
|
997
|
+
"basePath",
|
|
998
|
+
"indexPath",
|
|
999
|
+
"appName",
|
|
1000
|
+
"appId",
|
|
1001
|
+
"fileName",
|
|
1002
|
+
"version",
|
|
1003
|
+
"buildNum",
|
|
1004
|
+
"icon",
|
|
1005
|
+
"splash",
|
|
1006
|
+
"permissions",
|
|
1007
|
+
"plugins",
|
|
1008
|
+
"deepLinks",
|
|
1009
|
+
"updates",
|
|
1010
|
+
"ios",
|
|
1011
|
+
"android",
|
|
1012
|
+
"desktop"
|
|
1013
|
+
],
|
|
1014
|
+
ios: ["teamId", "infoPlist", "entitlements", "privacy", "files"],
|
|
1015
|
+
android: [
|
|
1016
|
+
"sha256CertFingerprints",
|
|
1017
|
+
"googleServices",
|
|
1018
|
+
"push",
|
|
1019
|
+
"autoplay",
|
|
1020
|
+
"manifest",
|
|
1021
|
+
"application",
|
|
1022
|
+
"activity",
|
|
1023
|
+
"files"
|
|
1024
|
+
],
|
|
1025
|
+
desktop: ["server", "recovery", "window", "screenCapture"],
|
|
1026
|
+
deepLinks: ["schemes", "domains"]
|
|
1027
|
+
};
|
|
1028
|
+
static #movedKeys = {
|
|
1029
|
+
native: "the platform sections and plugins sit directly in the native section: ios, android, desktop, plugins",
|
|
1030
|
+
assets: "icon and splash sit directly in the native section",
|
|
1031
|
+
files: "ios.files (keyed by the path in the app bundle) or android.files (keyed res/<type>/<file> or assets/<path>)",
|
|
1032
|
+
push: "android.push",
|
|
1033
|
+
privacy: "ios.privacy",
|
|
1034
|
+
"deepLinks.ios": "ios.teamId",
|
|
1035
|
+
"deepLinks.android": "android.sha256CertFingerprints"
|
|
1036
|
+
};
|
|
1037
|
+
static #assertNativeKeys(section, where, configPath) {
|
|
1038
|
+
const check = (value, known, at, kind) => {
|
|
1039
|
+
if (!AkanAppConfig.#isPlainObject(value))
|
|
1040
|
+
return;
|
|
1041
|
+
for (const key of Object.keys(value)) {
|
|
1042
|
+
if (known.includes(key))
|
|
1043
|
+
continue;
|
|
1044
|
+
const moved = AkanAppConfig.#movedKeys[kind === "native" ? key : `${kind}.${key}`];
|
|
1045
|
+
throw new Error(moved ? `${at}.${key} in ${configPath} has moved: ${moved}.` : `${at}.${key} in ${configPath} is not a native setting. Known: ${known.join(", ")}.`);
|
|
1046
|
+
}
|
|
1050
1047
|
};
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1048
|
+
check(section, AkanAppConfig.#nativeKeys.native, where, "native");
|
|
1049
|
+
const settings = section;
|
|
1050
|
+
check(settings.ios, AkanAppConfig.#nativeKeys.ios, `${where}.ios`, "ios");
|
|
1051
|
+
check(settings.android, AkanAppConfig.#nativeKeys.android, `${where}.android`, "android");
|
|
1052
|
+
check(settings.desktop, AkanAppConfig.#nativeKeys.desktop, `${where}.desktop`, "desktop");
|
|
1053
|
+
check(settings.deepLinks, AkanAppConfig.#nativeKeys.deepLinks, `${where}.deepLinks`, "deepLinks");
|
|
1054
|
+
}
|
|
1055
|
+
static #androidFilePattern = /^(?:res\/[^/]+\/[^/]+|assets\/.+)$/;
|
|
1056
|
+
static #assertFiles(settings, where, configPath) {
|
|
1057
|
+
const check = (files, at, valid, shape) => {
|
|
1058
|
+
for (const [to, from] of Object.entries(files ?? {})) {
|
|
1059
|
+
if (typeof from !== "string")
|
|
1060
|
+
throw new Error(`${at}["${to}"] in ${configPath} must name its source file, relative to the app folder, e.g. { "${shape}": "assets/chime.mp3" }.`);
|
|
1061
|
+
if (!valid(to))
|
|
1062
|
+
throw new Error(`${at}["${to}"] in ${configPath} must land at ${shape}.`);
|
|
1063
|
+
}
|
|
1058
1064
|
};
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
if (rawTargets && Object.keys(rawTargets).length > 0)
|
|
1062
|
-
return Object.keys(rawTargets)[0];
|
|
1063
|
-
return this.basePaths.has(this.app.name) ? this.app.name : "default";
|
|
1065
|
+
check(settings.ios?.files, `${where}.ios.files`, (to) => to.length > 0 && !to.startsWith("/") && !to.split("/").includes(".."), "<path in the app bundle>");
|
|
1066
|
+
check(settings.android?.files, `${where}.android.files`, (to) => AkanAppConfig.#androidFilePattern.test(to), "res/<type>/<file> or assets/<path>");
|
|
1064
1067
|
}
|
|
1065
1068
|
#applyRoutes(routes = []) {
|
|
1066
1069
|
for (const route of routes) {
|
|
@@ -1318,7 +1321,7 @@ class AkanLibConfig {
|
|
|
1318
1321
|
}
|
|
1319
1322
|
//! need to refactor
|
|
1320
1323
|
var shiftBuildNum = async (app, delta) => {
|
|
1321
|
-
const { buildNum } = (await AkanAppConfig.from(app)).
|
|
1324
|
+
const { buildNum } = (await AkanAppConfig.from(app)).native;
|
|
1322
1325
|
const akanConfigPath = path5.join(app.cwdPath, "akan.config.ts");
|
|
1323
1326
|
const akanConfig = fs2.readFileSync(akanConfigPath, "utf8");
|
|
1324
1327
|
fs2.writeFileSync(akanConfigPath, akanConfig.replace(`buildNum: ${buildNum}`, `buildNum: ${buildNum + delta}`));
|
|
@@ -1759,7 +1762,7 @@ var retiredAppRootEntries = new Set([
|
|
|
1759
1762
|
"capacitor.config.js",
|
|
1760
1763
|
"capacitor.config.json"
|
|
1761
1764
|
]);
|
|
1762
|
-
var rootEntryHintOf = (type, name) => type === "app" && retiredAppRootEntries.has(name) ? "a Capacitor-era entry; the native runtime generates its projects under .akan/
|
|
1765
|
+
var rootEntryHintOf = (type, name) => type === "app" && retiredAppRootEntries.has(name) ? "a Capacitor-era entry; the native runtime generates its projects under .akan/native/<target>, so delete it" : null;
|
|
1763
1766
|
var isScannedRootEntry = (type, name) => !name.startsWith(".") || rootAllowedDirs[type].has(name);
|
|
1764
1767
|
|
|
1765
1768
|
// pkgs/@akanjs/devkit/scanInfo.ts
|
|
@@ -3027,7 +3030,7 @@ class AppExecutor extends SysExecutor {
|
|
|
3027
3030
|
static from(executor, name) {
|
|
3028
3031
|
return new AppExecutor({ workspace: executor instanceof WorkspaceExecutor ? executor : executor.workspace, name });
|
|
3029
3032
|
}
|
|
3030
|
-
static #keptOnStart = [path9.join(".akan", "
|
|
3033
|
+
static #keptOnStart = [path9.join(".akan", "native"), path9.join(".akan", "cache", "bin")];
|
|
3031
3034
|
async#removeDevOutput(dir = ".akan") {
|
|
3032
3035
|
const entries = await readDirEntries(this.getPath(dir)).catch(() => []);
|
|
3033
3036
|
await Promise.all(entries.map(async (name) => {
|
|
@@ -5,19 +5,19 @@ import {
|
|
|
5
5
|
} from "./index-94s080qm.js";
|
|
6
6
|
import {
|
|
7
7
|
script
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-xb7qhxa8.js";
|
|
9
9
|
import {
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-n3jk2501.js";
|
|
12
12
|
import {
|
|
13
13
|
ApplicationScript
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-3rh7thcx.js";
|
|
15
15
|
import {
|
|
16
16
|
PackageScript
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-a4s954kq.js";
|
|
18
18
|
import {
|
|
19
19
|
CloudRunner
|
|
20
|
-
} from "./index-
|
|
20
|
+
} from "./index-5rp0h6na.js";
|
|
21
21
|
|
|
22
22
|
// pkgs/@akanjs/cli/cloud/cloud.script.ts
|
|
23
23
|
import { Logger } from "akanjs/common";
|