@akanjs/cli 2.3.5 → 2.3.6-rc.0
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 +754 -181
- package/index.js +727 -204
- package/package.json +2 -3
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,76 @@ 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
|
+
return message.devPlan.actions.includes("restart-backend");
|
|
4138
|
+
};
|
|
4139
|
+
var shouldRestartDevHostByDevPlan = (message) => message.devPlan?.actions.includes("restart-dev-host") ?? message.kinds.includes("config");
|
|
4140
|
+
var RESTART_ROLE_ORDER = ["server", "shared", "barrel", "config"];
|
|
4141
|
+
var generationValue = (generation) => generation ?? -1;
|
|
4142
|
+
var isLegacyBackendFallbackFile = (file, workspaceRoot) => {
|
|
4143
|
+
const abs = path9.resolve(file);
|
|
4144
|
+
const ext = path9.extname(abs).toLowerCase();
|
|
4145
|
+
if (!SOURCE_EXTS.has(ext))
|
|
4146
|
+
return false;
|
|
4147
|
+
const rel = path9.relative(path9.resolve(workspaceRoot), abs);
|
|
4148
|
+
if (!rel || rel.startsWith("..") || path9.isAbsolute(rel))
|
|
4149
|
+
return false;
|
|
4150
|
+
const parts = rel.split(path9.sep).filter(Boolean);
|
|
4151
|
+
const [scope] = parts;
|
|
4152
|
+
if (scope !== "apps" && scope !== "libs" && scope !== "pkgs")
|
|
4153
|
+
return false;
|
|
4154
|
+
const base = path9.basename(abs);
|
|
4155
|
+
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";
|
|
4156
|
+
};
|
|
4157
|
+
var shouldMarkBuildPhaseRecovered = (previousByPhase, status) => {
|
|
4158
|
+
const previous = previousByPhase.get(status.phase);
|
|
4159
|
+
return Boolean(previous && status.ok && !previous.ok && generationValue(status.generation) >= previous.generation);
|
|
4160
|
+
};
|
|
4161
|
+
var createBackendBuildStatus = ({
|
|
4162
|
+
generation,
|
|
4163
|
+
ok,
|
|
4164
|
+
files = [],
|
|
4165
|
+
message
|
|
4166
|
+
}) => ({
|
|
4167
|
+
generation,
|
|
4168
|
+
phase: "backend",
|
|
4169
|
+
ok,
|
|
4170
|
+
files,
|
|
4171
|
+
message
|
|
4172
|
+
});
|
|
4173
|
+
var backendRestartReasonFromMessage = (message) => {
|
|
4174
|
+
const roleSet = new Set;
|
|
4175
|
+
for (const role of message.devPlan?.roles ?? []) {
|
|
4176
|
+
if (role === "server" || role === "shared" || role === "barrel" || role === "config")
|
|
4177
|
+
roleSet.add(role);
|
|
4178
|
+
}
|
|
4179
|
+
return {
|
|
4180
|
+
generation: message.devPlan?.generation ?? message.generation,
|
|
4181
|
+
files: [...new Set(message.files)].sort(),
|
|
4182
|
+
roles: RESTART_ROLE_ORDER.filter((role) => roleSet.has(role))
|
|
4183
|
+
};
|
|
4184
|
+
};
|
|
4185
|
+
var mergeBackendRestartReasons = (current, next) => ({
|
|
4186
|
+
generation: generationValue(next.generation) >= generationValue(current?.generation) ? next.generation : current?.generation,
|
|
4187
|
+
files: [...new Set([...current?.files ?? [], ...next.files])].sort(),
|
|
4188
|
+
roles: RESTART_ROLE_ORDER.filter((role) => current?.roles.includes(role) || next.roles.includes(role))
|
|
4189
|
+
});
|
|
4190
|
+
var shouldReplaceLastGoodMessage = (current, next) => !current || generationValue(next.data.generation) >= generationValue(current.data.generation);
|
|
4191
|
+
var shouldQueueBuildStatusReplay = (backendReady, pendingReplayCount) => !backendReady || pendingReplayCount > 0;
|
|
4192
|
+
var buildStatusReplaySequence = (pendingReplay, latestByPhase) => [...pendingReplay, ...latestByPhase.values()];
|
|
4098
4193
|
|
|
4099
4194
|
class BackendImportGraph {
|
|
4100
4195
|
#app;
|
|
@@ -4105,6 +4200,7 @@ class BackendImportGraph {
|
|
|
4105
4200
|
#jsxTranspiler = new Bun.Transpiler({ loader: "jsx" });
|
|
4106
4201
|
#files = new Set;
|
|
4107
4202
|
#ready = false;
|
|
4203
|
+
#lastRefreshSucceeded = false;
|
|
4108
4204
|
constructor(app, logger) {
|
|
4109
4205
|
this.#app = app;
|
|
4110
4206
|
this.#logger = logger;
|
|
@@ -4112,6 +4208,9 @@ class BackendImportGraph {
|
|
|
4112
4208
|
get ready() {
|
|
4113
4209
|
return this.#ready;
|
|
4114
4210
|
}
|
|
4211
|
+
get lastRefreshSucceeded() {
|
|
4212
|
+
return this.#lastRefreshSucceeded;
|
|
4213
|
+
}
|
|
4115
4214
|
has(file) {
|
|
4116
4215
|
return this.#files.has(path9.resolve(file));
|
|
4117
4216
|
}
|
|
@@ -4120,10 +4219,12 @@ class BackendImportGraph {
|
|
|
4120
4219
|
const files = await this.#build();
|
|
4121
4220
|
this.#files = files;
|
|
4122
4221
|
this.#ready = true;
|
|
4222
|
+
this.#lastRefreshSucceeded = true;
|
|
4123
4223
|
this.#logger.verbose(`[backend-graph] scanned ${files.size} files`);
|
|
4124
4224
|
return true;
|
|
4125
4225
|
} catch (err) {
|
|
4126
4226
|
this.#ready = this.#files.size > 0;
|
|
4227
|
+
this.#lastRefreshSucceeded = false;
|
|
4127
4228
|
this.#logger.warn(`[backend-graph] scan failed; ${this.#ready ? "using previous graph" : "using fallback rules"}: ${err instanceof Error ? err.message : String(err)}`);
|
|
4128
4229
|
return this.#ready;
|
|
4129
4230
|
}
|
|
@@ -4210,9 +4311,13 @@ class AkanAppHost {
|
|
|
4210
4311
|
#restartTimer = null;
|
|
4211
4312
|
#backendRecoveryTimer = null;
|
|
4212
4313
|
#backendRecoveryAttempts = 0;
|
|
4213
|
-
#
|
|
4214
|
-
#
|
|
4215
|
-
#
|
|
4314
|
+
#backendLifecycleState = "stopped";
|
|
4315
|
+
#pendingRestartReason = null;
|
|
4316
|
+
#backendStartStatus = null;
|
|
4317
|
+
#backendBuildStatusGeneration = 0;
|
|
4318
|
+
#lastGoodFrontend = {};
|
|
4319
|
+
#buildStatusByPhase = new Map;
|
|
4320
|
+
#pendingBuildStatusReplay = [];
|
|
4216
4321
|
#builderMessageQueue = Promise.resolve();
|
|
4217
4322
|
#backendGraph;
|
|
4218
4323
|
constructor(app, { env, withInk = false }) {
|
|
@@ -4257,7 +4362,9 @@ class AkanAppHost {
|
|
|
4257
4362
|
return "localhost";
|
|
4258
4363
|
return await createTunnel(type, { app: this.app, environment });
|
|
4259
4364
|
}
|
|
4260
|
-
#startBackend() {
|
|
4365
|
+
#startBackend(startStatus = null) {
|
|
4366
|
+
this.#backendStartStatus = startStatus;
|
|
4367
|
+
this.#setBackendLifecycleState("starting");
|
|
4261
4368
|
this.#backendReady = false;
|
|
4262
4369
|
const backend = Bun.spawn(["bun", `apps/${this.app.name}/main.ts`], {
|
|
4263
4370
|
cwd: this.app.workspace.workspaceRoot,
|
|
@@ -4269,6 +4376,8 @@ class AkanAppHost {
|
|
|
4269
4376
|
if (msg.type === "backend-ready") {
|
|
4270
4377
|
this.#backendReady = true;
|
|
4271
4378
|
this.#backendRecoveryAttempts = 0;
|
|
4379
|
+
this.#setBackendLifecycleState("ready", `pid=${msg.pid}`);
|
|
4380
|
+
this.#recordBackendReadyStatus();
|
|
4272
4381
|
this.logger.verbose(`backend ready pid=${msg.pid}`);
|
|
4273
4382
|
this.#replayBuilderState();
|
|
4274
4383
|
return;
|
|
@@ -4291,9 +4400,53 @@ class AkanAppHost {
|
|
|
4291
4400
|
this.#backend = backend;
|
|
4292
4401
|
this.logger.verbose(`backend spawned pid=${backend.pid}`);
|
|
4293
4402
|
}
|
|
4403
|
+
#nextBackendBuildStatusGeneration(generation) {
|
|
4404
|
+
if (typeof generation === "number") {
|
|
4405
|
+
this.#backendBuildStatusGeneration = Math.max(this.#backendBuildStatusGeneration, generation);
|
|
4406
|
+
return generation;
|
|
4407
|
+
}
|
|
4408
|
+
this.#backendBuildStatusGeneration += 1;
|
|
4409
|
+
return this.#backendBuildStatusGeneration;
|
|
4410
|
+
}
|
|
4411
|
+
#recordBackendBuildStatus({
|
|
4412
|
+
generation,
|
|
4413
|
+
ok,
|
|
4414
|
+
files,
|
|
4415
|
+
message
|
|
4416
|
+
}) {
|
|
4417
|
+
const status = createBackendBuildStatus({
|
|
4418
|
+
generation: this.#nextBackendBuildStatusGeneration(generation),
|
|
4419
|
+
ok,
|
|
4420
|
+
files,
|
|
4421
|
+
message
|
|
4422
|
+
});
|
|
4423
|
+
this.#recordBuildStatus(status);
|
|
4424
|
+
return status;
|
|
4425
|
+
}
|
|
4426
|
+
#recordBackendReadyStatus() {
|
|
4427
|
+
const previous = this.#buildStatusByPhase.get("backend");
|
|
4428
|
+
const startStatus = this.#backendStartStatus;
|
|
4429
|
+
if (startStatus || previous?.ok === false) {
|
|
4430
|
+
const status = this.#recordBackendBuildStatus({
|
|
4431
|
+
generation: startStatus?.generation ?? previous?.generation,
|
|
4432
|
+
ok: true,
|
|
4433
|
+
files: startStatus?.files ?? previous?.files ?? [],
|
|
4434
|
+
message: "Backend ready"
|
|
4435
|
+
});
|
|
4436
|
+
this.#sendOrQueueBuildStatus(status);
|
|
4437
|
+
}
|
|
4438
|
+
this.#backendStartStatus = null;
|
|
4439
|
+
}
|
|
4440
|
+
#setBackendLifecycleState(next, detail) {
|
|
4441
|
+
if (this.#backendLifecycleState === next && !detail)
|
|
4442
|
+
return;
|
|
4443
|
+
const prev = this.#backendLifecycleState;
|
|
4444
|
+
this.#backendLifecycleState = next;
|
|
4445
|
+
this.logger.verbose(`[backend-lifecycle] ${prev} -> ${next}${detail ? ` ${detail}` : ""}`);
|
|
4446
|
+
}
|
|
4294
4447
|
#sendToBackend(message) {
|
|
4295
4448
|
if (!this.#backend || !this.#backendReady) {
|
|
4296
|
-
if (message.type === "css-updated" || message.type === "pages-updated") {
|
|
4449
|
+
if (message.type === "css-updated" || message.type === "pages-updated" || message.type === "build-status") {
|
|
4297
4450
|
this.logger.verbose(`backend is not ready; will replay ${message.type}`);
|
|
4298
4451
|
return;
|
|
4299
4452
|
}
|
|
@@ -4313,6 +4466,7 @@ class AkanAppHost {
|
|
|
4313
4466
|
const backend = this.#backend;
|
|
4314
4467
|
this.#plannedBackendStops.add(backend);
|
|
4315
4468
|
this.#backendReady = false;
|
|
4469
|
+
this.#setBackendLifecycleState("stopping", `pid=${backend.pid}`);
|
|
4316
4470
|
this.logger.verbose(`stopping backend pid=${backend.pid}`);
|
|
4317
4471
|
try {
|
|
4318
4472
|
backend.kill("SIGTERM");
|
|
@@ -4328,11 +4482,13 @@ class AkanAppHost {
|
|
|
4328
4482
|
} finally {
|
|
4329
4483
|
if (this.#backend === backend)
|
|
4330
4484
|
this.#backend = null;
|
|
4485
|
+
this.#setBackendLifecycleState("stopped", `pid=${backend.pid}`);
|
|
4331
4486
|
}
|
|
4332
4487
|
}
|
|
4333
|
-
#scheduleBackendRestart(
|
|
4334
|
-
|
|
4335
|
-
|
|
4488
|
+
#scheduleBackendRestart(reason) {
|
|
4489
|
+
this.#pendingRestartReason = mergeBackendRestartReasons(this.#pendingRestartReason, reason);
|
|
4490
|
+
const pending = this.#pendingRestartReason;
|
|
4491
|
+
this.#setBackendLifecycleState("restart-pending", `generation=${pending.generation ?? "(unknown)"} files=${pending.files.length} roles=${pending.roles.join(",") || "(none)"}`);
|
|
4336
4492
|
if (this.#backendRecoveryTimer) {
|
|
4337
4493
|
clearTimeout(this.#backendRecoveryTimer);
|
|
4338
4494
|
this.#backendRecoveryTimer = null;
|
|
@@ -4341,23 +4497,31 @@ class AkanAppHost {
|
|
|
4341
4497
|
clearTimeout(this.#restartTimer);
|
|
4342
4498
|
this.#restartTimer = setTimeout(() => {
|
|
4343
4499
|
this.#restartTimer = null;
|
|
4344
|
-
const
|
|
4345
|
-
this.#
|
|
4346
|
-
|
|
4500
|
+
const next = this.#pendingRestartReason;
|
|
4501
|
+
this.#pendingRestartReason = null;
|
|
4502
|
+
if (next)
|
|
4503
|
+
this.#restartBackend(next);
|
|
4347
4504
|
}, BACKEND_RESTART_DEBOUNCE_MS);
|
|
4348
4505
|
}
|
|
4349
|
-
async#restartBackend(
|
|
4350
|
-
this.logger.verbose(`[backend-reload] restarting backend
|
|
4506
|
+
async#restartBackend(reason) {
|
|
4507
|
+
this.logger.verbose(`[backend-reload] restarting backend generation=${reason.generation ?? "(unknown)"} files=${reason.files.length} roles=${reason.roles.join(",") || "(none)"}`);
|
|
4351
4508
|
this.#backendRecoveryAttempts = 0;
|
|
4352
4509
|
await Promise.all([this.#stopBackend(), this.#backendGraph.refresh()]);
|
|
4353
|
-
this.#startBackend();
|
|
4510
|
+
this.#startBackend({ generation: reason.generation, files: reason.files });
|
|
4354
4511
|
}
|
|
4355
4512
|
#scheduleBackendRecovery(reason) {
|
|
4356
4513
|
if (this.#backendRecoveryTimer || this.#backend)
|
|
4357
4514
|
return;
|
|
4515
|
+
this.#setBackendLifecycleState("recovering", reason);
|
|
4358
4516
|
const attempt = this.#backendRecoveryAttempts;
|
|
4359
4517
|
const delay = Math.min(BACKEND_RECOVERY_BASE_DELAY_MS * 2 ** attempt, BACKEND_RECOVERY_MAX_DELAY_MS);
|
|
4360
4518
|
this.#backendRecoveryAttempts = attempt + 1;
|
|
4519
|
+
const failureStatus = this.#recordBackendBuildStatus({
|
|
4520
|
+
ok: false,
|
|
4521
|
+
files: [],
|
|
4522
|
+
message: `Backend exited unexpectedly (${reason}); restarting in ${delay}ms`
|
|
4523
|
+
});
|
|
4524
|
+
this.#sendOrQueueBuildStatus(failureStatus);
|
|
4361
4525
|
this.logger.warn(`[backend-recovery] backend exited unexpectedly (${reason}); restarting in ${delay}ms (attempt ${this.#backendRecoveryAttempts})`);
|
|
4362
4526
|
this.#backendRecoveryTimer = setTimeout(() => {
|
|
4363
4527
|
this.#backendRecoveryTimer = null;
|
|
@@ -4365,7 +4529,7 @@ class AkanAppHost {
|
|
|
4365
4529
|
return;
|
|
4366
4530
|
this.#backendGraph.refresh().finally(() => {
|
|
4367
4531
|
if (!this.#backend)
|
|
4368
|
-
this.#startBackend();
|
|
4532
|
+
this.#startBackend({ generation: failureStatus.generation, files: failureStatus.files });
|
|
4369
4533
|
});
|
|
4370
4534
|
}, delay);
|
|
4371
4535
|
}
|
|
@@ -4375,10 +4539,15 @@ class AkanAppHost {
|
|
|
4375
4539
|
});
|
|
4376
4540
|
}
|
|
4377
4541
|
async#handleBuilderMessage(message) {
|
|
4542
|
+
if (message.type === "build-status") {
|
|
4543
|
+
this.#recordBuildStatus(message.data);
|
|
4544
|
+
this.#sendOrQueueBuildStatus(message.data);
|
|
4545
|
+
return;
|
|
4546
|
+
}
|
|
4378
4547
|
if (message.type === "pages-updated")
|
|
4379
|
-
this.#
|
|
4548
|
+
this.#recordLastGood(message);
|
|
4380
4549
|
if (message.type === "css-updated")
|
|
4381
|
-
this.#
|
|
4550
|
+
this.#recordLastGood(message);
|
|
4382
4551
|
if (message.type === "invalidate") {
|
|
4383
4552
|
await this.#handleInvalidate(message);
|
|
4384
4553
|
return;
|
|
@@ -4386,26 +4555,97 @@ class AkanAppHost {
|
|
|
4386
4555
|
this.#sendToBackend(message);
|
|
4387
4556
|
}
|
|
4388
4557
|
async#handleInvalidate(message) {
|
|
4558
|
+
if (shouldRestartDevHostByDevPlan(message)) {
|
|
4559
|
+
this.#recordDevHostRestartRequired(message);
|
|
4560
|
+
return;
|
|
4561
|
+
}
|
|
4389
4562
|
if (await this.#shouldRestartBackend(message)) {
|
|
4390
|
-
this.#scheduleBackendRestart(message
|
|
4563
|
+
this.#scheduleBackendRestart(backendRestartReasonFromMessage(message));
|
|
4391
4564
|
return;
|
|
4392
4565
|
}
|
|
4393
4566
|
this.#sendToBackend(message);
|
|
4394
4567
|
}
|
|
4568
|
+
#recordLastGood(message) {
|
|
4569
|
+
if (message.type === "pages-updated") {
|
|
4570
|
+
if (!shouldReplaceLastGoodMessage(this.#lastGoodFrontend.pages, message))
|
|
4571
|
+
return;
|
|
4572
|
+
this.#lastGoodFrontend.pages = message;
|
|
4573
|
+
this.logger.verbose(`[last-good] pages generation=${message.data.generation ?? "(unknown)"} buildId=${message.data.buildId}`);
|
|
4574
|
+
return;
|
|
4575
|
+
}
|
|
4576
|
+
if (!shouldReplaceLastGoodMessage(this.#lastGoodFrontend.css, message))
|
|
4577
|
+
return;
|
|
4578
|
+
this.#lastGoodFrontend.css = message;
|
|
4579
|
+
this.logger.verbose(`[last-good] css generation=${message.data.generation ?? "(unknown)"} assets=${Object.keys(message.data.cssAssets).length}`);
|
|
4580
|
+
}
|
|
4581
|
+
#recordDevHostRestartRequired(message) {
|
|
4582
|
+
const generation = message.devPlan?.generation ?? message.generation;
|
|
4583
|
+
const detail = `generation=${generation ?? "(unknown)"} files=${message.files.length}`;
|
|
4584
|
+
this.logger.warn(`[dev-host] config change requires a manual restart until controlled dev-host restart is implemented (${detail})`);
|
|
4585
|
+
if (typeof generation === "number") {
|
|
4586
|
+
const status = {
|
|
4587
|
+
generation,
|
|
4588
|
+
phase: "scan",
|
|
4589
|
+
ok: false,
|
|
4590
|
+
files: message.files,
|
|
4591
|
+
message: "Config change requires restarting `akan start` to apply."
|
|
4592
|
+
};
|
|
4593
|
+
this.#recordBuildStatus(status);
|
|
4594
|
+
this.#sendOrQueueBuildStatus(status);
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
#recordBuildStatus(status) {
|
|
4598
|
+
const recovered = shouldMarkBuildPhaseRecovered(this.#buildStatusByPhase, status);
|
|
4599
|
+
this.#buildStatusByPhase.set(status.phase, status);
|
|
4600
|
+
const label = `[build-status] generation=${status.generation} phase=${status.phase} ok=${status.ok} files=${status.files.length}`;
|
|
4601
|
+
if (status.ok)
|
|
4602
|
+
this.logger.verbose(`${label}${recovered ? " recovered=1" : ""}`);
|
|
4603
|
+
else
|
|
4604
|
+
this.logger.warn(`${label}${status.message ? ` message=${status.message}` : ""}`);
|
|
4605
|
+
}
|
|
4606
|
+
#sendOrQueueBuildStatus(status) {
|
|
4607
|
+
if (!this.#backend || shouldQueueBuildStatusReplay(this.#backendReady, this.#pendingBuildStatusReplay.length)) {
|
|
4608
|
+
this.#pendingBuildStatusReplay.push(status);
|
|
4609
|
+
this.logger.verbose(`backend is not ready; will replay build-status generation=${status.generation} phase=${status.phase}`);
|
|
4610
|
+
return;
|
|
4611
|
+
}
|
|
4612
|
+
this.#sendToBackend({ type: "build-status", data: status });
|
|
4613
|
+
}
|
|
4395
4614
|
#replayBuilderState() {
|
|
4396
4615
|
if (!this.#backendReady)
|
|
4397
4616
|
return;
|
|
4398
|
-
if (this.#
|
|
4399
|
-
this.#sendToBackend(this.#
|
|
4400
|
-
if (this.#
|
|
4401
|
-
this.#sendToBackend(this.#
|
|
4617
|
+
if (this.#lastGoodFrontend.css)
|
|
4618
|
+
this.#sendToBackend(this.#lastGoodFrontend.css);
|
|
4619
|
+
if (this.#lastGoodFrontend.pages)
|
|
4620
|
+
this.#sendToBackend(this.#lastGoodFrontend.pages);
|
|
4621
|
+
const queuedStatuses = this.#pendingBuildStatusReplay.splice(0);
|
|
4622
|
+
for (const status of buildStatusReplaySequence(queuedStatuses, this.#buildStatusByPhase)) {
|
|
4623
|
+
this.#sendToBackend({ type: "build-status", data: status });
|
|
4624
|
+
}
|
|
4402
4625
|
}
|
|
4403
4626
|
async#shouldRestartBackend(message) {
|
|
4404
4627
|
if (message.kinds.length === 1 && message.kinds[0] === "css")
|
|
4405
4628
|
return false;
|
|
4406
|
-
if (
|
|
4629
|
+
if (message.devPlan) {
|
|
4630
|
+
const { generation, roles, actions, reasonByFile } = message.devPlan;
|
|
4631
|
+
this.logger.verbose(`[dev-plan] generation=${generation} roles=${roles.join(",") || "(none)"} actions=${actions.join(",") || "(none)"} reasons=${Object.keys(reasonByFile).length}`);
|
|
4632
|
+
const shouldRestart = shouldRestartBackendByDevPlan(message) ?? false;
|
|
4633
|
+
if (shouldRestart && message.kinds.includes("code"))
|
|
4634
|
+
await this.#backendGraph.refresh();
|
|
4635
|
+
return shouldRestart;
|
|
4636
|
+
}
|
|
4637
|
+
if (message.kinds.includes("code"))
|
|
4407
4638
|
await this.#backendGraph.refresh();
|
|
4408
|
-
|
|
4639
|
+
if (message.files.some((file) => this.#isBackendFile(file)))
|
|
4640
|
+
return true;
|
|
4641
|
+
if (!this.#backendGraph.lastRefreshSucceeded) {
|
|
4642
|
+
const fallbackFiles = message.files.filter((file) => isLegacyBackendFallbackFile(file, this.app.workspace.workspaceRoot));
|
|
4643
|
+
if (fallbackFiles.length > 0) {
|
|
4644
|
+
this.logger.warn(`[backend-graph] using path-role fallback for legacy invalidate; restart files=${fallbackFiles.length}`);
|
|
4645
|
+
return true;
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
return false;
|
|
4409
4649
|
}
|
|
4410
4650
|
#isBackendFile(file) {
|
|
4411
4651
|
return this.#backendGraph.has(file);
|
|
@@ -4761,8 +5001,8 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
|
|
|
4761
5001
|
}
|
|
4762
5002
|
}
|
|
4763
5003
|
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
4764
|
-
import { mkdir as
|
|
4765
|
-
import
|
|
5004
|
+
import { mkdir as mkdir8, rm as rm3 } from "fs/promises";
|
|
5005
|
+
import path35 from "path";
|
|
4766
5006
|
|
|
4767
5007
|
// pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
|
|
4768
5008
|
import path20 from "path";
|
|
@@ -7230,9 +7470,292 @@ function getPageKeyBasePath(pageKey, basePaths) {
|
|
|
7230
7470
|
const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
|
|
7231
7471
|
return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
|
|
7232
7472
|
}
|
|
7233
|
-
// pkgs/@akanjs/devkit/frontendBuild/
|
|
7234
|
-
import { mkdir as mkdir6 } from "fs/promises";
|
|
7473
|
+
// pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
|
|
7235
7474
|
import path25 from "path";
|
|
7475
|
+
var SOURCE_EXTS4 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
7476
|
+
var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
7477
|
+
var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit"]);
|
|
7478
|
+
var CLIENT_SUFFIXES = [".Template.tsx", ".Unit.tsx", ".Util.tsx", ".View.tsx", ".Zone.tsx", ".store.ts"];
|
|
7479
|
+
var SHARED_SUFFIXES2 = [".constant.ts", ".dictionary.ts", ".signal.ts"];
|
|
7480
|
+
var SERVER_SUFFIXES2 = [".service.ts", ".document.ts"];
|
|
7481
|
+
var RUNTIME_METADATA_BASENAMES2 = new Set(["dict.ts", "sig.ts", "useClient.ts", "useServer.ts"]);
|
|
7482
|
+
|
|
7483
|
+
class DevChangePlanner {
|
|
7484
|
+
#workspaceRoot;
|
|
7485
|
+
constructor({ workspaceRoot }) {
|
|
7486
|
+
this.#workspaceRoot = path25.resolve(workspaceRoot);
|
|
7487
|
+
}
|
|
7488
|
+
plan({ generation, files, kinds, generatedFiles: generatedFiles2 = [] }) {
|
|
7489
|
+
const fileList = uniqueResolved([...files, ...generatedFiles2]);
|
|
7490
|
+
const generatedSet = new Set(generatedFiles2.map((file) => path25.resolve(file)));
|
|
7491
|
+
const kindSet = new Set(kinds);
|
|
7492
|
+
const roles = new Set;
|
|
7493
|
+
const actions = new Set;
|
|
7494
|
+
const reasonByFile = {};
|
|
7495
|
+
for (const kind of kindSet) {
|
|
7496
|
+
if (kind === "css") {
|
|
7497
|
+
roles.add("css");
|
|
7498
|
+
actions.add("rebuild-css");
|
|
7499
|
+
}
|
|
7500
|
+
if (kind === "config") {
|
|
7501
|
+
roles.add("config");
|
|
7502
|
+
actions.add("restart-dev-host");
|
|
7503
|
+
}
|
|
7504
|
+
}
|
|
7505
|
+
for (const file of fileList) {
|
|
7506
|
+
const reasons = new Set;
|
|
7507
|
+
const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(path25.resolve(file)), reasons });
|
|
7508
|
+
for (const role of fileRoles)
|
|
7509
|
+
roles.add(role);
|
|
7510
|
+
if (reasons.size > 0)
|
|
7511
|
+
reasonByFile[path25.resolve(file)] = [...reasons].sort();
|
|
7512
|
+
}
|
|
7513
|
+
if (roles.has("barrel"))
|
|
7514
|
+
actions.add("sync-generated");
|
|
7515
|
+
if (roles.has("server") || roles.has("shared"))
|
|
7516
|
+
actions.add("restart-backend");
|
|
7517
|
+
if (roles.has("client") || roles.has("shared"))
|
|
7518
|
+
actions.add("rebuild-client");
|
|
7519
|
+
if (roles.has("css"))
|
|
7520
|
+
actions.add("rebuild-css");
|
|
7521
|
+
return {
|
|
7522
|
+
generation,
|
|
7523
|
+
files: fileList,
|
|
7524
|
+
generatedFiles: uniqueResolved(generatedFiles2),
|
|
7525
|
+
roles: [...roles].sort(),
|
|
7526
|
+
actions: [...actions].sort(),
|
|
7527
|
+
reasonByFile
|
|
7528
|
+
};
|
|
7529
|
+
}
|
|
7530
|
+
#rolesForFile(file, { isGenerated, reasons }) {
|
|
7531
|
+
const roles = new Set;
|
|
7532
|
+
const abs = path25.resolve(file);
|
|
7533
|
+
const base = path25.basename(abs);
|
|
7534
|
+
const ext = path25.extname(abs).toLowerCase();
|
|
7535
|
+
const isSource = SOURCE_EXTS4.has(ext);
|
|
7536
|
+
const rel = path25.relative(this.#workspaceRoot, abs);
|
|
7537
|
+
const parts = rel.split(path25.sep).filter(Boolean);
|
|
7538
|
+
if (CONFIG_BASENAMES.has(base)) {
|
|
7539
|
+
roles.add("config");
|
|
7540
|
+
reasons.add("config-file");
|
|
7541
|
+
}
|
|
7542
|
+
if (ext === ".css") {
|
|
7543
|
+
roles.add("css");
|
|
7544
|
+
reasons.add("css-file");
|
|
7545
|
+
}
|
|
7546
|
+
if (isGenerated || isSource && this.#isBarrelFacetChild(parts)) {
|
|
7547
|
+
roles.add("barrel");
|
|
7548
|
+
reasons.add(isGenerated ? "generated-index" : "barrel-facet-child");
|
|
7549
|
+
}
|
|
7550
|
+
if (isSource && this.#isServerBiased(abs, parts)) {
|
|
7551
|
+
roles.add("server");
|
|
7552
|
+
reasons.add("server-path");
|
|
7553
|
+
}
|
|
7554
|
+
if (isSource && this.#isClientBiased(abs, parts)) {
|
|
7555
|
+
roles.add("client");
|
|
7556
|
+
reasons.add("client-path");
|
|
7557
|
+
}
|
|
7558
|
+
if (isSource && this.#isSharedBiased(abs, parts)) {
|
|
7559
|
+
roles.add("shared");
|
|
7560
|
+
reasons.add("shared-path");
|
|
7561
|
+
}
|
|
7562
|
+
if (roles.has("server") && roles.has("client")) {
|
|
7563
|
+
roles.delete("server");
|
|
7564
|
+
roles.delete("client");
|
|
7565
|
+
roles.add("shared");
|
|
7566
|
+
reasons.add("server-client-overlap");
|
|
7567
|
+
}
|
|
7568
|
+
if (roles.size === 0 && SOURCE_EXTS4.has(ext) && this.#isWorkspaceSource(rel)) {
|
|
7569
|
+
roles.add("shared");
|
|
7570
|
+
reasons.add("workspace-source-fallback");
|
|
7571
|
+
}
|
|
7572
|
+
return roles;
|
|
7573
|
+
}
|
|
7574
|
+
#isServerBiased(abs, parts) {
|
|
7575
|
+
const base = path25.basename(abs);
|
|
7576
|
+
return parts.includes("srvkit") || SERVER_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || base === "main.ts" || base === "server.ts";
|
|
7577
|
+
}
|
|
7578
|
+
#isClientBiased(abs, parts) {
|
|
7579
|
+
const base = path25.basename(abs);
|
|
7580
|
+
return parts.includes("ui") || parts.includes("webkit") || parts.includes("page") || CLIENT_SUFFIXES.some((suffix) => base.endsWith(suffix));
|
|
7581
|
+
}
|
|
7582
|
+
#isSharedBiased(abs, parts) {
|
|
7583
|
+
const base = path25.basename(abs);
|
|
7584
|
+
return parts.includes("common") || SHARED_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES2.has(base);
|
|
7585
|
+
}
|
|
7586
|
+
#isBarrelFacetChild(parts) {
|
|
7587
|
+
if (parts.length < 4)
|
|
7588
|
+
return false;
|
|
7589
|
+
const [scope, , facet, child] = parts;
|
|
7590
|
+
if (scope !== "apps" && scope !== "libs")
|
|
7591
|
+
return false;
|
|
7592
|
+
if (!facet || !BARREL_FACETS.has(facet))
|
|
7593
|
+
return false;
|
|
7594
|
+
if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
|
|
7595
|
+
return false;
|
|
7596
|
+
return true;
|
|
7597
|
+
}
|
|
7598
|
+
#isWorkspaceSource(rel) {
|
|
7599
|
+
if (!rel || rel.startsWith("..") || path25.isAbsolute(rel))
|
|
7600
|
+
return false;
|
|
7601
|
+
const [scope] = rel.split(path25.sep);
|
|
7602
|
+
return scope === "apps" || scope === "libs" || scope === "pkgs";
|
|
7603
|
+
}
|
|
7604
|
+
}
|
|
7605
|
+
var uniqueResolved = (files) => [...new Set(files.map((file) => path25.resolve(file)))].sort();
|
|
7606
|
+
// pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
|
|
7607
|
+
import { mkdir as mkdir6, readdir as readdir2, readFile, rm as rm2, stat as stat3, writeFile } from "fs/promises";
|
|
7608
|
+
import path26 from "path";
|
|
7609
|
+
var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit"]);
|
|
7610
|
+
var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
|
|
7611
|
+
var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
7612
|
+
var MODULE_UI_TYPES = ["Template", "Unit", "Util", "View", "Zone"];
|
|
7613
|
+
var SERVICE_UI_TYPES = ["Util", "Zone"];
|
|
7614
|
+
var SCALAR_UI_TYPES = ["Template", "Unit"];
|
|
7615
|
+
|
|
7616
|
+
class DevGeneratedIndexSync {
|
|
7617
|
+
#workspaceRoot;
|
|
7618
|
+
constructor({ workspaceRoot }) {
|
|
7619
|
+
this.#workspaceRoot = path26.resolve(workspaceRoot);
|
|
7620
|
+
}
|
|
7621
|
+
async syncForBatch(files) {
|
|
7622
|
+
const indexPaths = new Set;
|
|
7623
|
+
const errors = [];
|
|
7624
|
+
for (const file of files) {
|
|
7625
|
+
const facetIndex = this.#facetIndexFor(file);
|
|
7626
|
+
if (facetIndex)
|
|
7627
|
+
indexPaths.add(facetIndex);
|
|
7628
|
+
const moduleIndex = await this.#moduleIndexForDirectoryEvent(file).catch((err) => {
|
|
7629
|
+
errors.push(`[generated-index] module detection failed for ${file}: ${formatError(err)}`);
|
|
7630
|
+
return null;
|
|
7631
|
+
});
|
|
7632
|
+
if (moduleIndex)
|
|
7633
|
+
indexPaths.add(moduleIndex);
|
|
7634
|
+
}
|
|
7635
|
+
const changedFiles = [];
|
|
7636
|
+
for (const indexPath of [...indexPaths].sort()) {
|
|
7637
|
+
try {
|
|
7638
|
+
const changed = await this.#syncIndex(indexPath);
|
|
7639
|
+
if (changed)
|
|
7640
|
+
changedFiles.push(indexPath);
|
|
7641
|
+
} catch (err) {
|
|
7642
|
+
errors.push(`[generated-index] sync failed for ${indexPath}: ${formatError(err)}`);
|
|
7643
|
+
}
|
|
7644
|
+
}
|
|
7645
|
+
return { changedFiles, errors };
|
|
7646
|
+
}
|
|
7647
|
+
#facetIndexFor(file) {
|
|
7648
|
+
const abs = path26.resolve(file);
|
|
7649
|
+
const rel = path26.relative(this.#workspaceRoot, abs);
|
|
7650
|
+
if (rel.startsWith("..") || path26.isAbsolute(rel))
|
|
7651
|
+
return null;
|
|
7652
|
+
const parts = rel.split(path26.sep).filter(Boolean);
|
|
7653
|
+
if (parts.length < 4)
|
|
7654
|
+
return null;
|
|
7655
|
+
const [scope, project, facet, child] = parts;
|
|
7656
|
+
if (scope !== "apps" && scope !== "libs" || !project || !facet || !BARREL_FACETS2.has(facet))
|
|
7657
|
+
return null;
|
|
7658
|
+
if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
|
|
7659
|
+
return null;
|
|
7660
|
+
return path26.join(this.#workspaceRoot, scope, project, facet, "index.ts");
|
|
7661
|
+
}
|
|
7662
|
+
async#moduleIndexForDirectoryEvent(file) {
|
|
7663
|
+
const abs = path26.resolve(file);
|
|
7664
|
+
const rel = path26.relative(this.#workspaceRoot, abs);
|
|
7665
|
+
if (rel.startsWith("..") || path26.isAbsolute(rel))
|
|
7666
|
+
return null;
|
|
7667
|
+
const parts = rel.split(path26.sep).filter(Boolean);
|
|
7668
|
+
if (parts.length !== 4 && parts.length !== 5)
|
|
7669
|
+
return null;
|
|
7670
|
+
const [scope, project, libSegment, moduleSegment, scalarSegment] = parts;
|
|
7671
|
+
if (scope !== "apps" && scope !== "libs" || !project || libSegment !== "lib")
|
|
7672
|
+
return null;
|
|
7673
|
+
const isExistingDirectory = await stat3(abs).then((s) => s.isDirectory()).catch(() => false);
|
|
7674
|
+
const looksLikeDeletedDirectory = !path26.extname(abs);
|
|
7675
|
+
if (!isExistingDirectory && !looksLikeDeletedDirectory)
|
|
7676
|
+
return null;
|
|
7677
|
+
if (moduleSegment === "__scalar" && scalarSegment) {
|
|
7678
|
+
return path26.join(this.#workspaceRoot, scope, project, "lib", "__scalar", scalarSegment, "index.ts");
|
|
7679
|
+
}
|
|
7680
|
+
if (!moduleSegment || moduleSegment === "__scalar")
|
|
7681
|
+
return null;
|
|
7682
|
+
return path26.join(this.#workspaceRoot, scope, project, "lib", moduleSegment, "index.ts");
|
|
7683
|
+
}
|
|
7684
|
+
async#syncIndex(indexPath) {
|
|
7685
|
+
const dir = path26.dirname(indexPath);
|
|
7686
|
+
const content = await this.#contentForIndex(indexPath);
|
|
7687
|
+
if (content === null) {
|
|
7688
|
+
if (!await exists(indexPath))
|
|
7689
|
+
return false;
|
|
7690
|
+
await rm2(indexPath, { force: true });
|
|
7691
|
+
return true;
|
|
7692
|
+
}
|
|
7693
|
+
const current = await readFile(indexPath, "utf8").catch(() => null);
|
|
7694
|
+
if (current === content)
|
|
7695
|
+
return false;
|
|
7696
|
+
await mkdir6(dir, { recursive: true });
|
|
7697
|
+
await writeFile(indexPath, content);
|
|
7698
|
+
return true;
|
|
7699
|
+
}
|
|
7700
|
+
async#contentForIndex(indexPath) {
|
|
7701
|
+
const parts = path26.relative(this.#workspaceRoot, indexPath).split(path26.sep).filter(Boolean);
|
|
7702
|
+
const facet = parts.at(-2);
|
|
7703
|
+
if (facet && BARREL_FACETS2.has(facet))
|
|
7704
|
+
return this.#facetContent(path26.dirname(indexPath));
|
|
7705
|
+
return this.#moduleContent(path26.dirname(indexPath));
|
|
7706
|
+
}
|
|
7707
|
+
async#facetContent(dir) {
|
|
7708
|
+
const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
|
|
7709
|
+
const exportNames = entries.flatMap((entry) => {
|
|
7710
|
+
const name = entry.name;
|
|
7711
|
+
if (name.startsWith("."))
|
|
7712
|
+
return [];
|
|
7713
|
+
if (entry.isDirectory())
|
|
7714
|
+
return [name];
|
|
7715
|
+
if (!entry.isFile())
|
|
7716
|
+
return [];
|
|
7717
|
+
if (!FACET_SOURCE_FILE_RE.test(name) || FACET_EXCLUDED_FILE_RE.test(name))
|
|
7718
|
+
return [];
|
|
7719
|
+
return [name.replace(FACET_SOURCE_FILE_RE, "")];
|
|
7720
|
+
}).sort();
|
|
7721
|
+
if (exportNames.length === 0)
|
|
7722
|
+
return null;
|
|
7723
|
+
return `${exportNames.map((name) => `export * from "./${name}";`).join(`
|
|
7724
|
+
`)}
|
|
7725
|
+
`;
|
|
7726
|
+
}
|
|
7727
|
+
async#moduleContent(dir) {
|
|
7728
|
+
const rel = path26.relative(this.#workspaceRoot, dir);
|
|
7729
|
+
const parts = rel.split(path26.sep).filter(Boolean);
|
|
7730
|
+
const moduleSegment = parts.at(-1);
|
|
7731
|
+
if (!moduleSegment)
|
|
7732
|
+
return null;
|
|
7733
|
+
const isScalar = parts.at(-2) === "__scalar";
|
|
7734
|
+
const rawModel = moduleSegment.startsWith("_") ? moduleSegment.slice(1) : moduleSegment;
|
|
7735
|
+
if (!rawModel)
|
|
7736
|
+
return null;
|
|
7737
|
+
const modelName = capitalize3(rawModel);
|
|
7738
|
+
const allowedTypes = isScalar ? SCALAR_UI_TYPES : moduleSegment.startsWith("_") ? SERVICE_UI_TYPES : MODULE_UI_TYPES;
|
|
7739
|
+
const fileTypes = [];
|
|
7740
|
+
for (const type of allowedTypes) {
|
|
7741
|
+
if (await exists(path26.join(dir, `${modelName}.${type}.tsx`)))
|
|
7742
|
+
fileTypes.push(type);
|
|
7743
|
+
}
|
|
7744
|
+
if (fileTypes.length === 0)
|
|
7745
|
+
return null;
|
|
7746
|
+
return `
|
|
7747
|
+
${fileTypes.map((type) => `import * as ${type} from "./${modelName}.${type}";`).join(`
|
|
7748
|
+
`)}
|
|
7749
|
+
|
|
7750
|
+
export const ${modelName} = { ${fileTypes.join(", ")} };`;
|
|
7751
|
+
}
|
|
7752
|
+
}
|
|
7753
|
+
var exists = async (file) => stat3(file).then(() => true).catch(() => false);
|
|
7754
|
+
var capitalize3 = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
7755
|
+
var formatError = (err) => err instanceof Error ? err.message : String(err);
|
|
7756
|
+
// pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
|
|
7757
|
+
import { mkdir as mkdir7 } from "fs/promises";
|
|
7758
|
+
import path27 from "path";
|
|
7236
7759
|
import {
|
|
7237
7760
|
generateFontFace,
|
|
7238
7761
|
getMetricsForFamily,
|
|
@@ -7256,7 +7779,7 @@ class FontOptimizer {
|
|
|
7256
7779
|
constructor(app, command = "start") {
|
|
7257
7780
|
this.#app = app;
|
|
7258
7781
|
this.#command = command;
|
|
7259
|
-
this.#artifactRoot =
|
|
7782
|
+
this.#artifactRoot = path27.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
|
|
7260
7783
|
}
|
|
7261
7784
|
async optimize() {
|
|
7262
7785
|
const fonts = await this.discoverFonts();
|
|
@@ -7275,7 +7798,7 @@ class FontOptimizer {
|
|
|
7275
7798
|
const pageKeys = await this.#app.getPageKeys();
|
|
7276
7799
|
const fonts = [];
|
|
7277
7800
|
await Promise.all(pageKeys.map(async (key) => {
|
|
7278
|
-
const filePath =
|
|
7801
|
+
const filePath = path27.resolve(this.#app.cwdPath, "page", key);
|
|
7279
7802
|
const file = Bun.file(filePath);
|
|
7280
7803
|
if (!await file.exists())
|
|
7281
7804
|
return;
|
|
@@ -7291,8 +7814,8 @@ class FontOptimizer {
|
|
|
7291
7814
|
this.#app.logger.warn(`[font] source not found: ${face.src}`);
|
|
7292
7815
|
continue;
|
|
7293
7816
|
}
|
|
7294
|
-
const outputPath =
|
|
7295
|
-
await
|
|
7817
|
+
const outputPath = path27.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
|
|
7818
|
+
await mkdir7(path27.dirname(outputPath), { recursive: true });
|
|
7296
7819
|
const sourceBuffer = Buffer.from(await Bun.file(sourcePath).arrayBuffer());
|
|
7297
7820
|
const outputBuffer = font.subset === false ? await this.#convertToWoff2(sourceBuffer, sourcePath) : await subsetFont(sourceBuffer, await this.#getSubsetText(font), { targetFormat: "woff2" });
|
|
7298
7821
|
await Bun.write(outputPath, outputBuffer);
|
|
@@ -7439,8 +7962,8 @@ class FontOptimizer {
|
|
|
7439
7962
|
return null;
|
|
7440
7963
|
const rel = src.replace(/^\//, "");
|
|
7441
7964
|
const candidates = [
|
|
7442
|
-
this.#command === "build" ?
|
|
7443
|
-
|
|
7965
|
+
this.#command === "build" ? path27.join(this.#app.dist.cwdPath, "public", rel) : null,
|
|
7966
|
+
path27.join(this.#app.cwdPath, "public", rel),
|
|
7444
7967
|
this.#resolveWorkspacePublicPath(rel)
|
|
7445
7968
|
].filter(Boolean);
|
|
7446
7969
|
for (const candidate of candidates) {
|
|
@@ -7468,7 +7991,7 @@ class FontOptimizer {
|
|
|
7468
7991
|
return "woff2";
|
|
7469
7992
|
if (signature === "OTTO")
|
|
7470
7993
|
return "otf";
|
|
7471
|
-
const ext =
|
|
7994
|
+
const ext = path27.extname(sourcePath).slice(1).toLowerCase();
|
|
7472
7995
|
if (ext === "otf" || ext === "woff" || ext === "woff2")
|
|
7473
7996
|
return ext;
|
|
7474
7997
|
return "ttf";
|
|
@@ -7477,7 +8000,7 @@ class FontOptimizer {
|
|
|
7477
8000
|
const [root, dep, ...rest] = rel.split("/");
|
|
7478
8001
|
if (root !== "libs" || !dep || rest.length === 0)
|
|
7479
8002
|
return null;
|
|
7480
|
-
return
|
|
8003
|
+
return path27.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
|
|
7481
8004
|
}
|
|
7482
8005
|
async#getSubsetText(font) {
|
|
7483
8006
|
const parts = new Set;
|
|
@@ -7487,7 +8010,7 @@ class FontOptimizer {
|
|
|
7487
8010
|
if (font.subsetText)
|
|
7488
8011
|
parts.add(font.subsetText);
|
|
7489
8012
|
for (const filePath of font.subsetFiles ?? []) {
|
|
7490
|
-
const abs =
|
|
8013
|
+
const abs = path27.isAbsolute(filePath) ? filePath : path27.join(this.#app.cwdPath, filePath);
|
|
7491
8014
|
const file = Bun.file(abs);
|
|
7492
8015
|
if (await file.exists())
|
|
7493
8016
|
parts.add(await file.text());
|
|
@@ -7506,7 +8029,7 @@ class FontOptimizer {
|
|
|
7506
8029
|
return "";
|
|
7507
8030
|
}
|
|
7508
8031
|
async#collectAutoSubsetText() {
|
|
7509
|
-
const roots = ["page", "ui"].map((dir) =>
|
|
8032
|
+
const roots = ["page", "ui"].map((dir) => path27.join(this.#app.cwdPath, dir));
|
|
7510
8033
|
const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
|
|
7511
8034
|
const parts = [];
|
|
7512
8035
|
await Promise.all(roots.map(async (root) => {
|
|
@@ -7620,43 +8143,43 @@ ${declarations.map(([prop, value]) => ` ${prop}: ${value};`).join(`
|
|
|
7620
8143
|
}
|
|
7621
8144
|
}
|
|
7622
8145
|
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
7623
|
-
import
|
|
7624
|
-
var
|
|
8146
|
+
import path28 from "path";
|
|
8147
|
+
var SOURCE_EXTS5 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
7625
8148
|
var CSS_EXTS = new Set([".css"]);
|
|
7626
|
-
var
|
|
8149
|
+
var CONFIG_BASENAMES2 = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
7627
8150
|
|
|
7628
8151
|
class HmrChangeClassifier {
|
|
7629
8152
|
classify(abs) {
|
|
7630
8153
|
if (this.#isUninteresting(abs))
|
|
7631
8154
|
return "ignore";
|
|
7632
|
-
const base =
|
|
7633
|
-
if (
|
|
8155
|
+
const base = path28.basename(abs);
|
|
8156
|
+
if (CONFIG_BASENAMES2.has(base))
|
|
7634
8157
|
return "config";
|
|
7635
|
-
const ext =
|
|
8158
|
+
const ext = path28.extname(abs).toLowerCase();
|
|
7636
8159
|
if (CSS_EXTS.has(ext))
|
|
7637
8160
|
return "css";
|
|
7638
|
-
if (
|
|
8161
|
+
if (SOURCE_EXTS5.has(ext))
|
|
7639
8162
|
return "code";
|
|
7640
8163
|
return "ignore";
|
|
7641
8164
|
}
|
|
7642
8165
|
#isUninteresting(abs) {
|
|
7643
|
-
const base =
|
|
8166
|
+
const base = path28.basename(abs);
|
|
7644
8167
|
if (!base)
|
|
7645
8168
|
return true;
|
|
7646
8169
|
if (base.startsWith("."))
|
|
7647
8170
|
return true;
|
|
7648
8171
|
if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
|
|
7649
8172
|
return true;
|
|
7650
|
-
if (abs.includes(`${
|
|
8173
|
+
if (abs.includes(`${path28.sep}node_modules${path28.sep}`))
|
|
7651
8174
|
return true;
|
|
7652
|
-
if (abs.includes(`${
|
|
8175
|
+
if (abs.includes(`${path28.sep}.akan${path28.sep}`))
|
|
7653
8176
|
return true;
|
|
7654
8177
|
return false;
|
|
7655
8178
|
}
|
|
7656
8179
|
}
|
|
7657
8180
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7658
8181
|
import fs4 from "fs";
|
|
7659
|
-
import
|
|
8182
|
+
import path29 from "path";
|
|
7660
8183
|
class HmrWatcher {
|
|
7661
8184
|
#roots;
|
|
7662
8185
|
#debounceMs;
|
|
@@ -7669,7 +8192,7 @@ class HmrWatcher {
|
|
|
7669
8192
|
#stopped = false;
|
|
7670
8193
|
#flushing = false;
|
|
7671
8194
|
constructor(opts) {
|
|
7672
|
-
this.#roots = [...new Set(opts.roots.map((r) =>
|
|
8195
|
+
this.#roots = [...new Set(opts.roots.map((r) => path29.resolve(r)))];
|
|
7673
8196
|
this.#debounceMs = opts.debounceMs ?? 80;
|
|
7674
8197
|
this.#onBatch = opts.onBatch;
|
|
7675
8198
|
this.#logger = opts.logger;
|
|
@@ -7680,7 +8203,7 @@ class HmrWatcher {
|
|
|
7680
8203
|
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7681
8204
|
if (!filename)
|
|
7682
8205
|
return;
|
|
7683
|
-
const abs =
|
|
8206
|
+
const abs = path29.resolve(root, filename.toString());
|
|
7684
8207
|
this.#queue(abs);
|
|
7685
8208
|
});
|
|
7686
8209
|
this.#watchers.push(w);
|
|
@@ -7738,10 +8261,10 @@ class HmrWatcher {
|
|
|
7738
8261
|
}
|
|
7739
8262
|
}
|
|
7740
8263
|
// pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
|
|
7741
|
-
import
|
|
8264
|
+
import path31 from "path";
|
|
7742
8265
|
|
|
7743
8266
|
// pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
|
|
7744
|
-
import
|
|
8267
|
+
import path30 from "path";
|
|
7745
8268
|
var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
|
|
7746
8269
|
var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "@akanjs/cli", "@akanjs/devkit"]);
|
|
7747
8270
|
var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
|
|
@@ -7784,7 +8307,7 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
7784
8307
|
const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
|
|
7785
8308
|
if (!replPath)
|
|
7786
8309
|
continue;
|
|
7787
|
-
const candidate =
|
|
8310
|
+
const candidate = path30.resolve(workspaceRoot, replPath + suffix);
|
|
7788
8311
|
const hit = await firstExisting(candidate);
|
|
7789
8312
|
if (hit)
|
|
7790
8313
|
return hit;
|
|
@@ -7796,8 +8319,8 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
7796
8319
|
if (spec === pkg)
|
|
7797
8320
|
continue;
|
|
7798
8321
|
const suffix = spec.slice(pkg.length + 1);
|
|
7799
|
-
const pkgDir =
|
|
7800
|
-
const candidate =
|
|
8322
|
+
const pkgDir = path30.dirname(path30.resolve(workspaceRoot, entryFile));
|
|
8323
|
+
const candidate = path30.join(pkgDir, suffix);
|
|
7801
8324
|
const hit = await firstExisting(candidate);
|
|
7802
8325
|
if (hit)
|
|
7803
8326
|
return hit;
|
|
@@ -7847,7 +8370,7 @@ async function firstExisting(basePath2) {
|
|
|
7847
8370
|
return candidate;
|
|
7848
8371
|
}
|
|
7849
8372
|
for (const ext of CANDIDATE_EXTS3) {
|
|
7850
|
-
const candidate =
|
|
8373
|
+
const candidate = path30.join(basePath2, `index${ext}`);
|
|
7851
8374
|
if (await Bun.file(candidate).exists())
|
|
7852
8375
|
return candidate;
|
|
7853
8376
|
}
|
|
@@ -7938,11 +8461,11 @@ class PagesBundleBuilder {
|
|
|
7938
8461
|
const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
|
|
7939
8462
|
if (!entryArtifact)
|
|
7940
8463
|
throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
|
|
7941
|
-
const bundlePath =
|
|
8464
|
+
const bundlePath = path31.resolve(entryArtifact.path);
|
|
7942
8465
|
const buildId = Date.now();
|
|
7943
8466
|
const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
|
|
7944
8467
|
const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
|
|
7945
|
-
this.#app.verbose(`[PagesBundleBuilder] ${
|
|
8468
|
+
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
8469
|
return {
|
|
7947
8470
|
bundlePath,
|
|
7948
8471
|
buildId,
|
|
@@ -8024,11 +8547,11 @@ function loaderFor4(absPath) {
|
|
|
8024
8547
|
}
|
|
8025
8548
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
8026
8549
|
import fs5 from "fs";
|
|
8027
|
-
import
|
|
8550
|
+
import path32 from "path";
|
|
8028
8551
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
8029
8552
|
var MIN_COMPRESS_BYTES = 1024;
|
|
8030
8553
|
async function precompressArtifacts(app) {
|
|
8031
|
-
const roots = [
|
|
8554
|
+
const roots = [path32.join(app.dist.cwdPath, ".akan/artifact/client")];
|
|
8032
8555
|
const result = { files: 0, inputBytes: 0, outputBytes: 0 };
|
|
8033
8556
|
await Promise.all(roots.map((root) => precompressRoot(root, result)));
|
|
8034
8557
|
if (result.files > 0) {
|
|
@@ -8054,7 +8577,7 @@ async function precompressRoot(root, result) {
|
|
|
8054
8577
|
async function shouldPrecompress(filePath) {
|
|
8055
8578
|
if (filePath.endsWith(".gz"))
|
|
8056
8579
|
return false;
|
|
8057
|
-
if (!COMPRESSIBLE_EXTS.has(
|
|
8580
|
+
if (!COMPRESSIBLE_EXTS.has(path32.extname(filePath).toLowerCase()))
|
|
8058
8581
|
return false;
|
|
8059
8582
|
const file = Bun.file(filePath);
|
|
8060
8583
|
if (!await file.exists())
|
|
@@ -8072,7 +8595,7 @@ function formatBytes(bytes) {
|
|
|
8072
8595
|
return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
8073
8596
|
}
|
|
8074
8597
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
8075
|
-
import
|
|
8598
|
+
import path33 from "path";
|
|
8076
8599
|
import { optimize } from "@tailwindcss/node";
|
|
8077
8600
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
8078
8601
|
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
@@ -8088,7 +8611,7 @@ class SsrBaseArtifactBuilder {
|
|
|
8088
8611
|
this.#app = app;
|
|
8089
8612
|
this.#command = command;
|
|
8090
8613
|
this.#artifactDir = `${command === "build" ? app.dist.cwdPath : app.cwdPath}/.akan/artifact`;
|
|
8091
|
-
this.#absArtifactDir =
|
|
8614
|
+
this.#absArtifactDir = path33.resolve(this.#artifactDir);
|
|
8092
8615
|
}
|
|
8093
8616
|
async build() {
|
|
8094
8617
|
const akanConfig2 = await this.#app.getConfig();
|
|
@@ -8110,7 +8633,7 @@ class SsrBaseArtifactBuilder {
|
|
|
8110
8633
|
rscRuntimeSsrManifest,
|
|
8111
8634
|
vendorMap,
|
|
8112
8635
|
cssAssets,
|
|
8113
|
-
pagesBundlePath: this.#command === "build" ?
|
|
8636
|
+
pagesBundlePath: this.#command === "build" ? path33.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
|
|
8114
8637
|
pagesBundleBuildId: pagesBundle.buildId,
|
|
8115
8638
|
domains: [...akanConfig2.domains],
|
|
8116
8639
|
subRoutes: Object.fromEntries(Array.from(akanConfig2.subRoutes.entries()).map(([basePath2, domains]) => [basePath2, [...domains]])),
|
|
@@ -8119,7 +8642,7 @@ class SsrBaseArtifactBuilder {
|
|
|
8119
8642
|
i18n: akanConfig2.i18n,
|
|
8120
8643
|
imageConfig: akanConfig2.images
|
|
8121
8644
|
};
|
|
8122
|
-
await Bun.write(
|
|
8645
|
+
await Bun.write(path33.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
|
|
8123
8646
|
`);
|
|
8124
8647
|
this.#app.verbose(`[base-artifact] complete in ${Date.now() - this.#started}ms`);
|
|
8125
8648
|
return { artifact, seedIndex, cssCompiler, optimizedFonts };
|
|
@@ -8167,15 +8690,15 @@ class SsrBaseArtifactBuilder {
|
|
|
8167
8690
|
async#resolveAkanServerPath() {
|
|
8168
8691
|
const candidates = [];
|
|
8169
8692
|
try {
|
|
8170
|
-
candidates.push(
|
|
8693
|
+
candidates.push(path33.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
|
|
8171
8694
|
} catch {}
|
|
8172
|
-
candidates.push(
|
|
8695
|
+
candidates.push(path33.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path33.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
|
|
8173
8696
|
try {
|
|
8174
|
-
candidates.push(
|
|
8697
|
+
candidates.push(path33.dirname(Bun.resolveSync("akanjs/server", path33.dirname(Bun.main))));
|
|
8175
8698
|
} catch {}
|
|
8176
|
-
candidates.push(
|
|
8699
|
+
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
8700
|
for (const candidate of candidates) {
|
|
8178
|
-
if (await Bun.file(
|
|
8701
|
+
if (await Bun.file(path33.join(candidate, "rscClient.tsx")).exists())
|
|
8179
8702
|
return candidate;
|
|
8180
8703
|
}
|
|
8181
8704
|
throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
|
|
@@ -8204,14 +8727,14 @@ ${preparedCssText}`).toString(36);
|
|
|
8204
8727
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
8205
8728
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
8206
8729
|
];
|
|
8207
|
-
await Bun.write(
|
|
8730
|
+
await Bun.write(path33.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
8208
8731
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
8209
8732
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
8210
8733
|
}
|
|
8211
8734
|
}
|
|
8212
8735
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
8213
8736
|
import fs6 from "fs";
|
|
8214
|
-
import
|
|
8737
|
+
import path34 from "path";
|
|
8215
8738
|
|
|
8216
8739
|
class WatchRootResolver {
|
|
8217
8740
|
#app;
|
|
@@ -8221,15 +8744,15 @@ class WatchRootResolver {
|
|
|
8221
8744
|
async resolve() {
|
|
8222
8745
|
const tsconfig = await this.#app.getTsConfig();
|
|
8223
8746
|
const set = new Set;
|
|
8224
|
-
set.add(
|
|
8747
|
+
set.add(path34.resolve(`${this.#app.cwdPath}/page`));
|
|
8225
8748
|
for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
|
|
8226
8749
|
for (const target of targets) {
|
|
8227
8750
|
if (!target)
|
|
8228
8751
|
continue;
|
|
8229
|
-
if (
|
|
8752
|
+
if (path34.isAbsolute(target))
|
|
8230
8753
|
continue;
|
|
8231
8754
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
8232
|
-
const resolved =
|
|
8755
|
+
const resolved = path34.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
8233
8756
|
if (fs6.existsSync(resolved))
|
|
8234
8757
|
set.add(resolved);
|
|
8235
8758
|
}
|
|
@@ -8296,7 +8819,7 @@ class ApplicationBuildRunner {
|
|
|
8296
8819
|
phases: this.#phases,
|
|
8297
8820
|
durationMs: Date.now() - this.#startedAt,
|
|
8298
8821
|
outputDir: this.#app.dist.cwdPath,
|
|
8299
|
-
artifactDir:
|
|
8822
|
+
artifactDir: path35.join(this.#app.dist.cwdPath, ".akan/artifact")
|
|
8300
8823
|
};
|
|
8301
8824
|
}
|
|
8302
8825
|
async typecheck(options = {}) {
|
|
@@ -8304,7 +8827,7 @@ class ApplicationBuildRunner {
|
|
|
8304
8827
|
await this.#app.getPageKeys({ refresh: true });
|
|
8305
8828
|
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig({ incremental });
|
|
8306
8829
|
if (clean)
|
|
8307
|
-
await
|
|
8830
|
+
await rm3(path35.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
|
|
8308
8831
|
await this.#checkProjectInChildProcess(tsconfigPath);
|
|
8309
8832
|
}
|
|
8310
8833
|
async#runPhase(id, label, task, summarize, options = {}) {
|
|
@@ -8376,7 +8899,7 @@ class ApplicationBuildRunner {
|
|
|
8376
8899
|
};
|
|
8377
8900
|
}
|
|
8378
8901
|
async#writeConsoleShim() {
|
|
8379
|
-
await Bun.write(
|
|
8902
|
+
await Bun.write(path35.join(this.#app.dist.cwdPath, "console.js"), `import { cnst, db, dict, option, server, sig, srv } from "./server.js";
|
|
8380
8903
|
import { assertAkanConsoleAllowed, startAkanConsole } from "./console-runtime.js";
|
|
8381
8904
|
|
|
8382
8905
|
const run = async () => {
|
|
@@ -8399,14 +8922,14 @@ void run().catch((error) => {
|
|
|
8399
8922
|
try {
|
|
8400
8923
|
return Bun.resolveSync("akanjs/server/rsc-worker", import.meta.dir);
|
|
8401
8924
|
} catch {
|
|
8402
|
-
return
|
|
8925
|
+
return path35.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/rscWorker.tsx");
|
|
8403
8926
|
}
|
|
8404
8927
|
}
|
|
8405
8928
|
#resolveConsoleRuntimeBuildEntry() {
|
|
8406
8929
|
try {
|
|
8407
|
-
return
|
|
8930
|
+
return path35.join(path35.dirname(Bun.resolveSync("akanjs/server", import.meta.dir)), "console.ts");
|
|
8408
8931
|
} catch {
|
|
8409
|
-
return
|
|
8932
|
+
return path35.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/console.ts");
|
|
8410
8933
|
}
|
|
8411
8934
|
}
|
|
8412
8935
|
async#buildCsr() {
|
|
@@ -8423,8 +8946,8 @@ void run().catch((error) => {
|
|
|
8423
8946
|
return { base, allRoutes };
|
|
8424
8947
|
}
|
|
8425
8948
|
async#writeTypecheckTsconfig({ incremental = true } = {}) {
|
|
8426
|
-
const typecheckDir =
|
|
8427
|
-
await
|
|
8949
|
+
const typecheckDir = path35.join(this.#app.cwdPath, ".akan", "typecheck");
|
|
8950
|
+
await mkdir8(typecheckDir, { recursive: true });
|
|
8428
8951
|
const tsconfig = {
|
|
8429
8952
|
extends: "../../tsconfig.json",
|
|
8430
8953
|
compilerOptions: {
|
|
@@ -8442,7 +8965,7 @@ void run().catch((error) => {
|
|
|
8442
8965
|
],
|
|
8443
8966
|
references: []
|
|
8444
8967
|
};
|
|
8445
|
-
const tsconfigPath =
|
|
8968
|
+
const tsconfigPath = path35.join(typecheckDir, "tsconfig.json");
|
|
8446
8969
|
await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
8447
8970
|
`);
|
|
8448
8971
|
return { typecheckDir, tsconfigPath };
|
|
@@ -8468,10 +8991,10 @@ void run().catch((error) => {
|
|
|
8468
8991
|
}
|
|
8469
8992
|
async#resolveTypecheckWorkerEntry() {
|
|
8470
8993
|
const candidates = [
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8994
|
+
path35.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
8995
|
+
path35.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
8996
|
+
path35.join(import.meta.dir, "typecheck.proc.js"),
|
|
8997
|
+
path35.join(import.meta.dir, "typecheck.proc.ts")
|
|
8475
8998
|
];
|
|
8476
8999
|
for (const candidate of candidates)
|
|
8477
9000
|
if (await Bun.file(candidate).exists())
|
|
@@ -8504,7 +9027,7 @@ void run().catch((error) => {
|
|
|
8504
9027
|
}
|
|
8505
9028
|
}
|
|
8506
9029
|
// pkgs/@akanjs/devkit/applicationReleasePackager.ts
|
|
8507
|
-
import { cp, mkdir as
|
|
9030
|
+
import { cp, mkdir as mkdir9, rm as rm4 } from "fs/promises";
|
|
8508
9031
|
|
|
8509
9032
|
// pkgs/@akanjs/devkit/uploadRelease.ts
|
|
8510
9033
|
import { HttpClient as HttpClient2, Logger as Logger9 } from "akanjs/common";
|
|
@@ -8610,16 +9133,16 @@ class ApplicationReleasePackager {
|
|
|
8610
9133
|
const platformVersion = akanConfig2.mobile.version;
|
|
8611
9134
|
const buildRoot = `${this.#app.workspace.workspaceRoot}/releases/builds/${this.#app.name}`;
|
|
8612
9135
|
if (await FileSys.dirExists(buildRoot))
|
|
8613
|
-
await
|
|
8614
|
-
await
|
|
9136
|
+
await rm4(buildRoot, { recursive: true, force: true });
|
|
9137
|
+
await mkdir9(buildRoot, { recursive: true });
|
|
8615
9138
|
if (rebuild || !await FileSys.dirExists(`${this.#app.dist.cwdPath}/backend`))
|
|
8616
9139
|
await this.#build();
|
|
8617
9140
|
const buildVersion = `${platformVersion}-${buildNum}`;
|
|
8618
9141
|
const buildPath = `${buildRoot}/${buildVersion}`;
|
|
8619
|
-
await
|
|
9142
|
+
await mkdir9(buildPath, { recursive: true });
|
|
8620
9143
|
await cp(`${this.#app.dist.cwdPath}/backend`, `${buildPath}/backend`, { recursive: true });
|
|
8621
9144
|
await cp(this.#app.dist.cwdPath, buildRoot, { recursive: true });
|
|
8622
|
-
await
|
|
9145
|
+
await rm4(`${buildRoot}/frontend/.next`, { recursive: true, force: true });
|
|
8623
9146
|
await this.#app.workspace.spawn("tar", [
|
|
8624
9147
|
"-zcf",
|
|
8625
9148
|
`${this.#app.workspace.workspaceRoot}/releases/builds/${this.#app.name}-release.tar.gz`,
|
|
@@ -8639,7 +9162,7 @@ class ApplicationReleasePackager {
|
|
|
8639
9162
|
`${this.#app.workspace.workspaceRoot}/releases/builds/${this.#app.name}-appBuild.zip`,
|
|
8640
9163
|
"./csr"
|
|
8641
9164
|
]);
|
|
8642
|
-
await
|
|
9165
|
+
await rm4("./csr", { recursive: true, force: true });
|
|
8643
9166
|
}
|
|
8644
9167
|
async#writeSourceArchive({ readme }) {
|
|
8645
9168
|
const sourceRoot = `${this.#app.workspace.workspaceRoot}/releases/sources/${this.#app.name}`;
|
|
@@ -8647,13 +9170,13 @@ class ApplicationReleasePackager {
|
|
|
8647
9170
|
await cp(this.#app.dist.cwdPath, `${sourceRoot}/apps/${this.#app.name}`, { recursive: true });
|
|
8648
9171
|
const libDeps = ["social", "shared", "platform", "util"];
|
|
8649
9172
|
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}/${
|
|
9173
|
+
await Promise.all([".next", "ios", "android", "public/libs"].map(async (path36) => {
|
|
9174
|
+
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${path36}`;
|
|
8652
9175
|
if (await FileSys.dirExists(targetPath))
|
|
8653
|
-
await
|
|
9176
|
+
await rm4(targetPath, { recursive: true, force: true });
|
|
8654
9177
|
}));
|
|
8655
9178
|
const syncPaths = [".husky", ".gitignore", "package.json"];
|
|
8656
|
-
await Promise.all(syncPaths.map((
|
|
9179
|
+
await Promise.all(syncPaths.map((path36) => cp(`${this.#app.workspace.cwdPath}/${path36}`, `${sourceRoot}/${path36}`, { recursive: true })));
|
|
8657
9180
|
await this.#writeSourceTsconfig(sourceRoot, libDeps);
|
|
8658
9181
|
await Bun.write(`${sourceRoot}/README.md`, readme);
|
|
8659
9182
|
await this.#app.workspace.spawn("tar", [
|
|
@@ -8669,11 +9192,11 @@ class ApplicationReleasePackager {
|
|
|
8669
9192
|
const maxRetry = 3;
|
|
8670
9193
|
for (let i = 0;i < maxRetry; i++) {
|
|
8671
9194
|
try {
|
|
8672
|
-
await
|
|
9195
|
+
await rm4(sourceRoot, { recursive: true, force: true });
|
|
8673
9196
|
} catch {}
|
|
8674
9197
|
}
|
|
8675
9198
|
}
|
|
8676
|
-
await
|
|
9199
|
+
await mkdir9(sourceRoot, { recursive: true });
|
|
8677
9200
|
}
|
|
8678
9201
|
async#writeSourceTsconfig(sourceRoot, libDeps) {
|
|
8679
9202
|
const tsconfig = await this.#app.workspace.readJson("tsconfig.json");
|
|
@@ -8744,20 +9267,20 @@ class ApplicationReleasePackager {
|
|
|
8744
9267
|
}
|
|
8745
9268
|
}
|
|
8746
9269
|
// pkgs/@akanjs/devkit/applicationTestPreload.ts
|
|
8747
|
-
import
|
|
9270
|
+
import path36 from "path";
|
|
8748
9271
|
var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
|
|
8749
9272
|
async function resolveSignalTestPreloadPath(target) {
|
|
8750
9273
|
const candidates = [];
|
|
8751
9274
|
const addResolvedPackageCandidate = (basePath2) => {
|
|
8752
9275
|
try {
|
|
8753
|
-
candidates.push(
|
|
9276
|
+
candidates.push(path36.join(path36.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
|
|
8754
9277
|
} catch {}
|
|
8755
9278
|
};
|
|
8756
9279
|
addResolvedPackageCandidate(target.cwdPath);
|
|
8757
9280
|
addResolvedPackageCandidate(process.cwd());
|
|
8758
|
-
addResolvedPackageCandidate(
|
|
9281
|
+
addResolvedPackageCandidate(path36.dirname(Bun.main));
|
|
8759
9282
|
addResolvedPackageCandidate(import.meta.dir);
|
|
8760
|
-
candidates.push(
|
|
9283
|
+
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
9284
|
for (const candidate of [...new Set(candidates)]) {
|
|
8762
9285
|
if (await Bun.file(candidate).exists())
|
|
8763
9286
|
return candidate;
|
|
@@ -8766,8 +9289,8 @@ async function resolveSignalTestPreloadPath(target) {
|
|
|
8766
9289
|
}
|
|
8767
9290
|
// pkgs/@akanjs/devkit/builder.ts
|
|
8768
9291
|
import { existsSync as existsSync2 } from "fs";
|
|
8769
|
-
import { mkdir as
|
|
8770
|
-
import
|
|
9292
|
+
import { mkdir as mkdir10 } from "fs/promises";
|
|
9293
|
+
import path37 from "path";
|
|
8771
9294
|
var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
|
|
8772
9295
|
var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
|
|
8773
9296
|
var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
|
|
@@ -8784,14 +9307,14 @@ class Builder {
|
|
|
8784
9307
|
#globEntrypoints(cwd, pattern) {
|
|
8785
9308
|
const glob = new Bun.Glob(pattern);
|
|
8786
9309
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
8787
|
-
const segments = relativePath.split(
|
|
9310
|
+
const segments = relativePath.split(path37.sep);
|
|
8788
9311
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
8789
|
-
}).map((rel) =>
|
|
9312
|
+
}).map((rel) => path37.join(cwd, rel));
|
|
8790
9313
|
}
|
|
8791
9314
|
#globFiles(cwd, pattern = "**/*.*") {
|
|
8792
9315
|
const glob = new Bun.Glob(pattern);
|
|
8793
9316
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
8794
|
-
const segments = relativePath.split(
|
|
9317
|
+
const segments = relativePath.split(path37.sep);
|
|
8795
9318
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
8796
9319
|
});
|
|
8797
9320
|
}
|
|
@@ -8799,17 +9322,17 @@ class Builder {
|
|
|
8799
9322
|
const out = [];
|
|
8800
9323
|
for (const p of additionalEntryPoints) {
|
|
8801
9324
|
if (p.includes("*")) {
|
|
8802
|
-
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${
|
|
9325
|
+
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path37.sep}`) ? p.slice(cwd.length + 1) : p;
|
|
8803
9326
|
out.push(...this.#globEntrypoints(cwd, rel));
|
|
8804
9327
|
} else
|
|
8805
|
-
out.push(
|
|
9328
|
+
out.push(path37.isAbsolute(p) ? p : path37.join(cwd, p));
|
|
8806
9329
|
}
|
|
8807
9330
|
return out;
|
|
8808
9331
|
}
|
|
8809
9332
|
#getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
|
|
8810
9333
|
const cwd = this.#executor.cwdPath;
|
|
8811
9334
|
const entrypoints = [
|
|
8812
|
-
...bundle ? [
|
|
9335
|
+
...bundle ? [path37.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
|
|
8813
9336
|
...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
|
|
8814
9337
|
];
|
|
8815
9338
|
return {
|
|
@@ -8830,9 +9353,9 @@ class Builder {
|
|
|
8830
9353
|
for (const relativePath of this.#globFiles(cwd)) {
|
|
8831
9354
|
if (relativePath === "package.json")
|
|
8832
9355
|
continue;
|
|
8833
|
-
const sourcePath =
|
|
8834
|
-
const targetPath =
|
|
8835
|
-
await
|
|
9356
|
+
const sourcePath = path37.join(cwd, relativePath);
|
|
9357
|
+
const targetPath = path37.join(this.#distExecutor.cwdPath, relativePath);
|
|
9358
|
+
await mkdir10(path37.dirname(targetPath), { recursive: true });
|
|
8836
9359
|
await Bun.write(targetPath, Bun.file(sourcePath));
|
|
8837
9360
|
}
|
|
8838
9361
|
}
|
|
@@ -8843,13 +9366,13 @@ class Builder {
|
|
|
8843
9366
|
return withoutFormatDir;
|
|
8844
9367
|
if (!hasDotSlash && withoutFormatDir === publishedPath)
|
|
8845
9368
|
return publishedPath;
|
|
8846
|
-
const parsed =
|
|
9369
|
+
const parsed = path37.posix.parse(withoutFormatDir);
|
|
8847
9370
|
if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
|
|
8848
9371
|
return withoutFormatDir;
|
|
8849
|
-
const withoutExt =
|
|
9372
|
+
const withoutExt = path37.posix.join(parsed.dir, parsed.name);
|
|
8850
9373
|
const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
|
|
8851
9374
|
const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
|
|
8852
|
-
const matchedSource = sourceCandidates.find((candidate) => existsSync2(
|
|
9375
|
+
const matchedSource = sourceCandidates.find((candidate) => existsSync2(path37.join(this.#executor.cwdPath, candidate)));
|
|
8853
9376
|
if (!matchedSource)
|
|
8854
9377
|
return withoutFormatDir;
|
|
8855
9378
|
return hasDotSlash ? `./${matchedSource}` : matchedSource;
|
|
@@ -8898,10 +9421,10 @@ class Builder {
|
|
|
8898
9421
|
}
|
|
8899
9422
|
}
|
|
8900
9423
|
// pkgs/@akanjs/devkit/capacitorApp.ts
|
|
8901
|
-
import { cp as cp2, mkdir as
|
|
8902
|
-
import
|
|
9424
|
+
import { cp as cp2, mkdir as mkdir11, rm as rm5 } from "fs/promises";
|
|
9425
|
+
import path38 from "path";
|
|
8903
9426
|
import { MobileProject } from "@trapezedev/project";
|
|
8904
|
-
import { capitalize as
|
|
9427
|
+
import { capitalize as capitalize4 } from "akanjs/common";
|
|
8905
9428
|
|
|
8906
9429
|
// pkgs/@akanjs/devkit/fileEditor.ts
|
|
8907
9430
|
class FileEditor {
|
|
@@ -9094,10 +9617,10 @@ class CapacitorApp {
|
|
|
9094
9617
|
constructor(app, target) {
|
|
9095
9618
|
this.app = app;
|
|
9096
9619
|
this.target = target;
|
|
9097
|
-
this.targetRootPath =
|
|
9098
|
-
this.targetRoot =
|
|
9099
|
-
this.targetWebRoot =
|
|
9100
|
-
this.targetAssetRoot =
|
|
9620
|
+
this.targetRootPath = path38.posix.join(".akan", "mobile", this.target.name);
|
|
9621
|
+
this.targetRoot = path38.join(this.app.cwdPath, this.targetRootPath);
|
|
9622
|
+
this.targetWebRoot = path38.join(this.targetRoot, "www");
|
|
9623
|
+
this.targetAssetRoot = path38.join(this.targetRoot, "assets");
|
|
9101
9624
|
this.project = new MobileProject(this.app.cwdPath, {
|
|
9102
9625
|
android: { path: this.androidRootPath },
|
|
9103
9626
|
ios: { path: this.iosProjectPath }
|
|
@@ -9109,13 +9632,13 @@ class CapacitorApp {
|
|
|
9109
9632
|
env = "debug",
|
|
9110
9633
|
regenerate = false
|
|
9111
9634
|
} = {}) {
|
|
9112
|
-
await
|
|
9635
|
+
await mkdir11(this.targetRoot, { recursive: true });
|
|
9113
9636
|
await this.#writeCapacitorConfig();
|
|
9114
9637
|
if (regenerate) {
|
|
9115
9638
|
if (!platform || platform === "ios")
|
|
9116
|
-
await
|
|
9639
|
+
await rm5(path38.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
|
|
9117
9640
|
if (!platform || platform === "android")
|
|
9118
|
-
await
|
|
9641
|
+
await rm5(path38.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
|
|
9119
9642
|
}
|
|
9120
9643
|
const project = this.project;
|
|
9121
9644
|
await this.project.load();
|
|
@@ -9179,7 +9702,7 @@ class CapacitorApp {
|
|
|
9179
9702
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
9180
9703
|
}
|
|
9181
9704
|
async#updateAndroidBuildTypes() {
|
|
9182
|
-
const appGradle = await FileEditor.create(
|
|
9705
|
+
const appGradle = await FileEditor.create(path38.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
|
|
9183
9706
|
const buildTypesBlock = `
|
|
9184
9707
|
debug {
|
|
9185
9708
|
applicationIdSuffix ".debug"
|
|
@@ -9222,7 +9745,7 @@ class CapacitorApp {
|
|
|
9222
9745
|
const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
|
|
9223
9746
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
9224
9747
|
stdio: "inherit",
|
|
9225
|
-
cwd:
|
|
9748
|
+
cwd: path38.join(this.app.cwdPath, this.androidRootPath),
|
|
9226
9749
|
env: await this.#commandEnv("release", env)
|
|
9227
9750
|
});
|
|
9228
9751
|
}
|
|
@@ -9230,10 +9753,10 @@ class CapacitorApp {
|
|
|
9230
9753
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
9231
9754
|
}
|
|
9232
9755
|
async#ensureAndroidAssetsDir() {
|
|
9233
|
-
await
|
|
9756
|
+
await mkdir11(path38.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
9234
9757
|
}
|
|
9235
9758
|
async#ensureAndroidDebugKeystore() {
|
|
9236
|
-
const keystorePath =
|
|
9759
|
+
const keystorePath = path38.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
9237
9760
|
if (await Bun.file(keystorePath).exists())
|
|
9238
9761
|
return;
|
|
9239
9762
|
await this.#spawn("keytool", [
|
|
@@ -9279,12 +9802,12 @@ class CapacitorApp {
|
|
|
9279
9802
|
await this.#prepareAndroid({ operation: "release", env: "main" });
|
|
9280
9803
|
}
|
|
9281
9804
|
async prepareWww() {
|
|
9282
|
-
const htmlSource =
|
|
9805
|
+
const htmlSource = path38.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
|
|
9283
9806
|
if (!await Bun.file(htmlSource).exists())
|
|
9284
9807
|
throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
|
|
9285
|
-
await
|
|
9286
|
-
await
|
|
9287
|
-
await Bun.write(
|
|
9808
|
+
await rm5(this.targetWebRoot, { recursive: true, force: true });
|
|
9809
|
+
await mkdir11(this.targetWebRoot, { recursive: true });
|
|
9810
|
+
await Bun.write(path38.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
|
|
9288
9811
|
}
|
|
9289
9812
|
#injectMobileTargetMeta(html) {
|
|
9290
9813
|
const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
@@ -9295,8 +9818,8 @@ class CapacitorApp {
|
|
|
9295
9818
|
</head>`);
|
|
9296
9819
|
}
|
|
9297
9820
|
async#writeCapacitorConfig() {
|
|
9298
|
-
await
|
|
9299
|
-
const appInfoPath =
|
|
9821
|
+
await mkdir11(this.targetRoot, { recursive: true });
|
|
9822
|
+
const appInfoPath = path38.relative(this.app.cwdPath, path38.join(this.app.cwdPath, "akan.app.json")).split(path38.sep).join("/");
|
|
9300
9823
|
const content = `import type { AppScanResult } from "akanjs";
|
|
9301
9824
|
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
9302
9825
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
@@ -9317,18 +9840,18 @@ export default withBase(
|
|
|
9317
9840
|
appInfo as AppScanResult,
|
|
9318
9841
|
);
|
|
9319
9842
|
`;
|
|
9320
|
-
await Bun.write(
|
|
9843
|
+
await Bun.write(path38.join(this.app.cwdPath, "capacitor.config.ts"), content);
|
|
9321
9844
|
}
|
|
9322
9845
|
async#prepareTargetAssets() {
|
|
9323
9846
|
if (!this.target.assets)
|
|
9324
9847
|
return;
|
|
9325
|
-
await
|
|
9848
|
+
await mkdir11(this.targetAssetRoot, { recursive: true });
|
|
9326
9849
|
if (this.target.assets.icon)
|
|
9327
|
-
await cp2(
|
|
9850
|
+
await cp2(path38.join(this.app.cwdPath, this.target.assets.icon), path38.join(this.targetAssetRoot, "icon.png"), {
|
|
9328
9851
|
force: true
|
|
9329
9852
|
});
|
|
9330
9853
|
if (this.target.assets.splash)
|
|
9331
|
-
await cp2(
|
|
9854
|
+
await cp2(path38.join(this.app.cwdPath, this.target.assets.splash), path38.join(this.targetAssetRoot, "splash.png"), {
|
|
9332
9855
|
force: true
|
|
9333
9856
|
});
|
|
9334
9857
|
}
|
|
@@ -9336,11 +9859,11 @@ export default withBase(
|
|
|
9336
9859
|
const files = this.target.files?.[platform];
|
|
9337
9860
|
if (!files)
|
|
9338
9861
|
return;
|
|
9339
|
-
const platformRoot =
|
|
9862
|
+
const platformRoot = path38.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
|
|
9340
9863
|
await Promise.all(Object.entries(files).map(async ([to, from]) => {
|
|
9341
|
-
const targetPath =
|
|
9342
|
-
await
|
|
9343
|
-
await cp2(
|
|
9864
|
+
const targetPath = path38.join(platformRoot, to);
|
|
9865
|
+
await mkdir11(path38.dirname(targetPath), { recursive: true });
|
|
9866
|
+
await cp2(path38.join(this.app.cwdPath, from), targetPath, { force: true });
|
|
9344
9867
|
}));
|
|
9345
9868
|
}
|
|
9346
9869
|
async#generateAssets({ operation, env }) {
|
|
@@ -9350,7 +9873,7 @@ export default withBase(
|
|
|
9350
9873
|
"@capacitor/assets",
|
|
9351
9874
|
"generate",
|
|
9352
9875
|
"--assetPath",
|
|
9353
|
-
|
|
9876
|
+
path38.posix.join(this.targetRootPath, "assets"),
|
|
9354
9877
|
"--iosProject",
|
|
9355
9878
|
this.iosProjectPath,
|
|
9356
9879
|
"--androidProject",
|
|
@@ -9452,7 +9975,7 @@ export default withBase(
|
|
|
9452
9975
|
this.#setPermissionsInAndroid(["POST_NOTIFICATIONS"]);
|
|
9453
9976
|
}
|
|
9454
9977
|
async#setPermissionInIos(permissions) {
|
|
9455
|
-
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${
|
|
9978
|
+
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${capitalize4(key)}`, value]));
|
|
9456
9979
|
await Promise.all([
|
|
9457
9980
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Debug", updateNs),
|
|
9458
9981
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Release", updateNs)
|
|
@@ -9537,15 +10060,15 @@ var Pkg = createInternalArgToken("Pkg");
|
|
|
9537
10060
|
var Module = createInternalArgToken("Module");
|
|
9538
10061
|
var Workspace = createInternalArgToken("Workspace");
|
|
9539
10062
|
// pkgs/@akanjs/devkit/commandDecorators/command.ts
|
|
9540
|
-
import
|
|
10063
|
+
import path39 from "path";
|
|
9541
10064
|
import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
|
|
9542
10065
|
import { Logger as Logger10 } from "akanjs/common";
|
|
9543
10066
|
import chalk6 from "chalk";
|
|
9544
10067
|
import { program } from "commander";
|
|
9545
10068
|
|
|
9546
10069
|
// pkgs/@akanjs/devkit/commandDecorators/dependencyBuilder.ts
|
|
9547
|
-
var
|
|
9548
|
-
var createDependencyKey = (refName, kind) => `${refName}${
|
|
10070
|
+
var capitalize5 = (value) => value.slice(0, 1).toUpperCase() + value.slice(1);
|
|
10071
|
+
var createDependencyKey = (refName, kind) => `${refName}${capitalize5(kind)}`;
|
|
9549
10072
|
|
|
9550
10073
|
class CommandContainer {
|
|
9551
10074
|
static #instances = new Map;
|
|
@@ -10037,7 +10560,7 @@ var runCommands = async (...commands) => {
|
|
|
10037
10560
|
process.exit(1);
|
|
10038
10561
|
});
|
|
10039
10562
|
const __dirname2 = getDirname(import.meta.url);
|
|
10040
|
-
const packageJsonCandidates = [`${
|
|
10563
|
+
const packageJsonCandidates = [`${path39.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
|
|
10041
10564
|
let cliPackageJson = null;
|
|
10042
10565
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
10043
10566
|
if (!await FileSys.fileExists(packageJsonPath))
|
|
@@ -10315,8 +10838,8 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
10315
10838
|
return importSpecifiers;
|
|
10316
10839
|
};
|
|
10317
10840
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
10318
|
-
const configFile = ts7.readConfigFile(tsConfigPath, (
|
|
10319
|
-
return ts7.sys.readFile(
|
|
10841
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path40) => {
|
|
10842
|
+
return ts7.sys.readFile(path40);
|
|
10320
10843
|
});
|
|
10321
10844
|
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
10322
10845
|
};
|
|
@@ -11513,7 +12036,7 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
|
|
|
11513
12036
|
import { Logger as Logger16 } from "akanjs/common";
|
|
11514
12037
|
|
|
11515
12038
|
// pkgs/@akanjs/cli/package/package.runner.ts
|
|
11516
|
-
import
|
|
12039
|
+
import path40 from "path";
|
|
11517
12040
|
import { Logger as Logger14 } from "akanjs/common";
|
|
11518
12041
|
var {$: $2 } = globalThis.Bun;
|
|
11519
12042
|
|
|
@@ -11533,11 +12056,11 @@ class PackageRunner extends runner("package") {
|
|
|
11533
12056
|
}
|
|
11534
12057
|
async#getInstalledPackageJson() {
|
|
11535
12058
|
const packageJsonCandidates = [
|
|
11536
|
-
`${
|
|
12059
|
+
`${path40.dirname(Bun.main)}/package.json`,
|
|
11537
12060
|
`${process.cwd()}/node_modules/akanjs/package.json`
|
|
11538
12061
|
];
|
|
11539
12062
|
try {
|
|
11540
|
-
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json",
|
|
12063
|
+
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json", path40.dirname(Bun.main)));
|
|
11541
12064
|
} catch {}
|
|
11542
12065
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
11543
12066
|
if (!await Bun.file(packageJsonPath).exists())
|
|
@@ -11546,7 +12069,7 @@ class PackageRunner extends runner("package") {
|
|
|
11546
12069
|
if (packageJson.name === "akanjs" || packageJson.name === "@akanjs/cli")
|
|
11547
12070
|
return packageJson;
|
|
11548
12071
|
}
|
|
11549
|
-
throw new Error(`[package] failed to locate akanjs package.json from ${
|
|
12072
|
+
throw new Error(`[package] failed to locate akanjs package.json from ${path40.dirname(Bun.main)}`);
|
|
11550
12073
|
}
|
|
11551
12074
|
async createPackage(workspace, pkgName) {
|
|
11552
12075
|
await workspace.applyTemplate({ basePath: `pkgs/${pkgName}`, template: "pkgRoot", dict: { pkgName } });
|
|
@@ -11721,7 +12244,7 @@ class PackageScript extends script("package", [PackageRunner]) {
|
|
|
11721
12244
|
}
|
|
11722
12245
|
|
|
11723
12246
|
// pkgs/@akanjs/cli/cloud/cloud.runner.ts
|
|
11724
|
-
import
|
|
12247
|
+
import path41 from "path";
|
|
11725
12248
|
import { confirm as confirm4, input as input5, select as select7 } from "@inquirer/prompts";
|
|
11726
12249
|
import { Logger as Logger15, sleep } from "akanjs/common";
|
|
11727
12250
|
import chalk7 from "chalk";
|
|
@@ -11992,7 +12515,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
11992
12515
|
await Promise.all(akanPkgs.map(async (library) => {
|
|
11993
12516
|
Logger15.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
|
|
11994
12517
|
await workspace.spawn("npm", ["publish", "--tag", tag, ...this.#getRegistryArgs(registry), ...this.#getLocalRegistryAuthArgs(registry)], {
|
|
11995
|
-
cwd:
|
|
12518
|
+
cwd: path41.join(workspace.workspaceRoot, "dist/pkgs", library),
|
|
11996
12519
|
env: this.#getRegistryEnv(registry),
|
|
11997
12520
|
stdio: "inherit"
|
|
11998
12521
|
});
|
|
@@ -12050,7 +12573,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
12050
12573
|
await workspace.remove(localPath);
|
|
12051
12574
|
}
|
|
12052
12575
|
async uploadEnv(cloudApi2, workspaceId, filePath) {
|
|
12053
|
-
const file = new File([Bun.file(filePath)],
|
|
12576
|
+
const file = new File([Bun.file(filePath)], path41.basename(filePath));
|
|
12054
12577
|
await cloudApi2.uploadEnv(workspaceId, file);
|
|
12055
12578
|
}
|
|
12056
12579
|
async downloadEnvByScp(workspace) {
|
|
@@ -12142,14 +12665,14 @@ class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, Packa
|
|
|
12142
12665
|
}
|
|
12143
12666
|
async uploadEnv(workspace) {
|
|
12144
12667
|
const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
|
|
12145
|
-
const { path:
|
|
12668
|
+
const { path: path42 } = await this.cloudRunner.gatherEnvFiles(workspace);
|
|
12146
12669
|
if (workspaceId) {
|
|
12147
12670
|
await this.login(workspace);
|
|
12148
12671
|
const cloudApi2 = await CloudApi.fromHost(workspace);
|
|
12149
|
-
await this.cloudRunner.uploadEnv(cloudApi2, workspaceId,
|
|
12672
|
+
await this.cloudRunner.uploadEnv(cloudApi2, workspaceId, path42);
|
|
12150
12673
|
return;
|
|
12151
12674
|
}
|
|
12152
|
-
await this.cloudRunner.uploadEnvByScp(workspace,
|
|
12675
|
+
await this.cloudRunner.uploadEnvByScp(workspace, path42);
|
|
12153
12676
|
}
|
|
12154
12677
|
async deployAkan(workspace, { test = true, registryUrl } = {}) {
|
|
12155
12678
|
const akanPkgs = await this.cloudRunner.getAkanPkgs(workspace);
|
|
@@ -12563,14 +13086,14 @@ class GuidelinePrompt extends Prompter {
|
|
|
12563
13086
|
async#getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
|
|
12564
13087
|
const glob = new Bun.Glob(matchPattern);
|
|
12565
13088
|
const paths = [];
|
|
12566
|
-
for await (const
|
|
12567
|
-
if (avoidDirs.some((dir) =>
|
|
13089
|
+
for await (const path42 of glob.scan({ cwd: this.workspace.workspaceRoot, absolute: true })) {
|
|
13090
|
+
if (avoidDirs.some((dir) => path42.includes(dir)))
|
|
12568
13091
|
continue;
|
|
12569
|
-
const fileContent = await FileSys.readText(
|
|
13092
|
+
const fileContent = await FileSys.readText(path42);
|
|
12570
13093
|
const textFilter = filterText ? new RegExp(filterText) : null;
|
|
12571
13094
|
if (filterText && !textFilter?.test(fileContent))
|
|
12572
13095
|
continue;
|
|
12573
|
-
paths.push(
|
|
13096
|
+
paths.push(path42);
|
|
12574
13097
|
}
|
|
12575
13098
|
return paths;
|
|
12576
13099
|
}
|
|
@@ -12889,8 +13412,8 @@ class LibraryCommand extends command("library", [LibraryScript], ({ public: targ
|
|
|
12889
13412
|
}
|
|
12890
13413
|
|
|
12891
13414
|
// pkgs/@akanjs/cli/localRegistry/localRegistry.runner.ts
|
|
12892
|
-
import { mkdir as
|
|
12893
|
-
import
|
|
13415
|
+
import { mkdir as mkdir12, rm as rm6 } from "fs/promises";
|
|
13416
|
+
import path42 from "path";
|
|
12894
13417
|
import { Logger as Logger19 } from "akanjs/common";
|
|
12895
13418
|
var defaultLocalRegistryUrl = "http://127.0.0.1:4873";
|
|
12896
13419
|
var containerName = "akan-verdaccio";
|
|
@@ -12908,9 +13431,9 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
12908
13431
|
Logger19.info(`Local registry is already running at ${registry}`);
|
|
12909
13432
|
return registry;
|
|
12910
13433
|
} catch {}
|
|
12911
|
-
const configPath2 =
|
|
12912
|
-
const storagePath =
|
|
12913
|
-
await
|
|
13434
|
+
const configPath2 = path42.join(workspace.workspaceRoot, "pkgs/@akanjs/cli/localRegistry/verdaccio.yaml");
|
|
13435
|
+
const storagePath = path42.join(workspace.workspaceRoot, ".akan/verdaccio/storage");
|
|
13436
|
+
await mkdir12(storagePath, { recursive: true });
|
|
12914
13437
|
await workspace.spawn("docker", [
|
|
12915
13438
|
"run",
|
|
12916
13439
|
"--rm",
|
|
@@ -12932,13 +13455,13 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
12932
13455
|
try {
|
|
12933
13456
|
await workspace.spawn("docker", ["rm", "-f", containerName], { stdio: "inherit" });
|
|
12934
13457
|
} catch {}
|
|
12935
|
-
await
|
|
13458
|
+
await rm6(path42.join(workspace.workspaceRoot, ".akan/verdaccio"), { recursive: true, force: true });
|
|
12936
13459
|
Logger19.info("Local registry storage has been reset");
|
|
12937
13460
|
}
|
|
12938
13461
|
async smoke(workspace, { registryUrl } = {}) {
|
|
12939
13462
|
const registry = this.getRegistryUrl(registryUrl);
|
|
12940
|
-
const smokeRoot =
|
|
12941
|
-
await
|
|
13463
|
+
const smokeRoot = path42.join(workspace.workspaceRoot, ".akan/e2e");
|
|
13464
|
+
await rm6(path42.join(smokeRoot, smokeRepoName), { recursive: true, force: true });
|
|
12942
13465
|
await workspace.spawn(process.execPath, [
|
|
12943
13466
|
"dist/pkgs/create-akan-workspace/index.js",
|
|
12944
13467
|
smokeRepoName,
|
|
@@ -12955,12 +13478,12 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
12955
13478
|
stdio: "inherit"
|
|
12956
13479
|
});
|
|
12957
13480
|
await workspace.spawn("akan", ["typecheck", smokeAppName], {
|
|
12958
|
-
cwd:
|
|
13481
|
+
cwd: path42.join(smokeRoot, smokeRepoName),
|
|
12959
13482
|
env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
|
|
12960
13483
|
stdio: "inherit"
|
|
12961
13484
|
});
|
|
12962
13485
|
await workspace.spawn("akan", ["build", smokeAppName], {
|
|
12963
|
-
cwd:
|
|
13486
|
+
cwd: path42.join(smokeRoot, smokeRepoName),
|
|
12964
13487
|
env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
|
|
12965
13488
|
stdio: "inherit"
|
|
12966
13489
|
});
|
|
@@ -13040,7 +13563,7 @@ import { lowerlize } from "akanjs/common";
|
|
|
13040
13563
|
|
|
13041
13564
|
// pkgs/@akanjs/cli/module/module.script.ts
|
|
13042
13565
|
import { input as input6 } from "@inquirer/prompts";
|
|
13043
|
-
import { capitalize as
|
|
13566
|
+
import { capitalize as capitalize8, randomPicks as randomPicks2 } from "akanjs/common";
|
|
13044
13567
|
|
|
13045
13568
|
// pkgs/@akanjs/cli/page/page.runner.ts
|
|
13046
13569
|
class PageRunner extends runner("page") {
|
|
@@ -13070,7 +13593,7 @@ function pluralizeName(name) {
|
|
|
13070
13593
|
}
|
|
13071
13594
|
|
|
13072
13595
|
// pkgs/@akanjs/cli/module/module.request.ts
|
|
13073
|
-
import { capitalize as
|
|
13596
|
+
import { capitalize as capitalize6 } from "akanjs/common";
|
|
13074
13597
|
|
|
13075
13598
|
// pkgs/@akanjs/cli/module/module.prompt.ts
|
|
13076
13599
|
var componentDefaultDescription = ({
|
|
@@ -13195,7 +13718,7 @@ var requestTemplate = ({
|
|
|
13195
13718
|
${componentDefaultDescription({
|
|
13196
13719
|
sysName,
|
|
13197
13720
|
modelName,
|
|
13198
|
-
ModelName: ModelName ??
|
|
13721
|
+
ModelName: ModelName ?? capitalize6(modelName),
|
|
13199
13722
|
exampleFiles,
|
|
13200
13723
|
constant,
|
|
13201
13724
|
properties
|
|
@@ -13252,7 +13775,7 @@ var requestView = ({
|
|
|
13252
13775
|
${componentDefaultDescription({
|
|
13253
13776
|
sysName,
|
|
13254
13777
|
modelName,
|
|
13255
|
-
ModelName: ModelName ??
|
|
13778
|
+
ModelName: ModelName ?? capitalize6(modelName),
|
|
13256
13779
|
exampleFiles,
|
|
13257
13780
|
constant,
|
|
13258
13781
|
properties
|
|
@@ -13313,7 +13836,7 @@ var requestUnit = ({
|
|
|
13313
13836
|
${componentDefaultDescription({
|
|
13314
13837
|
sysName,
|
|
13315
13838
|
modelName,
|
|
13316
|
-
ModelName: ModelName ??
|
|
13839
|
+
ModelName: ModelName ?? capitalize6(modelName),
|
|
13317
13840
|
exampleFiles,
|
|
13318
13841
|
constant,
|
|
13319
13842
|
properties
|
|
@@ -13362,7 +13885,7 @@ var requestUnit = ({
|
|
|
13362
13885
|
`;
|
|
13363
13886
|
|
|
13364
13887
|
// pkgs/@akanjs/cli/module/module.runner.ts
|
|
13365
|
-
import { capitalize as
|
|
13888
|
+
import { capitalize as capitalize7 } from "akanjs/common";
|
|
13366
13889
|
class ModuleRunner extends runner("module") {
|
|
13367
13890
|
async createService(module) {
|
|
13368
13891
|
const serviceName = module.name.replace(/^_+/, "");
|
|
@@ -13392,13 +13915,13 @@ class ModuleRunner extends runner("module") {
|
|
|
13392
13915
|
async createComponentTemplate(module, type) {
|
|
13393
13916
|
await module.sys.applyTemplate({
|
|
13394
13917
|
basePath: `./lib/${module.name}`,
|
|
13395
|
-
template: `module/__Model__.${
|
|
13918
|
+
template: `module/__Model__.${capitalize7(type)}.tsx`,
|
|
13396
13919
|
dict: { model: module.name, appName: module.sys.name }
|
|
13397
13920
|
});
|
|
13398
13921
|
return {
|
|
13399
13922
|
component: {
|
|
13400
|
-
filename: `${module.name}.${
|
|
13401
|
-
content: await module.sys.readFile(`lib/${module.name}/${
|
|
13923
|
+
filename: `${module.name}.${capitalize7(type)}.tsx`,
|
|
13924
|
+
content: await module.sys.readFile(`lib/${module.name}/${capitalize7(module.name)}.${capitalize7(type)}.tsx`)
|
|
13402
13925
|
}
|
|
13403
13926
|
};
|
|
13404
13927
|
}
|
|
@@ -13524,7 +14047,7 @@ class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
|
13524
14047
|
async createTemplate(mod) {
|
|
13525
14048
|
const { component: template } = await this.moduleRunner.createComponentTemplate(mod, "template");
|
|
13526
14049
|
const templateExampleFiles = (await mod.sys.getTemplatesSourceCode()).filter((f) => !f.filePath.includes(`${mod.name}.Template.tsx`));
|
|
13527
|
-
const Name =
|
|
14050
|
+
const Name = capitalize8(mod.name);
|
|
13528
14051
|
const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13529
14052
|
const constant = await FileSys.readText(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13530
14053
|
const session = new AiSession("createTemplate", { workspace: mod.sys.workspace, cacheKey: mod.name });
|
|
@@ -13543,7 +14066,7 @@ class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
|
13543
14066
|
}
|
|
13544
14067
|
async createUnit(mod) {
|
|
13545
14068
|
const { component: unit } = await this.moduleRunner.createComponentTemplate(mod, "unit");
|
|
13546
|
-
const Name =
|
|
14069
|
+
const Name = capitalize8(mod.name);
|
|
13547
14070
|
const unitExampleFiles = (await mod.sys.getUnitsSourceCode()).filter((f) => !f.filePath.includes(`${mod.name}.Unit.tsx`));
|
|
13548
14071
|
const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13549
14072
|
const constant = await FileSys.readText(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
@@ -13564,7 +14087,7 @@ class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
|
13564
14087
|
async createView(mod) {
|
|
13565
14088
|
const { component: view } = await this.moduleRunner.createComponentTemplate(mod, "view");
|
|
13566
14089
|
const viewExampleFiles = (await mod.sys.getViewsSourceCode()).filter((f) => !f.filePath.includes(`${mod.name}.View.tsx`));
|
|
13567
|
-
const Name =
|
|
14090
|
+
const Name = capitalize8(mod.name);
|
|
13568
14091
|
const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13569
14092
|
const constant = await FileSys.readText(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
|
|
13570
14093
|
const session = new AiSession("createView", { workspace: mod.sys.workspace, cacheKey: mod.name });
|
|
@@ -13841,11 +14364,11 @@ class ScalarCommand extends command("scalar", [ScalarScript], ({ public: target
|
|
|
13841
14364
|
}
|
|
13842
14365
|
|
|
13843
14366
|
// pkgs/@akanjs/cli/workspace/workspace.script.ts
|
|
13844
|
-
import
|
|
14367
|
+
import path44 from "path";
|
|
13845
14368
|
import { Logger as Logger20 } from "akanjs/common";
|
|
13846
14369
|
|
|
13847
14370
|
// pkgs/@akanjs/cli/workspace/workspace.runner.ts
|
|
13848
|
-
import
|
|
14371
|
+
import path43 from "path";
|
|
13849
14372
|
var defaultWorkspacePeerDependencies = new Set([
|
|
13850
14373
|
"@react-spring/web",
|
|
13851
14374
|
"@use-gesture/react",
|
|
@@ -13896,7 +14419,7 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13896
14419
|
owner = ""
|
|
13897
14420
|
}) {
|
|
13898
14421
|
const cwdPath = process.cwd();
|
|
13899
|
-
const workspaceRoot =
|
|
14422
|
+
const workspaceRoot = path43.join(cwdPath, dirname2, repoName);
|
|
13900
14423
|
const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
|
|
13901
14424
|
const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
|
|
13902
14425
|
const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname2}/${repoName}...`);
|
|
@@ -13952,9 +14475,9 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13952
14475
|
}
|
|
13953
14476
|
async#getCliPackageJson() {
|
|
13954
14477
|
const packageJsonCandidates = [
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
14478
|
+
path43.join(import.meta.dir, "../package.json"),
|
|
14479
|
+
path43.join(import.meta.dir, "package.json"),
|
|
14480
|
+
path43.join(path43.dirname(Bun.main), "package.json")
|
|
13958
14481
|
];
|
|
13959
14482
|
try {
|
|
13960
14483
|
packageJsonCandidates.unshift(Bun.resolveSync("@akanjs/cli/package.json", import.meta.dir));
|
|
@@ -13970,9 +14493,9 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13970
14493
|
}
|
|
13971
14494
|
async#getAkanPackageJson() {
|
|
13972
14495
|
const packageJsonCandidates = [
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
14496
|
+
path43.join(import.meta.dir, "../../../akanjs/package.json"),
|
|
14497
|
+
path43.join(process.cwd(), "pkgs/akanjs/package.json"),
|
|
14498
|
+
path43.join(path43.dirname(Bun.main), "node_modules/akanjs/package.json")
|
|
13976
14499
|
];
|
|
13977
14500
|
try {
|
|
13978
14501
|
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json", import.meta.dir));
|
|
@@ -13986,13 +14509,13 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
13986
14509
|
}
|
|
13987
14510
|
let current = import.meta.dir;
|
|
13988
14511
|
for (let depth = 0;depth < 6; depth++) {
|
|
13989
|
-
const packageJsonPath =
|
|
14512
|
+
const packageJsonPath = path43.join(current, "package.json");
|
|
13990
14513
|
if (await Bun.file(packageJsonPath).exists()) {
|
|
13991
14514
|
const packageJson = await FileSys.readJson(packageJsonPath);
|
|
13992
14515
|
if (packageJson.name === "akanjs")
|
|
13993
14516
|
return packageJson;
|
|
13994
14517
|
}
|
|
13995
|
-
const parent =
|
|
14518
|
+
const parent = path43.dirname(current);
|
|
13996
14519
|
if (parent === current)
|
|
13997
14520
|
break;
|
|
13998
14521
|
current = parent;
|
|
@@ -14069,7 +14592,7 @@ class WorkspaceScript extends script("workspace", [
|
|
|
14069
14592
|
} catch (_) {
|
|
14070
14593
|
gitSpinner.fail("Git repository initialization failed. It's not fatal, you can commit manually");
|
|
14071
14594
|
}
|
|
14072
|
-
const workspacePath =
|
|
14595
|
+
const workspacePath = path44.join(dirname2, repoName);
|
|
14073
14596
|
Logger20.rawLog(`
|
|
14074
14597
|
\uD83C\uDF89 Welcome aboard! Workspace created in ${dirname2}/${repoName}`);
|
|
14075
14598
|
Logger20.rawLog(`\uD83D\uDE80 Run \`cd ${workspacePath} && akan start ${appName}\` to start the development server.`);
|