@akanjs/cli 2.3.5 → 2.3.6-rc.1
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/incrementalBuilder.proc.js +814 -181
- package/index.js +787 -204
- package/package.json +2 -3
- package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +17 -0
- package/templates/workspaceRoot/.cursor/rules/akan-scan-conventions.mdc.template +19 -0
- package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +16 -0
- package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +12 -0
- package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +17 -0
- package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +24 -0
- package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +17 -0
- package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +12 -0
- package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +17 -0
- package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +14 -0
- package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +13 -0
- package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +14 -0
- package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +13 -0
- package/templates/workspaceRoot/AGENTS.md.template +12 -9
package/index.js
CHANGED
|
@@ -3938,6 +3938,36 @@ var createTunnel = async (service, { app, environment, port = service === "postg
|
|
|
3938
3938
|
return `localhost:${port}`;
|
|
3939
3939
|
};
|
|
3940
3940
|
|
|
3941
|
+
// pkgs/@akanjs/devkit/incrementalBuilder/devWatchBatch.ts
|
|
3942
|
+
var prepareDevWatchBatch = ({
|
|
3943
|
+
generation,
|
|
3944
|
+
batch,
|
|
3945
|
+
indexSync,
|
|
3946
|
+
changePlanner
|
|
3947
|
+
}) => {
|
|
3948
|
+
const files = [...new Set([...batch.files, ...indexSync.changedFiles])].sort();
|
|
3949
|
+
const kindSet = new Set(batch.kinds);
|
|
3950
|
+
if (indexSync.changedFiles.length > 0)
|
|
3951
|
+
kindSet.add("code");
|
|
3952
|
+
const kinds = [...kindSet];
|
|
3953
|
+
const expandedBatch = { files, kinds: kindSet };
|
|
3954
|
+
const devPlan = changePlanner.plan({
|
|
3955
|
+
generation,
|
|
3956
|
+
files,
|
|
3957
|
+
kinds,
|
|
3958
|
+
generatedFiles: indexSync.changedFiles
|
|
3959
|
+
});
|
|
3960
|
+
if (indexSync.errors.length > 0 && !devPlan.actions.includes("report-error")) {
|
|
3961
|
+
devPlan.actions = [...devPlan.actions, "report-error"].sort();
|
|
3962
|
+
}
|
|
3963
|
+
return {
|
|
3964
|
+
files,
|
|
3965
|
+
kinds,
|
|
3966
|
+
expandedBatch,
|
|
3967
|
+
event: { type: "invalidate", kinds, files, generation, devPlan },
|
|
3968
|
+
hasSyncErrors: indexSync.errors.length > 0
|
|
3969
|
+
};
|
|
3970
|
+
};
|
|
3941
3971
|
// pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.host.ts
|
|
3942
3972
|
import path8 from "path";
|
|
3943
3973
|
import { Logger as Logger4 } from "akanjs/common";
|
|
@@ -3946,7 +3976,8 @@ var builderMsgTypeSet = new Set([
|
|
|
3946
3976
|
"builder-ready",
|
|
3947
3977
|
"invalidate",
|
|
3948
3978
|
"css-updated",
|
|
3949
|
-
"pages-updated"
|
|
3979
|
+
"pages-updated",
|
|
3980
|
+
"build-status"
|
|
3950
3981
|
]);
|
|
3951
3982
|
|
|
3952
3983
|
class IncrementalBuilderHost {
|
|
@@ -4089,12 +4120,79 @@ var BUILDER_READY_TIMEOUT_MS = 15000;
|
|
|
4089
4120
|
var BUILDER_START_MAX_ATTEMPTS = 3;
|
|
4090
4121
|
var SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
4091
4122
|
var NON_SOURCE_EXT_RE = /\.(css|scss|sass|less|json|svg|png|jpe?g|webp|gif|avif|ico|woff2?|ttf|otf|mp3|mp4|wav|html)$/i;
|
|
4123
|
+
var SERVER_SUFFIXES = [".service.ts", ".document.ts"];
|
|
4124
|
+
var SHARED_SUFFIXES = [".constant.ts", ".dictionary.ts", ".signal.ts"];
|
|
4125
|
+
var RUNTIME_METADATA_BASENAMES = new Set(["dict.ts", "sig.ts", "useClient.ts", "useServer.ts"]);
|
|
4092
4126
|
var GRAPH_IMPORT_KINDS = new Set([
|
|
4093
4127
|
"import-statement",
|
|
4094
4128
|
"require-call",
|
|
4095
4129
|
"require-resolve",
|
|
4096
4130
|
"dynamic-import"
|
|
4097
4131
|
]);
|
|
4132
|
+
var shouldRestartBackendByDevPlan = (message) => {
|
|
4133
|
+
if (!message.devPlan)
|
|
4134
|
+
return null;
|
|
4135
|
+
if (message.devPlan.actions.includes("report-error"))
|
|
4136
|
+
return false;
|
|
4137
|
+
if (message.devPlan.actions.includes("restart-builder"))
|
|
4138
|
+
return false;
|
|
4139
|
+
return message.devPlan.actions.includes("restart-backend");
|
|
4140
|
+
};
|
|
4141
|
+
var shouldRestartBuilderByDevPlan = (message) => message.devPlan?.actions.includes("restart-builder") ?? false;
|
|
4142
|
+
var shouldRestartDevHostByDevPlan = (message) => message.devPlan?.actions.includes("restart-dev-host") ?? message.kinds.includes("config");
|
|
4143
|
+
var RESTART_ROLE_ORDER = ["server", "shared", "barrel", "config"];
|
|
4144
|
+
var generationValue = (generation) => generation ?? -1;
|
|
4145
|
+
var isLegacyBackendFallbackFile = (file, workspaceRoot) => {
|
|
4146
|
+
const abs = path9.resolve(file);
|
|
4147
|
+
const ext = path9.extname(abs).toLowerCase();
|
|
4148
|
+
if (!SOURCE_EXTS.has(ext))
|
|
4149
|
+
return false;
|
|
4150
|
+
const rel = path9.relative(path9.resolve(workspaceRoot), abs);
|
|
4151
|
+
if (!rel || rel.startsWith("..") || path9.isAbsolute(rel))
|
|
4152
|
+
return false;
|
|
4153
|
+
const parts = rel.split(path9.sep).filter(Boolean);
|
|
4154
|
+
const [scope] = parts;
|
|
4155
|
+
if (scope !== "apps" && scope !== "libs" && scope !== "pkgs")
|
|
4156
|
+
return false;
|
|
4157
|
+
const base = path9.basename(abs);
|
|
4158
|
+
return parts.includes("srvkit") || parts.includes("common") || SERVER_SUFFIXES.some((suffix) => base.endsWith(suffix)) || SHARED_SUFFIXES.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES.has(base) || base === "main.ts" || base === "server.ts";
|
|
4159
|
+
};
|
|
4160
|
+
var shouldMarkBuildPhaseRecovered = (previousByPhase, status) => {
|
|
4161
|
+
const previous = previousByPhase.get(status.phase);
|
|
4162
|
+
return Boolean(previous && status.ok && !previous.ok && generationValue(status.generation) >= previous.generation);
|
|
4163
|
+
};
|
|
4164
|
+
var createBackendBuildStatus = ({
|
|
4165
|
+
generation,
|
|
4166
|
+
ok,
|
|
4167
|
+
files = [],
|
|
4168
|
+
message
|
|
4169
|
+
}) => ({
|
|
4170
|
+
generation,
|
|
4171
|
+
phase: "backend",
|
|
4172
|
+
ok,
|
|
4173
|
+
files,
|
|
4174
|
+
message
|
|
4175
|
+
});
|
|
4176
|
+
var backendRestartReasonFromMessage = (message) => {
|
|
4177
|
+
const roleSet = new Set;
|
|
4178
|
+
for (const role of message.devPlan?.roles ?? []) {
|
|
4179
|
+
if (role === "server" || role === "shared" || role === "barrel" || role === "config")
|
|
4180
|
+
roleSet.add(role);
|
|
4181
|
+
}
|
|
4182
|
+
return {
|
|
4183
|
+
generation: message.devPlan?.generation ?? message.generation,
|
|
4184
|
+
files: [...new Set(message.files)].sort(),
|
|
4185
|
+
roles: RESTART_ROLE_ORDER.filter((role) => roleSet.has(role))
|
|
4186
|
+
};
|
|
4187
|
+
};
|
|
4188
|
+
var mergeBackendRestartReasons = (current, next) => ({
|
|
4189
|
+
generation: generationValue(next.generation) >= generationValue(current?.generation) ? next.generation : current?.generation,
|
|
4190
|
+
files: [...new Set([...current?.files ?? [], ...next.files])].sort(),
|
|
4191
|
+
roles: RESTART_ROLE_ORDER.filter((role) => current?.roles.includes(role) || next.roles.includes(role))
|
|
4192
|
+
});
|
|
4193
|
+
var shouldReplaceLastGoodMessage = (current, next) => !current || generationValue(next.data.generation) >= generationValue(current.data.generation);
|
|
4194
|
+
var shouldQueueBuildStatusReplay = (backendReady, pendingReplayCount) => !backendReady || pendingReplayCount > 0;
|
|
4195
|
+
var buildStatusReplaySequence = (pendingReplay, latestByPhase) => [...pendingReplay, ...latestByPhase.values()];
|
|
4098
4196
|
|
|
4099
4197
|
class BackendImportGraph {
|
|
4100
4198
|
#app;
|
|
@@ -4105,6 +4203,7 @@ class BackendImportGraph {
|
|
|
4105
4203
|
#jsxTranspiler = new Bun.Transpiler({ loader: "jsx" });
|
|
4106
4204
|
#files = new Set;
|
|
4107
4205
|
#ready = false;
|
|
4206
|
+
#lastRefreshSucceeded = false;
|
|
4108
4207
|
constructor(app, logger) {
|
|
4109
4208
|
this.#app = app;
|
|
4110
4209
|
this.#logger = logger;
|
|
@@ -4112,6 +4211,9 @@ class BackendImportGraph {
|
|
|
4112
4211
|
get ready() {
|
|
4113
4212
|
return this.#ready;
|
|
4114
4213
|
}
|
|
4214
|
+
get lastRefreshSucceeded() {
|
|
4215
|
+
return this.#lastRefreshSucceeded;
|
|
4216
|
+
}
|
|
4115
4217
|
has(file) {
|
|
4116
4218
|
return this.#files.has(path9.resolve(file));
|
|
4117
4219
|
}
|
|
@@ -4120,10 +4222,12 @@ class BackendImportGraph {
|
|
|
4120
4222
|
const files = await this.#build();
|
|
4121
4223
|
this.#files = files;
|
|
4122
4224
|
this.#ready = true;
|
|
4225
|
+
this.#lastRefreshSucceeded = true;
|
|
4123
4226
|
this.#logger.verbose(`[backend-graph] scanned ${files.size} files`);
|
|
4124
4227
|
return true;
|
|
4125
4228
|
} catch (err) {
|
|
4126
4229
|
this.#ready = this.#files.size > 0;
|
|
4230
|
+
this.#lastRefreshSucceeded = false;
|
|
4127
4231
|
this.#logger.warn(`[backend-graph] scan failed; ${this.#ready ? "using previous graph" : "using fallback rules"}: ${err instanceof Error ? err.message : String(err)}`);
|
|
4128
4232
|
return this.#ready;
|
|
4129
4233
|
}
|
|
@@ -4210,9 +4314,13 @@ class AkanAppHost {
|
|
|
4210
4314
|
#restartTimer = null;
|
|
4211
4315
|
#backendRecoveryTimer = null;
|
|
4212
4316
|
#backendRecoveryAttempts = 0;
|
|
4213
|
-
#
|
|
4214
|
-
#
|
|
4215
|
-
#
|
|
4317
|
+
#backendLifecycleState = "stopped";
|
|
4318
|
+
#pendingRestartReason = null;
|
|
4319
|
+
#backendStartStatus = null;
|
|
4320
|
+
#backendBuildStatusGeneration = 0;
|
|
4321
|
+
#lastGoodFrontend = {};
|
|
4322
|
+
#buildStatusByPhase = new Map;
|
|
4323
|
+
#pendingBuildStatusReplay = [];
|
|
4216
4324
|
#builderMessageQueue = Promise.resolve();
|
|
4217
4325
|
#backendGraph;
|
|
4218
4326
|
constructor(app, { env, withInk = false }) {
|
|
@@ -4257,7 +4365,9 @@ class AkanAppHost {
|
|
|
4257
4365
|
return "localhost";
|
|
4258
4366
|
return await createTunnel(type, { app: this.app, environment });
|
|
4259
4367
|
}
|
|
4260
|
-
#startBackend() {
|
|
4368
|
+
#startBackend(startStatus = null) {
|
|
4369
|
+
this.#backendStartStatus = startStatus;
|
|
4370
|
+
this.#setBackendLifecycleState("starting");
|
|
4261
4371
|
this.#backendReady = false;
|
|
4262
4372
|
const backend = Bun.spawn(["bun", `apps/${this.app.name}/main.ts`], {
|
|
4263
4373
|
cwd: this.app.workspace.workspaceRoot,
|
|
@@ -4269,6 +4379,8 @@ class AkanAppHost {
|
|
|
4269
4379
|
if (msg.type === "backend-ready") {
|
|
4270
4380
|
this.#backendReady = true;
|
|
4271
4381
|
this.#backendRecoveryAttempts = 0;
|
|
4382
|
+
this.#setBackendLifecycleState("ready", `pid=${msg.pid}`);
|
|
4383
|
+
this.#recordBackendReadyStatus();
|
|
4272
4384
|
this.logger.verbose(`backend ready pid=${msg.pid}`);
|
|
4273
4385
|
this.#replayBuilderState();
|
|
4274
4386
|
return;
|
|
@@ -4291,9 +4403,53 @@ class AkanAppHost {
|
|
|
4291
4403
|
this.#backend = backend;
|
|
4292
4404
|
this.logger.verbose(`backend spawned pid=${backend.pid}`);
|
|
4293
4405
|
}
|
|
4406
|
+
#nextBackendBuildStatusGeneration(generation) {
|
|
4407
|
+
if (typeof generation === "number") {
|
|
4408
|
+
this.#backendBuildStatusGeneration = Math.max(this.#backendBuildStatusGeneration, generation);
|
|
4409
|
+
return generation;
|
|
4410
|
+
}
|
|
4411
|
+
this.#backendBuildStatusGeneration += 1;
|
|
4412
|
+
return this.#backendBuildStatusGeneration;
|
|
4413
|
+
}
|
|
4414
|
+
#recordBackendBuildStatus({
|
|
4415
|
+
generation,
|
|
4416
|
+
ok,
|
|
4417
|
+
files,
|
|
4418
|
+
message
|
|
4419
|
+
}) {
|
|
4420
|
+
const status = createBackendBuildStatus({
|
|
4421
|
+
generation: this.#nextBackendBuildStatusGeneration(generation),
|
|
4422
|
+
ok,
|
|
4423
|
+
files,
|
|
4424
|
+
message
|
|
4425
|
+
});
|
|
4426
|
+
this.#recordBuildStatus(status);
|
|
4427
|
+
return status;
|
|
4428
|
+
}
|
|
4429
|
+
#recordBackendReadyStatus() {
|
|
4430
|
+
const previous = this.#buildStatusByPhase.get("backend");
|
|
4431
|
+
const startStatus = this.#backendStartStatus;
|
|
4432
|
+
if (startStatus || previous?.ok === false) {
|
|
4433
|
+
const status = this.#recordBackendBuildStatus({
|
|
4434
|
+
generation: startStatus?.generation ?? previous?.generation,
|
|
4435
|
+
ok: true,
|
|
4436
|
+
files: startStatus?.files ?? previous?.files ?? [],
|
|
4437
|
+
message: "Backend ready"
|
|
4438
|
+
});
|
|
4439
|
+
this.#sendOrQueueBuildStatus(status);
|
|
4440
|
+
}
|
|
4441
|
+
this.#backendStartStatus = null;
|
|
4442
|
+
}
|
|
4443
|
+
#setBackendLifecycleState(next, detail) {
|
|
4444
|
+
if (this.#backendLifecycleState === next && !detail)
|
|
4445
|
+
return;
|
|
4446
|
+
const prev = this.#backendLifecycleState;
|
|
4447
|
+
this.#backendLifecycleState = next;
|
|
4448
|
+
this.logger.verbose(`[backend-lifecycle] ${prev} -> ${next}${detail ? ` ${detail}` : ""}`);
|
|
4449
|
+
}
|
|
4294
4450
|
#sendToBackend(message) {
|
|
4295
4451
|
if (!this.#backend || !this.#backendReady) {
|
|
4296
|
-
if (message.type === "css-updated" || message.type === "pages-updated") {
|
|
4452
|
+
if (message.type === "css-updated" || message.type === "pages-updated" || message.type === "build-status") {
|
|
4297
4453
|
this.logger.verbose(`backend is not ready; will replay ${message.type}`);
|
|
4298
4454
|
return;
|
|
4299
4455
|
}
|
|
@@ -4313,6 +4469,7 @@ class AkanAppHost {
|
|
|
4313
4469
|
const backend = this.#backend;
|
|
4314
4470
|
this.#plannedBackendStops.add(backend);
|
|
4315
4471
|
this.#backendReady = false;
|
|
4472
|
+
this.#setBackendLifecycleState("stopping", `pid=${backend.pid}`);
|
|
4316
4473
|
this.logger.verbose(`stopping backend pid=${backend.pid}`);
|
|
4317
4474
|
try {
|
|
4318
4475
|
backend.kill("SIGTERM");
|
|
@@ -4328,11 +4485,13 @@ class AkanAppHost {
|
|
|
4328
4485
|
} finally {
|
|
4329
4486
|
if (this.#backend === backend)
|
|
4330
4487
|
this.#backend = null;
|
|
4488
|
+
this.#setBackendLifecycleState("stopped", `pid=${backend.pid}`);
|
|
4331
4489
|
}
|
|
4332
4490
|
}
|
|
4333
|
-
#scheduleBackendRestart(
|
|
4334
|
-
|
|
4335
|
-
|
|
4491
|
+
#scheduleBackendRestart(reason) {
|
|
4492
|
+
this.#pendingRestartReason = mergeBackendRestartReasons(this.#pendingRestartReason, reason);
|
|
4493
|
+
const pending = this.#pendingRestartReason;
|
|
4494
|
+
this.#setBackendLifecycleState("restart-pending", `generation=${pending.generation ?? "(unknown)"} files=${pending.files.length} roles=${pending.roles.join(",") || "(none)"}`);
|
|
4336
4495
|
if (this.#backendRecoveryTimer) {
|
|
4337
4496
|
clearTimeout(this.#backendRecoveryTimer);
|
|
4338
4497
|
this.#backendRecoveryTimer = null;
|
|
@@ -4341,23 +4500,31 @@ class AkanAppHost {
|
|
|
4341
4500
|
clearTimeout(this.#restartTimer);
|
|
4342
4501
|
this.#restartTimer = setTimeout(() => {
|
|
4343
4502
|
this.#restartTimer = null;
|
|
4344
|
-
const
|
|
4345
|
-
this.#
|
|
4346
|
-
|
|
4503
|
+
const next = this.#pendingRestartReason;
|
|
4504
|
+
this.#pendingRestartReason = null;
|
|
4505
|
+
if (next)
|
|
4506
|
+
this.#restartBackend(next);
|
|
4347
4507
|
}, BACKEND_RESTART_DEBOUNCE_MS);
|
|
4348
4508
|
}
|
|
4349
|
-
async#restartBackend(
|
|
4350
|
-
this.logger.verbose(`[backend-reload] restarting backend
|
|
4509
|
+
async#restartBackend(reason) {
|
|
4510
|
+
this.logger.verbose(`[backend-reload] restarting backend generation=${reason.generation ?? "(unknown)"} files=${reason.files.length} roles=${reason.roles.join(",") || "(none)"}`);
|
|
4351
4511
|
this.#backendRecoveryAttempts = 0;
|
|
4352
4512
|
await Promise.all([this.#stopBackend(), this.#backendGraph.refresh()]);
|
|
4353
|
-
this.#startBackend();
|
|
4513
|
+
this.#startBackend({ generation: reason.generation, files: reason.files });
|
|
4354
4514
|
}
|
|
4355
4515
|
#scheduleBackendRecovery(reason) {
|
|
4356
4516
|
if (this.#backendRecoveryTimer || this.#backend)
|
|
4357
4517
|
return;
|
|
4518
|
+
this.#setBackendLifecycleState("recovering", reason);
|
|
4358
4519
|
const attempt = this.#backendRecoveryAttempts;
|
|
4359
4520
|
const delay = Math.min(BACKEND_RECOVERY_BASE_DELAY_MS * 2 ** attempt, BACKEND_RECOVERY_MAX_DELAY_MS);
|
|
4360
4521
|
this.#backendRecoveryAttempts = attempt + 1;
|
|
4522
|
+
const failureStatus = this.#recordBackendBuildStatus({
|
|
4523
|
+
ok: false,
|
|
4524
|
+
files: [],
|
|
4525
|
+
message: `Backend exited unexpectedly (${reason}); restarting in ${delay}ms`
|
|
4526
|
+
});
|
|
4527
|
+
this.#sendOrQueueBuildStatus(failureStatus);
|
|
4361
4528
|
this.logger.warn(`[backend-recovery] backend exited unexpectedly (${reason}); restarting in ${delay}ms (attempt ${this.#backendRecoveryAttempts})`);
|
|
4362
4529
|
this.#backendRecoveryTimer = setTimeout(() => {
|
|
4363
4530
|
this.#backendRecoveryTimer = null;
|
|
@@ -4365,7 +4532,7 @@ class AkanAppHost {
|
|
|
4365
4532
|
return;
|
|
4366
4533
|
this.#backendGraph.refresh().finally(() => {
|
|
4367
4534
|
if (!this.#backend)
|
|
4368
|
-
this.#startBackend();
|
|
4535
|
+
this.#startBackend({ generation: failureStatus.generation, files: failureStatus.files });
|
|
4369
4536
|
});
|
|
4370
4537
|
}, delay);
|
|
4371
4538
|
}
|
|
@@ -4375,10 +4542,15 @@ class AkanAppHost {
|
|
|
4375
4542
|
});
|
|
4376
4543
|
}
|
|
4377
4544
|
async#handleBuilderMessage(message) {
|
|
4545
|
+
if (message.type === "build-status") {
|
|
4546
|
+
this.#recordBuildStatus(message.data);
|
|
4547
|
+
this.#sendOrQueueBuildStatus(message.data);
|
|
4548
|
+
return;
|
|
4549
|
+
}
|
|
4378
4550
|
if (message.type === "pages-updated")
|
|
4379
|
-
this.#
|
|
4551
|
+
this.#recordLastGood(message);
|
|
4380
4552
|
if (message.type === "css-updated")
|
|
4381
|
-
this.#
|
|
4553
|
+
this.#recordLastGood(message);
|
|
4382
4554
|
if (message.type === "invalidate") {
|
|
4383
4555
|
await this.#handleInvalidate(message);
|
|
4384
4556
|
return;
|
|
@@ -4386,26 +4558,140 @@ class AkanAppHost {
|
|
|
4386
4558
|
this.#sendToBackend(message);
|
|
4387
4559
|
}
|
|
4388
4560
|
async#handleInvalidate(message) {
|
|
4561
|
+
if (shouldRestartBuilderByDevPlan(message)) {
|
|
4562
|
+
try {
|
|
4563
|
+
await this.#restartDevChildren(message);
|
|
4564
|
+
} catch (err) {
|
|
4565
|
+
this.#recordDevHostRestartFailure(message, err);
|
|
4566
|
+
}
|
|
4567
|
+
return;
|
|
4568
|
+
}
|
|
4569
|
+
if (shouldRestartDevHostByDevPlan(message)) {
|
|
4570
|
+
this.#recordDevHostRestartRequired(message);
|
|
4571
|
+
return;
|
|
4572
|
+
}
|
|
4389
4573
|
if (await this.#shouldRestartBackend(message)) {
|
|
4390
|
-
this.#scheduleBackendRestart(message
|
|
4574
|
+
this.#scheduleBackendRestart(backendRestartReasonFromMessage(message));
|
|
4391
4575
|
return;
|
|
4392
4576
|
}
|
|
4393
4577
|
this.#sendToBackend(message);
|
|
4394
4578
|
}
|
|
4579
|
+
async#restartDevChildren(message) {
|
|
4580
|
+
const generation = message.devPlan?.generation ?? message.generation;
|
|
4581
|
+
this.logger.warn(`[dev-host] recycling builder/backend for runtime metadata generation=${generation ?? "(unknown)"} files=${message.files.length}`);
|
|
4582
|
+
if (this.#restartTimer) {
|
|
4583
|
+
clearTimeout(this.#restartTimer);
|
|
4584
|
+
this.#restartTimer = null;
|
|
4585
|
+
}
|
|
4586
|
+
if (this.#backendRecoveryTimer) {
|
|
4587
|
+
clearTimeout(this.#backendRecoveryTimer);
|
|
4588
|
+
this.#backendRecoveryTimer = null;
|
|
4589
|
+
}
|
|
4590
|
+
this.#pendingRestartReason = null;
|
|
4591
|
+
this.#lastGoodFrontend = {};
|
|
4592
|
+
this.#buildStatusByPhase.clear();
|
|
4593
|
+
this.#pendingBuildStatusReplay = [];
|
|
4594
|
+
await this.#stopBackend();
|
|
4595
|
+
this.#stopBuilder();
|
|
4596
|
+
await this.#backendGraph.refresh();
|
|
4597
|
+
await this.#startBuilder();
|
|
4598
|
+
this.#startBackend({ generation, files: message.files });
|
|
4599
|
+
}
|
|
4600
|
+
#recordLastGood(message) {
|
|
4601
|
+
if (message.type === "pages-updated") {
|
|
4602
|
+
if (!shouldReplaceLastGoodMessage(this.#lastGoodFrontend.pages, message))
|
|
4603
|
+
return;
|
|
4604
|
+
this.#lastGoodFrontend.pages = message;
|
|
4605
|
+
this.logger.verbose(`[last-good] pages generation=${message.data.generation ?? "(unknown)"} buildId=${message.data.buildId}`);
|
|
4606
|
+
return;
|
|
4607
|
+
}
|
|
4608
|
+
if (!shouldReplaceLastGoodMessage(this.#lastGoodFrontend.css, message))
|
|
4609
|
+
return;
|
|
4610
|
+
this.#lastGoodFrontend.css = message;
|
|
4611
|
+
this.logger.verbose(`[last-good] css generation=${message.data.generation ?? "(unknown)"} assets=${Object.keys(message.data.cssAssets).length}`);
|
|
4612
|
+
}
|
|
4613
|
+
#recordDevHostRestartRequired(message) {
|
|
4614
|
+
const generation = message.devPlan?.generation ?? message.generation;
|
|
4615
|
+
const detail = `generation=${generation ?? "(unknown)"} files=${message.files.length}`;
|
|
4616
|
+
this.logger.warn(`[dev-host] config change requires a manual restart until controlled dev-host restart is implemented (${detail})`);
|
|
4617
|
+
if (typeof generation === "number") {
|
|
4618
|
+
const status = {
|
|
4619
|
+
generation,
|
|
4620
|
+
phase: "scan",
|
|
4621
|
+
ok: false,
|
|
4622
|
+
files: message.files,
|
|
4623
|
+
message: "Config change requires restarting `akan start` to apply."
|
|
4624
|
+
};
|
|
4625
|
+
this.#recordBuildStatus(status);
|
|
4626
|
+
this.#sendOrQueueBuildStatus(status);
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
#recordDevHostRestartFailure(message, err) {
|
|
4630
|
+
const generation = message.devPlan?.generation ?? message.generation ?? this.#nextBackendBuildStatusGeneration();
|
|
4631
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
4632
|
+
this.logger.warn(`[dev-host] runtime metadata restart failed generation=${generation}: ${detail}`);
|
|
4633
|
+
const status = {
|
|
4634
|
+
generation,
|
|
4635
|
+
phase: "scan",
|
|
4636
|
+
ok: false,
|
|
4637
|
+
files: message.files,
|
|
4638
|
+
message: `Runtime metadata change requires restarting \`akan start\` to apply: ${detail}`
|
|
4639
|
+
};
|
|
4640
|
+
this.#recordBuildStatus(status);
|
|
4641
|
+
this.#sendOrQueueBuildStatus(status);
|
|
4642
|
+
}
|
|
4643
|
+
#recordBuildStatus(status) {
|
|
4644
|
+
const recovered = shouldMarkBuildPhaseRecovered(this.#buildStatusByPhase, status);
|
|
4645
|
+
this.#buildStatusByPhase.set(status.phase, status);
|
|
4646
|
+
const label = `[build-status] generation=${status.generation} phase=${status.phase} ok=${status.ok} files=${status.files.length}`;
|
|
4647
|
+
if (status.ok)
|
|
4648
|
+
this.logger.verbose(`${label}${recovered ? " recovered=1" : ""}`);
|
|
4649
|
+
else
|
|
4650
|
+
this.logger.warn(`${label}${status.message ? ` message=${status.message}` : ""}`);
|
|
4651
|
+
}
|
|
4652
|
+
#sendOrQueueBuildStatus(status) {
|
|
4653
|
+
if (!this.#backend || shouldQueueBuildStatusReplay(this.#backendReady, this.#pendingBuildStatusReplay.length)) {
|
|
4654
|
+
this.#pendingBuildStatusReplay.push(status);
|
|
4655
|
+
this.logger.verbose(`backend is not ready; will replay build-status generation=${status.generation} phase=${status.phase}`);
|
|
4656
|
+
return;
|
|
4657
|
+
}
|
|
4658
|
+
this.#sendToBackend({ type: "build-status", data: status });
|
|
4659
|
+
}
|
|
4395
4660
|
#replayBuilderState() {
|
|
4396
4661
|
if (!this.#backendReady)
|
|
4397
4662
|
return;
|
|
4398
|
-
if (this.#
|
|
4399
|
-
this.#sendToBackend(this.#
|
|
4400
|
-
if (this.#
|
|
4401
|
-
this.#sendToBackend(this.#
|
|
4663
|
+
if (this.#lastGoodFrontend.css)
|
|
4664
|
+
this.#sendToBackend(this.#lastGoodFrontend.css);
|
|
4665
|
+
if (this.#lastGoodFrontend.pages)
|
|
4666
|
+
this.#sendToBackend(this.#lastGoodFrontend.pages);
|
|
4667
|
+
const queuedStatuses = this.#pendingBuildStatusReplay.splice(0);
|
|
4668
|
+
for (const status of buildStatusReplaySequence(queuedStatuses, this.#buildStatusByPhase)) {
|
|
4669
|
+
this.#sendToBackend({ type: "build-status", data: status });
|
|
4670
|
+
}
|
|
4402
4671
|
}
|
|
4403
4672
|
async#shouldRestartBackend(message) {
|
|
4404
4673
|
if (message.kinds.length === 1 && message.kinds[0] === "css")
|
|
4405
4674
|
return false;
|
|
4406
|
-
if (
|
|
4675
|
+
if (message.devPlan) {
|
|
4676
|
+
const { generation, roles, actions, reasonByFile } = message.devPlan;
|
|
4677
|
+
this.logger.verbose(`[dev-plan] generation=${generation} roles=${roles.join(",") || "(none)"} actions=${actions.join(",") || "(none)"} reasons=${Object.keys(reasonByFile).length}`);
|
|
4678
|
+
const shouldRestart = shouldRestartBackendByDevPlan(message) ?? false;
|
|
4679
|
+
if (shouldRestart && message.kinds.includes("code"))
|
|
4680
|
+
await this.#backendGraph.refresh();
|
|
4681
|
+
return shouldRestart;
|
|
4682
|
+
}
|
|
4683
|
+
if (message.kinds.includes("code"))
|
|
4407
4684
|
await this.#backendGraph.refresh();
|
|
4408
|
-
|
|
4685
|
+
if (message.files.some((file) => this.#isBackendFile(file)))
|
|
4686
|
+
return true;
|
|
4687
|
+
if (!this.#backendGraph.lastRefreshSucceeded) {
|
|
4688
|
+
const fallbackFiles = message.files.filter((file) => isLegacyBackendFallbackFile(file, this.app.workspace.workspaceRoot));
|
|
4689
|
+
if (fallbackFiles.length > 0) {
|
|
4690
|
+
this.logger.warn(`[backend-graph] using path-role fallback for legacy invalidate; restart files=${fallbackFiles.length}`);
|
|
4691
|
+
return true;
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
return false;
|
|
4409
4695
|
}
|
|
4410
4696
|
#isBackendFile(file) {
|
|
4411
4697
|
return this.#backendGraph.has(file);
|
|
@@ -4761,8 +5047,8 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
|
|
|
4761
5047
|
}
|
|
4762
5048
|
}
|
|
4763
5049
|
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
4764
|
-
import { mkdir as
|
|
4765
|
-
import
|
|
5050
|
+
import { mkdir as mkdir8, rm as rm3 } from "fs/promises";
|
|
5051
|
+
import path35 from "path";
|
|
4766
5052
|
|
|
4767
5053
|
// pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
|
|
4768
5054
|
import path20 from "path";
|
|
@@ -7230,9 +7516,306 @@ function getPageKeyBasePath(pageKey, basePaths) {
|
|
|
7230
7516
|
const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
|
|
7231
7517
|
return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
|
|
7232
7518
|
}
|
|
7233
|
-
// pkgs/@akanjs/devkit/frontendBuild/
|
|
7234
|
-
import { mkdir as mkdir6 } from "fs/promises";
|
|
7519
|
+
// pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
|
|
7235
7520
|
import path25 from "path";
|
|
7521
|
+
var SOURCE_EXTS4 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
7522
|
+
var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
7523
|
+
var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit"]);
|
|
7524
|
+
var CLIENT_SUFFIXES = [".Template.tsx", ".Unit.tsx", ".Util.tsx", ".View.tsx", ".Zone.tsx", ".store.ts"];
|
|
7525
|
+
var SHARED_SUFFIXES2 = [".constant.ts", ".dictionary.ts", ".signal.ts"];
|
|
7526
|
+
var SERVER_SUFFIXES2 = [".service.ts", ".document.ts"];
|
|
7527
|
+
var RUNTIME_METADATA_BASENAMES2 = new Set(["dict.ts", "sig.ts", "useClient.ts", "useServer.ts"]);
|
|
7528
|
+
|
|
7529
|
+
class DevChangePlanner {
|
|
7530
|
+
#workspaceRoot;
|
|
7531
|
+
constructor({ workspaceRoot }) {
|
|
7532
|
+
this.#workspaceRoot = path25.resolve(workspaceRoot);
|
|
7533
|
+
}
|
|
7534
|
+
plan({ generation, files, kinds, generatedFiles: generatedFiles2 = [] }) {
|
|
7535
|
+
const fileList = uniqueResolved([...files, ...generatedFiles2]);
|
|
7536
|
+
const generatedSet = new Set(generatedFiles2.map((file) => path25.resolve(file)));
|
|
7537
|
+
const kindSet = new Set(kinds);
|
|
7538
|
+
const roles = new Set;
|
|
7539
|
+
const actions = new Set;
|
|
7540
|
+
const reasonByFile = {};
|
|
7541
|
+
for (const kind of kindSet) {
|
|
7542
|
+
if (kind === "css") {
|
|
7543
|
+
roles.add("css");
|
|
7544
|
+
actions.add("rebuild-css");
|
|
7545
|
+
}
|
|
7546
|
+
if (kind === "config") {
|
|
7547
|
+
roles.add("config");
|
|
7548
|
+
actions.add("restart-dev-host");
|
|
7549
|
+
}
|
|
7550
|
+
}
|
|
7551
|
+
for (const file of fileList) {
|
|
7552
|
+
const reasons = new Set;
|
|
7553
|
+
const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(path25.resolve(file)), reasons });
|
|
7554
|
+
for (const role of fileRoles)
|
|
7555
|
+
roles.add(role);
|
|
7556
|
+
if (reasons.has("runtime-metadata"))
|
|
7557
|
+
actions.add("restart-builder");
|
|
7558
|
+
if (reasons.size > 0)
|
|
7559
|
+
reasonByFile[path25.resolve(file)] = [...reasons].sort();
|
|
7560
|
+
}
|
|
7561
|
+
if (roles.has("barrel"))
|
|
7562
|
+
actions.add("sync-generated");
|
|
7563
|
+
if (roles.has("server") || roles.has("shared"))
|
|
7564
|
+
actions.add("restart-backend");
|
|
7565
|
+
if (roles.has("client") || roles.has("shared"))
|
|
7566
|
+
actions.add("rebuild-client");
|
|
7567
|
+
if (roles.has("css"))
|
|
7568
|
+
actions.add("rebuild-css");
|
|
7569
|
+
return {
|
|
7570
|
+
generation,
|
|
7571
|
+
files: fileList,
|
|
7572
|
+
generatedFiles: uniqueResolved(generatedFiles2),
|
|
7573
|
+
roles: [...roles].sort(),
|
|
7574
|
+
actions: [...actions].sort(),
|
|
7575
|
+
reasonByFile
|
|
7576
|
+
};
|
|
7577
|
+
}
|
|
7578
|
+
#rolesForFile(file, { isGenerated, reasons }) {
|
|
7579
|
+
const roles = new Set;
|
|
7580
|
+
const abs = path25.resolve(file);
|
|
7581
|
+
const base = path25.basename(abs);
|
|
7582
|
+
const ext = path25.extname(abs).toLowerCase();
|
|
7583
|
+
const isSource = SOURCE_EXTS4.has(ext);
|
|
7584
|
+
const rel = path25.relative(this.#workspaceRoot, abs);
|
|
7585
|
+
const parts = rel.split(path25.sep).filter(Boolean);
|
|
7586
|
+
if (CONFIG_BASENAMES.has(base)) {
|
|
7587
|
+
roles.add("config");
|
|
7588
|
+
reasons.add("config-file");
|
|
7589
|
+
}
|
|
7590
|
+
if (ext === ".css") {
|
|
7591
|
+
roles.add("css");
|
|
7592
|
+
reasons.add("css-file");
|
|
7593
|
+
}
|
|
7594
|
+
if (isGenerated || isSource && this.#isBarrelFacetChild(parts)) {
|
|
7595
|
+
roles.add("barrel");
|
|
7596
|
+
reasons.add(isGenerated ? "generated-index" : "barrel-facet-child");
|
|
7597
|
+
}
|
|
7598
|
+
if (isSource && this.#isServerBiased(abs, parts)) {
|
|
7599
|
+
roles.add("server");
|
|
7600
|
+
reasons.add("server-path");
|
|
7601
|
+
}
|
|
7602
|
+
if (isSource && this.#isClientBiased(abs, parts)) {
|
|
7603
|
+
roles.add("client");
|
|
7604
|
+
reasons.add("client-path");
|
|
7605
|
+
}
|
|
7606
|
+
if (isSource && this.#isSharedBiased(abs, parts)) {
|
|
7607
|
+
roles.add("shared");
|
|
7608
|
+
reasons.add("shared-path");
|
|
7609
|
+
}
|
|
7610
|
+
if (isSource && this.#isRuntimeMetadataFile(parts, base)) {
|
|
7611
|
+
reasons.add("runtime-metadata");
|
|
7612
|
+
}
|
|
7613
|
+
if (roles.has("server") && roles.has("client")) {
|
|
7614
|
+
roles.delete("server");
|
|
7615
|
+
roles.delete("client");
|
|
7616
|
+
roles.add("shared");
|
|
7617
|
+
reasons.add("server-client-overlap");
|
|
7618
|
+
}
|
|
7619
|
+
if (roles.size === 0 && SOURCE_EXTS4.has(ext) && this.#isWorkspaceSource(rel)) {
|
|
7620
|
+
roles.add("shared");
|
|
7621
|
+
reasons.add("workspace-source-fallback");
|
|
7622
|
+
}
|
|
7623
|
+
return roles;
|
|
7624
|
+
}
|
|
7625
|
+
#isServerBiased(abs, parts) {
|
|
7626
|
+
const base = path25.basename(abs);
|
|
7627
|
+
return parts.includes("srvkit") || SERVER_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || base === "main.ts" || base === "server.ts";
|
|
7628
|
+
}
|
|
7629
|
+
#isClientBiased(abs, parts) {
|
|
7630
|
+
const base = path25.basename(abs);
|
|
7631
|
+
return parts.includes("ui") || parts.includes("webkit") || parts.includes("page") || CLIENT_SUFFIXES.some((suffix) => base.endsWith(suffix));
|
|
7632
|
+
}
|
|
7633
|
+
#isSharedBiased(abs, parts) {
|
|
7634
|
+
const base = path25.basename(abs);
|
|
7635
|
+
return parts.includes("common") || SHARED_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES2.has(base);
|
|
7636
|
+
}
|
|
7637
|
+
#isRuntimeMetadataFile(parts, base) {
|
|
7638
|
+
const parent = parts.at(-2);
|
|
7639
|
+
if (parent === "lib" && RUNTIME_METADATA_BASENAMES2.has(base))
|
|
7640
|
+
return true;
|
|
7641
|
+
const libIndex = parts.lastIndexOf("lib");
|
|
7642
|
+
if (libIndex < 0 || parts.length <= libIndex + 1)
|
|
7643
|
+
return false;
|
|
7644
|
+
return base.endsWith(".dictionary.ts") || base.endsWith(".signal.ts");
|
|
7645
|
+
}
|
|
7646
|
+
#isBarrelFacetChild(parts) {
|
|
7647
|
+
if (parts.length < 4)
|
|
7648
|
+
return false;
|
|
7649
|
+
const [scope, , facet, child] = parts;
|
|
7650
|
+
if (scope !== "apps" && scope !== "libs")
|
|
7651
|
+
return false;
|
|
7652
|
+
if (!facet || !BARREL_FACETS.has(facet))
|
|
7653
|
+
return false;
|
|
7654
|
+
if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
|
|
7655
|
+
return false;
|
|
7656
|
+
return true;
|
|
7657
|
+
}
|
|
7658
|
+
#isWorkspaceSource(rel) {
|
|
7659
|
+
if (!rel || rel.startsWith("..") || path25.isAbsolute(rel))
|
|
7660
|
+
return false;
|
|
7661
|
+
const [scope] = rel.split(path25.sep);
|
|
7662
|
+
return scope === "apps" || scope === "libs" || scope === "pkgs";
|
|
7663
|
+
}
|
|
7664
|
+
}
|
|
7665
|
+
var uniqueResolved = (files) => [...new Set(files.map((file) => path25.resolve(file)))].sort();
|
|
7666
|
+
// pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
|
|
7667
|
+
import { mkdir as mkdir6, readdir as readdir2, readFile, rm as rm2, stat as stat3, writeFile } from "fs/promises";
|
|
7668
|
+
import path26 from "path";
|
|
7669
|
+
var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit"]);
|
|
7670
|
+
var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
|
|
7671
|
+
var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
7672
|
+
var MODULE_UI_TYPES = ["Template", "Unit", "Util", "View", "Zone"];
|
|
7673
|
+
var SERVICE_UI_TYPES = ["Util", "Zone"];
|
|
7674
|
+
var SCALAR_UI_TYPES = ["Template", "Unit"];
|
|
7675
|
+
|
|
7676
|
+
class DevGeneratedIndexSync {
|
|
7677
|
+
#workspaceRoot;
|
|
7678
|
+
constructor({ workspaceRoot }) {
|
|
7679
|
+
this.#workspaceRoot = path26.resolve(workspaceRoot);
|
|
7680
|
+
}
|
|
7681
|
+
async syncForBatch(files) {
|
|
7682
|
+
const indexPaths = new Set;
|
|
7683
|
+
const errors = [];
|
|
7684
|
+
for (const file of files) {
|
|
7685
|
+
const facetIndex = this.#facetIndexFor(file);
|
|
7686
|
+
if (facetIndex)
|
|
7687
|
+
indexPaths.add(facetIndex);
|
|
7688
|
+
const moduleIndex = await this.#moduleIndexForDirectoryEvent(file).catch((err) => {
|
|
7689
|
+
errors.push(`[generated-index] module detection failed for ${file}: ${formatError(err)}`);
|
|
7690
|
+
return null;
|
|
7691
|
+
});
|
|
7692
|
+
if (moduleIndex)
|
|
7693
|
+
indexPaths.add(moduleIndex);
|
|
7694
|
+
}
|
|
7695
|
+
const changedFiles = [];
|
|
7696
|
+
for (const indexPath of [...indexPaths].sort()) {
|
|
7697
|
+
try {
|
|
7698
|
+
const changed = await this.#syncIndex(indexPath);
|
|
7699
|
+
if (changed)
|
|
7700
|
+
changedFiles.push(indexPath);
|
|
7701
|
+
} catch (err) {
|
|
7702
|
+
errors.push(`[generated-index] sync failed for ${indexPath}: ${formatError(err)}`);
|
|
7703
|
+
}
|
|
7704
|
+
}
|
|
7705
|
+
return { changedFiles, errors };
|
|
7706
|
+
}
|
|
7707
|
+
#facetIndexFor(file) {
|
|
7708
|
+
const abs = path26.resolve(file);
|
|
7709
|
+
const rel = path26.relative(this.#workspaceRoot, abs);
|
|
7710
|
+
if (rel.startsWith("..") || path26.isAbsolute(rel))
|
|
7711
|
+
return null;
|
|
7712
|
+
const parts = rel.split(path26.sep).filter(Boolean);
|
|
7713
|
+
if (parts.length < 4)
|
|
7714
|
+
return null;
|
|
7715
|
+
const [scope, project, facet, child] = parts;
|
|
7716
|
+
if (scope !== "apps" && scope !== "libs" || !project || !facet || !BARREL_FACETS2.has(facet))
|
|
7717
|
+
return null;
|
|
7718
|
+
if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
|
|
7719
|
+
return null;
|
|
7720
|
+
return path26.join(this.#workspaceRoot, scope, project, facet, "index.ts");
|
|
7721
|
+
}
|
|
7722
|
+
async#moduleIndexForDirectoryEvent(file) {
|
|
7723
|
+
const abs = path26.resolve(file);
|
|
7724
|
+
const rel = path26.relative(this.#workspaceRoot, abs);
|
|
7725
|
+
if (rel.startsWith("..") || path26.isAbsolute(rel))
|
|
7726
|
+
return null;
|
|
7727
|
+
const parts = rel.split(path26.sep).filter(Boolean);
|
|
7728
|
+
if (parts.length !== 4 && parts.length !== 5)
|
|
7729
|
+
return null;
|
|
7730
|
+
const [scope, project, libSegment, moduleSegment, scalarSegment] = parts;
|
|
7731
|
+
if (scope !== "apps" && scope !== "libs" || !project || libSegment !== "lib")
|
|
7732
|
+
return null;
|
|
7733
|
+
const isExistingDirectory = await stat3(abs).then((s) => s.isDirectory()).catch(() => false);
|
|
7734
|
+
const looksLikeDeletedDirectory = !path26.extname(abs);
|
|
7735
|
+
if (!isExistingDirectory && !looksLikeDeletedDirectory)
|
|
7736
|
+
return null;
|
|
7737
|
+
if (moduleSegment === "__scalar" && scalarSegment) {
|
|
7738
|
+
return path26.join(this.#workspaceRoot, scope, project, "lib", "__scalar", scalarSegment, "index.ts");
|
|
7739
|
+
}
|
|
7740
|
+
if (!moduleSegment || moduleSegment === "__scalar")
|
|
7741
|
+
return null;
|
|
7742
|
+
return path26.join(this.#workspaceRoot, scope, project, "lib", moduleSegment, "index.ts");
|
|
7743
|
+
}
|
|
7744
|
+
async#syncIndex(indexPath) {
|
|
7745
|
+
const dir = path26.dirname(indexPath);
|
|
7746
|
+
const content = await this.#contentForIndex(indexPath);
|
|
7747
|
+
if (content === null) {
|
|
7748
|
+
if (!await exists(indexPath))
|
|
7749
|
+
return false;
|
|
7750
|
+
await rm2(indexPath, { force: true });
|
|
7751
|
+
return true;
|
|
7752
|
+
}
|
|
7753
|
+
const current = await readFile(indexPath, "utf8").catch(() => null);
|
|
7754
|
+
if (current === content)
|
|
7755
|
+
return false;
|
|
7756
|
+
await mkdir6(dir, { recursive: true });
|
|
7757
|
+
await writeFile(indexPath, content);
|
|
7758
|
+
return true;
|
|
7759
|
+
}
|
|
7760
|
+
async#contentForIndex(indexPath) {
|
|
7761
|
+
const parts = path26.relative(this.#workspaceRoot, indexPath).split(path26.sep).filter(Boolean);
|
|
7762
|
+
const facet = parts.at(-2);
|
|
7763
|
+
if (facet && BARREL_FACETS2.has(facet))
|
|
7764
|
+
return this.#facetContent(path26.dirname(indexPath));
|
|
7765
|
+
return this.#moduleContent(path26.dirname(indexPath));
|
|
7766
|
+
}
|
|
7767
|
+
async#facetContent(dir) {
|
|
7768
|
+
const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
|
|
7769
|
+
const exportNames = entries.flatMap((entry) => {
|
|
7770
|
+
const name = entry.name;
|
|
7771
|
+
if (name.startsWith("."))
|
|
7772
|
+
return [];
|
|
7773
|
+
if (entry.isDirectory())
|
|
7774
|
+
return [name];
|
|
7775
|
+
if (!entry.isFile())
|
|
7776
|
+
return [];
|
|
7777
|
+
if (!FACET_SOURCE_FILE_RE.test(name) || FACET_EXCLUDED_FILE_RE.test(name))
|
|
7778
|
+
return [];
|
|
7779
|
+
return [name.replace(FACET_SOURCE_FILE_RE, "")];
|
|
7780
|
+
}).sort();
|
|
7781
|
+
if (exportNames.length === 0)
|
|
7782
|
+
return null;
|
|
7783
|
+
return `${exportNames.map((name) => `export * from "./${name}";`).join(`
|
|
7784
|
+
`)}
|
|
7785
|
+
`;
|
|
7786
|
+
}
|
|
7787
|
+
async#moduleContent(dir) {
|
|
7788
|
+
const rel = path26.relative(this.#workspaceRoot, dir);
|
|
7789
|
+
const parts = rel.split(path26.sep).filter(Boolean);
|
|
7790
|
+
const moduleSegment = parts.at(-1);
|
|
7791
|
+
if (!moduleSegment)
|
|
7792
|
+
return null;
|
|
7793
|
+
const isScalar = parts.at(-2) === "__scalar";
|
|
7794
|
+
const rawModel = moduleSegment.startsWith("_") ? moduleSegment.slice(1) : moduleSegment;
|
|
7795
|
+
if (!rawModel)
|
|
7796
|
+
return null;
|
|
7797
|
+
const modelName = capitalize3(rawModel);
|
|
7798
|
+
const allowedTypes = isScalar ? SCALAR_UI_TYPES : moduleSegment.startsWith("_") ? SERVICE_UI_TYPES : MODULE_UI_TYPES;
|
|
7799
|
+
const fileTypes = [];
|
|
7800
|
+
for (const type of allowedTypes) {
|
|
7801
|
+
if (await exists(path26.join(dir, `${modelName}.${type}.tsx`)))
|
|
7802
|
+
fileTypes.push(type);
|
|
7803
|
+
}
|
|
7804
|
+
if (fileTypes.length === 0)
|
|
7805
|
+
return null;
|
|
7806
|
+
return `
|
|
7807
|
+
${fileTypes.map((type) => `import * as ${type} from "./${modelName}.${type}";`).join(`
|
|
7808
|
+
`)}
|
|
7809
|
+
|
|
7810
|
+
export const ${modelName} = { ${fileTypes.join(", ")} };`;
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
var exists = async (file) => stat3(file).then(() => true).catch(() => false);
|
|
7814
|
+
var capitalize3 = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
7815
|
+
var formatError = (err) => err instanceof Error ? err.message : String(err);
|
|
7816
|
+
// pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
|
|
7817
|
+
import { mkdir as mkdir7 } from "fs/promises";
|
|
7818
|
+
import path27 from "path";
|
|
7236
7819
|
import {
|
|
7237
7820
|
generateFontFace,
|
|
7238
7821
|
getMetricsForFamily,
|
|
@@ -7256,7 +7839,7 @@ class FontOptimizer {
|
|
|
7256
7839
|
constructor(app, command = "start") {
|
|
7257
7840
|
this.#app = app;
|
|
7258
7841
|
this.#command = command;
|
|
7259
|
-
this.#artifactRoot =
|
|
7842
|
+
this.#artifactRoot = path27.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
|
|
7260
7843
|
}
|
|
7261
7844
|
async optimize() {
|
|
7262
7845
|
const fonts = await this.discoverFonts();
|
|
@@ -7275,7 +7858,7 @@ class FontOptimizer {
|
|
|
7275
7858
|
const pageKeys = await this.#app.getPageKeys();
|
|
7276
7859
|
const fonts = [];
|
|
7277
7860
|
await Promise.all(pageKeys.map(async (key) => {
|
|
7278
|
-
const filePath =
|
|
7861
|
+
const filePath = path27.resolve(this.#app.cwdPath, "page", key);
|
|
7279
7862
|
const file = Bun.file(filePath);
|
|
7280
7863
|
if (!await file.exists())
|
|
7281
7864
|
return;
|
|
@@ -7291,8 +7874,8 @@ class FontOptimizer {
|
|
|
7291
7874
|
this.#app.logger.warn(`[font] source not found: ${face.src}`);
|
|
7292
7875
|
continue;
|
|
7293
7876
|
}
|
|
7294
|
-
const outputPath =
|
|
7295
|
-
await
|
|
7877
|
+
const outputPath = path27.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
|
|
7878
|
+
await mkdir7(path27.dirname(outputPath), { recursive: true });
|
|
7296
7879
|
const sourceBuffer = Buffer.from(await Bun.file(sourcePath).arrayBuffer());
|
|
7297
7880
|
const outputBuffer = font.subset === false ? await this.#convertToWoff2(sourceBuffer, sourcePath) : await subsetFont(sourceBuffer, await this.#getSubsetText(font), { targetFormat: "woff2" });
|
|
7298
7881
|
await Bun.write(outputPath, outputBuffer);
|
|
@@ -7439,8 +8022,8 @@ class FontOptimizer {
|
|
|
7439
8022
|
return null;
|
|
7440
8023
|
const rel = src.replace(/^\//, "");
|
|
7441
8024
|
const candidates = [
|
|
7442
|
-
this.#command === "build" ?
|
|
7443
|
-
|
|
8025
|
+
this.#command === "build" ? path27.join(this.#app.dist.cwdPath, "public", rel) : null,
|
|
8026
|
+
path27.join(this.#app.cwdPath, "public", rel),
|
|
7444
8027
|
this.#resolveWorkspacePublicPath(rel)
|
|
7445
8028
|
].filter(Boolean);
|
|
7446
8029
|
for (const candidate of candidates) {
|
|
@@ -7468,7 +8051,7 @@ class FontOptimizer {
|
|
|
7468
8051
|
return "woff2";
|
|
7469
8052
|
if (signature === "OTTO")
|
|
7470
8053
|
return "otf";
|
|
7471
|
-
const ext =
|
|
8054
|
+
const ext = path27.extname(sourcePath).slice(1).toLowerCase();
|
|
7472
8055
|
if (ext === "otf" || ext === "woff" || ext === "woff2")
|
|
7473
8056
|
return ext;
|
|
7474
8057
|
return "ttf";
|
|
@@ -7477,7 +8060,7 @@ class FontOptimizer {
|
|
|
7477
8060
|
const [root, dep, ...rest] = rel.split("/");
|
|
7478
8061
|
if (root !== "libs" || !dep || rest.length === 0)
|
|
7479
8062
|
return null;
|
|
7480
|
-
return
|
|
8063
|
+
return path27.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
|
|
7481
8064
|
}
|
|
7482
8065
|
async#getSubsetText(font) {
|
|
7483
8066
|
const parts = new Set;
|
|
@@ -7487,7 +8070,7 @@ class FontOptimizer {
|
|
|
7487
8070
|
if (font.subsetText)
|
|
7488
8071
|
parts.add(font.subsetText);
|
|
7489
8072
|
for (const filePath of font.subsetFiles ?? []) {
|
|
7490
|
-
const abs =
|
|
8073
|
+
const abs = path27.isAbsolute(filePath) ? filePath : path27.join(this.#app.cwdPath, filePath);
|
|
7491
8074
|
const file = Bun.file(abs);
|
|
7492
8075
|
if (await file.exists())
|
|
7493
8076
|
parts.add(await file.text());
|
|
@@ -7506,7 +8089,7 @@ class FontOptimizer {
|
|
|
7506
8089
|
return "";
|
|
7507
8090
|
}
|
|
7508
8091
|
async#collectAutoSubsetText() {
|
|
7509
|
-
const roots = ["page", "ui"].map((dir) =>
|
|
8092
|
+
const roots = ["page", "ui"].map((dir) => path27.join(this.#app.cwdPath, dir));
|
|
7510
8093
|
const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
|
|
7511
8094
|
const parts = [];
|
|
7512
8095
|
await Promise.all(roots.map(async (root) => {
|
|
@@ -7620,43 +8203,43 @@ ${declarations.map(([prop, value]) => ` ${prop}: ${value};`).join(`
|
|
|
7620
8203
|
}
|
|
7621
8204
|
}
|
|
7622
8205
|
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
7623
|
-
import
|
|
7624
|
-
var
|
|
8206
|
+
import path28 from "path";
|
|
8207
|
+
var SOURCE_EXTS5 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
7625
8208
|
var CSS_EXTS = new Set([".css"]);
|
|
7626
|
-
var
|
|
8209
|
+
var CONFIG_BASENAMES2 = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
7627
8210
|
|
|
7628
8211
|
class HmrChangeClassifier {
|
|
7629
8212
|
classify(abs) {
|
|
7630
8213
|
if (this.#isUninteresting(abs))
|
|
7631
8214
|
return "ignore";
|
|
7632
|
-
const base =
|
|
7633
|
-
if (
|
|
8215
|
+
const base = path28.basename(abs);
|
|
8216
|
+
if (CONFIG_BASENAMES2.has(base))
|
|
7634
8217
|
return "config";
|
|
7635
|
-
const ext =
|
|
8218
|
+
const ext = path28.extname(abs).toLowerCase();
|
|
7636
8219
|
if (CSS_EXTS.has(ext))
|
|
7637
8220
|
return "css";
|
|
7638
|
-
if (
|
|
8221
|
+
if (SOURCE_EXTS5.has(ext))
|
|
7639
8222
|
return "code";
|
|
7640
8223
|
return "ignore";
|
|
7641
8224
|
}
|
|
7642
8225
|
#isUninteresting(abs) {
|
|
7643
|
-
const base =
|
|
8226
|
+
const base = path28.basename(abs);
|
|
7644
8227
|
if (!base)
|
|
7645
8228
|
return true;
|
|
7646
8229
|
if (base.startsWith("."))
|
|
7647
8230
|
return true;
|
|
7648
8231
|
if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
|
|
7649
8232
|
return true;
|
|
7650
|
-
if (abs.includes(`${
|
|
8233
|
+
if (abs.includes(`${path28.sep}node_modules${path28.sep}`))
|
|
7651
8234
|
return true;
|
|
7652
|
-
if (abs.includes(`${
|
|
8235
|
+
if (abs.includes(`${path28.sep}.akan${path28.sep}`))
|
|
7653
8236
|
return true;
|
|
7654
8237
|
return false;
|
|
7655
8238
|
}
|
|
7656
8239
|
}
|
|
7657
8240
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7658
8241
|
import fs4 from "fs";
|
|
7659
|
-
import
|
|
8242
|
+
import path29 from "path";
|
|
7660
8243
|
class HmrWatcher {
|
|
7661
8244
|
#roots;
|
|
7662
8245
|
#debounceMs;
|
|
@@ -7669,7 +8252,7 @@ class HmrWatcher {
|
|
|
7669
8252
|
#stopped = false;
|
|
7670
8253
|
#flushing = false;
|
|
7671
8254
|
constructor(opts) {
|
|
7672
|
-
this.#roots = [...new Set(opts.roots.map((r) =>
|
|
8255
|
+
this.#roots = [...new Set(opts.roots.map((r) => path29.resolve(r)))];
|
|
7673
8256
|
this.#debounceMs = opts.debounceMs ?? 80;
|
|
7674
8257
|
this.#onBatch = opts.onBatch;
|
|
7675
8258
|
this.#logger = opts.logger;
|
|
@@ -7680,7 +8263,7 @@ class HmrWatcher {
|
|
|
7680
8263
|
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7681
8264
|
if (!filename)
|
|
7682
8265
|
return;
|
|
7683
|
-
const abs =
|
|
8266
|
+
const abs = path29.resolve(root, filename.toString());
|
|
7684
8267
|
this.#queue(abs);
|
|
7685
8268
|
});
|
|
7686
8269
|
this.#watchers.push(w);
|
|
@@ -7738,10 +8321,10 @@ class HmrWatcher {
|
|
|
7738
8321
|
}
|
|
7739
8322
|
}
|
|
7740
8323
|
// pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
|
|
7741
|
-
import
|
|
8324
|
+
import path31 from "path";
|
|
7742
8325
|
|
|
7743
8326
|
// pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
|
|
7744
|
-
import
|
|
8327
|
+
import path30 from "path";
|
|
7745
8328
|
var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
|
|
7746
8329
|
var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "@akanjs/cli", "@akanjs/devkit"]);
|
|
7747
8330
|
var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
|
|
@@ -7784,7 +8367,7 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
7784
8367
|
const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
|
|
7785
8368
|
if (!replPath)
|
|
7786
8369
|
continue;
|
|
7787
|
-
const candidate =
|
|
8370
|
+
const candidate = path30.resolve(workspaceRoot, replPath + suffix);
|
|
7788
8371
|
const hit = await firstExisting(candidate);
|
|
7789
8372
|
if (hit)
|
|
7790
8373
|
return hit;
|
|
@@ -7796,8 +8379,8 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
7796
8379
|
if (spec === pkg)
|
|
7797
8380
|
continue;
|
|
7798
8381
|
const suffix = spec.slice(pkg.length + 1);
|
|
7799
|
-
const pkgDir =
|
|
7800
|
-
const candidate =
|
|
8382
|
+
const pkgDir = path30.dirname(path30.resolve(workspaceRoot, entryFile));
|
|
8383
|
+
const candidate = path30.join(pkgDir, suffix);
|
|
7801
8384
|
const hit = await firstExisting(candidate);
|
|
7802
8385
|
if (hit)
|
|
7803
8386
|
return hit;
|
|
@@ -7847,7 +8430,7 @@ async function firstExisting(basePath2) {
|
|
|
7847
8430
|
return candidate;
|
|
7848
8431
|
}
|
|
7849
8432
|
for (const ext of CANDIDATE_EXTS3) {
|
|
7850
|
-
const candidate =
|
|
8433
|
+
const candidate = path30.join(basePath2, `index${ext}`);
|
|
7851
8434
|
if (await Bun.file(candidate).exists())
|
|
7852
8435
|
return candidate;
|
|
7853
8436
|
}
|
|
@@ -7938,11 +8521,11 @@ class PagesBundleBuilder {
|
|
|
7938
8521
|
const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
|
|
7939
8522
|
if (!entryArtifact)
|
|
7940
8523
|
throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
|
|
7941
|
-
const bundlePath =
|
|
8524
|
+
const bundlePath = path31.resolve(entryArtifact.path);
|
|
7942
8525
|
const buildId = Date.now();
|
|
7943
8526
|
const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
|
|
7944
8527
|
const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
|
|
7945
|
-
this.#app.verbose(`[PagesBundleBuilder] ${
|
|
8528
|
+
this.#app.verbose(`[PagesBundleBuilder] ${path31.basename(bundlePath)} emitted in ${Date.now() - this.#started}ms splitting=${this.#splitting} entry=${entryArtifact.size} bytes outputs=${result.outputs.length} chunks=${chunkCount} total=${outputBytes} bytes`);
|
|
7946
8529
|
return {
|
|
7947
8530
|
bundlePath,
|
|
7948
8531
|
buildId,
|
|
@@ -8024,11 +8607,11 @@ function loaderFor4(absPath) {
|
|
|
8024
8607
|
}
|
|
8025
8608
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
8026
8609
|
import fs5 from "fs";
|
|
8027
|
-
import
|
|
8610
|
+
import path32 from "path";
|
|
8028
8611
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
8029
8612
|
var MIN_COMPRESS_BYTES = 1024;
|
|
8030
8613
|
async function precompressArtifacts(app) {
|
|
8031
|
-
const roots = [
|
|
8614
|
+
const roots = [path32.join(app.dist.cwdPath, ".akan/artifact/client")];
|
|
8032
8615
|
const result = { files: 0, inputBytes: 0, outputBytes: 0 };
|
|
8033
8616
|
await Promise.all(roots.map((root) => precompressRoot(root, result)));
|
|
8034
8617
|
if (result.files > 0) {
|
|
@@ -8054,7 +8637,7 @@ async function precompressRoot(root, result) {
|
|
|
8054
8637
|
async function shouldPrecompress(filePath) {
|
|
8055
8638
|
if (filePath.endsWith(".gz"))
|
|
8056
8639
|
return false;
|
|
8057
|
-
if (!COMPRESSIBLE_EXTS.has(
|
|
8640
|
+
if (!COMPRESSIBLE_EXTS.has(path32.extname(filePath).toLowerCase()))
|
|
8058
8641
|
return false;
|
|
8059
8642
|
const file = Bun.file(filePath);
|
|
8060
8643
|
if (!await file.exists())
|
|
@@ -8072,7 +8655,7 @@ function formatBytes(bytes) {
|
|
|
8072
8655
|
return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
8073
8656
|
}
|
|
8074
8657
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
8075
|
-
import
|
|
8658
|
+
import path33 from "path";
|
|
8076
8659
|
import { optimize } from "@tailwindcss/node";
|
|
8077
8660
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
8078
8661
|
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
@@ -8088,7 +8671,7 @@ class SsrBaseArtifactBuilder {
|
|
|
8088
8671
|
this.#app = app;
|
|
8089
8672
|
this.#command = command;
|
|
8090
8673
|
this.#artifactDir = `${command === "build" ? app.dist.cwdPath : app.cwdPath}/.akan/artifact`;
|
|
8091
|
-
this.#absArtifactDir =
|
|
8674
|
+
this.#absArtifactDir = path33.resolve(this.#artifactDir);
|
|
8092
8675
|
}
|
|
8093
8676
|
async build() {
|
|
8094
8677
|
const akanConfig2 = await this.#app.getConfig();
|
|
@@ -8110,7 +8693,7 @@ class SsrBaseArtifactBuilder {
|
|
|
8110
8693
|
rscRuntimeSsrManifest,
|
|
8111
8694
|
vendorMap,
|
|
8112
8695
|
cssAssets,
|
|
8113
|
-
pagesBundlePath: this.#command === "build" ?
|
|
8696
|
+
pagesBundlePath: this.#command === "build" ? path33.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
|
|
8114
8697
|
pagesBundleBuildId: pagesBundle.buildId,
|
|
8115
8698
|
domains: [...akanConfig2.domains],
|
|
8116
8699
|
subRoutes: Object.fromEntries(Array.from(akanConfig2.subRoutes.entries()).map(([basePath2, domains]) => [basePath2, [...domains]])),
|
|
@@ -8119,7 +8702,7 @@ class SsrBaseArtifactBuilder {
|
|
|
8119
8702
|
i18n: akanConfig2.i18n,
|
|
8120
8703
|
imageConfig: akanConfig2.images
|
|
8121
8704
|
};
|
|
8122
|
-
await Bun.write(
|
|
8705
|
+
await Bun.write(path33.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
|
|
8123
8706
|
`);
|
|
8124
8707
|
this.#app.verbose(`[base-artifact] complete in ${Date.now() - this.#started}ms`);
|
|
8125
8708
|
return { artifact, seedIndex, cssCompiler, optimizedFonts };
|
|
@@ -8167,15 +8750,15 @@ class SsrBaseArtifactBuilder {
|
|
|
8167
8750
|
async#resolveAkanServerPath() {
|
|
8168
8751
|
const candidates = [];
|
|
8169
8752
|
try {
|
|
8170
|
-
candidates.push(
|
|
8753
|
+
candidates.push(path33.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
|
|
8171
8754
|
} catch {}
|
|
8172
|
-
candidates.push(
|
|
8755
|
+
candidates.push(path33.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path33.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
|
|
8173
8756
|
try {
|
|
8174
|
-
candidates.push(
|
|
8757
|
+
candidates.push(path33.dirname(Bun.resolveSync("akanjs/server", path33.dirname(Bun.main))));
|
|
8175
8758
|
} catch {}
|
|
8176
|
-
candidates.push(
|
|
8759
|
+
candidates.push(path33.join(path33.dirname(Bun.main), "node_modules/akanjs/server"), path33.join(path33.dirname(Bun.main), "../../akanjs/server"), path33.resolve(import.meta.dir, "../../server"), path33.resolve(import.meta.dir, "../server"));
|
|
8177
8760
|
for (const candidate of candidates) {
|
|
8178
|
-
if (await Bun.file(
|
|
8761
|
+
if (await Bun.file(path33.join(candidate, "rscClient.tsx")).exists())
|
|
8179
8762
|
return candidate;
|
|
8180
8763
|
}
|
|
8181
8764
|
throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
|
|
@@ -8204,14 +8787,14 @@ ${preparedCssText}`).toString(36);
|
|
|
8204
8787
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
8205
8788
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
8206
8789
|
];
|
|
8207
|
-
await Bun.write(
|
|
8790
|
+
await Bun.write(path33.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
8208
8791
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
8209
8792
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
8210
8793
|
}
|
|
8211
8794
|
}
|
|
8212
8795
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
8213
8796
|
import fs6 from "fs";
|
|
8214
|
-
import
|
|
8797
|
+
import path34 from "path";
|
|
8215
8798
|
|
|
8216
8799
|
class WatchRootResolver {
|
|
8217
8800
|
#app;
|
|
@@ -8221,15 +8804,15 @@ class WatchRootResolver {
|
|
|
8221
8804
|
async resolve() {
|
|
8222
8805
|
const tsconfig = await this.#app.getTsConfig();
|
|
8223
8806
|
const set = new Set;
|
|
8224
|
-
set.add(
|
|
8807
|
+
set.add(path34.resolve(`${this.#app.cwdPath}/page`));
|
|
8225
8808
|
for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
|
|
8226
8809
|
for (const target of targets) {
|
|
8227
8810
|
if (!target)
|
|
8228
8811
|
continue;
|
|
8229
|
-
if (
|
|
8812
|
+
if (path34.isAbsolute(target))
|
|
8230
8813
|
continue;
|
|
8231
8814
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
8232
|
-
const resolved =
|
|
8815
|
+
const resolved = path34.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
8233
8816
|
if (fs6.existsSync(resolved))
|
|
8234
8817
|
set.add(resolved);
|
|
8235
8818
|
}
|
|
@@ -8296,7 +8879,7 @@ class ApplicationBuildRunner {
|
|
|
8296
8879
|
phases: this.#phases,
|
|
8297
8880
|
durationMs: Date.now() - this.#startedAt,
|
|
8298
8881
|
outputDir: this.#app.dist.cwdPath,
|
|
8299
|
-
artifactDir:
|
|
8882
|
+
artifactDir: path35.join(this.#app.dist.cwdPath, ".akan/artifact")
|
|
8300
8883
|
};
|
|
8301
8884
|
}
|
|
8302
8885
|
async typecheck(options = {}) {
|
|
@@ -8304,7 +8887,7 @@ class ApplicationBuildRunner {
|
|
|
8304
8887
|
await this.#app.getPageKeys({ refresh: true });
|
|
8305
8888
|
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig({ incremental });
|
|
8306
8889
|
if (clean)
|
|
8307
|
-
await
|
|
8890
|
+
await rm3(path35.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
|
|
8308
8891
|
await this.#checkProjectInChildProcess(tsconfigPath);
|
|
8309
8892
|
}
|
|
8310
8893
|
async#runPhase(id, label, task, summarize, options = {}) {
|
|
@@ -8376,7 +8959,7 @@ class ApplicationBuildRunner {
|
|
|
8376
8959
|
};
|
|
8377
8960
|
}
|
|
8378
8961
|
async#writeConsoleShim() {
|
|
8379
|
-
await Bun.write(
|
|
8962
|
+
await Bun.write(path35.join(this.#app.dist.cwdPath, "console.js"), `import { cnst, db, dict, option, server, sig, srv } from "./server.js";
|
|
8380
8963
|
import { assertAkanConsoleAllowed, startAkanConsole } from "./console-runtime.js";
|
|
8381
8964
|
|
|
8382
8965
|
const run = async () => {
|
|
@@ -8399,14 +8982,14 @@ void run().catch((error) => {
|
|
|
8399
8982
|
try {
|
|
8400
8983
|
return Bun.resolveSync("akanjs/server/rsc-worker", import.meta.dir);
|
|
8401
8984
|
} catch {
|
|
8402
|
-
return
|
|
8985
|
+
return path35.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/rscWorker.tsx");
|
|
8403
8986
|
}
|
|
8404
8987
|
}
|
|
8405
8988
|
#resolveConsoleRuntimeBuildEntry() {
|
|
8406
8989
|
try {
|
|
8407
|
-
return
|
|
8990
|
+
return path35.join(path35.dirname(Bun.resolveSync("akanjs/server", import.meta.dir)), "console.ts");
|
|
8408
8991
|
} catch {
|
|
8409
|
-
return
|
|
8992
|
+
return path35.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/console.ts");
|
|
8410
8993
|
}
|
|
8411
8994
|
}
|
|
8412
8995
|
async#buildCsr() {
|
|
@@ -8423,8 +9006,8 @@ void run().catch((error) => {
|
|
|
8423
9006
|
return { base, allRoutes };
|
|
8424
9007
|
}
|
|
8425
9008
|
async#writeTypecheckTsconfig({ incremental = true } = {}) {
|
|
8426
|
-
const typecheckDir =
|
|
8427
|
-
await
|
|
9009
|
+
const typecheckDir = path35.join(this.#app.cwdPath, ".akan", "typecheck");
|
|
9010
|
+
await mkdir8(typecheckDir, { recursive: true });
|
|
8428
9011
|
const tsconfig = {
|
|
8429
9012
|
extends: "../../tsconfig.json",
|
|
8430
9013
|
compilerOptions: {
|
|
@@ -8442,7 +9025,7 @@ void run().catch((error) => {
|
|
|
8442
9025
|
],
|
|
8443
9026
|
references: []
|
|
8444
9027
|
};
|
|
8445
|
-
const tsconfigPath =
|
|
9028
|
+
const tsconfigPath = path35.join(typecheckDir, "tsconfig.json");
|
|
8446
9029
|
await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
8447
9030
|
`);
|
|
8448
9031
|
return { typecheckDir, tsconfigPath };
|
|
@@ -8468,10 +9051,10 @@ void run().catch((error) => {
|
|
|
8468
9051
|
}
|
|
8469
9052
|
async#resolveTypecheckWorkerEntry() {
|
|
8470
9053
|
const candidates = [
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
9054
|
+
path35.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
9055
|
+
path35.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
9056
|
+
path35.join(import.meta.dir, "typecheck.proc.js"),
|
|
9057
|
+
path35.join(import.meta.dir, "typecheck.proc.ts")
|
|
8475
9058
|
];
|
|
8476
9059
|
for (const candidate of candidates)
|
|
8477
9060
|
if (await Bun.file(candidate).exists())
|
|
@@ -8504,7 +9087,7 @@ void run().catch((error) => {
|
|
|
8504
9087
|
}
|
|
8505
9088
|
}
|
|
8506
9089
|
// pkgs/@akanjs/devkit/applicationReleasePackager.ts
|
|
8507
|
-
import { cp, mkdir as
|
|
9090
|
+
import { cp, mkdir as mkdir9, rm as rm4 } from "fs/promises";
|
|
8508
9091
|
|
|
8509
9092
|
// pkgs/@akanjs/devkit/uploadRelease.ts
|
|
8510
9093
|
import { HttpClient as HttpClient2, Logger as Logger9 } from "akanjs/common";
|
|
@@ -8610,16 +9193,16 @@ class ApplicationReleasePackager {
|
|
|
8610
9193
|
const platformVersion = akanConfig2.mobile.version;
|
|
8611
9194
|
const buildRoot = `${this.#app.workspace.workspaceRoot}/releases/builds/${this.#app.name}`;
|
|
8612
9195
|
if (await FileSys.dirExists(buildRoot))
|
|
8613
|
-
await
|
|
8614
|
-
await
|
|
9196
|
+
await rm4(buildRoot, { recursive: true, force: true });
|
|
9197
|
+
await mkdir9(buildRoot, { recursive: true });
|
|
8615
9198
|
if (rebuild || !await FileSys.dirExists(`${this.#app.dist.cwdPath}/backend`))
|
|
8616
9199
|
await this.#build();
|
|
8617
9200
|
const buildVersion = `${platformVersion}-${buildNum}`;
|
|
8618
9201
|
const buildPath = `${buildRoot}/${buildVersion}`;
|
|
8619
|
-
await
|
|
9202
|
+
await mkdir9(buildPath, { recursive: true });
|
|
8620
9203
|
await cp(`${this.#app.dist.cwdPath}/backend`, `${buildPath}/backend`, { recursive: true });
|
|
8621
9204
|
await cp(this.#app.dist.cwdPath, buildRoot, { recursive: true });
|
|
8622
|
-
await
|
|
9205
|
+
await rm4(`${buildRoot}/frontend/.next`, { recursive: true, force: true });
|
|
8623
9206
|
await this.#app.workspace.spawn("tar", [
|
|
8624
9207
|
"-zcf",
|
|
8625
9208
|
`${this.#app.workspace.workspaceRoot}/releases/builds/${this.#app.name}-release.tar.gz`,
|
|
@@ -8639,7 +9222,7 @@ class ApplicationReleasePackager {
|
|
|
8639
9222
|
`${this.#app.workspace.workspaceRoot}/releases/builds/${this.#app.name}-appBuild.zip`,
|
|
8640
9223
|
"./csr"
|
|
8641
9224
|
]);
|
|
8642
|
-
await
|
|
9225
|
+
await rm4("./csr", { recursive: true, force: true });
|
|
8643
9226
|
}
|
|
8644
9227
|
async#writeSourceArchive({ readme }) {
|
|
8645
9228
|
const sourceRoot = `${this.#app.workspace.workspaceRoot}/releases/sources/${this.#app.name}`;
|
|
@@ -8647,13 +9230,13 @@ class ApplicationReleasePackager {
|
|
|
8647
9230
|
await cp(this.#app.dist.cwdPath, `${sourceRoot}/apps/${this.#app.name}`, { recursive: true });
|
|
8648
9231
|
const libDeps = ["social", "shared", "platform", "util"];
|
|
8649
9232
|
await Promise.all(libDeps.map((lib) => cp(`${this.#app.workspace.cwdPath}/libs/${lib}`, `${sourceRoot}/libs/${lib}`, { recursive: true })));
|
|
8650
|
-
await Promise.all([".next", "ios", "android", "public/libs"].map(async (
|
|
8651
|
-
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${
|
|
9233
|
+
await Promise.all([".next", "ios", "android", "public/libs"].map(async (path36) => {
|
|
9234
|
+
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${path36}`;
|
|
8652
9235
|
if (await FileSys.dirExists(targetPath))
|
|
8653
|
-
await
|
|
9236
|
+
await rm4(targetPath, { recursive: true, force: true });
|
|
8654
9237
|
}));
|
|
8655
9238
|
const syncPaths = [".husky", ".gitignore", "package.json"];
|
|
8656
|
-
await Promise.all(syncPaths.map((
|
|
9239
|
+
await Promise.all(syncPaths.map((path36) => cp(`${this.#app.workspace.cwdPath}/${path36}`, `${sourceRoot}/${path36}`, { recursive: true })));
|
|
8657
9240
|
await this.#writeSourceTsconfig(sourceRoot, libDeps);
|
|
8658
9241
|
await Bun.write(`${sourceRoot}/README.md`, readme);
|
|
8659
9242
|
await this.#app.workspace.spawn("tar", [
|
|
@@ -8669,11 +9252,11 @@ class ApplicationReleasePackager {
|
|
|
8669
9252
|
const maxRetry = 3;
|
|
8670
9253
|
for (let i = 0;i < maxRetry; i++) {
|
|
8671
9254
|
try {
|
|
8672
|
-
await
|
|
9255
|
+
await rm4(sourceRoot, { recursive: true, force: true });
|
|
8673
9256
|
} catch {}
|
|
8674
9257
|
}
|
|
8675
9258
|
}
|
|
8676
|
-
await
|
|
9259
|
+
await mkdir9(sourceRoot, { recursive: true });
|
|
8677
9260
|
}
|
|
8678
9261
|
async#writeSourceTsconfig(sourceRoot, libDeps) {
|
|
8679
9262
|
const tsconfig = await this.#app.workspace.readJson("tsconfig.json");
|
|
@@ -8744,20 +9327,20 @@ class ApplicationReleasePackager {
|
|
|
8744
9327
|
}
|
|
8745
9328
|
}
|
|
8746
9329
|
// pkgs/@akanjs/devkit/applicationTestPreload.ts
|
|
8747
|
-
import
|
|
9330
|
+
import path36 from "path";
|
|
8748
9331
|
var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
|
|
8749
9332
|
async function resolveSignalTestPreloadPath(target) {
|
|
8750
9333
|
const candidates = [];
|
|
8751
9334
|
const addResolvedPackageCandidate = (basePath2) => {
|
|
8752
9335
|
try {
|
|
8753
|
-
candidates.push(
|
|
9336
|
+
candidates.push(path36.join(path36.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
|
|
8754
9337
|
} catch {}
|
|
8755
9338
|
};
|
|
8756
9339
|
addResolvedPackageCandidate(target.cwdPath);
|
|
8757
9340
|
addResolvedPackageCandidate(process.cwd());
|
|
8758
|
-
addResolvedPackageCandidate(
|
|
9341
|
+
addResolvedPackageCandidate(path36.dirname(Bun.main));
|
|
8759
9342
|
addResolvedPackageCandidate(import.meta.dir);
|
|
8760
|
-
candidates.push(
|
|
9343
|
+
candidates.push(path36.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path36.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path36.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path36.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path36.join(path36.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path36.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
|
|
8761
9344
|
for (const candidate of [...new Set(candidates)]) {
|
|
8762
9345
|
if (await Bun.file(candidate).exists())
|
|
8763
9346
|
return candidate;
|
|
@@ -8766,8 +9349,8 @@ async function resolveSignalTestPreloadPath(target) {
|
|
|
8766
9349
|
}
|
|
8767
9350
|
// pkgs/@akanjs/devkit/builder.ts
|
|
8768
9351
|
import { existsSync as existsSync2 } from "fs";
|
|
8769
|
-
import { mkdir as
|
|
8770
|
-
import
|
|
9352
|
+
import { mkdir as mkdir10 } from "fs/promises";
|
|
9353
|
+
import path37 from "path";
|
|
8771
9354
|
var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
|
|
8772
9355
|
var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
|
|
8773
9356
|
var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
|
|
@@ -8784,14 +9367,14 @@ class Builder {
|
|
|
8784
9367
|
#globEntrypoints(cwd, pattern) {
|
|
8785
9368
|
const glob = new Bun.Glob(pattern);
|
|
8786
9369
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
8787
|
-
const segments = relativePath.split(
|
|
9370
|
+
const segments = relativePath.split(path37.sep);
|
|
8788
9371
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
8789
|
-
}).map((rel) =>
|
|
9372
|
+
}).map((rel) => path37.join(cwd, rel));
|
|
8790
9373
|
}
|
|
8791
9374
|
#globFiles(cwd, pattern = "**/*.*") {
|
|
8792
9375
|
const glob = new Bun.Glob(pattern);
|
|
8793
9376
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
8794
|
-
const segments = relativePath.split(
|
|
9377
|
+
const segments = relativePath.split(path37.sep);
|
|
8795
9378
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
8796
9379
|
});
|
|
8797
9380
|
}
|
|
@@ -8799,17 +9382,17 @@ class Builder {
|
|
|
8799
9382
|
const out = [];
|
|
8800
9383
|
for (const p of additionalEntryPoints) {
|
|
8801
9384
|
if (p.includes("*")) {
|
|
8802
|
-
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${
|
|
9385
|
+
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path37.sep}`) ? p.slice(cwd.length + 1) : p;
|
|
8803
9386
|
out.push(...this.#globEntrypoints(cwd, rel));
|
|
8804
9387
|
} else
|
|
8805
|
-
out.push(
|
|
9388
|
+
out.push(path37.isAbsolute(p) ? p : path37.join(cwd, p));
|
|
8806
9389
|
}
|
|
8807
9390
|
return out;
|
|
8808
9391
|
}
|
|
8809
9392
|
#getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
|
|
8810
9393
|
const cwd = this.#executor.cwdPath;
|
|
8811
9394
|
const entrypoints = [
|
|
8812
|
-
...bundle ? [
|
|
9395
|
+
...bundle ? [path37.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
|
|
8813
9396
|
...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
|
|
8814
9397
|
];
|
|
8815
9398
|
return {
|
|
@@ -8830,9 +9413,9 @@ class Builder {
|
|
|
8830
9413
|
for (const relativePath of this.#globFiles(cwd)) {
|
|
8831
9414
|
if (relativePath === "package.json")
|
|
8832
9415
|
continue;
|
|
8833
|
-
const sourcePath =
|
|
8834
|
-
const targetPath =
|
|
8835
|
-
await
|
|
9416
|
+
const sourcePath = path37.join(cwd, relativePath);
|
|
9417
|
+
const targetPath = path37.join(this.#distExecutor.cwdPath, relativePath);
|
|
9418
|
+
await mkdir10(path37.dirname(targetPath), { recursive: true });
|
|
8836
9419
|
await Bun.write(targetPath, Bun.file(sourcePath));
|
|
8837
9420
|
}
|
|
8838
9421
|
}
|
|
@@ -8843,13 +9426,13 @@ class Builder {
|
|
|
8843
9426
|
return withoutFormatDir;
|
|
8844
9427
|
if (!hasDotSlash && withoutFormatDir === publishedPath)
|
|
8845
9428
|
return publishedPath;
|
|
8846
|
-
const parsed =
|
|
9429
|
+
const parsed = path37.posix.parse(withoutFormatDir);
|
|
8847
9430
|
if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
|
|
8848
9431
|
return withoutFormatDir;
|
|
8849
|
-
const withoutExt =
|
|
9432
|
+
const withoutExt = path37.posix.join(parsed.dir, parsed.name);
|
|
8850
9433
|
const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
|
|
8851
9434
|
const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
|
|
8852
|
-
const matchedSource = sourceCandidates.find((candidate) => existsSync2(
|
|
9435
|
+
const matchedSource = sourceCandidates.find((candidate) => existsSync2(path37.join(this.#executor.cwdPath, candidate)));
|
|
8853
9436
|
if (!matchedSource)
|
|
8854
9437
|
return withoutFormatDir;
|
|
8855
9438
|
return hasDotSlash ? `./${matchedSource}` : matchedSource;
|
|
@@ -8898,10 +9481,10 @@ class Builder {
|
|
|
8898
9481
|
}
|
|
8899
9482
|
}
|
|
8900
9483
|
// pkgs/@akanjs/devkit/capacitorApp.ts
|
|
8901
|
-
import { cp as cp2, mkdir as
|
|
8902
|
-
import
|
|
9484
|
+
import { cp as cp2, mkdir as mkdir11, rm as rm5 } from "fs/promises";
|
|
9485
|
+
import path38 from "path";
|
|
8903
9486
|
import { MobileProject } from "@trapezedev/project";
|
|
8904
|
-
import { capitalize as
|
|
9487
|
+
import { capitalize as capitalize4 } from "akanjs/common";
|
|
8905
9488
|
|
|
8906
9489
|
// pkgs/@akanjs/devkit/fileEditor.ts
|
|
8907
9490
|
class FileEditor {
|
|
@@ -9094,10 +9677,10 @@ class CapacitorApp {
|
|
|
9094
9677
|
constructor(app, target) {
|
|
9095
9678
|
this.app = app;
|
|
9096
9679
|
this.target = target;
|
|
9097
|
-
this.targetRootPath =
|
|
9098
|
-
this.targetRoot =
|
|
9099
|
-
this.targetWebRoot =
|
|
9100
|
-
this.targetAssetRoot =
|
|
9680
|
+
this.targetRootPath = path38.posix.join(".akan", "mobile", this.target.name);
|
|
9681
|
+
this.targetRoot = path38.join(this.app.cwdPath, this.targetRootPath);
|
|
9682
|
+
this.targetWebRoot = path38.join(this.targetRoot, "www");
|
|
9683
|
+
this.targetAssetRoot = path38.join(this.targetRoot, "assets");
|
|
9101
9684
|
this.project = new MobileProject(this.app.cwdPath, {
|
|
9102
9685
|
android: { path: this.androidRootPath },
|
|
9103
9686
|
ios: { path: this.iosProjectPath }
|
|
@@ -9109,13 +9692,13 @@ class CapacitorApp {
|
|
|
9109
9692
|
env = "debug",
|
|
9110
9693
|
regenerate = false
|
|
9111
9694
|
} = {}) {
|
|
9112
|
-
await
|
|
9695
|
+
await mkdir11(this.targetRoot, { recursive: true });
|
|
9113
9696
|
await this.#writeCapacitorConfig();
|
|
9114
9697
|
if (regenerate) {
|
|
9115
9698
|
if (!platform || platform === "ios")
|
|
9116
|
-
await
|
|
9699
|
+
await rm5(path38.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
|
|
9117
9700
|
if (!platform || platform === "android")
|
|
9118
|
-
await
|
|
9701
|
+
await rm5(path38.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
|
|
9119
9702
|
}
|
|
9120
9703
|
const project = this.project;
|
|
9121
9704
|
await this.project.load();
|
|
@@ -9179,7 +9762,7 @@ class CapacitorApp {
|
|
|
9179
9762
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
9180
9763
|
}
|
|
9181
9764
|
async#updateAndroidBuildTypes() {
|
|
9182
|
-
const appGradle = await FileEditor.create(
|
|
9765
|
+
const appGradle = await FileEditor.create(path38.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
|
|
9183
9766
|
const buildTypesBlock = `
|
|
9184
9767
|
debug {
|
|
9185
9768
|
applicationIdSuffix ".debug"
|
|
@@ -9222,7 +9805,7 @@ class CapacitorApp {
|
|
|
9222
9805
|
const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
|
|
9223
9806
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
9224
9807
|
stdio: "inherit",
|
|
9225
|
-
cwd:
|
|
9808
|
+
cwd: path38.join(this.app.cwdPath, this.androidRootPath),
|
|
9226
9809
|
env: await this.#commandEnv("release", env)
|
|
9227
9810
|
});
|
|
9228
9811
|
}
|
|
@@ -9230,10 +9813,10 @@ class CapacitorApp {
|
|
|
9230
9813
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
9231
9814
|
}
|
|
9232
9815
|
async#ensureAndroidAssetsDir() {
|
|
9233
|
-
await
|
|
9816
|
+
await mkdir11(path38.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
9234
9817
|
}
|
|
9235
9818
|
async#ensureAndroidDebugKeystore() {
|
|
9236
|
-
const keystorePath =
|
|
9819
|
+
const keystorePath = path38.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
9237
9820
|
if (await Bun.file(keystorePath).exists())
|
|
9238
9821
|
return;
|
|
9239
9822
|
await this.#spawn("keytool", [
|
|
@@ -9279,12 +9862,12 @@ class CapacitorApp {
|
|
|
9279
9862
|
await this.#prepareAndroid({ operation: "release", env: "main" });
|
|
9280
9863
|
}
|
|
9281
9864
|
async prepareWww() {
|
|
9282
|
-
const htmlSource =
|
|
9865
|
+
const htmlSource = path38.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
|
|
9283
9866
|
if (!await Bun.file(htmlSource).exists())
|
|
9284
9867
|
throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
|
|
9285
|
-
await
|
|
9286
|
-
await
|
|
9287
|
-
await Bun.write(
|
|
9868
|
+
await rm5(this.targetWebRoot, { recursive: true, force: true });
|
|
9869
|
+
await mkdir11(this.targetWebRoot, { recursive: true });
|
|
9870
|
+
await Bun.write(path38.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
|
|
9288
9871
|
}
|
|
9289
9872
|
#injectMobileTargetMeta(html) {
|
|
9290
9873
|
const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
@@ -9295,8 +9878,8 @@ class CapacitorApp {
|
|
|
9295
9878
|
</head>`);
|
|
9296
9879
|
}
|
|
9297
9880
|
async#writeCapacitorConfig() {
|
|
9298
|
-
await
|
|
9299
|
-
const appInfoPath =
|
|
9881
|
+
await mkdir11(this.targetRoot, { recursive: true });
|
|
9882
|
+
const appInfoPath = path38.relative(this.app.cwdPath, path38.join(this.app.cwdPath, "akan.app.json")).split(path38.sep).join("/");
|
|
9300
9883
|
const content = `import type { AppScanResult } from "akanjs";
|
|
9301
9884
|
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
9302
9885
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
@@ -9317,18 +9900,18 @@ export default withBase(
|
|
|
9317
9900
|
appInfo as AppScanResult,
|
|
9318
9901
|
);
|
|
9319
9902
|
`;
|
|
9320
|
-
await Bun.write(
|
|
9903
|
+
await Bun.write(path38.join(this.app.cwdPath, "capacitor.config.ts"), content);
|
|
9321
9904
|
}
|
|
9322
9905
|
async#prepareTargetAssets() {
|
|
9323
9906
|
if (!this.target.assets)
|
|
9324
9907
|
return;
|
|
9325
|
-
await
|
|
9908
|
+
await mkdir11(this.targetAssetRoot, { recursive: true });
|
|
9326
9909
|
if (this.target.assets.icon)
|
|
9327
|
-
await cp2(
|
|
9910
|
+
await cp2(path38.join(this.app.cwdPath, this.target.assets.icon), path38.join(this.targetAssetRoot, "icon.png"), {
|
|
9328
9911
|
force: true
|
|
9329
9912
|
});
|
|
9330
9913
|
if (this.target.assets.splash)
|
|
9331
|
-
await cp2(
|
|
9914
|
+
await cp2(path38.join(this.app.cwdPath, this.target.assets.splash), path38.join(this.targetAssetRoot, "splash.png"), {
|
|
9332
9915
|
force: true
|
|
9333
9916
|
});
|
|
9334
9917
|
}
|
|
@@ -9336,11 +9919,11 @@ export default withBase(
|
|
|
9336
9919
|
const files = this.target.files?.[platform];
|
|
9337
9920
|
if (!files)
|
|
9338
9921
|
return;
|
|
9339
|
-
const platformRoot =
|
|
9922
|
+
const platformRoot = path38.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
|
|
9340
9923
|
await Promise.all(Object.entries(files).map(async ([to, from]) => {
|
|
9341
|
-
const targetPath =
|
|
9342
|
-
await
|
|
9343
|
-
await cp2(
|
|
9924
|
+
const targetPath = path38.join(platformRoot, to);
|
|
9925
|
+
await mkdir11(path38.dirname(targetPath), { recursive: true });
|
|
9926
|
+
await cp2(path38.join(this.app.cwdPath, from), targetPath, { force: true });
|
|
9344
9927
|
}));
|
|
9345
9928
|
}
|
|
9346
9929
|
async#generateAssets({ operation, env }) {
|
|
@@ -9350,7 +9933,7 @@ export default withBase(
|
|
|
9350
9933
|
"@capacitor/assets",
|
|
9351
9934
|
"generate",
|
|
9352
9935
|
"--assetPath",
|
|
9353
|
-
|
|
9936
|
+
path38.posix.join(this.targetRootPath, "assets"),
|
|
9354
9937
|
"--iosProject",
|
|
9355
9938
|
this.iosProjectPath,
|
|
9356
9939
|
"--androidProject",
|
|
@@ -9452,7 +10035,7 @@ export default withBase(
|
|
|
9452
10035
|
this.#setPermissionsInAndroid(["POST_NOTIFICATIONS"]);
|
|
9453
10036
|
}
|
|
9454
10037
|
async#setPermissionInIos(permissions) {
|
|
9455
|
-
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${
|
|
10038
|
+
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${capitalize4(key)}`, value]));
|
|
9456
10039
|
await Promise.all([
|
|
9457
10040
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Debug", updateNs),
|
|
9458
10041
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Release", updateNs)
|
|
@@ -9537,15 +10120,15 @@ var Pkg = createInternalArgToken("Pkg");
|
|
|
9537
10120
|
var Module = createInternalArgToken("Module");
|
|
9538
10121
|
var Workspace = createInternalArgToken("Workspace");
|
|
9539
10122
|
// pkgs/@akanjs/devkit/commandDecorators/command.ts
|
|
9540
|
-
import
|
|
10123
|
+
import path39 from "path";
|
|
9541
10124
|
import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
|
|
9542
10125
|
import { Logger as Logger10 } from "akanjs/common";
|
|
9543
10126
|
import chalk6 from "chalk";
|
|
9544
10127
|
import { program } from "commander";
|
|
9545
10128
|
|
|
9546
10129
|
// pkgs/@akanjs/devkit/commandDecorators/dependencyBuilder.ts
|
|
9547
|
-
var
|
|
9548
|
-
var createDependencyKey = (refName, kind) => `${refName}${
|
|
10130
|
+
var capitalize5 = (value) => value.slice(0, 1).toUpperCase() + value.slice(1);
|
|
10131
|
+
var createDependencyKey = (refName, kind) => `${refName}${capitalize5(kind)}`;
|
|
9549
10132
|
|
|
9550
10133
|
class CommandContainer {
|
|
9551
10134
|
static #instances = new Map;
|
|
@@ -10037,7 +10620,7 @@ var runCommands = async (...commands) => {
|
|
|
10037
10620
|
process.exit(1);
|
|
10038
10621
|
});
|
|
10039
10622
|
const __dirname2 = getDirname(import.meta.url);
|
|
10040
|
-
const packageJsonCandidates = [`${
|
|
10623
|
+
const packageJsonCandidates = [`${path39.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
|
|
10041
10624
|
let cliPackageJson = null;
|
|
10042
10625
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
10043
10626
|
if (!await FileSys.fileExists(packageJsonPath))
|
|
@@ -10315,8 +10898,8 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
10315
10898
|
return importSpecifiers;
|
|
10316
10899
|
};
|
|
10317
10900
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
10318
|
-
const configFile = ts7.readConfigFile(tsConfigPath, (
|
|
10319
|
-
return ts7.sys.readFile(
|
|
10901
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path40) => {
|
|
10902
|
+
return ts7.sys.readFile(path40);
|
|
10320
10903
|
});
|
|
10321
10904
|
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
10322
10905
|
};
|
|
@@ -11513,7 +12096,7 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
|
|
|
11513
12096
|
import { Logger as Logger16 } from "akanjs/common";
|
|
11514
12097
|
|
|
11515
12098
|
// pkgs/@akanjs/cli/package/package.runner.ts
|
|
11516
|
-
import
|
|
12099
|
+
import path40 from "path";
|
|
11517
12100
|
import { Logger as Logger14 } from "akanjs/common";
|
|
11518
12101
|
var {$: $2 } = globalThis.Bun;
|
|
11519
12102
|
|
|
@@ -11533,11 +12116,11 @@ class PackageRunner extends runner("package") {
|
|
|
11533
12116
|
}
|
|
11534
12117
|
async#getInstalledPackageJson() {
|
|
11535
12118
|
const packageJsonCandidates = [
|
|
11536
|
-
`${
|
|
12119
|
+
`${path40.dirname(Bun.main)}/package.json`,
|
|
11537
12120
|
`${process.cwd()}/node_modules/akanjs/package.json`
|
|
11538
12121
|
];
|
|
11539
12122
|
try {
|
|
11540
|
-
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json",
|
|
12123
|
+
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json", path40.dirname(Bun.main)));
|
|
11541
12124
|
} catch {}
|
|
11542
12125
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
11543
12126
|
if (!await Bun.file(packageJsonPath).exists())
|
|
@@ -11546,7 +12129,7 @@ class PackageRunner extends runner("package") {
|
|
|
11546
12129
|
if (packageJson.name === "akanjs" || packageJson.name === "@akanjs/cli")
|
|
11547
12130
|
return packageJson;
|
|
11548
12131
|
}
|
|
11549
|
-
throw new Error(`[package] failed to locate akanjs package.json from ${
|
|
12132
|
+
throw new Error(`[package] failed to locate akanjs package.json from ${path40.dirname(Bun.main)}`);
|
|
11550
12133
|
}
|
|
11551
12134
|
async createPackage(workspace, pkgName) {
|
|
11552
12135
|
await workspace.applyTemplate({ basePath: `pkgs/${pkgName}`, template: "pkgRoot", dict: { pkgName } });
|
|
@@ -11721,7 +12304,7 @@ class PackageScript extends script("package", [PackageRunner]) {
|
|
|
11721
12304
|
}
|
|
11722
12305
|
|
|
11723
12306
|
// pkgs/@akanjs/cli/cloud/cloud.runner.ts
|
|
11724
|
-
import
|
|
12307
|
+
import path41 from "path";
|
|
11725
12308
|
import { confirm as confirm4, input as input5, select as select7 } from "@inquirer/prompts";
|
|
11726
12309
|
import { Logger as Logger15, sleep } from "akanjs/common";
|
|
11727
12310
|
import chalk7 from "chalk";
|
|
@@ -11992,7 +12575,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
11992
12575
|
await Promise.all(akanPkgs.map(async (library) => {
|
|
11993
12576
|
Logger15.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
|
|
11994
12577
|
await workspace.spawn("npm", ["publish", "--tag", tag, ...this.#getRegistryArgs(registry), ...this.#getLocalRegistryAuthArgs(registry)], {
|
|
11995
|
-
cwd:
|
|
12578
|
+
cwd: path41.join(workspace.workspaceRoot, "dist/pkgs", library),
|
|
11996
12579
|
env: this.#getRegistryEnv(registry),
|
|
11997
12580
|
stdio: "inherit"
|
|
11998
12581
|
});
|
|
@@ -12050,7 +12633,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
12050
12633
|
await workspace.remove(localPath);
|
|
12051
12634
|
}
|
|
12052
12635
|
async uploadEnv(cloudApi2, workspaceId, filePath) {
|
|
12053
|
-
const file = new File([Bun.file(filePath)],
|
|
12636
|
+
const file = new File([Bun.file(filePath)], path41.basename(filePath));
|
|
12054
12637
|
await cloudApi2.uploadEnv(workspaceId, file);
|
|
12055
12638
|
}
|
|
12056
12639
|
async downloadEnvByScp(workspace) {
|
|
@@ -12142,14 +12725,14 @@ class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, Packa
|
|
|
12142
12725
|
}
|
|
12143
12726
|
async uploadEnv(workspace) {
|
|
12144
12727
|
const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
|
|
12145
|
-
const { path:
|
|
12728
|
+
const { path: path42 } = await this.cloudRunner.gatherEnvFiles(workspace);
|
|
12146
12729
|
if (workspaceId) {
|
|
12147
12730
|
await this.login(workspace);
|
|
12148
12731
|
const cloudApi2 = await CloudApi.fromHost(workspace);
|
|
12149
|
-
await this.cloudRunner.uploadEnv(cloudApi2, workspaceId,
|
|
12732
|
+
await this.cloudRunner.uploadEnv(cloudApi2, workspaceId, path42);
|
|
12150
12733
|
return;
|
|
12151
12734
|
}
|
|
12152
|
-
await this.cloudRunner.uploadEnvByScp(workspace,
|
|
12735
|
+
await this.cloudRunner.uploadEnvByScp(workspace, path42);
|
|
12153
12736
|
}
|
|
12154
12737
|
async deployAkan(workspace, { test = true, registryUrl } = {}) {
|
|
12155
12738
|
const akanPkgs = await this.cloudRunner.getAkanPkgs(workspace);
|
|
@@ -12563,14 +13146,14 @@ class GuidelinePrompt extends Prompter {
|
|
|
12563
13146
|
async#getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
|
|
12564
13147
|
const glob = new Bun.Glob(matchPattern);
|
|
12565
13148
|
const paths = [];
|
|
12566
|
-
for await (const
|
|
12567
|
-
if (avoidDirs.some((dir) =>
|
|
13149
|
+
for await (const path42 of glob.scan({ cwd: this.workspace.workspaceRoot, absolute: true })) {
|
|
13150
|
+
if (avoidDirs.some((dir) => path42.includes(dir)))
|
|
12568
13151
|
continue;
|
|
12569
|
-
const fileContent = await FileSys.readText(
|
|
13152
|
+
const fileContent = await FileSys.readText(path42);
|
|
12570
13153
|
const textFilter = filterText ? new RegExp(filterText) : null;
|
|
12571
13154
|
if (filterText && !textFilter?.test(fileContent))
|
|
12572
13155
|
continue;
|
|
12573
|
-
paths.push(
|
|
13156
|
+
paths.push(path42);
|
|
12574
13157
|
}
|
|
12575
13158
|
return paths;
|
|
12576
13159
|
}
|
|
@@ -12889,8 +13472,8 @@ class LibraryCommand extends command("library", [LibraryScript], ({ public: targ
|
|
|
12889
13472
|
}
|
|
12890
13473
|
|
|
12891
13474
|
// pkgs/@akanjs/cli/localRegistry/localRegistry.runner.ts
|
|
12892
|
-
import { mkdir as
|
|
12893
|
-
import
|
|
13475
|
+
import { mkdir as mkdir12, rm as rm6 } from "fs/promises";
|
|
13476
|
+
import path42 from "path";
|
|
12894
13477
|
import { Logger as Logger19 } from "akanjs/common";
|
|
12895
13478
|
var defaultLocalRegistryUrl = "http://127.0.0.1:4873";
|
|
12896
13479
|
var containerName = "akan-verdaccio";
|
|
@@ -12908,9 +13491,9 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
12908
13491
|
Logger19.info(`Local registry is already running at ${registry}`);
|
|
12909
13492
|
return registry;
|
|
12910
13493
|
} catch {}
|
|
12911
|
-
const configPath2 =
|
|
12912
|
-
const storagePath =
|
|
12913
|
-
await
|
|
13494
|
+
const configPath2 = path42.join(workspace.workspaceRoot, "pkgs/@akanjs/cli/localRegistry/verdaccio.yaml");
|
|
13495
|
+
const storagePath = path42.join(workspace.workspaceRoot, ".akan/verdaccio/storage");
|
|
13496
|
+
await mkdir12(storagePath, { recursive: true });
|
|
12914
13497
|
await workspace.spawn("docker", [
|
|
12915
13498
|
"run",
|
|
12916
13499
|
"--rm",
|
|
@@ -12932,13 +13515,13 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
12932
13515
|
try {
|
|
12933
13516
|
await workspace.spawn("docker", ["rm", "-f", containerName], { stdio: "inherit" });
|
|
12934
13517
|
} catch {}
|
|
12935
|
-
await
|
|
13518
|
+
await rm6(path42.join(workspace.workspaceRoot, ".akan/verdaccio"), { recursive: true, force: true });
|
|
12936
13519
|
Logger19.info("Local registry storage has been reset");
|
|
12937
13520
|
}
|
|
12938
13521
|
async smoke(workspace, { registryUrl } = {}) {
|
|
12939
13522
|
const registry = this.getRegistryUrl(registryUrl);
|
|
12940
|
-
const smokeRoot =
|
|
12941
|
-
await
|
|
13523
|
+
const smokeRoot = path42.join(workspace.workspaceRoot, ".akan/e2e");
|
|
13524
|
+
await rm6(path42.join(smokeRoot, smokeRepoName), { recursive: true, force: true });
|
|
12942
13525
|
await workspace.spawn(process.execPath, [
|
|
12943
13526
|
"dist/pkgs/create-akan-workspace/index.js",
|
|
12944
13527
|
smokeRepoName,
|
|
@@ -12955,12 +13538,12 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
12955
13538
|
stdio: "inherit"
|
|
12956
13539
|
});
|
|
12957
13540
|
await workspace.spawn("akan", ["typecheck", smokeAppName], {
|
|
12958
|
-
cwd:
|
|
13541
|
+
cwd: path42.join(smokeRoot, smokeRepoName),
|
|
12959
13542
|
env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
|
|
12960
13543
|
stdio: "inherit"
|
|
12961
13544
|
});
|
|
12962
13545
|
await workspace.spawn("akan", ["build", smokeAppName], {
|
|
12963
|
-
cwd:
|
|
13546
|
+
cwd: path42.join(smokeRoot, smokeRepoName),
|
|
12964
13547
|
env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
|
|
12965
13548
|
stdio: "inherit"
|
|
12966
13549
|
});
|
|
@@ -13040,7 +13623,7 @@ import { lowerlize } from "akanjs/common";
|
|
|
13040
13623
|
|
|
13041
13624
|
// pkgs/@akanjs/cli/module/module.script.ts
|
|
13042
13625
|
import { input as input6 } from "@inquirer/prompts";
|
|
13043
|
-
import { capitalize as
|
|
13626
|
+
import { capitalize as capitalize8, randomPicks as randomPicks2 } from "akanjs/common";
|
|
13044
13627
|
|
|
13045
13628
|
// pkgs/@akanjs/cli/page/page.runner.ts
|
|
13046
13629
|
class PageRunner extends runner("page") {
|
|
@@ -13070,7 +13653,7 @@ function pluralizeName(name) {
|
|
|
13070
13653
|
}
|
|
13071
13654
|
|
|
13072
13655
|
// pkgs/@akanjs/cli/module/module.request.ts
|
|
13073
|
-
import { capitalize as
|
|
13656
|
+
import { capitalize as capitalize6 } from "akanjs/common";
|
|
13074
13657
|
|
|
13075
13658
|
// pkgs/@akanjs/cli/module/module.prompt.ts
|
|
13076
13659
|
var componentDefaultDescription = ({
|
|
@@ -13195,7 +13778,7 @@ var requestTemplate = ({
|
|
|
13195
13778
|
${componentDefaultDescription({
|
|
13196
13779
|
sysName,
|
|
13197
13780
|
modelName,
|
|
13198
|
-
ModelName: ModelName ??
|
|
13781
|
+
ModelName: ModelName ?? capitalize6(modelName),
|
|
13199
13782
|
exampleFiles,
|
|
13200
13783
|
constant,
|
|
13201
13784
|
properties
|
|
@@ -13252,7 +13835,7 @@ var requestView = ({
|
|
|
13252
13835
|
${componentDefaultDescription({
|
|
13253
13836
|
sysName,
|
|
13254
13837
|
modelName,
|
|
13255
|
-
ModelName: ModelName ??
|
|
13838
|
+
ModelName: ModelName ?? capitalize6(modelName),
|
|
13256
13839
|
exampleFiles,
|
|
13257
13840
|
constant,
|
|
13258
13841
|
properties
|
|
@@ -13313,7 +13896,7 @@ var requestUnit = ({
|
|
|
13313
13896
|
${componentDefaultDescription({
|
|
13314
13897
|
sysName,
|
|
13315
13898
|
modelName,
|
|
13316
|
-
ModelName: ModelName ??
|
|
13899
|
+
ModelName: ModelName ?? capitalize6(modelName),
|
|
13317
13900
|
exampleFiles,
|
|
13318
13901
|
constant,
|
|
13319
13902
|
properties
|
|
@@ -13362,7 +13945,7 @@ var requestUnit = ({
|
|
|
13362
13945
|
`;
|
|
13363
13946
|
|
|
13364
13947
|
// pkgs/@akanjs/cli/module/module.runner.ts
|
|
13365
|
-
import { capitalize as
|
|
13948
|
+
import { capitalize as capitalize7 } from "akanjs/common";
|
|
13366
13949
|
class ModuleRunner extends runner("module") {
|
|
13367
13950
|
async createService(module) {
|
|
13368
13951
|
const serviceName = module.name.replace(/^_+/, "");
|
|
@@ -13392,13 +13975,13 @@ class ModuleRunner extends runner("module") {
|
|
|
13392
13975
|
async createComponentTemplate(module, type) {
|
|
13393
13976
|
await module.sys.applyTemplate({
|
|
13394
13977
|
basePath: `./lib/${module.name}`,
|
|
13395
|
-
template: `module/__Model__.${
|
|
13978
|
+
template: `module/__Model__.${capitalize7(type)}.tsx`,
|
|
13396
13979
|
dict: { model: module.name, appName: module.sys.name }
|
|
13397
13980
|
});
|
|
13398
13981
|
return {
|
|
13399
13982
|
component: {
|
|
13400
|
-
filename: `${module.name}.${
|
|
13401
|
-
content: await module.sys.readFile(`lib/${module.name}/${
|
|
13983
|
+
filename: `${module.name}.${capitalize7(type)}.tsx`,
|
|
13984
|
+
content: await module.sys.readFile(`lib/${module.name}/${capitalize7(module.name)}.${capitalize7(type)}.tsx`)
|
|
13402
13985
|
}
|
|
13403
13986
|
};
|
|
13404
13987
|
}
|
|
@@ -13524,7 +14107,7 @@ class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
|
13524
14107
|
async createTemplate(mod) {
|
|
13525
14108
|
const { component: template } = await this.moduleRunner.createComponentTemplate(mod, "template");
|
|
13526
14109
|
const templateExampleFiles = (await mod.sys.getTemplatesSourceCode()).filter((f) => !f.filePath.includes(`${mod.name}.Template.tsx`));
|
|
13527
|
-
const Name =
|
|
14110
|
+
const Name = capitalize8(mod.name);
|
|
13528
14111
|
const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13529
14112
|
const constant = await FileSys.readText(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13530
14113
|
const session = new AiSession("createTemplate", { workspace: mod.sys.workspace, cacheKey: mod.name });
|
|
@@ -13543,7 +14126,7 @@ class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
|
13543
14126
|
}
|
|
13544
14127
|
async createUnit(mod) {
|
|
13545
14128
|
const { component: unit } = await this.moduleRunner.createComponentTemplate(mod, "unit");
|
|
13546
|
-
const Name =
|
|
14129
|
+
const Name = capitalize8(mod.name);
|
|
13547
14130
|
const unitExampleFiles = (await mod.sys.getUnitsSourceCode()).filter((f) => !f.filePath.includes(`${mod.name}.Unit.tsx`));
|
|
13548
14131
|
const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13549
14132
|
const constant = await FileSys.readText(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
@@ -13564,7 +14147,7 @@ class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
|
13564
14147
|
async createView(mod) {
|
|
13565
14148
|
const { component: view } = await this.moduleRunner.createComponentTemplate(mod, "view");
|
|
13566
14149
|
const viewExampleFiles = (await mod.sys.getViewsSourceCode()).filter((f) => !f.filePath.includes(`${mod.name}.View.tsx`));
|
|
13567
|
-
const Name =
|
|
14150
|
+
const Name = capitalize8(mod.name);
|
|
13568
14151
|
const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13569
14152
|
const constant = await FileSys.readText(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13570
14153
|
const session = new AiSession("createView", { workspace: mod.sys.workspace, cacheKey: mod.name });
|
|
@@ -13841,11 +14424,11 @@ class ScalarCommand extends command("scalar", [ScalarScript], ({ public: target
|
|
|
13841
14424
|
}
|
|
13842
14425
|
|
|
13843
14426
|
// pkgs/@akanjs/cli/workspace/workspace.script.ts
|
|
13844
|
-
import
|
|
14427
|
+
import path44 from "path";
|
|
13845
14428
|
import { Logger as Logger20 } from "akanjs/common";
|
|
13846
14429
|
|
|
13847
14430
|
// pkgs/@akanjs/cli/workspace/workspace.runner.ts
|
|
13848
|
-
import
|
|
14431
|
+
import path43 from "path";
|
|
13849
14432
|
var defaultWorkspacePeerDependencies = new Set([
|
|
13850
14433
|
"@react-spring/web",
|
|
13851
14434
|
"@use-gesture/react",
|
|
@@ -13896,7 +14479,7 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13896
14479
|
owner = ""
|
|
13897
14480
|
}) {
|
|
13898
14481
|
const cwdPath = process.cwd();
|
|
13899
|
-
const workspaceRoot =
|
|
14482
|
+
const workspaceRoot = path43.join(cwdPath, dirname2, repoName);
|
|
13900
14483
|
const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
|
|
13901
14484
|
const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
|
|
13902
14485
|
const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname2}/${repoName}...`);
|
|
@@ -13952,9 +14535,9 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13952
14535
|
}
|
|
13953
14536
|
async#getCliPackageJson() {
|
|
13954
14537
|
const packageJsonCandidates = [
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
14538
|
+
path43.join(import.meta.dir, "../package.json"),
|
|
14539
|
+
path43.join(import.meta.dir, "package.json"),
|
|
14540
|
+
path43.join(path43.dirname(Bun.main), "package.json")
|
|
13958
14541
|
];
|
|
13959
14542
|
try {
|
|
13960
14543
|
packageJsonCandidates.unshift(Bun.resolveSync("@akanjs/cli/package.json", import.meta.dir));
|
|
@@ -13970,9 +14553,9 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13970
14553
|
}
|
|
13971
14554
|
async#getAkanPackageJson() {
|
|
13972
14555
|
const packageJsonCandidates = [
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
14556
|
+
path43.join(import.meta.dir, "../../../akanjs/package.json"),
|
|
14557
|
+
path43.join(process.cwd(), "pkgs/akanjs/package.json"),
|
|
14558
|
+
path43.join(path43.dirname(Bun.main), "node_modules/akanjs/package.json")
|
|
13976
14559
|
];
|
|
13977
14560
|
try {
|
|
13978
14561
|
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json", import.meta.dir));
|
|
@@ -13986,13 +14569,13 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13986
14569
|
}
|
|
13987
14570
|
let current = import.meta.dir;
|
|
13988
14571
|
for (let depth = 0;depth < 6; depth++) {
|
|
13989
|
-
const packageJsonPath =
|
|
14572
|
+
const packageJsonPath = path43.join(current, "package.json");
|
|
13990
14573
|
if (await Bun.file(packageJsonPath).exists()) {
|
|
13991
14574
|
const packageJson = await FileSys.readJson(packageJsonPath);
|
|
13992
14575
|
if (packageJson.name === "akanjs")
|
|
13993
14576
|
return packageJson;
|
|
13994
14577
|
}
|
|
13995
|
-
const parent =
|
|
14578
|
+
const parent = path43.dirname(current);
|
|
13996
14579
|
if (parent === current)
|
|
13997
14580
|
break;
|
|
13998
14581
|
current = parent;
|
|
@@ -14069,7 +14652,7 @@ class WorkspaceScript extends script("workspace", [
|
|
|
14069
14652
|
} catch (_) {
|
|
14070
14653
|
gitSpinner.fail("Git repository initialization failed. It's not fatal, you can commit manually");
|
|
14071
14654
|
}
|
|
14072
|
-
const workspacePath =
|
|
14655
|
+
const workspacePath = path44.join(dirname2, repoName);
|
|
14073
14656
|
Logger20.rawLog(`
|
|
14074
14657
|
\uD83C\uDF89 Welcome aboard! Workspace created in ${dirname2}/${repoName}`);
|
|
14075
14658
|
Logger20.rawLog(`\uD83D\uDE80 Run \`cd ${workspacePath} && akan start ${appName}\` to start the development server.`);
|