akanjs 2.0.0-beta.0 → 2.0.0-beta.10
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/cli/application/application.command.ts +11 -3
- package/cli/guidelines/databaseModule/databaseModule.instruction.md +1 -1
- package/cli/guidelines/modelConstant/modelConstant.instruction.md +5 -5
- package/cli/guidelines/modelDocument/modelDocument.instruction.md +34 -61
- package/cli/guidelines/modelService/modelService.instruction.md +1 -1
- package/cli/index.js +160 -63
- package/cli/package/package.runner.ts +24 -7
- package/cli/package/package.script.ts +2 -2
- package/cli/templates/app/page/_index.tsx +200 -76
- package/cli/templates/app/page/_layout.tsx +0 -1
- package/cli/templates/module/__Model__.Zone.tsx +1 -1
- package/cli/templates/module/__model__.document.ts +1 -1
- package/cli/templates/workspaceRoot/.gitignore.template +1 -11
- package/cli/templates/workspaceRoot/biome.json.template +16 -0
- package/cli/workspace/workspace.command.ts +2 -7
- package/cli/workspace/workspace.runner.ts +1 -7
- package/cli/workspace/workspace.script.ts +14 -8
- package/client/csrTypes.ts +1 -1
- package/constant/fieldInfo.ts +1 -1
- package/devkit/capacitor.base.config.ts +1 -1
- package/devkit/capacitorApp.ts +5 -1
- package/devkit/commandDecorators/argMeta.ts +28 -14
- package/devkit/commandDecorators/command.ts +41 -15
- package/devkit/commandDecorators/commandBuilder.ts +78 -42
- package/devkit/commandDecorators/helpFormatter.ts +7 -4
- package/devkit/executors.ts +2 -3
- package/devkit/frontendBuild/cssCompiler.ts +9 -3
- package/devkit/incrementalBuilder/incrementalBuilder.proc.ts +2 -1
- package/devkit/lint/no-deep-internal-import.grit +25 -0
- package/devkit/mobile/mobileTarget.ts +48 -8
- package/devkit/src/capacitorApp.ts +277 -0
- package/devkit/transforms/barrelImportsPlugin.ts +6 -0
- package/package.json +3 -1
- package/server/hmr/clientScript.ts +8 -5
- package/server/resolver/resolver.contract.fixture.ts +1 -1
- package/ui/Field.tsx +0 -1
- package/ui/Portal.tsx +2 -0
- package/ui/System/CSR.tsx +6 -5
- package/ui/System/SSR.tsx +1 -1
- package/ui/System/SelectLanguage.tsx +1 -1
- package/webkit/bootCsr.tsx +8 -5
- package/cli/templates/app/common/commonLogic.ts +0 -12
- package/cli/templates/app/common/index.ts +0 -10
- package/cli/templates/app/srvkit/backendLogic.ts +0 -12
- package/cli/templates/app/srvkit/index.ts +0 -10
- package/cli/templates/app/ui/UiComponent.ts +0 -16
- package/cli/templates/app/ui/index.ts +0 -10
- package/cli/templates/app/webkit/frontendLogic.ts +0 -12
- package/cli/templates/app/webkit/index.ts +0 -10
- package/cli/templates/module/index.tsx +0 -44
- /package/cli/templates/app/public/{favicon.ico → favicon.ico.template} +0 -0
- /package/cli/templates/app/public/{logo.png → logo.png.template} +0 -0
package/cli/index.js
CHANGED
|
@@ -867,7 +867,9 @@ import {
|
|
|
867
867
|
import { readFileSync as readFileSync3 } from "fs";
|
|
868
868
|
import { mkdir as mkdir2, readdir as readDirEntries, stat as stat2 } from "fs/promises";
|
|
869
869
|
import path7 from "path";
|
|
870
|
+
var {$ } = globalThis.Bun;
|
|
870
871
|
import chalk4 from "chalk";
|
|
872
|
+
import ts3 from "typescript";
|
|
871
873
|
|
|
872
874
|
import fs from "fs";
|
|
873
875
|
import path from "path";
|
|
@@ -1163,9 +1165,6 @@ var decreaseBuildNum = async (app) => {
|
|
|
1163
1165
|
fs.writeFileSync(akanConfigPath, akanConfigContent);
|
|
1164
1166
|
};
|
|
1165
1167
|
|
|
1166
|
-
var {$ } = globalThis.Bun;
|
|
1167
|
-
import ts3 from "typescript";
|
|
1168
|
-
|
|
1169
1168
|
import path2 from "path";
|
|
1170
1169
|
var getDirname = (url) => path2.dirname(new URL(url).pathname);
|
|
1171
1170
|
|
|
@@ -4817,6 +4816,9 @@ var rewriteSingleStatement = (stmt, map) => {
|
|
|
4817
4816
|
return null;
|
|
4818
4817
|
const lines = [];
|
|
4819
4818
|
const tail = ";";
|
|
4819
|
+
if (shouldPreserveBarrelSideEffects(stmt.specifier)) {
|
|
4820
|
+
lines.push(`import "${stmt.specifier}"${tail}`);
|
|
4821
|
+
}
|
|
4820
4822
|
if (clause.defaultImport || remaining.length > 0) {
|
|
4821
4823
|
const parts = [];
|
|
4822
4824
|
if (clause.defaultImport)
|
|
@@ -4832,6 +4834,7 @@ var rewriteSingleStatement = (stmt, map) => {
|
|
|
4832
4834
|
return lines.join(`
|
|
4833
4835
|
`);
|
|
4834
4836
|
};
|
|
4837
|
+
var shouldPreserveBarrelSideEffects = (specifier) => /^@(apps|libs)\/[^/]+\/client$/.test(specifier);
|
|
4835
4838
|
var serializeNamedItem = (item) => {
|
|
4836
4839
|
const prefix = item.isType ? "type " : "";
|
|
4837
4840
|
if (item.imported === item.local)
|
|
@@ -6049,6 +6052,8 @@ class CssImportResolver {
|
|
|
6049
6052
|
|
|
6050
6053
|
var SOURCE_EXTS3 = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
6051
6054
|
var NON_SOURCE_EXT_RE3 = /\.(json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav)$/i;
|
|
6055
|
+
var NODE_MODULES_RE3 = /[\\/]node_modules[\\/]/;
|
|
6056
|
+
var AKANJS_NODE_MODULE_RE3 = /[\\/]node_modules[\\/]akanjs[\\/]/;
|
|
6052
6057
|
|
|
6053
6058
|
class CssCompiler {
|
|
6054
6059
|
#logger = new Logger("CssCompiler");
|
|
@@ -6116,7 +6121,7 @@ class CssCompiler {
|
|
|
6116
6121
|
const akanConfig2 = await this.#app.getConfig({ refresh });
|
|
6117
6122
|
while (queue.length > 0) {
|
|
6118
6123
|
const filePath = queue.shift();
|
|
6119
|
-
if (!filePath || sourceFiles.has(filePath) || filePath
|
|
6124
|
+
if (!filePath || sourceFiles.has(filePath) || isIgnoredNodeModuleSource(filePath))
|
|
6120
6125
|
continue;
|
|
6121
6126
|
sourceFiles.add(filePath);
|
|
6122
6127
|
let content;
|
|
@@ -6152,7 +6157,7 @@ class CssCompiler {
|
|
|
6152
6157
|
if (NON_SOURCE_EXT_RE3.test(spec))
|
|
6153
6158
|
continue;
|
|
6154
6159
|
const resolved = await this.#resolveSourceImport(spec, importerDir, resolvePackage);
|
|
6155
|
-
if (!resolved || sourceFiles.has(resolved) || resolved
|
|
6160
|
+
if (!resolved || sourceFiles.has(resolved) || isIgnoredNodeModuleSource(resolved))
|
|
6156
6161
|
continue;
|
|
6157
6162
|
queue.push(resolved);
|
|
6158
6163
|
}
|
|
@@ -6240,7 +6245,7 @@ class CssCompiler {
|
|
|
6240
6245
|
const files = new Set(sourcePaths);
|
|
6241
6246
|
await Promise.all(dirs.map(async (dir) => {
|
|
6242
6247
|
for await (const file of glob.scan({ cwd: dir, absolute: true })) {
|
|
6243
|
-
if (file
|
|
6248
|
+
if (isIgnoredNodeModuleSource(file))
|
|
6244
6249
|
continue;
|
|
6245
6250
|
files.add(file);
|
|
6246
6251
|
}
|
|
@@ -6287,6 +6292,9 @@ function resolveSourceWithRequire(id, fromBase) {
|
|
|
6287
6292
|
function isSourceFile(filePath) {
|
|
6288
6293
|
return SOURCE_EXTS3.includes(path23.extname(filePath));
|
|
6289
6294
|
}
|
|
6295
|
+
function isIgnoredNodeModuleSource(filePath) {
|
|
6296
|
+
return NODE_MODULES_RE3.test(filePath) && !AKANJS_NODE_MODULE_RE3.test(filePath);
|
|
6297
|
+
}
|
|
6290
6298
|
function getPageKeyBasePath(pageKey, basePaths) {
|
|
6291
6299
|
const normalized = pageKey.split(path23.sep).join("/").replace(/^\.\//, "");
|
|
6292
6300
|
const segments = normalized.split("/");
|
|
@@ -7904,21 +7912,65 @@ var getMobileTargets = async (app) => {
|
|
|
7904
7912
|
const config = await app.getConfig();
|
|
7905
7913
|
return Object.entries(config.mobile.targets).map(([name, target]) => ({ name, config: target }));
|
|
7906
7914
|
};
|
|
7915
|
+
var getMobileTargetChoices = async (app) => {
|
|
7916
|
+
const config = await app.getConfig();
|
|
7917
|
+
const targetNames = Object.keys(config.mobile.targets);
|
|
7918
|
+
if (targetNames.length > 1)
|
|
7919
|
+
return targetNames;
|
|
7920
|
+
const basePaths = [...config.basePaths];
|
|
7921
|
+
if (basePaths.length > 1)
|
|
7922
|
+
return basePaths;
|
|
7923
|
+
if (targetNames.length > 0)
|
|
7924
|
+
return targetNames;
|
|
7925
|
+
return basePaths;
|
|
7926
|
+
};
|
|
7927
|
+
var resolveMobileTargetByBasePath = (targets, basePath2) => {
|
|
7928
|
+
const normalizedBasePath = basePath2.replace(/^\/+|\/+$/g, "");
|
|
7929
|
+
const byBasePath = targets.find((target) => target.config.basePath?.replace(/^\/+|\/+$/g, "") === normalizedBasePath);
|
|
7930
|
+
if (byBasePath)
|
|
7931
|
+
return byBasePath;
|
|
7932
|
+
const [template] = targets;
|
|
7933
|
+
if (!template)
|
|
7934
|
+
return;
|
|
7935
|
+
return {
|
|
7936
|
+
name: template.name,
|
|
7937
|
+
config: {
|
|
7938
|
+
...template.config,
|
|
7939
|
+
basePath: normalizedBasePath
|
|
7940
|
+
}
|
|
7941
|
+
};
|
|
7942
|
+
};
|
|
7907
7943
|
var resolveMobileTargets = async (app, selection) => {
|
|
7944
|
+
const config = await app.getConfig();
|
|
7908
7945
|
const targets = await getMobileTargets(app);
|
|
7909
7946
|
if (targets.length === 0)
|
|
7910
7947
|
throw new Error(`No mobile targets configured for ${app.name}`);
|
|
7911
7948
|
if (!selection) {
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7949
|
+
const choices2 = await getMobileTargetChoices(app);
|
|
7950
|
+
if (choices2.length === 1)
|
|
7951
|
+
return resolveMobileTargets(app, choices2[0]);
|
|
7952
|
+
throw new Error(`Multiple mobile targets found for ${app.name}. Pass --target <${choices2.join("|")}|all>.`);
|
|
7915
7953
|
}
|
|
7916
|
-
if (selection === "all")
|
|
7954
|
+
if (selection === "all") {
|
|
7955
|
+
if (Object.keys(config.mobile.targets).length > 1)
|
|
7956
|
+
return targets;
|
|
7957
|
+
const basePaths = [...config.basePaths];
|
|
7958
|
+
if (basePaths.length > 1) {
|
|
7959
|
+
return basePaths.flatMap((basePath2) => {
|
|
7960
|
+
const resolved = resolveMobileTargetByBasePath(targets, basePath2);
|
|
7961
|
+
return resolved ? [resolved] : [];
|
|
7962
|
+
});
|
|
7963
|
+
}
|
|
7917
7964
|
return targets;
|
|
7965
|
+
}
|
|
7918
7966
|
const target = targets.find((candidate) => candidate.name === selection);
|
|
7919
|
-
if (
|
|
7920
|
-
|
|
7921
|
-
|
|
7967
|
+
if (target)
|
|
7968
|
+
return [target];
|
|
7969
|
+
const basePathTarget = resolveMobileTargetByBasePath(targets, selection);
|
|
7970
|
+
if (basePathTarget && config.basePaths.has(selection.replace(/^\/+|\/+$/g, "")))
|
|
7971
|
+
return [basePathTarget];
|
|
7972
|
+
const choices = await getMobileTargetChoices(app);
|
|
7973
|
+
throw new Error(`Mobile target '${selection}' was not found. Available: ${choices.join(", ")}`);
|
|
7922
7974
|
};
|
|
7923
7975
|
var resolveMobilePath = (target, pathname) => {
|
|
7924
7976
|
const basePath2 = target.basePath?.replace(/^\/+|\/+$/g, "");
|
|
@@ -8115,7 +8167,8 @@ class CapacitorApp {
|
|
|
8115
8167
|
async#writeCapacitorConfig() {
|
|
8116
8168
|
await mkdir10(this.targetRoot, { recursive: true });
|
|
8117
8169
|
const appInfoPath = path34.relative(this.targetRoot, path34.join(this.app.cwdPath, "akan.app.json")).split(path34.sep).join("/");
|
|
8118
|
-
const
|
|
8170
|
+
const baseConfigPath = path34.relative(this.targetRoot, path34.join(this.app.workspace.cwdPath, "pkgs/akanjs/devkit/capacitor.base.config")).split(path34.sep).join("/");
|
|
8171
|
+
const content = `import { withBase } from "${baseConfigPath.startsWith(".") ? baseConfigPath : `./${baseConfigPath}`}";
|
|
8119
8172
|
import appInfo from "${appInfoPath}";
|
|
8120
8173
|
|
|
8121
8174
|
export default withBase((config) => config, appInfo, "${this.target.name}");
|
|
@@ -8565,7 +8618,7 @@ var formatCommandHelp = (command, key) => {
|
|
|
8565
8618
|
const optName = `${flag}--${kebabName}`;
|
|
8566
8619
|
const optDesc = opt.desc ?? "";
|
|
8567
8620
|
const defaultVal = opt.default !== undefined ? chalk5.gray(` [default: ${String(opt.default)}]`) : "";
|
|
8568
|
-
const choices = opt.enum ? chalk5.gray(` (${opt.enum.map(formatChoice).join(", ")})`) : "";
|
|
8621
|
+
const choices = opt.enum ? chalk5.gray(typeof opt.enum === "function" ? " ([dynamic choices])" : ` (${opt.enum.map(formatChoice).join(", ")})`) : "";
|
|
8569
8622
|
lines.push(` ${chalk5.green(optName)} ${chalk5.gray(optDesc)}${defaultVal}${choices}`);
|
|
8570
8623
|
}
|
|
8571
8624
|
lines.push("");
|
|
@@ -8585,7 +8638,7 @@ var handleOption = (programCommand, argMeta) => {
|
|
|
8585
8638
|
ask
|
|
8586
8639
|
} = argMeta.argsOption;
|
|
8587
8640
|
const kebabName = camelToKebabCase2(argMeta.name);
|
|
8588
|
-
const choices = enumChoices
|
|
8641
|
+
const choices = enumChoices && typeof enumChoices !== "function" ? normalizeEnumChoices(enumChoices) : null;
|
|
8589
8642
|
programCommand.option(`-${flag}, --${kebabName}${type === "boolean" ? " [boolean]" : ` <${kebabName}>`}`, `${desc}${ask ? ` (${ask})` : ""}${example ? ` (example: ${example})` : ""}${choices ? ` (choices: ${choices.map((choice) => choice.name).join(", ")})` : ""}`);
|
|
8590
8643
|
return programCommand;
|
|
8591
8644
|
};
|
|
@@ -8602,7 +8655,16 @@ var convertArgValue = (value, type) => {
|
|
|
8602
8655
|
else
|
|
8603
8656
|
return value === true || value === "true";
|
|
8604
8657
|
};
|
|
8605
|
-
var
|
|
8658
|
+
var normalizeEnumChoices = (enumChoices) => enumChoices.map((choice) => typeof choice === "object" ? { value: choice.value, name: choice.label } : { value: choice, name: choice.toString() });
|
|
8659
|
+
var resolveEnumChoices = async (argMeta, context) => {
|
|
8660
|
+
const enumChoices = argMeta.argsOption.enum;
|
|
8661
|
+
if (!enumChoices)
|
|
8662
|
+
return null;
|
|
8663
|
+
if (typeof enumChoices === "function")
|
|
8664
|
+
return await enumChoices(context);
|
|
8665
|
+
return enumChoices;
|
|
8666
|
+
};
|
|
8667
|
+
var getOptionValue = async (argMeta, opt, context) => {
|
|
8606
8668
|
const {
|
|
8607
8669
|
name,
|
|
8608
8670
|
argsOption: { enum: enumChoices, default: defaultValue, type, desc, nullable, example, ask }
|
|
@@ -8611,13 +8673,13 @@ var getOptionValue = async (argMeta, opt) => {
|
|
|
8611
8673
|
return convertArgValue(opt[argMeta.name], type ?? "string");
|
|
8612
8674
|
else if (defaultValue !== undefined)
|
|
8613
8675
|
return defaultValue;
|
|
8614
|
-
else if (nullable)
|
|
8615
|
-
return null;
|
|
8616
8676
|
if (enumChoices) {
|
|
8617
|
-
const choices =
|
|
8677
|
+
const choices = normalizeEnumChoices(await resolveEnumChoices(argMeta, context) ?? []);
|
|
8618
8678
|
const choice = await select2({ message: ask ?? desc ?? `Select the ${name} value`, choices });
|
|
8619
8679
|
return choice;
|
|
8620
|
-
} else if (
|
|
8680
|
+
} else if (nullable)
|
|
8681
|
+
return null;
|
|
8682
|
+
else if (type === "boolean") {
|
|
8621
8683
|
const message = ask ?? desc ?? `Do you want to set ${name}? ${desc ? ` (${desc})` : ""}: `;
|
|
8622
8684
|
return await confirm({ message });
|
|
8623
8685
|
} else {
|
|
@@ -8642,6 +8704,22 @@ var getArgumentValue = async (argMeta, value) => {
|
|
|
8642
8704
|
const message = ask ? `${ask}: ` : desc ? `${desc}: ` : `Enter the ${name} value${example ? ` (example: ${example})` : ""}: `;
|
|
8643
8705
|
return convertArgValue(await input2({ message }), type ?? "string");
|
|
8644
8706
|
};
|
|
8707
|
+
var assignCommandContext = (context, argMeta, value) => {
|
|
8708
|
+
if (value instanceof AppExecutor)
|
|
8709
|
+
context.app = value;
|
|
8710
|
+
else if (value instanceof LibExecutor)
|
|
8711
|
+
context.lib = value;
|
|
8712
|
+
else if (value instanceof PkgExecutor)
|
|
8713
|
+
context.pkg = value;
|
|
8714
|
+
else if (value instanceof ModuleExecutor)
|
|
8715
|
+
context.module = value;
|
|
8716
|
+
else if (value instanceof Executor)
|
|
8717
|
+
context.exec = value;
|
|
8718
|
+
if (argMeta.type === "Argument" || argMeta.type === "Option")
|
|
8719
|
+
context.values[argMeta.name] = value;
|
|
8720
|
+
else
|
|
8721
|
+
context.values[argMeta.type.toLowerCase()] = value;
|
|
8722
|
+
};
|
|
8645
8723
|
var assertCurrentDirectoryIsWorkspaceRoot = async () => {
|
|
8646
8724
|
const cwd = process.cwd();
|
|
8647
8725
|
const [hasPackageJson, hasTsConfig, hasEnv] = await Promise.all([
|
|
@@ -8817,15 +8895,17 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
|
|
|
8817
8895
|
if (targetMeta.targetOption.runsOnWorkspaceRoot)
|
|
8818
8896
|
await assertCurrentDirectoryIsWorkspaceRoot();
|
|
8819
8897
|
const workspace = WorkspaceExecutor.fromRoot();
|
|
8898
|
+
const commandContext = { values: {} };
|
|
8820
8899
|
for (const argMeta of allArgMetas) {
|
|
8821
8900
|
if (argMeta.type === "Option")
|
|
8822
|
-
commandArgs[argMeta.idx] = await getOptionValue(argMeta, opt);
|
|
8901
|
+
commandArgs[argMeta.idx] = await getOptionValue(argMeta, opt, commandContext);
|
|
8823
8902
|
else if (argMeta.type === "Argument")
|
|
8824
8903
|
commandArgs[argMeta.idx] = await getArgumentValue(argMeta, cmdArgs[argMeta.idx]);
|
|
8825
8904
|
else
|
|
8826
8905
|
commandArgs[argMeta.idx] = await getInternalArgumentValue(argMeta, cmdArgs[argMeta.idx], workspace);
|
|
8827
8906
|
if (commandArgs[argMeta.idx] instanceof AppExecutor)
|
|
8828
8907
|
process.env.AKAN_PUBLIC_APP_NAME = commandArgs[argMeta.idx].name;
|
|
8908
|
+
assignCommandContext(commandContext, argMeta, commandArgs[argMeta.idx]);
|
|
8829
8909
|
if (opt.verbose)
|
|
8830
8910
|
Executor.setVerbose(true);
|
|
8831
8911
|
}
|
|
@@ -9847,14 +9927,22 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
|
|
|
9847
9927
|
test: target({ desc: "Prepare and test an app, library, or package" }).with(Exec).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(exec2, write) {
|
|
9848
9928
|
await this.applicationScript.test(exec2, { write });
|
|
9849
9929
|
}),
|
|
9850
|
-
buildIos: target({ short: true, desc: "Build iOS app with Capacitor" }).with(App).option("target", String, {
|
|
9930
|
+
buildIos: target({ short: true, desc: "Build iOS app with Capacitor" }).with(App).option("target", String, {
|
|
9931
|
+
desc: "mobile target name or all",
|
|
9932
|
+
ask: "Select mobile target",
|
|
9933
|
+
enum: async ({ app }) => await getMobileTargetChoices(app)
|
|
9934
|
+
}).option("env", String, {
|
|
9851
9935
|
enum: ["local", "debug", "develop", "main"],
|
|
9852
9936
|
desc: "backend environment",
|
|
9853
9937
|
default: "debug"
|
|
9854
9938
|
}).option("write", Boolean, { desc: "write code generation", default: true }).option("regenerate", Boolean, { flag: "g", desc: "delete and regenerate native project", default: false }).exec(async function(app, target2, env, write, regenerate) {
|
|
9855
9939
|
await this.applicationScript.buildIos(app, { target: target2, env: asMobileEnv(env), write, regenerate });
|
|
9856
9940
|
}),
|
|
9857
|
-
buildAndroid: target({ short: true, desc: "Build Android app with Capacitor" }).with(App).option("target", String, {
|
|
9941
|
+
buildAndroid: target({ short: true, desc: "Build Android app with Capacitor" }).with(App).option("target", String, {
|
|
9942
|
+
desc: "mobile target name or all",
|
|
9943
|
+
ask: "Select mobile target",
|
|
9944
|
+
enum: async ({ app }) => await getMobileTargetChoices(app)
|
|
9945
|
+
}).option("env", String, {
|
|
9858
9946
|
enum: ["local", "debug", "develop", "main"],
|
|
9859
9947
|
desc: "backend environment",
|
|
9860
9948
|
default: "debug"
|
|
@@ -9947,13 +10035,16 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
|
|
|
9947
10035
|
})) {
|
|
9948
10036
|
}
|
|
9949
10037
|
|
|
10038
|
+
import path36 from "path";
|
|
9950
10039
|
var {$: $2 } = globalThis.Bun;
|
|
9951
10040
|
|
|
9952
10041
|
class PackageRunner extends runner("package") {
|
|
9953
|
-
async version(workspace) {
|
|
9954
|
-
const pkgJson = await FileSys.readJson("package.json
|
|
10042
|
+
async version(workspace, { log = true } = {}) {
|
|
10043
|
+
const pkgJson = await FileSys.readJson(process.env.USE_AKANJS_PKGS === "true" ? `${workspace.workspaceRoot}/pkgs/akanjs/package.json` : `${path36.dirname(Bun.main)}/../package.json`);
|
|
9955
10044
|
const version = pkgJson.version;
|
|
9956
|
-
|
|
10045
|
+
if (log)
|
|
10046
|
+
Logger.rawLog(`${pkgJson.name}@${version}`);
|
|
10047
|
+
return version;
|
|
9957
10048
|
}
|
|
9958
10049
|
async createPackage(workspace, pkgName) {
|
|
9959
10050
|
await workspace.applyTemplate({ basePath: `pkgs/${pkgName}`, template: "pkgRoot", dict: { pkgName } });
|
|
@@ -9972,15 +10063,26 @@ class PackageRunner extends runner("package") {
|
|
|
9972
10063
|
await pkg.dist.mkdir(pkg.dist.cwdPath);
|
|
9973
10064
|
const scanner = await TypeScriptDependencyScanner.from(pkg);
|
|
9974
10065
|
const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
10066
|
+
const packageRuntimeDependencies = { akanjs: ["daisyui"] };
|
|
10067
|
+
const packageRuntimeDevDependencies = { akanjs: ["@biomejs/biome"] };
|
|
10068
|
+
const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
|
|
10069
|
+
const forcedRuntimeDevDeps = packageRuntimeDevDependencies[pkg.name] ?? [];
|
|
10070
|
+
const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])];
|
|
10071
|
+
const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])];
|
|
10072
|
+
const rootPackageJson = await pkg.workspace.getPackageJson();
|
|
10073
|
+
const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
|
|
10074
|
+
const missingForcedDeps = forcedRuntimeDeps.filter((dep) => !rootDeps[dep]);
|
|
10075
|
+
const missingForcedDevDeps = forcedRuntimeDevDeps.filter((dep) => !rootDeps[dep]);
|
|
10076
|
+
const allMissingDeps = [...new Set([...missingDeps, ...missingForcedDeps, ...missingForcedDevDeps])].sort();
|
|
10077
|
+
if (allMissingDeps.length > 0)
|
|
10078
|
+
throw new Error(`Missing dependency versions in root package.json: ${allMissingDeps.join(", ")}`);
|
|
10079
|
+
await pkg.updatePackageJsonDependencies(packageRuntimeDeps, packageRuntimeDevDeps);
|
|
9978
10080
|
const hasBuildFile = await Bun.file(`${pkg.cwdPath}/build.ts`).exists();
|
|
9979
10081
|
if (hasBuildFile) {
|
|
9980
10082
|
await pkg.workspace.spawn(process.execPath, [`${pkg.cwdPath}/build.ts`], { env: process.env, stdio: "inherit" });
|
|
9981
10083
|
} else {
|
|
9982
10084
|
await $2`cp -r ${pkg.cwdPath}/. ${pkg.dist.cwdPath}`;
|
|
9983
|
-
await Promise.all([pkg.generateDistPackageJson(
|
|
10085
|
+
await Promise.all([pkg.generateDistPackageJson(packageRuntimeDeps, packageRuntimeDevDeps), pkg.generateTsconfigJson()]);
|
|
9984
10086
|
}
|
|
9985
10087
|
}
|
|
9986
10088
|
async updateWorskpaceRootPackageJson(workspace, rootPackageJson) {
|
|
@@ -9997,8 +10099,8 @@ class PackageRunner extends runner("package") {
|
|
|
9997
10099
|
}
|
|
9998
10100
|
|
|
9999
10101
|
class PackageScript extends script("package", [PackageRunner]) {
|
|
10000
|
-
async version(workspace) {
|
|
10001
|
-
await this.packageRunner.version(workspace);
|
|
10102
|
+
async version(workspace, { log = true } = {}) {
|
|
10103
|
+
return await this.packageRunner.version(workspace, { log });
|
|
10002
10104
|
}
|
|
10003
10105
|
async createPackage(workspace, pkgName) {
|
|
10004
10106
|
const spinner2 = workspace.spinning(`Creating package in pkgs/${pkgName}...`);
|
|
@@ -10257,14 +10359,14 @@ class GuidelinePrompt extends Prompter {
|
|
|
10257
10359
|
async#getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
|
|
10258
10360
|
const glob = new Bun.Glob(matchPattern);
|
|
10259
10361
|
const paths = [];
|
|
10260
|
-
for await (const
|
|
10261
|
-
if (avoidDirs.some((dir) =>
|
|
10362
|
+
for await (const path37 of glob.scan({ cwd: this.workspace.workspaceRoot, absolute: true })) {
|
|
10363
|
+
if (avoidDirs.some((dir) => path37.includes(dir)))
|
|
10262
10364
|
continue;
|
|
10263
|
-
const fileContent = await FileSys.readText(
|
|
10365
|
+
const fileContent = await FileSys.readText(path37);
|
|
10264
10366
|
const textFilter = filterText ? new RegExp(filterText) : null;
|
|
10265
10367
|
if (filterText && !textFilter?.test(fileContent))
|
|
10266
10368
|
continue;
|
|
10267
|
-
paths.push(
|
|
10369
|
+
paths.push(path37);
|
|
10268
10370
|
}
|
|
10269
10371
|
return paths;
|
|
10270
10372
|
}
|
|
@@ -11250,18 +11352,13 @@ class ScalarCommand extends command("scalar", [ScalarScript], ({ public: target
|
|
|
11250
11352
|
})) {
|
|
11251
11353
|
}
|
|
11252
11354
|
|
|
11253
|
-
import
|
|
11254
|
-
|
|
11255
|
-
import path36 from "path";
|
|
11256
|
-
import latestVersion2 from "latest-version";
|
|
11355
|
+
import path38 from "path";
|
|
11257
11356
|
|
|
11357
|
+
import path37 from "path";
|
|
11258
11358
|
class WorkspaceRunner extends runner("workspace") {
|
|
11259
|
-
async
|
|
11260
|
-
return /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(tag) ? tag : await latestVersion2("akanjs", { version: tag });
|
|
11261
|
-
}
|
|
11262
|
-
async createWorkspace(repoName, appName, { dirname: dirname3 = ".", tag = "latest", init = true }) {
|
|
11359
|
+
async createWorkspace(repoName, appName, { dirname: dirname3 = ".", init = true, akanVersion }) {
|
|
11263
11360
|
const cwdPath = process.cwd();
|
|
11264
|
-
const workspaceRoot =
|
|
11361
|
+
const workspaceRoot = path37.join(cwdPath, dirname3, repoName);
|
|
11265
11362
|
const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
|
|
11266
11363
|
const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname3}/${repoName}...`);
|
|
11267
11364
|
await workspace.applyTemplate({
|
|
@@ -11271,7 +11368,6 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
11271
11368
|
});
|
|
11272
11369
|
templateSpinner.succeed(`Workspace files created in ${dirname3}/${repoName}`);
|
|
11273
11370
|
const rootPackageJson = await workspace.getPackageJson();
|
|
11274
|
-
const akanVersion = await this.#resolveAkanVersion(tag);
|
|
11275
11371
|
const packageJson = {
|
|
11276
11372
|
...rootPackageJson,
|
|
11277
11373
|
dependencies: {
|
|
@@ -11300,14 +11396,19 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
11300
11396
|
}
|
|
11301
11397
|
}
|
|
11302
11398
|
|
|
11303
|
-
class WorkspaceScript extends script("workspace", [
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
}) {
|
|
11310
|
-
const
|
|
11399
|
+
class WorkspaceScript extends script("workspace", [
|
|
11400
|
+
WorkspaceRunner,
|
|
11401
|
+
ApplicationScript,
|
|
11402
|
+
LibraryScript,
|
|
11403
|
+
PackageScript
|
|
11404
|
+
]) {
|
|
11405
|
+
async createWorkspace(repoName, appName, { dirname: dirname3 = ".", installLibs = false, init = true }) {
|
|
11406
|
+
const akanVersion = await this.packageScript.version({ log: false });
|
|
11407
|
+
const workspace = await this.workspaceRunner.createWorkspace(repoName, appName, {
|
|
11408
|
+
dirname: dirname3,
|
|
11409
|
+
init,
|
|
11410
|
+
akanVersion
|
|
11411
|
+
});
|
|
11311
11412
|
if (installLibs) {
|
|
11312
11413
|
await this.libraryScript.installLibrary(workspace, "util");
|
|
11313
11414
|
await this.libraryScript.installLibrary(workspace, "shared");
|
|
@@ -11320,7 +11421,7 @@ class WorkspaceScript extends script("workspace", [WorkspaceRunner, ApplicationS
|
|
|
11320
11421
|
} catch (_) {
|
|
11321
11422
|
gitSpinner.fail("Git repository initialization failed. It's not fatal, you can commit manually");
|
|
11322
11423
|
}
|
|
11323
|
-
const workspacePath =
|
|
11424
|
+
const workspacePath = path38.join(dirname3, repoName);
|
|
11324
11425
|
Logger.rawLog(`
|
|
11325
11426
|
\uD83C\uDF89 Welcome aboard! Workspace created in ${dirname3}/${repoName}`);
|
|
11326
11427
|
Logger.rawLog(`\uD83D\uDE80 Run \`cd ${workspacePath} && akan start ${appName}\` to start the development server.`);
|
|
@@ -11362,8 +11463,7 @@ class WorkspaceScript extends script("workspace", [WorkspaceRunner, ApplicationS
|
|
|
11362
11463
|
|
|
11363
11464
|
class WorkspaceCommand extends command("workspace", [WorkspaceScript], ({ public: target }) => ({
|
|
11364
11465
|
createWorkspace: target({ desc: "Create a new Akan.js workspace", runsOnWorkspaceRoot: false }).arg("workspaceName", String, { desc: "what is the name of your organization?" }).option("app", String, {
|
|
11365
|
-
desc: "what is the codename of your first application? (e.g. myapp)"
|
|
11366
|
-
default: "app"
|
|
11466
|
+
desc: "what is the codename of your first application? (e.g. myapp)"
|
|
11367
11467
|
}).option("dir", String, {
|
|
11368
11468
|
desc: "directory of workspace",
|
|
11369
11469
|
default: process.env.USE_AKANJS_PKGS === "true" ? "local" : "."
|
|
@@ -11376,15 +11476,12 @@ class WorkspaceCommand extends command("workspace", [WorkspaceScript], ({ public
|
|
|
11376
11476
|
value: true
|
|
11377
11477
|
}
|
|
11378
11478
|
]
|
|
11379
|
-
}).option("tag", String, {
|
|
11380
|
-
desc: "tag of the update",
|
|
11381
|
-
default: "latest"
|
|
11382
11479
|
}).option("init", Boolean, {
|
|
11383
11480
|
desc: "Do you want to initialize the workspace? (Recommended)",
|
|
11384
11481
|
default: true
|
|
11385
|
-
}).exec(async function(workspaceName, app, dir, libs,
|
|
11482
|
+
}).exec(async function(workspaceName, app, dir, libs, init) {
|
|
11386
11483
|
const appName = app || "app";
|
|
11387
|
-
await this.workspaceScript.createWorkspace(workspaceName.toLowerCase().replace(/ /g, "-"), appName.toLowerCase().replace(/ /g, "-"), { dirname: dir, installLibs: libs,
|
|
11484
|
+
await this.workspaceScript.createWorkspace(workspaceName.toLowerCase().replace(/ /g, "-"), appName.toLowerCase().replace(/ /g, "-"), { dirname: dir, installLibs: libs, init });
|
|
11388
11485
|
}),
|
|
11389
11486
|
lint: target({ desc: "Lint and fix code in a specific app/lib/pkg" }).with(Exec).option("fix", Boolean, { default: true }).with(Workspace).exec(async function(exec2, fix, workspace) {
|
|
11390
11487
|
await this.workspaceScript.lint(exec2, workspace, { fix });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import { Logger } from "akanjs/common";
|
|
2
3
|
import {
|
|
3
4
|
FileSys,
|
|
@@ -10,10 +11,15 @@ import {
|
|
|
10
11
|
import { $ } from "bun";
|
|
11
12
|
|
|
12
13
|
export class PackageRunner extends runner("package") {
|
|
13
|
-
async version(workspace: Workspace) {
|
|
14
|
-
const pkgJson = await FileSys.readJson<PackageJson>(
|
|
14
|
+
async version(workspace: Workspace, { log = true }: { log?: boolean } = {}) {
|
|
15
|
+
const pkgJson = await FileSys.readJson<PackageJson>(
|
|
16
|
+
process.env.USE_AKANJS_PKGS === "true"
|
|
17
|
+
? `${workspace.workspaceRoot}/pkgs/akanjs/package.json`
|
|
18
|
+
: `${path.dirname(Bun.main)}/../package.json`,
|
|
19
|
+
);
|
|
15
20
|
const version = pkgJson.version;
|
|
16
|
-
Logger.rawLog(`${pkgJson.name}@${version}`);
|
|
21
|
+
if (log) Logger.rawLog(`${pkgJson.name}@${version}`);
|
|
22
|
+
return version;
|
|
17
23
|
}
|
|
18
24
|
async createPackage(workspace: Workspace, pkgName: string) {
|
|
19
25
|
await workspace.applyTemplate({ basePath: `pkgs/${pkgName}`, template: "pkgRoot", dict: { pkgName } });
|
|
@@ -32,17 +38,28 @@ export class PackageRunner extends runner("package") {
|
|
|
32
38
|
await pkg.dist.mkdir(pkg.dist.cwdPath);
|
|
33
39
|
const scanner = await TypeScriptDependencyScanner.from(pkg);
|
|
34
40
|
const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
const packageRuntimeDependencies: Record<string, string[]> = { akanjs: ["daisyui"] };
|
|
42
|
+
const packageRuntimeDevDependencies: Record<string, string[]> = { akanjs: ["@biomejs/biome"] };
|
|
43
|
+
const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
|
|
44
|
+
const forcedRuntimeDevDeps = packageRuntimeDevDependencies[pkg.name] ?? [];
|
|
45
|
+
const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])];
|
|
46
|
+
const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])];
|
|
47
|
+
const rootPackageJson = await pkg.workspace.getPackageJson();
|
|
48
|
+
const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
|
|
49
|
+
const missingForcedDeps = forcedRuntimeDeps.filter((dep) => !rootDeps[dep]);
|
|
50
|
+
const missingForcedDevDeps = forcedRuntimeDevDeps.filter((dep) => !rootDeps[dep]);
|
|
51
|
+
const allMissingDeps = [...new Set([...missingDeps, ...missingForcedDeps, ...missingForcedDevDeps])].sort();
|
|
52
|
+
if (allMissingDeps.length > 0)
|
|
53
|
+
throw new Error(`Missing dependency versions in root package.json: ${allMissingDeps.join(", ")}`);
|
|
37
54
|
|
|
38
|
-
await pkg.updatePackageJsonDependencies(
|
|
55
|
+
await pkg.updatePackageJsonDependencies(packageRuntimeDeps, packageRuntimeDevDeps);
|
|
39
56
|
|
|
40
57
|
const hasBuildFile = await Bun.file(`${pkg.cwdPath}/build.ts`).exists();
|
|
41
58
|
if (hasBuildFile) {
|
|
42
59
|
await pkg.workspace.spawn(process.execPath, [`${pkg.cwdPath}/build.ts`], { env: process.env, stdio: "inherit" });
|
|
43
60
|
} else {
|
|
44
61
|
await $`cp -r ${pkg.cwdPath}/. ${pkg.dist.cwdPath}`;
|
|
45
|
-
await Promise.all([pkg.generateDistPackageJson(
|
|
62
|
+
await Promise.all([pkg.generateDistPackageJson(packageRuntimeDeps, packageRuntimeDevDeps), pkg.generateTsconfigJson()]);
|
|
46
63
|
}
|
|
47
64
|
}
|
|
48
65
|
|
|
@@ -3,8 +3,8 @@ import { type Pkg, script, type Workspace } from "akanjs/devkit";
|
|
|
3
3
|
import { PackageRunner } from "./package.runner";
|
|
4
4
|
|
|
5
5
|
export class PackageScript extends script("package", [PackageRunner]) {
|
|
6
|
-
async version(workspace: Workspace) {
|
|
7
|
-
await this.packageRunner.version(workspace);
|
|
6
|
+
async version(workspace: Workspace, { log = true }: { log?: boolean } = {}) {
|
|
7
|
+
return await this.packageRunner.version(workspace, { log });
|
|
8
8
|
}
|
|
9
9
|
async createPackage(workspace: Workspace, pkgName: string) {
|
|
10
10
|
const spinner = workspace.spinning(`Creating package in pkgs/${pkgName}...`);
|