@akanjs/cli 2.3.11-rc.3 → 2.3.11-rc.4
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 +172 -4
- package/index.js +414 -11
- package/package.json +2 -2
- package/templates/workspaceRoot/.gitignore.template +2 -1
|
@@ -4170,6 +4170,7 @@ var BACKEND_RESTART_DEBOUNCE_MS = 120;
|
|
|
4170
4170
|
var BACKEND_GRACEFUL_TIMEOUT_MS = 3000;
|
|
4171
4171
|
var BACKEND_RECOVERY_BASE_DELAY_MS = 1000;
|
|
4172
4172
|
var BACKEND_RECOVERY_MAX_DELAY_MS = 30000;
|
|
4173
|
+
var BACKEND_STDERR_TAIL_LIMIT = 40;
|
|
4173
4174
|
var BUILDER_READY_TIMEOUT_MS = 150000;
|
|
4174
4175
|
var BUILDER_START_MAX_ATTEMPTS = 3;
|
|
4175
4176
|
var SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
@@ -4372,6 +4373,7 @@ class AkanAppHost {
|
|
|
4372
4373
|
#pendingRestartReason = null;
|
|
4373
4374
|
#backendStartStatus = null;
|
|
4374
4375
|
#backendBuildStatusGeneration = 0;
|
|
4376
|
+
#backendStderrTail = [];
|
|
4375
4377
|
#lastGoodFrontend = {};
|
|
4376
4378
|
#buildStatusByPhase = new Map;
|
|
4377
4379
|
#pendingBuildStatusReplay = [];
|
|
@@ -4423,6 +4425,7 @@ class AkanAppHost {
|
|
|
4423
4425
|
this.#backendStartStatus = startStatus;
|
|
4424
4426
|
this.#setBackendLifecycleState("starting");
|
|
4425
4427
|
this.#backendReady = false;
|
|
4428
|
+
this.#backendStderrTail = [];
|
|
4426
4429
|
const backend = Bun.spawn(["bun", `apps/${this.app.name}/main.ts`], {
|
|
4427
4430
|
cwd: this.app.workspace.workspaceRoot,
|
|
4428
4431
|
stdio: this.withInk ? ["ignore", "pipe", "pipe"] : ["inherit", "inherit", "inherit"],
|
|
@@ -4456,6 +4459,37 @@ class AkanAppHost {
|
|
|
4456
4459
|
});
|
|
4457
4460
|
this.#backend = backend;
|
|
4458
4461
|
this.logger.verbose(`backend spawned pid=${backend.pid}`);
|
|
4462
|
+
if (this.withInk) {
|
|
4463
|
+
this.#forwardBackendStream(backend.stderr, "stderr");
|
|
4464
|
+
this.#forwardBackendStream(backend.stdout, "stdout");
|
|
4465
|
+
}
|
|
4466
|
+
}
|
|
4467
|
+
#recordBackendStderr(chunk) {
|
|
4468
|
+
const lines = chunk.split(/\r?\n/).filter((line) => line.length > 0);
|
|
4469
|
+
if (lines.length === 0)
|
|
4470
|
+
return;
|
|
4471
|
+
this.#backendStderrTail.push(...lines);
|
|
4472
|
+
if (this.#backendStderrTail.length > BACKEND_STDERR_TAIL_LIMIT) {
|
|
4473
|
+
this.#backendStderrTail.splice(0, this.#backendStderrTail.length - BACKEND_STDERR_TAIL_LIMIT);
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
async#forwardBackendStream(stream, kind) {
|
|
4477
|
+
if (!stream)
|
|
4478
|
+
return;
|
|
4479
|
+
const decoder = new TextDecoder;
|
|
4480
|
+
try {
|
|
4481
|
+
for await (const chunk of stream) {
|
|
4482
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
4483
|
+
if (!text.trim())
|
|
4484
|
+
continue;
|
|
4485
|
+
if (kind === "stderr") {
|
|
4486
|
+
this.#recordBackendStderr(text);
|
|
4487
|
+
this.logger.warn(`[backend] ${text.trimEnd()}`);
|
|
4488
|
+
} else {
|
|
4489
|
+
this.logger.verbose(`[backend] ${text.trimEnd()}`);
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
} catch {}
|
|
4459
4493
|
}
|
|
4460
4494
|
#nextBackendBuildStatusGeneration(generation) {
|
|
4461
4495
|
if (typeof generation === "number") {
|
|
@@ -4580,6 +4614,11 @@ class AkanAppHost {
|
|
|
4580
4614
|
});
|
|
4581
4615
|
this.#sendOrQueueBuildStatus(failureStatus);
|
|
4582
4616
|
this.logger.warn(`[backend-recovery] backend exited unexpectedly (${reason}); restarting in ${delay}ms (attempt ${this.#backendRecoveryAttempts})`);
|
|
4617
|
+
if (this.#backendStderrTail.length > 0) {
|
|
4618
|
+
this.logger.warn(`[backend-recovery] recent backend stderr:
|
|
4619
|
+
${this.#backendStderrTail.join(`
|
|
4620
|
+
`)}`);
|
|
4621
|
+
}
|
|
4583
4622
|
this.#backendRecoveryTimer = setTimeout(() => {
|
|
4584
4623
|
this.#backendRecoveryTimer = null;
|
|
4585
4624
|
if (this.#backend)
|
|
@@ -5945,6 +5984,117 @@ ${values.map((value) => ` ${value}: t([${JSON.stringify(titleize(value))}, ${
|
|
|
5945
5984
|
return `${content.slice(0, insertBeforeIndex)}${enumBlock}${content.slice(insertBeforeIndex)}`;
|
|
5946
5985
|
};
|
|
5947
5986
|
var parseValues = (value) => value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
|
|
5987
|
+
var hasSourceParseErrors = (content, fileName = "source.ts") => hasParseDiagnostics(sourceFileFor(fileName, content));
|
|
5988
|
+
var findClassDeclaration = (source, className) => {
|
|
5989
|
+
let found = null;
|
|
5990
|
+
const visit = (node) => {
|
|
5991
|
+
if (found)
|
|
5992
|
+
return;
|
|
5993
|
+
if (ts4.isClassDeclaration(node) && node.name?.text === className) {
|
|
5994
|
+
found = node;
|
|
5995
|
+
return;
|
|
5996
|
+
}
|
|
5997
|
+
ts4.forEachChild(node, visit);
|
|
5998
|
+
};
|
|
5999
|
+
ts4.forEachChild(source, visit);
|
|
6000
|
+
return found;
|
|
6001
|
+
};
|
|
6002
|
+
var firstHeritageCall = (node) => {
|
|
6003
|
+
const expression = (node.heritageClauses?.flatMap((clause) => [...clause.types]) ?? [])[0]?.expression;
|
|
6004
|
+
return expression && ts4.isCallExpression(expression) ? expression : null;
|
|
6005
|
+
};
|
|
6006
|
+
var factoryArrowOf = (call) => {
|
|
6007
|
+
const arg = call.arguments.find((argument) => ts4.isArrowFunction(argument) || ts4.isFunctionExpression(argument));
|
|
6008
|
+
return arg && (ts4.isArrowFunction(arg) || ts4.isFunctionExpression(arg)) ? arg : null;
|
|
6009
|
+
};
|
|
6010
|
+
var hasClassMethod = (content, className, methodName) => {
|
|
6011
|
+
const node = findClassDeclaration(sourceFileFor("service.ts", content), className);
|
|
6012
|
+
return Boolean(node?.members.some((member) => ts4.isMethodDeclaration(member) && nodeName(member.name) === methodName));
|
|
6013
|
+
};
|
|
6014
|
+
var insertClassMethod = (content, className, methodBlock) => {
|
|
6015
|
+
const source = sourceFileFor("service.ts", content);
|
|
6016
|
+
const node = findClassDeclaration(source, className);
|
|
6017
|
+
if (!node)
|
|
6018
|
+
return null;
|
|
6019
|
+
const closeBrace = node.getEnd() - 1;
|
|
6020
|
+
if (content[closeBrace] !== "}")
|
|
6021
|
+
return null;
|
|
6022
|
+
const lead = content.slice(0, closeBrace).endsWith(`
|
|
6023
|
+
`) ? "" : `
|
|
6024
|
+
`;
|
|
6025
|
+
return spliceText(content, closeBrace, closeBrace, `${lead}${methodBlock}
|
|
6026
|
+
`);
|
|
6027
|
+
};
|
|
6028
|
+
var arrowParamInnerRegion = (content, source, arrow) => {
|
|
6029
|
+
if (arrow.parameters.length > 0) {
|
|
6030
|
+
return {
|
|
6031
|
+
start: arrow.parameters[0].getStart(source),
|
|
6032
|
+
end: arrow.parameters[arrow.parameters.length - 1].getEnd()
|
|
6033
|
+
};
|
|
6034
|
+
}
|
|
6035
|
+
const open = content.indexOf("(", arrow.getStart(source));
|
|
6036
|
+
if (open < 0)
|
|
6037
|
+
return null;
|
|
6038
|
+
const close = content.indexOf(")", open);
|
|
6039
|
+
if (close < 0)
|
|
6040
|
+
return null;
|
|
6041
|
+
return { start: open + 1, end: close };
|
|
6042
|
+
};
|
|
6043
|
+
var factoryParamEdit = (content, source, arrow, plan) => {
|
|
6044
|
+
if (arrow.parameters.length > 1)
|
|
6045
|
+
return null;
|
|
6046
|
+
const region = arrowParamInnerRegion(content, source, arrow);
|
|
6047
|
+
if (!region)
|
|
6048
|
+
return null;
|
|
6049
|
+
if (arrow.parameters.length === 0) {
|
|
6050
|
+
return { ...region, text: plan.mode === "destructure" ? `{ ${plan.name} }` : plan.name };
|
|
6051
|
+
}
|
|
6052
|
+
const param = arrow.parameters[0];
|
|
6053
|
+
if (plan.mode === "positional")
|
|
6054
|
+
return nodeName(param.name) === plan.name ? "unchanged" : null;
|
|
6055
|
+
if (!ts4.isObjectBindingPattern(param.name))
|
|
6056
|
+
return null;
|
|
6057
|
+
const names = param.name.elements.map((element) => ts4.isIdentifier(element.name) ? element.name.text : null);
|
|
6058
|
+
if (names.some((name) => name === null))
|
|
6059
|
+
return null;
|
|
6060
|
+
if (names.includes(plan.name))
|
|
6061
|
+
return "unchanged";
|
|
6062
|
+
return {
|
|
6063
|
+
start: param.getStart(source),
|
|
6064
|
+
end: param.getEnd(),
|
|
6065
|
+
text: `{ ${[...names, plan.name].join(", ")} }`
|
|
6066
|
+
};
|
|
6067
|
+
};
|
|
6068
|
+
var factoryObjectOf = (source, className) => {
|
|
6069
|
+
const node = findClassDeclaration(source, className);
|
|
6070
|
+
const call = node ? firstHeritageCall(node) : null;
|
|
6071
|
+
const arrow = call ? factoryArrowOf(call) : null;
|
|
6072
|
+
const object = arrow ? firstObjectReturnedByArrow(arrow) : null;
|
|
6073
|
+
return arrow && object ? { arrow, object } : null;
|
|
6074
|
+
};
|
|
6075
|
+
var hasSignalFactoryEntry = (content, className, entryName) => {
|
|
6076
|
+
const located = factoryObjectOf(sourceFileFor("signal.ts", content), className);
|
|
6077
|
+
return Boolean(located?.object.properties.some((property) => propertyName(property) === entryName));
|
|
6078
|
+
};
|
|
6079
|
+
var insertSignalFactoryEntry = (content, className, entryName, entryLine, param) => {
|
|
6080
|
+
const source = sourceFileFor("signal.ts", content);
|
|
6081
|
+
const located = factoryObjectOf(source, className);
|
|
6082
|
+
if (!located)
|
|
6083
|
+
return null;
|
|
6084
|
+
const locator = locatedObject(source, located.object);
|
|
6085
|
+
if (locator.fields.some((field) => field.name === entryName))
|
|
6086
|
+
return content;
|
|
6087
|
+
const paramEdit = factoryParamEdit(content, source, located.arrow, param);
|
|
6088
|
+
if (paramEdit === null)
|
|
6089
|
+
return null;
|
|
6090
|
+
const withEntry = insertOrderedFieldLine(content, locator, entryName, entryLine, {
|
|
6091
|
+
fieldIndent: " ",
|
|
6092
|
+
closingIndent: ""
|
|
6093
|
+
});
|
|
6094
|
+
if (withEntry === content)
|
|
6095
|
+
return null;
|
|
6096
|
+
return paramEdit === "unchanged" ? withEntry : spliceText(withEntry, paramEdit.start, paramEdit.end, paramEdit.text);
|
|
6097
|
+
};
|
|
5948
6098
|
|
|
5949
6099
|
// pkgs/@akanjs/devkit/workflow/moduleIndex.ts
|
|
5950
6100
|
var indexFileKinds = [
|
|
@@ -6662,7 +6812,9 @@ var createWorkflowStepRegistry = ({
|
|
|
6662
6812
|
createScalar,
|
|
6663
6813
|
createUi,
|
|
6664
6814
|
addField,
|
|
6665
|
-
addEnumField
|
|
6815
|
+
addEnumField,
|
|
6816
|
+
addMutation,
|
|
6817
|
+
addSlice
|
|
6666
6818
|
}) => {
|
|
6667
6819
|
const inspect = async () => {
|
|
6668
6820
|
return;
|
|
@@ -6738,7 +6890,19 @@ var createWorkflowStepRegistry = ({
|
|
|
6738
6890
|
defaultValue: workflowStringInput(plan.inputs.default)
|
|
6739
6891
|
})),
|
|
6740
6892
|
[workflowStepKey("add-enum-field", "update-dictionary")]: inspect,
|
|
6741
|
-
[workflowStepKey("add-enum-field", "update-option")]: inspect
|
|
6893
|
+
[workflowStepKey("add-enum-field", "update-option")]: inspect,
|
|
6894
|
+
[workflowStepKey("add-mutation", "update-service")]: async (_step, plan) => primitiveReportToWorkflowStepResult(await addMutation({
|
|
6895
|
+
app: workflowStringInput(plan.inputs.app),
|
|
6896
|
+
module: workflowStringInput(plan.inputs.module),
|
|
6897
|
+
mutation: workflowStringInput(plan.inputs.mutation)
|
|
6898
|
+
})),
|
|
6899
|
+
[workflowStepKey("add-mutation", "update-signal")]: inspect,
|
|
6900
|
+
[workflowStepKey("add-slice", "update-service-query")]: async (_step, plan) => primitiveReportToWorkflowStepResult(await addSlice({
|
|
6901
|
+
app: workflowStringInput(plan.inputs.app),
|
|
6902
|
+
module: workflowStringInput(plan.inputs.module),
|
|
6903
|
+
slice: workflowStringInput(plan.inputs.slice)
|
|
6904
|
+
})),
|
|
6905
|
+
[workflowStepKey("add-slice", "update-signal-slice")]: inspect
|
|
6742
6906
|
};
|
|
6743
6907
|
};
|
|
6744
6908
|
class WorkflowExecutor {
|
|
@@ -12807,11 +12971,15 @@ async function resolveSignalTestPreloadPath(target) {
|
|
|
12807
12971
|
addResolvedPackageCandidate(path39.dirname(Bun.main));
|
|
12808
12972
|
addResolvedPackageCandidate(import.meta.dir);
|
|
12809
12973
|
candidates.push(path39.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(path39.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
|
|
12810
|
-
|
|
12974
|
+
const uniqueCandidates = [...new Set(candidates)];
|
|
12975
|
+
for (const candidate of uniqueCandidates) {
|
|
12811
12976
|
if (await Bun.file(candidate).exists())
|
|
12812
12977
|
return candidate;
|
|
12813
12978
|
}
|
|
12814
|
-
throw new Error(`Failed to locate ${SIGNAL_TEST_PRELOAD_PATH} from ${target.cwdPath}
|
|
12979
|
+
throw new Error(`Failed to locate ${SIGNAL_TEST_PRELOAD_PATH} from ${target.cwdPath}.
|
|
12980
|
+
Probed paths:
|
|
12981
|
+
${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
12982
|
+
`)}`);
|
|
12815
12983
|
}
|
|
12816
12984
|
// pkgs/@akanjs/devkit/builder.ts
|
|
12817
12985
|
import { existsSync as existsSync2 } from "fs";
|
package/index.js
CHANGED
|
@@ -4168,6 +4168,7 @@ var BACKEND_RESTART_DEBOUNCE_MS = 120;
|
|
|
4168
4168
|
var BACKEND_GRACEFUL_TIMEOUT_MS = 3000;
|
|
4169
4169
|
var BACKEND_RECOVERY_BASE_DELAY_MS = 1000;
|
|
4170
4170
|
var BACKEND_RECOVERY_MAX_DELAY_MS = 30000;
|
|
4171
|
+
var BACKEND_STDERR_TAIL_LIMIT = 40;
|
|
4171
4172
|
var BUILDER_READY_TIMEOUT_MS = 150000;
|
|
4172
4173
|
var BUILDER_START_MAX_ATTEMPTS = 3;
|
|
4173
4174
|
var SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
@@ -4370,6 +4371,7 @@ class AkanAppHost {
|
|
|
4370
4371
|
#pendingRestartReason = null;
|
|
4371
4372
|
#backendStartStatus = null;
|
|
4372
4373
|
#backendBuildStatusGeneration = 0;
|
|
4374
|
+
#backendStderrTail = [];
|
|
4373
4375
|
#lastGoodFrontend = {};
|
|
4374
4376
|
#buildStatusByPhase = new Map;
|
|
4375
4377
|
#pendingBuildStatusReplay = [];
|
|
@@ -4421,6 +4423,7 @@ class AkanAppHost {
|
|
|
4421
4423
|
this.#backendStartStatus = startStatus;
|
|
4422
4424
|
this.#setBackendLifecycleState("starting");
|
|
4423
4425
|
this.#backendReady = false;
|
|
4426
|
+
this.#backendStderrTail = [];
|
|
4424
4427
|
const backend = Bun.spawn(["bun", `apps/${this.app.name}/main.ts`], {
|
|
4425
4428
|
cwd: this.app.workspace.workspaceRoot,
|
|
4426
4429
|
stdio: this.withInk ? ["ignore", "pipe", "pipe"] : ["inherit", "inherit", "inherit"],
|
|
@@ -4454,6 +4457,37 @@ class AkanAppHost {
|
|
|
4454
4457
|
});
|
|
4455
4458
|
this.#backend = backend;
|
|
4456
4459
|
this.logger.verbose(`backend spawned pid=${backend.pid}`);
|
|
4460
|
+
if (this.withInk) {
|
|
4461
|
+
this.#forwardBackendStream(backend.stderr, "stderr");
|
|
4462
|
+
this.#forwardBackendStream(backend.stdout, "stdout");
|
|
4463
|
+
}
|
|
4464
|
+
}
|
|
4465
|
+
#recordBackendStderr(chunk) {
|
|
4466
|
+
const lines = chunk.split(/\r?\n/).filter((line) => line.length > 0);
|
|
4467
|
+
if (lines.length === 0)
|
|
4468
|
+
return;
|
|
4469
|
+
this.#backendStderrTail.push(...lines);
|
|
4470
|
+
if (this.#backendStderrTail.length > BACKEND_STDERR_TAIL_LIMIT) {
|
|
4471
|
+
this.#backendStderrTail.splice(0, this.#backendStderrTail.length - BACKEND_STDERR_TAIL_LIMIT);
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
async#forwardBackendStream(stream, kind) {
|
|
4475
|
+
if (!stream)
|
|
4476
|
+
return;
|
|
4477
|
+
const decoder = new TextDecoder;
|
|
4478
|
+
try {
|
|
4479
|
+
for await (const chunk of stream) {
|
|
4480
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
4481
|
+
if (!text.trim())
|
|
4482
|
+
continue;
|
|
4483
|
+
if (kind === "stderr") {
|
|
4484
|
+
this.#recordBackendStderr(text);
|
|
4485
|
+
this.logger.warn(`[backend] ${text.trimEnd()}`);
|
|
4486
|
+
} else {
|
|
4487
|
+
this.logger.verbose(`[backend] ${text.trimEnd()}`);
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
} catch {}
|
|
4457
4491
|
}
|
|
4458
4492
|
#nextBackendBuildStatusGeneration(generation) {
|
|
4459
4493
|
if (typeof generation === "number") {
|
|
@@ -4578,6 +4612,11 @@ class AkanAppHost {
|
|
|
4578
4612
|
});
|
|
4579
4613
|
this.#sendOrQueueBuildStatus(failureStatus);
|
|
4580
4614
|
this.logger.warn(`[backend-recovery] backend exited unexpectedly (${reason}); restarting in ${delay}ms (attempt ${this.#backendRecoveryAttempts})`);
|
|
4615
|
+
if (this.#backendStderrTail.length > 0) {
|
|
4616
|
+
this.logger.warn(`[backend-recovery] recent backend stderr:
|
|
4617
|
+
${this.#backendStderrTail.join(`
|
|
4618
|
+
`)}`);
|
|
4619
|
+
}
|
|
4581
4620
|
this.#backendRecoveryTimer = setTimeout(() => {
|
|
4582
4621
|
this.#backendRecoveryTimer = null;
|
|
4583
4622
|
if (this.#backend)
|
|
@@ -5943,6 +5982,117 @@ ${values.map((value) => ` ${value}: t([${JSON.stringify(titleize(value))}, ${
|
|
|
5943
5982
|
return `${content.slice(0, insertBeforeIndex)}${enumBlock}${content.slice(insertBeforeIndex)}`;
|
|
5944
5983
|
};
|
|
5945
5984
|
var parseValues = (value) => value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
|
|
5985
|
+
var hasSourceParseErrors = (content, fileName = "source.ts") => hasParseDiagnostics(sourceFileFor(fileName, content));
|
|
5986
|
+
var findClassDeclaration = (source, className) => {
|
|
5987
|
+
let found = null;
|
|
5988
|
+
const visit = (node) => {
|
|
5989
|
+
if (found)
|
|
5990
|
+
return;
|
|
5991
|
+
if (ts4.isClassDeclaration(node) && node.name?.text === className) {
|
|
5992
|
+
found = node;
|
|
5993
|
+
return;
|
|
5994
|
+
}
|
|
5995
|
+
ts4.forEachChild(node, visit);
|
|
5996
|
+
};
|
|
5997
|
+
ts4.forEachChild(source, visit);
|
|
5998
|
+
return found;
|
|
5999
|
+
};
|
|
6000
|
+
var firstHeritageCall = (node) => {
|
|
6001
|
+
const expression = (node.heritageClauses?.flatMap((clause) => [...clause.types]) ?? [])[0]?.expression;
|
|
6002
|
+
return expression && ts4.isCallExpression(expression) ? expression : null;
|
|
6003
|
+
};
|
|
6004
|
+
var factoryArrowOf = (call) => {
|
|
6005
|
+
const arg = call.arguments.find((argument) => ts4.isArrowFunction(argument) || ts4.isFunctionExpression(argument));
|
|
6006
|
+
return arg && (ts4.isArrowFunction(arg) || ts4.isFunctionExpression(arg)) ? arg : null;
|
|
6007
|
+
};
|
|
6008
|
+
var hasClassMethod = (content, className, methodName) => {
|
|
6009
|
+
const node = findClassDeclaration(sourceFileFor("service.ts", content), className);
|
|
6010
|
+
return Boolean(node?.members.some((member) => ts4.isMethodDeclaration(member) && nodeName(member.name) === methodName));
|
|
6011
|
+
};
|
|
6012
|
+
var insertClassMethod = (content, className, methodBlock) => {
|
|
6013
|
+
const source = sourceFileFor("service.ts", content);
|
|
6014
|
+
const node = findClassDeclaration(source, className);
|
|
6015
|
+
if (!node)
|
|
6016
|
+
return null;
|
|
6017
|
+
const closeBrace = node.getEnd() - 1;
|
|
6018
|
+
if (content[closeBrace] !== "}")
|
|
6019
|
+
return null;
|
|
6020
|
+
const lead = content.slice(0, closeBrace).endsWith(`
|
|
6021
|
+
`) ? "" : `
|
|
6022
|
+
`;
|
|
6023
|
+
return spliceText(content, closeBrace, closeBrace, `${lead}${methodBlock}
|
|
6024
|
+
`);
|
|
6025
|
+
};
|
|
6026
|
+
var arrowParamInnerRegion = (content, source, arrow) => {
|
|
6027
|
+
if (arrow.parameters.length > 0) {
|
|
6028
|
+
return {
|
|
6029
|
+
start: arrow.parameters[0].getStart(source),
|
|
6030
|
+
end: arrow.parameters[arrow.parameters.length - 1].getEnd()
|
|
6031
|
+
};
|
|
6032
|
+
}
|
|
6033
|
+
const open = content.indexOf("(", arrow.getStart(source));
|
|
6034
|
+
if (open < 0)
|
|
6035
|
+
return null;
|
|
6036
|
+
const close = content.indexOf(")", open);
|
|
6037
|
+
if (close < 0)
|
|
6038
|
+
return null;
|
|
6039
|
+
return { start: open + 1, end: close };
|
|
6040
|
+
};
|
|
6041
|
+
var factoryParamEdit = (content, source, arrow, plan) => {
|
|
6042
|
+
if (arrow.parameters.length > 1)
|
|
6043
|
+
return null;
|
|
6044
|
+
const region = arrowParamInnerRegion(content, source, arrow);
|
|
6045
|
+
if (!region)
|
|
6046
|
+
return null;
|
|
6047
|
+
if (arrow.parameters.length === 0) {
|
|
6048
|
+
return { ...region, text: plan.mode === "destructure" ? `{ ${plan.name} }` : plan.name };
|
|
6049
|
+
}
|
|
6050
|
+
const param = arrow.parameters[0];
|
|
6051
|
+
if (plan.mode === "positional")
|
|
6052
|
+
return nodeName(param.name) === plan.name ? "unchanged" : null;
|
|
6053
|
+
if (!ts4.isObjectBindingPattern(param.name))
|
|
6054
|
+
return null;
|
|
6055
|
+
const names = param.name.elements.map((element) => ts4.isIdentifier(element.name) ? element.name.text : null);
|
|
6056
|
+
if (names.some((name) => name === null))
|
|
6057
|
+
return null;
|
|
6058
|
+
if (names.includes(plan.name))
|
|
6059
|
+
return "unchanged";
|
|
6060
|
+
return {
|
|
6061
|
+
start: param.getStart(source),
|
|
6062
|
+
end: param.getEnd(),
|
|
6063
|
+
text: `{ ${[...names, plan.name].join(", ")} }`
|
|
6064
|
+
};
|
|
6065
|
+
};
|
|
6066
|
+
var factoryObjectOf = (source, className) => {
|
|
6067
|
+
const node = findClassDeclaration(source, className);
|
|
6068
|
+
const call = node ? firstHeritageCall(node) : null;
|
|
6069
|
+
const arrow = call ? factoryArrowOf(call) : null;
|
|
6070
|
+
const object = arrow ? firstObjectReturnedByArrow(arrow) : null;
|
|
6071
|
+
return arrow && object ? { arrow, object } : null;
|
|
6072
|
+
};
|
|
6073
|
+
var hasSignalFactoryEntry = (content, className, entryName) => {
|
|
6074
|
+
const located = factoryObjectOf(sourceFileFor("signal.ts", content), className);
|
|
6075
|
+
return Boolean(located?.object.properties.some((property) => propertyName(property) === entryName));
|
|
6076
|
+
};
|
|
6077
|
+
var insertSignalFactoryEntry = (content, className, entryName, entryLine, param) => {
|
|
6078
|
+
const source = sourceFileFor("signal.ts", content);
|
|
6079
|
+
const located = factoryObjectOf(source, className);
|
|
6080
|
+
if (!located)
|
|
6081
|
+
return null;
|
|
6082
|
+
const locator = locatedObject(source, located.object);
|
|
6083
|
+
if (locator.fields.some((field) => field.name === entryName))
|
|
6084
|
+
return content;
|
|
6085
|
+
const paramEdit = factoryParamEdit(content, source, located.arrow, param);
|
|
6086
|
+
if (paramEdit === null)
|
|
6087
|
+
return null;
|
|
6088
|
+
const withEntry = insertOrderedFieldLine(content, locator, entryName, entryLine, {
|
|
6089
|
+
fieldIndent: " ",
|
|
6090
|
+
closingIndent: ""
|
|
6091
|
+
});
|
|
6092
|
+
if (withEntry === content)
|
|
6093
|
+
return null;
|
|
6094
|
+
return paramEdit === "unchanged" ? withEntry : spliceText(withEntry, paramEdit.start, paramEdit.end, paramEdit.text);
|
|
6095
|
+
};
|
|
5946
6096
|
|
|
5947
6097
|
// pkgs/@akanjs/devkit/workflow/moduleIndex.ts
|
|
5948
6098
|
var indexFileKinds = [
|
|
@@ -6660,7 +6810,9 @@ var createWorkflowStepRegistry = ({
|
|
|
6660
6810
|
createScalar,
|
|
6661
6811
|
createUi,
|
|
6662
6812
|
addField,
|
|
6663
|
-
addEnumField
|
|
6813
|
+
addEnumField,
|
|
6814
|
+
addMutation,
|
|
6815
|
+
addSlice
|
|
6664
6816
|
}) => {
|
|
6665
6817
|
const inspect = async () => {
|
|
6666
6818
|
return;
|
|
@@ -6736,7 +6888,19 @@ var createWorkflowStepRegistry = ({
|
|
|
6736
6888
|
defaultValue: workflowStringInput(plan.inputs.default)
|
|
6737
6889
|
})),
|
|
6738
6890
|
[workflowStepKey("add-enum-field", "update-dictionary")]: inspect,
|
|
6739
|
-
[workflowStepKey("add-enum-field", "update-option")]: inspect
|
|
6891
|
+
[workflowStepKey("add-enum-field", "update-option")]: inspect,
|
|
6892
|
+
[workflowStepKey("add-mutation", "update-service")]: async (_step, plan) => primitiveReportToWorkflowStepResult(await addMutation({
|
|
6893
|
+
app: workflowStringInput(plan.inputs.app),
|
|
6894
|
+
module: workflowStringInput(plan.inputs.module),
|
|
6895
|
+
mutation: workflowStringInput(plan.inputs.mutation)
|
|
6896
|
+
})),
|
|
6897
|
+
[workflowStepKey("add-mutation", "update-signal")]: inspect,
|
|
6898
|
+
[workflowStepKey("add-slice", "update-service-query")]: async (_step, plan) => primitiveReportToWorkflowStepResult(await addSlice({
|
|
6899
|
+
app: workflowStringInput(plan.inputs.app),
|
|
6900
|
+
module: workflowStringInput(plan.inputs.module),
|
|
6901
|
+
slice: workflowStringInput(plan.inputs.slice)
|
|
6902
|
+
})),
|
|
6903
|
+
[workflowStepKey("add-slice", "update-signal-slice")]: inspect
|
|
6740
6904
|
};
|
|
6741
6905
|
};
|
|
6742
6906
|
class WorkflowExecutor {
|
|
@@ -12805,11 +12969,15 @@ async function resolveSignalTestPreloadPath(target) {
|
|
|
12805
12969
|
addResolvedPackageCandidate(path39.dirname(Bun.main));
|
|
12806
12970
|
addResolvedPackageCandidate(import.meta.dir);
|
|
12807
12971
|
candidates.push(path39.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.join(path39.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path39.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
|
|
12808
|
-
|
|
12972
|
+
const uniqueCandidates = [...new Set(candidates)];
|
|
12973
|
+
for (const candidate of uniqueCandidates) {
|
|
12809
12974
|
if (await Bun.file(candidate).exists())
|
|
12810
12975
|
return candidate;
|
|
12811
12976
|
}
|
|
12812
|
-
throw new Error(`Failed to locate ${SIGNAL_TEST_PRELOAD_PATH} from ${target.cwdPath}
|
|
12977
|
+
throw new Error(`Failed to locate ${SIGNAL_TEST_PRELOAD_PATH} from ${target.cwdPath}.
|
|
12978
|
+
Probed paths:
|
|
12979
|
+
${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
12980
|
+
`)}`);
|
|
12813
12981
|
}
|
|
12814
12982
|
// pkgs/@akanjs/devkit/builder.ts
|
|
12815
12983
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -17997,8 +18165,18 @@ var addMutationWorkflowSpec = {
|
|
|
17997
18165
|
}
|
|
17998
18166
|
],
|
|
17999
18167
|
predictedChanges: [
|
|
18000
|
-
{
|
|
18001
|
-
|
|
18168
|
+
{
|
|
18169
|
+
target: "*/lib/<module>/<module>.service.ts",
|
|
18170
|
+
action: "modify",
|
|
18171
|
+
applyScope: "auto",
|
|
18172
|
+
reason: "Service mutation method stub is added."
|
|
18173
|
+
},
|
|
18174
|
+
{
|
|
18175
|
+
target: "*/lib/<module>/<module>.signal.ts",
|
|
18176
|
+
action: "modify",
|
|
18177
|
+
applyScope: "auto",
|
|
18178
|
+
reason: "Signal endpoint mutation is added."
|
|
18179
|
+
},
|
|
18002
18180
|
{ target: "*/lib/srv.ts", action: "sync", reason: "Generated service barrel may change after sync." },
|
|
18003
18181
|
{ target: "*/lib/sig.ts", action: "sync", reason: "Generated signal barrel may change after sync." }
|
|
18004
18182
|
],
|
|
@@ -18070,9 +18248,24 @@ var addSliceWorkflowSpec = {
|
|
|
18070
18248
|
}
|
|
18071
18249
|
],
|
|
18072
18250
|
predictedChanges: [
|
|
18073
|
-
{
|
|
18074
|
-
|
|
18075
|
-
|
|
18251
|
+
{
|
|
18252
|
+
target: "*/lib/<module>/<module>.service.ts",
|
|
18253
|
+
action: "modify",
|
|
18254
|
+
applyScope: "auto",
|
|
18255
|
+
reason: "Query helper method stub is added."
|
|
18256
|
+
},
|
|
18257
|
+
{
|
|
18258
|
+
target: "*/lib/<module>/<module>.signal.ts",
|
|
18259
|
+
action: "modify",
|
|
18260
|
+
applyScope: "auto",
|
|
18261
|
+
reason: "Signal slice entry is added."
|
|
18262
|
+
},
|
|
18263
|
+
{
|
|
18264
|
+
target: "*/lib/<module>/<Module>.Zone.tsx",
|
|
18265
|
+
action: "modify",
|
|
18266
|
+
applyScope: "manual-review",
|
|
18267
|
+
reason: "Zone may connect slice state."
|
|
18268
|
+
},
|
|
18076
18269
|
{ target: "*/lib/sig.ts", action: "sync", reason: "Generated signal barrel may change after sync." }
|
|
18077
18270
|
],
|
|
18078
18271
|
validation: [
|
|
@@ -19384,6 +19577,12 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
19384
19577
|
code: "primitive-field-type-unsupported",
|
|
19385
19578
|
message: `Field type "${input7.type}" is ambiguous in Akan. Use Int for integer fields or Float for decimal fields.`,
|
|
19386
19579
|
input: "type"
|
|
19580
|
+
} : null,
|
|
19581
|
+
input7.type && input7.type.toLowerCase() === "upload" ? {
|
|
19582
|
+
severity: "error",
|
|
19583
|
+
code: "primitive-field-type-upload-misuse",
|
|
19584
|
+
message: "Upload is not a model field type. Declare an image/file field as a relation to the File model (e.g. field(File)); Upload is only valid in a { fileUpload: true } signal body. Note the File model is provided by the shared file library.",
|
|
19585
|
+
input: "type"
|
|
19387
19586
|
} : null
|
|
19388
19587
|
]);
|
|
19389
19588
|
if (!sys3 || !input7.module || !input7.field || !input7.type || diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
@@ -19582,6 +19781,206 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
19582
19781
|
nextActions: nextActionsForTarget(sys3.name)
|
|
19583
19782
|
});
|
|
19584
19783
|
}
|
|
19784
|
+
async addMutation(workspace, input7) {
|
|
19785
|
+
const moduleClassName = input7.module ? moduleComponentName(input7.module) : "";
|
|
19786
|
+
const serviceRef = lowerlize(moduleClassName);
|
|
19787
|
+
const name = input7.mutation;
|
|
19788
|
+
return await this.#writeServiceSignalEntry(workspace, {
|
|
19789
|
+
command: "add-mutation",
|
|
19790
|
+
app: input7.app,
|
|
19791
|
+
module: input7.module,
|
|
19792
|
+
entryKind: "mutation",
|
|
19793
|
+
entryName: name,
|
|
19794
|
+
requiredInput: "mutation",
|
|
19795
|
+
serviceMethod: name ? {
|
|
19796
|
+
name,
|
|
19797
|
+
block: [
|
|
19798
|
+
` async ${name}() {`,
|
|
19799
|
+
` // TODO(service): implement ${moduleClassName}Service.${name}`,
|
|
19800
|
+
` return true;`,
|
|
19801
|
+
` }`
|
|
19802
|
+
].join(`
|
|
19803
|
+
`)
|
|
19804
|
+
} : null,
|
|
19805
|
+
signal: name ? {
|
|
19806
|
+
className: `${moduleClassName}Endpoint`,
|
|
19807
|
+
entryLine: [
|
|
19808
|
+
`${name}: mutation(Boolean)`,
|
|
19809
|
+
` .exec(async function () {`,
|
|
19810
|
+
` return await this.${serviceRef}Service.${name}();`,
|
|
19811
|
+
` }),`
|
|
19812
|
+
].join(`
|
|
19813
|
+
`),
|
|
19814
|
+
param: { mode: "destructure", name: "mutation" }
|
|
19815
|
+
} : null
|
|
19816
|
+
});
|
|
19817
|
+
}
|
|
19818
|
+
async addSlice(workspace, input7) {
|
|
19819
|
+
const moduleClassName = input7.module ? moduleComponentName(input7.module) : "";
|
|
19820
|
+
const serviceRef = lowerlize(moduleClassName);
|
|
19821
|
+
const name = input7.slice;
|
|
19822
|
+
const queryName = name ? `query${capitalize12(name)}` : null;
|
|
19823
|
+
return await this.#writeServiceSignalEntry(workspace, {
|
|
19824
|
+
command: "add-slice",
|
|
19825
|
+
app: input7.app,
|
|
19826
|
+
module: input7.module,
|
|
19827
|
+
entryKind: "slice",
|
|
19828
|
+
entryName: name,
|
|
19829
|
+
requiredInput: "slice",
|
|
19830
|
+
serviceMethod: name && queryName ? {
|
|
19831
|
+
name: queryName,
|
|
19832
|
+
block: [
|
|
19833
|
+
` ${queryName}() {`,
|
|
19834
|
+
` // TODO(service): return a QueryOf for the ${name} slice`,
|
|
19835
|
+
` return {};`,
|
|
19836
|
+
` }`
|
|
19837
|
+
].join(`
|
|
19838
|
+
`)
|
|
19839
|
+
} : null,
|
|
19840
|
+
signal: name && queryName ? {
|
|
19841
|
+
className: `${moduleClassName}Slice`,
|
|
19842
|
+
entryLine: [
|
|
19843
|
+
`${name}: init()`,
|
|
19844
|
+
` .exec(function () {`,
|
|
19845
|
+
` return this.${serviceRef}Service.${queryName}();`,
|
|
19846
|
+
` }),`
|
|
19847
|
+
].join(`
|
|
19848
|
+
`),
|
|
19849
|
+
param: { mode: "positional", name: "init" }
|
|
19850
|
+
} : null
|
|
19851
|
+
});
|
|
19852
|
+
}
|
|
19853
|
+
async#writeServiceSignalEntry(workspace, spec) {
|
|
19854
|
+
const sys3 = await this.resolveSys(workspace, spec.app);
|
|
19855
|
+
const diagnostics = compactDiagnostics([
|
|
19856
|
+
!sys3 && { severity: "error", code: "primitive-target-missing", message: "Target app or library was not found." },
|
|
19857
|
+
!spec.module && {
|
|
19858
|
+
severity: "error",
|
|
19859
|
+
code: "primitive-input-missing",
|
|
19860
|
+
message: "Module is required.",
|
|
19861
|
+
input: "module"
|
|
19862
|
+
},
|
|
19863
|
+
!spec.entryName && {
|
|
19864
|
+
severity: "error",
|
|
19865
|
+
code: "primitive-input-missing",
|
|
19866
|
+
message: `${capitalize12(spec.requiredInput)} name is required.`,
|
|
19867
|
+
input: spec.requiredInput
|
|
19868
|
+
}
|
|
19869
|
+
]);
|
|
19870
|
+
if (!sys3 || !spec.module || !spec.entryName || !spec.serviceMethod || !spec.signal) {
|
|
19871
|
+
return createPrimitiveWriteReport({
|
|
19872
|
+
command: spec.command,
|
|
19873
|
+
changedFiles: [],
|
|
19874
|
+
generatedFiles: [],
|
|
19875
|
+
validationCommands: [],
|
|
19876
|
+
diagnostics,
|
|
19877
|
+
nextActions: []
|
|
19878
|
+
});
|
|
19879
|
+
}
|
|
19880
|
+
const paths = moduleSourcePaths(spec.module);
|
|
19881
|
+
const servicePath = paths.service;
|
|
19882
|
+
const signalPath = paths.signal;
|
|
19883
|
+
const changedFiles = [];
|
|
19884
|
+
const generatedFiles2 = generatedFilesForSync(sys3);
|
|
19885
|
+
const [hasServiceFile, hasSignalFile] = await Promise.all([sys3.exists(servicePath), sys3.exists(signalPath)]);
|
|
19886
|
+
if (!hasServiceFile) {
|
|
19887
|
+
diagnostics.push({
|
|
19888
|
+
severity: "error",
|
|
19889
|
+
code: "primitive-source-missing",
|
|
19890
|
+
message: `Service source file was not found: ${servicePath}.`
|
|
19891
|
+
});
|
|
19892
|
+
}
|
|
19893
|
+
if (!hasSignalFile) {
|
|
19894
|
+
diagnostics.push({
|
|
19895
|
+
severity: "error",
|
|
19896
|
+
code: "primitive-source-missing",
|
|
19897
|
+
message: `Signal source file was not found: ${signalPath}.`
|
|
19898
|
+
});
|
|
19899
|
+
}
|
|
19900
|
+
if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
19901
|
+
return createPrimitiveWriteReport({
|
|
19902
|
+
command: spec.command,
|
|
19903
|
+
changedFiles,
|
|
19904
|
+
generatedFiles: generatedFiles2,
|
|
19905
|
+
validationCommands: validationCommandsForTarget(sys3.name),
|
|
19906
|
+
diagnostics,
|
|
19907
|
+
nextActions: nextActionsForTarget(sys3.name)
|
|
19908
|
+
});
|
|
19909
|
+
}
|
|
19910
|
+
const serviceClassName = `${moduleComponentName(spec.module)}Service`;
|
|
19911
|
+
const serviceContent = await sys3.readFile(servicePath);
|
|
19912
|
+
const signalContent = await sys3.readFile(signalPath);
|
|
19913
|
+
const serviceMethodExists = hasClassMethod(serviceContent, serviceClassName, spec.serviceMethod.name);
|
|
19914
|
+
if (serviceMethodExists) {
|
|
19915
|
+
diagnostics.push({
|
|
19916
|
+
severity: "error",
|
|
19917
|
+
code: "primitive-service-method-exists",
|
|
19918
|
+
input: spec.requiredInput,
|
|
19919
|
+
message: `Method "${spec.serviceMethod.name}" already exists in ${serviceClassName}.`
|
|
19920
|
+
});
|
|
19921
|
+
}
|
|
19922
|
+
if (hasSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName)) {
|
|
19923
|
+
diagnostics.push({
|
|
19924
|
+
severity: "error",
|
|
19925
|
+
code: "primitive-signal-entry-exists",
|
|
19926
|
+
input: spec.requiredInput,
|
|
19927
|
+
message: `Entry "${spec.entryName}" already exists in ${spec.signal.className}.`
|
|
19928
|
+
});
|
|
19929
|
+
}
|
|
19930
|
+
const nextServiceContent = serviceMethodExists ? serviceContent : insertClassMethod(serviceContent, serviceClassName, spec.serviceMethod.block);
|
|
19931
|
+
const nextSignalContent = insertSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName, spec.signal.entryLine, spec.signal.param);
|
|
19932
|
+
if (!nextServiceContent) {
|
|
19933
|
+
diagnostics.push({
|
|
19934
|
+
severity: "error",
|
|
19935
|
+
code: "primitive-service-shape-unsupported",
|
|
19936
|
+
message: `Could not find ${serviceClassName} class body in ${servicePath}.`
|
|
19937
|
+
});
|
|
19938
|
+
}
|
|
19939
|
+
if (!nextSignalContent) {
|
|
19940
|
+
diagnostics.push({
|
|
19941
|
+
severity: "error",
|
|
19942
|
+
code: "primitive-signal-shape-unsupported",
|
|
19943
|
+
message: `Could not find a safe insertion point in ${spec.signal.className} within ${signalPath}. Ensure the class exists and its factory returns an object literal.`
|
|
19944
|
+
});
|
|
19945
|
+
}
|
|
19946
|
+
if (nextServiceContent && hasSourceParseErrors(nextServiceContent, "service.ts")) {
|
|
19947
|
+
diagnostics.push({
|
|
19948
|
+
severity: "error",
|
|
19949
|
+
code: "primitive-post-edit-service-parse-failed",
|
|
19950
|
+
failureScope: "source-change",
|
|
19951
|
+
message: `Edited ${servicePath} did not parse cleanly; refusing to write source.`
|
|
19952
|
+
});
|
|
19953
|
+
}
|
|
19954
|
+
if (nextSignalContent && hasSourceParseErrors(nextSignalContent, "signal.ts")) {
|
|
19955
|
+
diagnostics.push({
|
|
19956
|
+
severity: "error",
|
|
19957
|
+
code: "primitive-post-edit-signal-parse-failed",
|
|
19958
|
+
failureScope: "source-change",
|
|
19959
|
+
message: `Edited ${signalPath} did not parse cleanly; refusing to write source.`
|
|
19960
|
+
});
|
|
19961
|
+
}
|
|
19962
|
+
if (nextSignalContent && !hasSignalFactoryEntry(nextSignalContent, spec.signal.className, spec.entryName)) {
|
|
19963
|
+
diagnostics.push({
|
|
19964
|
+
severity: "error",
|
|
19965
|
+
code: "primitive-post-edit-signal-verify-failed",
|
|
19966
|
+
failureScope: "source-change",
|
|
19967
|
+
message: `Edited ${signalPath} did not contain entry "${spec.entryName}" in ${spec.signal.className}.`
|
|
19968
|
+
});
|
|
19969
|
+
}
|
|
19970
|
+
if (!diagnostics.some((diagnostic) => diagnostic.severity === "error") && nextServiceContent && nextSignalContent) {
|
|
19971
|
+
await sys3.writeFile(servicePath, nextServiceContent);
|
|
19972
|
+
await sys3.writeFile(signalPath, nextSignalContent);
|
|
19973
|
+
changedFiles.push(sourceFile(sys3, servicePath, "modify", `Service ${spec.entryKind} was added.`), sourceFile(sys3, signalPath, "modify", `Signal ${spec.entryKind} was added.`));
|
|
19974
|
+
}
|
|
19975
|
+
return createPrimitiveWriteReport({
|
|
19976
|
+
command: spec.command,
|
|
19977
|
+
changedFiles,
|
|
19978
|
+
generatedFiles: generatedFiles2,
|
|
19979
|
+
validationCommands: validationCommandsForTarget(sys3.name),
|
|
19980
|
+
diagnostics,
|
|
19981
|
+
nextActions: nextActionsForTarget(sys3.name)
|
|
19982
|
+
});
|
|
19983
|
+
}
|
|
19585
19984
|
}
|
|
19586
19985
|
|
|
19587
19986
|
// pkgs/@akanjs/cli/scalar/scalar.prompt.ts
|
|
@@ -19799,7 +20198,9 @@ var createCliWorkflowStepRegistry = (workspace) => createWorkflowStepRegistry({
|
|
|
19799
20198
|
createScalar: (sys3, scalar) => CommandContainer.get(ScalarScript).createScalar(sys3, scalar),
|
|
19800
20199
|
createUi: (input8) => CommandContainer.get(PrimitiveScript).createUi(workspace, input8),
|
|
19801
20200
|
addField: (input8) => CommandContainer.get(PrimitiveScript).addField(workspace, input8),
|
|
19802
|
-
addEnumField: (input8) => CommandContainer.get(PrimitiveScript).addEnumField(workspace, input8)
|
|
20201
|
+
addEnumField: (input8) => CommandContainer.get(PrimitiveScript).addEnumField(workspace, input8),
|
|
20202
|
+
addMutation: (input8) => CommandContainer.get(PrimitiveScript).addMutation(workspace, input8),
|
|
20203
|
+
addSlice: (input8) => CommandContainer.get(PrimitiveScript).addSlice(workspace, input8)
|
|
19803
20204
|
});
|
|
19804
20205
|
|
|
19805
20206
|
// pkgs/@akanjs/cli/context/context.runner.ts
|
|
@@ -20990,7 +21391,9 @@ class WorkflowScript extends script("workflow", [WorkflowRunner, ModuleScript, S
|
|
|
20990
21391
|
createScalar: (sys3, scalar) => this.scalarScript.createScalar(sys3, scalar),
|
|
20991
21392
|
createUi: (input8) => this.primitiveScript.createUi(workspace, input8),
|
|
20992
21393
|
addField: (input8) => this.primitiveScript.addField(workspace, input8),
|
|
20993
|
-
addEnumField: (input8) => this.primitiveScript.addEnumField(workspace, input8)
|
|
21394
|
+
addEnumField: (input8) => this.primitiveScript.addEnumField(workspace, input8),
|
|
21395
|
+
addMutation: (input8) => this.primitiveScript.addMutation(workspace, input8),
|
|
21396
|
+
addSlice: (input8) => this.primitiveScript.addSlice(workspace, input8)
|
|
20994
21397
|
})
|
|
20995
21398
|
}));
|
|
20996
21399
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "2.3.11-rc.
|
|
3
|
+
"version": "2.3.11-rc.4",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@langchain/openai": "^1.4.6",
|
|
35
35
|
"@tailwindcss/node": "^4.3.0",
|
|
36
36
|
"@trapezedev/project": "^7.1.4",
|
|
37
|
-
"akanjs": "2.3.11-rc.
|
|
37
|
+
"akanjs": "2.3.11-rc.4",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"daisyui": "5.5.23",
|