@akanjs/cli 2.3.9-rc.3 → 2.3.9-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 +563 -445
- package/index.js +873 -635
- package/package.json +2 -2
- package/templates/module/__model__.constant.ts +1 -2
|
@@ -4778,238 +4778,11 @@ class AkanAppHost {
|
|
|
4778
4778
|
// pkgs/@akanjs/devkit/akanContext.ts
|
|
4779
4779
|
import { readdir } from "fs/promises";
|
|
4780
4780
|
import path10 from "path";
|
|
4781
|
-
import { capitalize as
|
|
4781
|
+
import { capitalize as capitalize4 } from "akanjs/common";
|
|
4782
4782
|
|
|
4783
|
-
// pkgs/@akanjs/devkit/workflow/
|
|
4784
|
-
import { capitalize as capitalize2 } from "akanjs/common";
|
|
4783
|
+
// pkgs/@akanjs/devkit/workflow/utils.ts
|
|
4785
4784
|
var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
|
|
4786
4785
|
` : ""}`;
|
|
4787
|
-
var surfaceModes = new Set(["infer", "include", "skip"]);
|
|
4788
|
-
var parseStringList = (value) => {
|
|
4789
|
-
if (Array.isArray(value)) {
|
|
4790
|
-
const values = value.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
4791
|
-
return values.length === value.length ? values : null;
|
|
4792
|
-
}
|
|
4793
|
-
if (typeof value !== "string")
|
|
4794
|
-
return null;
|
|
4795
|
-
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
4796
|
-
};
|
|
4797
|
-
var normalizeInputValue = (name, spec, value) => {
|
|
4798
|
-
if (spec.type === "string")
|
|
4799
|
-
return typeof value === "string" && value.length > 0 ? value : null;
|
|
4800
|
-
if (spec.type === "string-list") {
|
|
4801
|
-
const values = parseStringList(value);
|
|
4802
|
-
return values && values.length > 0 ? values : null;
|
|
4803
|
-
}
|
|
4804
|
-
if (typeof value === "string" && surfaceModes.has(value))
|
|
4805
|
-
return value;
|
|
4806
|
-
throw new Error(`Unsupported workflow input value for ${name}`);
|
|
4807
|
-
};
|
|
4808
|
-
var listWorkflowSpecs = (specs) => [...specs].sort((a, b) => a.name.localeCompare(b.name));
|
|
4809
|
-
var getWorkflowSpec = (specs, name) => specs.find((spec) => spec.name === name) ?? null;
|
|
4810
|
-
var compactWorkflowInputs = (inputs) => Object.fromEntries(Object.entries(inputs).filter(([, value]) => value !== null && value !== ""));
|
|
4811
|
-
var addFieldComponentForType = (typeName) => {
|
|
4812
|
-
const normalizedType = normalizeFieldType(typeName);
|
|
4813
|
-
if (normalizedType === "Boolean")
|
|
4814
|
-
return "Field.ToggleSelect";
|
|
4815
|
-
if (normalizedType === "Date")
|
|
4816
|
-
return "Field.Date";
|
|
4817
|
-
if (normalizedType === "Int" || normalizedType === "Float")
|
|
4818
|
-
return "Field.ToggleSelect or Field.Text";
|
|
4819
|
-
if (typeName.toLowerCase() === "enum")
|
|
4820
|
-
return "Field.ToggleSelect";
|
|
4821
|
-
return "Field.Text";
|
|
4822
|
-
};
|
|
4823
|
-
var createAddFieldRecommendations = (inputs) => {
|
|
4824
|
-
const app = typeof inputs.app === "string" ? inputs.app : "<app-or-lib>";
|
|
4825
|
-
const module = typeof inputs.module === "string" ? inputs.module : "<module>";
|
|
4826
|
-
const field = typeof inputs.field === "string" ? inputs.field : "<field>";
|
|
4827
|
-
const typeName = typeof inputs.type === "string" ? inputs.type : null;
|
|
4828
|
-
if (!typeName)
|
|
4829
|
-
return [];
|
|
4830
|
-
const normalizedType = typeName.toLowerCase() === "enum" ? "enum" : normalizeFieldType(typeName);
|
|
4831
|
-
const constantPath = `*/lib/${module}/${module}.constant.ts`;
|
|
4832
|
-
const dictionaryPath = `*/lib/${module}/${module}.dictionary.ts`;
|
|
4833
|
-
const templatePath = `*/lib/${module}/${capitalize2(module)}.Template.tsx`;
|
|
4834
|
-
return [
|
|
4835
|
-
...normalizedType === "Int" || normalizedType === "Float" ? [
|
|
4836
|
-
{
|
|
4837
|
-
code: "add-field-import",
|
|
4838
|
-
kind: "import",
|
|
4839
|
-
target: constantPath,
|
|
4840
|
-
confidence: "high",
|
|
4841
|
-
message: `Import ${normalizedType} from "akanjs/base" before writing field(${normalizedType}).`
|
|
4842
|
-
}
|
|
4843
|
-
] : [],
|
|
4844
|
-
{
|
|
4845
|
-
code: "add-field-placement-constant",
|
|
4846
|
-
kind: "placement",
|
|
4847
|
-
target: constantPath,
|
|
4848
|
-
confidence: "high",
|
|
4849
|
-
message: `Insert ${field}: field(${normalizedType}) in ${capitalize2(module)}Input.`
|
|
4850
|
-
},
|
|
4851
|
-
{
|
|
4852
|
-
code: "add-field-placement-dictionary",
|
|
4853
|
-
kind: "placement",
|
|
4854
|
-
target: dictionaryPath,
|
|
4855
|
-
confidence: "high",
|
|
4856
|
-
message: `Add dictionary labels for ${module}.${field}.`
|
|
4857
|
-
},
|
|
4858
|
-
{
|
|
4859
|
-
code: "add-field-component",
|
|
4860
|
-
kind: "ui-component",
|
|
4861
|
-
target: templatePath,
|
|
4862
|
-
confidence: normalizedType === "Int" || normalizedType === "Float" ? "medium" : "high",
|
|
4863
|
-
message: `Recommended UI component for ${field} (${normalizedType}): ${addFieldComponentForType(typeName)}.`
|
|
4864
|
-
},
|
|
4865
|
-
{
|
|
4866
|
-
code: "add-field-ui-manual-review",
|
|
4867
|
-
kind: "manual-action",
|
|
4868
|
-
target: templatePath,
|
|
4869
|
-
action: `Review ${app}:${module} Template/Unit/View/Store surfaces and add ${field} only where the existing pattern is clear.`,
|
|
4870
|
-
confidence: "medium",
|
|
4871
|
-
message: "UI surface edits are planned as manual-review unless a safe existing field-list pattern is detected."
|
|
4872
|
-
}
|
|
4873
|
-
];
|
|
4874
|
-
};
|
|
4875
|
-
var createWorkflowPlanRecommendations = (spec, inputs) => [
|
|
4876
|
-
{
|
|
4877
|
-
code: "workflow-apply-first",
|
|
4878
|
-
kind: "auto-apply",
|
|
4879
|
-
confidence: "high",
|
|
4880
|
-
action: "Call apply_workflow with the MCP planPath before editing source files directly.",
|
|
4881
|
-
message: `Apply the ${spec.name} plan through apply_workflow when MCP returns planPath or next.tool=apply_workflow.`
|
|
4882
|
-
},
|
|
4883
|
-
{
|
|
4884
|
-
code: "workflow-validate-apply-report",
|
|
4885
|
-
kind: "validation",
|
|
4886
|
-
confidence: "high",
|
|
4887
|
-
action: "After apply_workflow, call run_validation with validationTarget when present; otherwise use applyReportPath.",
|
|
4888
|
-
message: "Validate the apply report artifact so diagnostics and recommendations follow the actual apply result."
|
|
4889
|
-
},
|
|
4890
|
-
...spec.name === "add-field" ? createAddFieldRecommendations(inputs) : []
|
|
4891
|
-
];
|
|
4892
|
-
var createWorkflowPlan = (spec, rawInputs) => {
|
|
4893
|
-
const inputs = {};
|
|
4894
|
-
const diagnostics = [];
|
|
4895
|
-
for (const [name, inputSpec] of Object.entries(spec.inputs)) {
|
|
4896
|
-
const rawValue = rawInputs[name];
|
|
4897
|
-
if (rawValue === undefined || rawValue === null || rawValue === "") {
|
|
4898
|
-
if (inputSpec.required) {
|
|
4899
|
-
diagnostics.push({
|
|
4900
|
-
severity: "error",
|
|
4901
|
-
code: "workflow-input-missing",
|
|
4902
|
-
input: name,
|
|
4903
|
-
message: `Workflow ${spec.name} requires input "${name}".`
|
|
4904
|
-
});
|
|
4905
|
-
}
|
|
4906
|
-
continue;
|
|
4907
|
-
}
|
|
4908
|
-
const value = normalizeInputValue(name, inputSpec, rawValue);
|
|
4909
|
-
if (value === null) {
|
|
4910
|
-
diagnostics.push({
|
|
4911
|
-
severity: "error",
|
|
4912
|
-
code: "workflow-input-invalid",
|
|
4913
|
-
input: name,
|
|
4914
|
-
message: `Workflow ${spec.name} input "${name}" must be ${inputSpec.type}.`
|
|
4915
|
-
});
|
|
4916
|
-
continue;
|
|
4917
|
-
}
|
|
4918
|
-
if (inputSpec.allowedValues && typeof value === "string" && !inputSpec.allowedValues.includes(value)) {
|
|
4919
|
-
diagnostics.push({
|
|
4920
|
-
severity: "error",
|
|
4921
|
-
code: "workflow-input-not-allowed",
|
|
4922
|
-
input: name,
|
|
4923
|
-
message: `Workflow ${spec.name} input "${name}" must be one of: ${inputSpec.allowedValues.join(", ")}.`
|
|
4924
|
-
});
|
|
4925
|
-
continue;
|
|
4926
|
-
}
|
|
4927
|
-
inputs[name] = value;
|
|
4928
|
-
}
|
|
4929
|
-
const fieldType = inputs.type;
|
|
4930
|
-
if (spec.name === "add-field" && typeof fieldType === "string" && (fieldType.toLowerCase() === "number" || fieldType.toLowerCase() === "numeric")) {
|
|
4931
|
-
diagnostics.push({
|
|
4932
|
-
severity: "error",
|
|
4933
|
-
code: "primitive-field-type-unsupported",
|
|
4934
|
-
input: "type",
|
|
4935
|
-
message: `Field type "${fieldType}" is ambiguous in Akan. Use Int for integer fields or Float for decimal fields.`
|
|
4936
|
-
});
|
|
4937
|
-
}
|
|
4938
|
-
return {
|
|
4939
|
-
schemaVersion: 1,
|
|
4940
|
-
workflow: spec.name,
|
|
4941
|
-
mode: "plan",
|
|
4942
|
-
inputs,
|
|
4943
|
-
optionalSurfaces: spec.optionalSurfaces ?? {},
|
|
4944
|
-
steps: spec.steps,
|
|
4945
|
-
predictedChanges: spec.predictedChanges,
|
|
4946
|
-
validation: spec.validation,
|
|
4947
|
-
diagnostics,
|
|
4948
|
-
recommendations: createWorkflowPlanRecommendations(spec, inputs),
|
|
4949
|
-
requiresApproval: true
|
|
4950
|
-
};
|
|
4951
|
-
};
|
|
4952
|
-
var renderWorkflowList = (specs) => [
|
|
4953
|
-
"# Akan Workflows",
|
|
4954
|
-
"",
|
|
4955
|
-
...specs.flatMap((spec) => [`- \`${spec.name}\`: ${spec.description}`, ` - When: ${spec.whenToUse}`]),
|
|
4956
|
-
""
|
|
4957
|
-
].join(`
|
|
4958
|
-
`);
|
|
4959
|
-
var renderWorkflowExplain = (spec) => [
|
|
4960
|
-
`# Workflow: ${spec.name}`,
|
|
4961
|
-
"",
|
|
4962
|
-
spec.description,
|
|
4963
|
-
"",
|
|
4964
|
-
"## When To Use",
|
|
4965
|
-
spec.whenToUse,
|
|
4966
|
-
"",
|
|
4967
|
-
"## Inputs",
|
|
4968
|
-
...Object.entries(spec.inputs).map(([name, input2]) => `- \`${name}\`${input2.required ? " (required)" : ""}: ${input2.description}${input2.allowedValues ? ` Allowed: ${input2.allowedValues.join(", ")}.` : ""}`),
|
|
4969
|
-
"",
|
|
4970
|
-
"## Optional Surfaces",
|
|
4971
|
-
...Object.entries(spec.optionalSurfaces ?? {}).map(([name, mode]) => `- \`${name}\`: ${mode}`),
|
|
4972
|
-
"",
|
|
4973
|
-
"## Steps",
|
|
4974
|
-
...spec.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
|
|
4975
|
-
"",
|
|
4976
|
-
"## Validation",
|
|
4977
|
-
...spec.validation.map((validation) => `- \`${validation.command}\`: ${validation.reason}`),
|
|
4978
|
-
""
|
|
4979
|
-
].join(`
|
|
4980
|
-
`);
|
|
4981
|
-
var renderWorkflowPlan = (plan) => [
|
|
4982
|
-
`# Workflow Plan: ${plan.workflow}`,
|
|
4983
|
-
"",
|
|
4984
|
-
`- Mode: ${plan.mode}`,
|
|
4985
|
-
`- Requires approval: ${plan.requiresApproval}`,
|
|
4986
|
-
"",
|
|
4987
|
-
"## Inputs",
|
|
4988
|
-
...Object.entries(plan.inputs).map(([name, value]) => `- \`${name}\`: ${Array.isArray(value) ? value.join(", ") : value}`),
|
|
4989
|
-
"",
|
|
4990
|
-
"## Optional Surfaces",
|
|
4991
|
-
...Object.entries(plan.optionalSurfaces).map(([name, mode]) => `- \`${name}\`: ${mode}`),
|
|
4992
|
-
"",
|
|
4993
|
-
"## Steps",
|
|
4994
|
-
...plan.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
|
|
4995
|
-
"",
|
|
4996
|
-
"## Predicted Changes",
|
|
4997
|
-
...plan.predictedChanges.map((change) => {
|
|
4998
|
-
const scope = change.applyScope ? ` (${change.applyScope})` : "";
|
|
4999
|
-
return `- \`${change.action}\`${scope} ${change.target}: ${change.reason}`;
|
|
5000
|
-
}),
|
|
5001
|
-
"",
|
|
5002
|
-
"## Validation",
|
|
5003
|
-
...plan.validation.map((validation) => `- \`${validation.command}\`: ${validation.reason}`),
|
|
5004
|
-
"",
|
|
5005
|
-
"## Diagnostics",
|
|
5006
|
-
...plan.diagnostics.length ? plan.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5007
|
-
"",
|
|
5008
|
-
"## Recommendations",
|
|
5009
|
-
...plan.recommendations.length ? plan.recommendations.map((recommendation) => `- [${recommendation.kind}] ${recommendation.message}`) : ["- none"],
|
|
5010
|
-
""
|
|
5011
|
-
].join(`
|
|
5012
|
-
`);
|
|
5013
4786
|
var workflowStatus = (diagnostics) => diagnostics.some((diagnostic) => diagnostic.severity === "error") ? "failed" : "passed";
|
|
5014
4787
|
var commandStatus = (commands) => commands.some((command) => command.status === "failed") ? "failed" : "passed";
|
|
5015
4788
|
var uniqueBy = (values, key) => {
|
|
@@ -5022,6 +4795,9 @@ var uniqueBy = (values, key) => {
|
|
|
5022
4795
|
return true;
|
|
5023
4796
|
});
|
|
5024
4797
|
};
|
|
4798
|
+
var compactDiagnostics = (diagnostics) => diagnostics.filter((diagnostic) => !!diagnostic);
|
|
4799
|
+
|
|
4800
|
+
// pkgs/@akanjs/devkit/workflow/artifacts.ts
|
|
5025
4801
|
var createWorkflowApplyReport = ({
|
|
5026
4802
|
workflow,
|
|
5027
4803
|
mode,
|
|
@@ -5104,6 +4880,50 @@ var readWorkflowRunArtifact = async (workspace, runId) => {
|
|
|
5104
4880
|
throw new Error(`Workflow run artifact does not exist: ${artifactPath}`);
|
|
5105
4881
|
return await workspace.readJson(artifactPath);
|
|
5106
4882
|
};
|
|
4883
|
+
var failedCommandScopes = (commands) => commands.filter((command) => command.status === "failed").map((command) => command.failureScope ?? "unknown");
|
|
4884
|
+
var errorDiagnosticScopes = (diagnostics) => diagnostics.filter((diagnostic) => diagnostic.severity === "error").map((diagnostic) => diagnostic.failureScope ?? (diagnostic.scope === "baseline" ? "workspace-config" : diagnostic.scope === "workflow" ? "source-change" : "unknown"));
|
|
4885
|
+
var hasScopeFailure = (scopes, scope, diagnostics = []) => scopes.includes(scope) || diagnostics.some((diagnostic) => diagnostic.severity === "error" && diagnostic.failureScope === scope);
|
|
4886
|
+
var statusForScope = (commands, diagnostics, scopes, expectedScope) => {
|
|
4887
|
+
const hasCommands = commands.length > 0 || diagnostics.length > 0;
|
|
4888
|
+
if (!hasCommands)
|
|
4889
|
+
return "unknown";
|
|
4890
|
+
return hasScopeFailure(scopes, expectedScope, diagnostics) ? "failed" : "passed";
|
|
4891
|
+
};
|
|
4892
|
+
var createKnownBlockers = (commands, diagnostics) => {
|
|
4893
|
+
const commandBlockers = commands.filter((command) => command.status === "failed" && (command.failureScope === "workspace-config" || command.failureScope === "environment")).map((command) => ({
|
|
4894
|
+
code: `workflow-validation-${command.failureScope}`,
|
|
4895
|
+
message: `${command.failureScope === "environment" ? "Environment" : "Workspace configuration"} blocker: ${command.command}`,
|
|
4896
|
+
failureScope: command.failureScope ?? "unknown",
|
|
4897
|
+
command: command.command,
|
|
4898
|
+
kind: command.kind,
|
|
4899
|
+
count: 1
|
|
4900
|
+
}));
|
|
4901
|
+
const diagnosticBlockers = diagnostics.filter((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "workspace-config" || diagnostic.failureScope === "environment" || diagnostic.scope === "baseline")).map((diagnostic) => ({
|
|
4902
|
+
code: diagnostic.code,
|
|
4903
|
+
message: diagnostic.message,
|
|
4904
|
+
failureScope: diagnostic.failureScope ?? "workspace-config",
|
|
4905
|
+
command: diagnostic.command,
|
|
4906
|
+
kind: diagnostic.kind,
|
|
4907
|
+
count: 1
|
|
4908
|
+
}));
|
|
4909
|
+
const grouped = new Map;
|
|
4910
|
+
for (const blocker of [...commandBlockers, ...diagnosticBlockers]) {
|
|
4911
|
+
const key = `${blocker.failureScope}:${blocker.code}:${blocker.command ?? ""}:${blocker.message}`;
|
|
4912
|
+
const existing = grouped.get(key);
|
|
4913
|
+
if (existing)
|
|
4914
|
+
existing.count += blocker.count;
|
|
4915
|
+
else
|
|
4916
|
+
grouped.set(key, blocker);
|
|
4917
|
+
}
|
|
4918
|
+
return [...grouped.values()];
|
|
4919
|
+
};
|
|
4920
|
+
var createValidationStatuses = (commands, diagnostics) => {
|
|
4921
|
+
const scopes = [...failedCommandScopes(commands), ...errorDiagnosticScopes(diagnostics)];
|
|
4922
|
+
const sourceStatus = statusForScope(commands, diagnostics, scopes, "source-change");
|
|
4923
|
+
const workspaceStatus = hasScopeFailure(scopes, "workspace-config", diagnostics) || hasScopeFailure(scopes, "environment", diagnostics) ? "failed" : commands.length || diagnostics.length ? "passed" : "unknown";
|
|
4924
|
+
const overallStatus = hasScopeFailure(scopes, "source-change", diagnostics) ? "failed" : hasScopeFailure(scopes, "workspace-config", diagnostics) ? "blocked-by-workspace-config" : hasScopeFailure(scopes, "environment", diagnostics) ? "blocked-by-environment" : workflowStatus(diagnostics) === "failed" || commandStatus(commands) === "failed" ? "failed" : "passed";
|
|
4925
|
+
return { sourceStatus, workspaceStatus, overallStatus };
|
|
4926
|
+
};
|
|
5107
4927
|
var createWorkflowValidationRunReport = async ({
|
|
5108
4928
|
runId = createWorkflowRunId("validation"),
|
|
5109
4929
|
workflow,
|
|
@@ -5130,15 +4950,20 @@ var createWorkflowValidationRunReport = async ({
|
|
|
5130
4950
|
failureScope: result.failureScope
|
|
5131
4951
|
}
|
|
5132
4952
|
] : []);
|
|
4953
|
+
const reportDiagnostics = [...diagnostics, ...commandDiagnostics];
|
|
4954
|
+
const scopedDiagnostics = [...reportDiagnostics, ...baselineDiagnostics, ...workflowDiagnostics];
|
|
4955
|
+
const statuses = createValidationStatuses(results, scopedDiagnostics);
|
|
5133
4956
|
return {
|
|
5134
4957
|
schemaVersion: 1,
|
|
5135
4958
|
runId,
|
|
5136
4959
|
workflow,
|
|
5137
4960
|
mode: "validate",
|
|
5138
4961
|
source,
|
|
5139
|
-
status:
|
|
4962
|
+
status: statuses.overallStatus === "passed" ? "passed" : "failed",
|
|
4963
|
+
...statuses,
|
|
4964
|
+
knownBlockers: createKnownBlockers(results, scopedDiagnostics),
|
|
5140
4965
|
commands: results,
|
|
5141
|
-
diagnostics:
|
|
4966
|
+
diagnostics: reportDiagnostics,
|
|
5142
4967
|
baselineDiagnostics,
|
|
5143
4968
|
workflowDiagnostics,
|
|
5144
4969
|
repairActions: uniqueBy(repairActions, (action) => action.command),
|
|
@@ -5182,6 +5007,31 @@ var createDryRunWorkflowApplyReport = (plan) => {
|
|
|
5182
5007
|
plan
|
|
5183
5008
|
});
|
|
5184
5009
|
};
|
|
5010
|
+
var createRepairReport = ({
|
|
5011
|
+
command,
|
|
5012
|
+
kind,
|
|
5013
|
+
target = null,
|
|
5014
|
+
diagnostics = [],
|
|
5015
|
+
repairActions = [],
|
|
5016
|
+
nextActions = [],
|
|
5017
|
+
commands = [],
|
|
5018
|
+
generatedFiles = [],
|
|
5019
|
+
syncedAt
|
|
5020
|
+
}) => ({
|
|
5021
|
+
schemaVersion: 1,
|
|
5022
|
+
command,
|
|
5023
|
+
kind,
|
|
5024
|
+
target,
|
|
5025
|
+
status: workflowStatus(diagnostics) === "failed" || commandStatus(commands) === "failed" ? "failed" : "passed",
|
|
5026
|
+
diagnostics,
|
|
5027
|
+
repairActions: uniqueBy(repairActions, (action) => action.command),
|
|
5028
|
+
nextActions: uniqueBy(nextActions, (action) => action.command),
|
|
5029
|
+
commands,
|
|
5030
|
+
generatedFiles,
|
|
5031
|
+
...syncedAt ? { syncedAt } : {}
|
|
5032
|
+
});
|
|
5033
|
+
// pkgs/@akanjs/devkit/workflow/executor.ts
|
|
5034
|
+
import { capitalize as capitalize2 } from "akanjs/common";
|
|
5185
5035
|
var workflowStepKey = (workflow, stepId) => `${workflow}:${stepId}`;
|
|
5186
5036
|
var primitiveReportToWorkflowStepResult = (report) => ({
|
|
5187
5037
|
changedFiles: report.changedFiles,
|
|
@@ -5222,19 +5072,22 @@ var unsupportedInput = (input2, message) => ({
|
|
|
5222
5072
|
message
|
|
5223
5073
|
});
|
|
5224
5074
|
var addFieldUiSurfaceInspection = (plan) => {
|
|
5075
|
+
const app = workflowStringInput(plan.inputs.app);
|
|
5225
5076
|
const module = workflowStringInput(plan.inputs.module) ?? "<module>";
|
|
5226
5077
|
const field = workflowStringInput(plan.inputs.field) ?? "<field>";
|
|
5078
|
+
const typeName = workflowStringInput(plan.inputs.type);
|
|
5079
|
+
const isNumeric = typeName === "Int" || typeName === "Float" || typeName === "integer" || typeName === "float";
|
|
5227
5080
|
const moduleClassName = capitalize2(module);
|
|
5228
|
-
const target =
|
|
5081
|
+
const target = `${app ? `apps/${app}` : "*"}/lib/${module}/${moduleClassName}.Template.tsx`;
|
|
5229
5082
|
return {
|
|
5230
5083
|
recommendations: [
|
|
5231
5084
|
{
|
|
5232
5085
|
code: "add-field-ui-surface-review",
|
|
5233
5086
|
kind: "manual-action",
|
|
5234
5087
|
target,
|
|
5235
|
-
action: `Add ${field} to ${moduleClassName} UI surfaces only when the local Field.* pattern is clear.`,
|
|
5088
|
+
action: isNumeric ? `Review ${moduleClassName} Template/Unit/View/Store surfaces before adding ${field}; confirm the local Field.Text numeric parser/formatter, validation rule, and dictionary label pattern.` : `Add ${field} to ${moduleClassName} UI surfaces only when the local Field.* pattern is clear.`,
|
|
5236
5089
|
confidence: "medium",
|
|
5237
|
-
message: `Review Template/Unit/View/Store surfaces for ${module}.${field}; no UI file was modified automatically.`
|
|
5090
|
+
message: isNumeric ? `No UI file was modified automatically because a safe numeric input component pattern is not yet detected for ${module}.${field}.` : `Review Template/Unit/View/Store surfaces for ${module}.${field}; no UI file was modified automatically.`
|
|
5238
5091
|
}
|
|
5239
5092
|
],
|
|
5240
5093
|
nextActions: [
|
|
@@ -5326,112 +5179,6 @@ var createWorkflowStepRegistry = ({
|
|
|
5326
5179
|
[workflowStepKey("add-enum-field", "update-option")]: inspect
|
|
5327
5180
|
};
|
|
5328
5181
|
};
|
|
5329
|
-
var renderWorkflowApplyReport = (report) => [
|
|
5330
|
-
`# Workflow Apply: ${report.workflow}`,
|
|
5331
|
-
"",
|
|
5332
|
-
`- Mode: ${report.mode}`,
|
|
5333
|
-
`- Status: ${report.status}`,
|
|
5334
|
-
"",
|
|
5335
|
-
"## Changed Files",
|
|
5336
|
-
...report.changedFiles.length ? report.changedFiles.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
|
|
5337
|
-
"",
|
|
5338
|
-
"## Generated Files",
|
|
5339
|
-
...report.generatedFiles.length ? report.generatedFiles.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
|
|
5340
|
-
"",
|
|
5341
|
-
"## Applied Commands",
|
|
5342
|
-
...report.appliedCommands.length ? report.appliedCommands.map((command) => `- \`${command.command}\`: ${command.reason}`) : ["- none"],
|
|
5343
|
-
"",
|
|
5344
|
-
"## Recommended Validation Commands",
|
|
5345
|
-
...report.recommendedValidationCommands.length ? report.recommendedValidationCommands.map((command) => `- \`${command.command}\`: ${command.reason}`) : ["- none"],
|
|
5346
|
-
"",
|
|
5347
|
-
"## Diagnostics",
|
|
5348
|
-
...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5349
|
-
"",
|
|
5350
|
-
"## Recommendations",
|
|
5351
|
-
...report.recommendations.length ? report.recommendations.map((recommendation) => `- [${recommendation.kind}] ${recommendation.message}`) : ["- none"],
|
|
5352
|
-
"",
|
|
5353
|
-
"## Next Actions",
|
|
5354
|
-
...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5355
|
-
""
|
|
5356
|
-
].join(`
|
|
5357
|
-
`);
|
|
5358
|
-
var renderWorkflowApply = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowApplyReport(report);
|
|
5359
|
-
var renderWorkflowValidationRunReport = (report) => [
|
|
5360
|
-
`# Workflow Validation: ${report.workflow}`,
|
|
5361
|
-
"",
|
|
5362
|
-
`- Run: ${report.runId}`,
|
|
5363
|
-
`- Status: ${report.status}`,
|
|
5364
|
-
"",
|
|
5365
|
-
"## Commands",
|
|
5366
|
-
...report.commands.length ? report.commands.map((command) => {
|
|
5367
|
-
const scope = command.failureScope ? ` (${command.failureScope})` : "";
|
|
5368
|
-
return `- [${command.status}] \`${command.command}\`${scope}: ${command.reason}`;
|
|
5369
|
-
}) : ["- none"],
|
|
5370
|
-
"",
|
|
5371
|
-
"## Diagnostics",
|
|
5372
|
-
...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5373
|
-
"",
|
|
5374
|
-
"## Repair Actions",
|
|
5375
|
-
...report.repairActions.length ? report.repairActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5376
|
-
"",
|
|
5377
|
-
"## Next Actions",
|
|
5378
|
-
...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5379
|
-
""
|
|
5380
|
-
].join(`
|
|
5381
|
-
`);
|
|
5382
|
-
var renderWorkflowValidation = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowValidationRunReport(report);
|
|
5383
|
-
var renderWorkflowRunArtifact = (artifact, format = "markdown") => {
|
|
5384
|
-
if ("kind" in artifact)
|
|
5385
|
-
return renderRepairReport(artifact, format);
|
|
5386
|
-
if ("mode" in artifact && artifact.mode === "validate")
|
|
5387
|
-
return renderWorkflowValidation(artifact, format);
|
|
5388
|
-
if ("mode" in artifact && (artifact.mode === "apply" || artifact.mode === "dry-run")) {
|
|
5389
|
-
return renderWorkflowApply(artifact, format);
|
|
5390
|
-
}
|
|
5391
|
-
return jsonText(artifact);
|
|
5392
|
-
};
|
|
5393
|
-
var createRepairReport = ({
|
|
5394
|
-
command,
|
|
5395
|
-
kind,
|
|
5396
|
-
target = null,
|
|
5397
|
-
diagnostics = [],
|
|
5398
|
-
repairActions = [],
|
|
5399
|
-
nextActions = [],
|
|
5400
|
-
commands = [],
|
|
5401
|
-
generatedFiles = [],
|
|
5402
|
-
syncedAt
|
|
5403
|
-
}) => ({
|
|
5404
|
-
schemaVersion: 1,
|
|
5405
|
-
command,
|
|
5406
|
-
kind,
|
|
5407
|
-
target,
|
|
5408
|
-
status: workflowStatus(diagnostics) === "failed" || commandStatus(commands) === "failed" ? "failed" : "passed",
|
|
5409
|
-
diagnostics,
|
|
5410
|
-
repairActions: uniqueBy(repairActions, (action) => action.command),
|
|
5411
|
-
nextActions: uniqueBy(nextActions, (action) => action.command),
|
|
5412
|
-
commands,
|
|
5413
|
-
generatedFiles,
|
|
5414
|
-
...syncedAt ? { syncedAt } : {}
|
|
5415
|
-
});
|
|
5416
|
-
var renderRepairReportMarkdown = (report) => [
|
|
5417
|
-
`# Akan Repair: ${report.kind}`,
|
|
5418
|
-
"",
|
|
5419
|
-
`- Status: ${report.status}`,
|
|
5420
|
-
`- Target: ${report.target ?? "none"}`,
|
|
5421
|
-
"",
|
|
5422
|
-
"## Commands",
|
|
5423
|
-
...report.commands.length ? report.commands.map((command) => `- [${command.status}] \`${command.command}\`: ${command.reason}`) : ["- none"],
|
|
5424
|
-
"",
|
|
5425
|
-
"## Diagnostics",
|
|
5426
|
-
...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5427
|
-
"",
|
|
5428
|
-
"## Next Actions",
|
|
5429
|
-
...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5430
|
-
""
|
|
5431
|
-
].join(`
|
|
5432
|
-
`);
|
|
5433
|
-
var renderRepairReport = (report, format = "markdown") => format === "json" ? jsonText(report) : renderRepairReportMarkdown(report);
|
|
5434
|
-
|
|
5435
5182
|
class WorkflowExecutor {
|
|
5436
5183
|
registry;
|
|
5437
5184
|
constructor(registry) {
|
|
@@ -5498,6 +5245,10 @@ class WorkflowExecutor {
|
|
|
5498
5245
|
});
|
|
5499
5246
|
}
|
|
5500
5247
|
}
|
|
5248
|
+
// pkgs/@akanjs/devkit/workflow/plan.ts
|
|
5249
|
+
import { capitalize as capitalize3 } from "akanjs/common";
|
|
5250
|
+
|
|
5251
|
+
// pkgs/@akanjs/devkit/workflow/primitive.ts
|
|
5501
5252
|
var createPrimitiveWriteReport = ({
|
|
5502
5253
|
command,
|
|
5503
5254
|
status,
|
|
@@ -5539,6 +5290,8 @@ var renderPrimitiveWriteReport = (report) => [
|
|
|
5539
5290
|
].join(`
|
|
5540
5291
|
`);
|
|
5541
5292
|
var renderPrimitiveReport = (report, format = "markdown") => format === "json" ? jsonText(report) : renderPrimitiveWriteReport(report);
|
|
5293
|
+
|
|
5294
|
+
// pkgs/@akanjs/devkit/workflow/source.ts
|
|
5542
5295
|
var getSysRoot = (sys2) => `${sys2.type}s/${sys2.name}`;
|
|
5543
5296
|
var sourceFile = (sys2, path10, action, reason) => ({
|
|
5544
5297
|
path: `${getSysRoot(sys2)}/${path10}`,
|
|
@@ -5571,7 +5324,6 @@ var createPassedPrimitiveReport = ({
|
|
|
5571
5324
|
var scalarChangedFiles = (sys2, scalarName, files) => Object.values(files).map((file) => sourceFile(sys2, `lib/__scalar/${scalarName}/${file.filename}`, "create", "Scalar source file was created."));
|
|
5572
5325
|
var titleize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
5573
5326
|
var lowerlize = (value) => `${value.slice(0, 1).toLowerCase()}${value.slice(1)}`;
|
|
5574
|
-
var compactDiagnostics = (diagnostics) => diagnostics.filter((diagnostic) => !!diagnostic);
|
|
5575
5327
|
var normalizeFieldType = (typeName) => {
|
|
5576
5328
|
const normalizedTypes = {
|
|
5577
5329
|
string: "String",
|
|
@@ -5598,9 +5350,54 @@ var ensureBaseTypeImport = (content, typeName) => {
|
|
|
5598
5350
|
return `import { ${typeName} } from "akanjs/base";
|
|
5599
5351
|
${content}`;
|
|
5600
5352
|
};
|
|
5353
|
+
var numericDefault = (typeName, rawDefault) => {
|
|
5354
|
+
const trimmed = rawDefault.trim();
|
|
5355
|
+
if (!trimmed || !Number.isFinite(Number(trimmed)))
|
|
5356
|
+
return null;
|
|
5357
|
+
if (typeName === "Int" && !/^-?\d+$/.test(trimmed))
|
|
5358
|
+
return null;
|
|
5359
|
+
return trimmed;
|
|
5360
|
+
};
|
|
5361
|
+
var coerceFieldDefault = (typeName, defaultValue) => {
|
|
5362
|
+
if (defaultValue === undefined || defaultValue === null || defaultValue === "")
|
|
5363
|
+
return { expression: null };
|
|
5364
|
+
const normalizedType = normalizeFieldType(typeName);
|
|
5365
|
+
if (normalizedType === "Int" || normalizedType === "Float") {
|
|
5366
|
+
const expression = numericDefault(normalizedType, defaultValue);
|
|
5367
|
+
if (expression !== null)
|
|
5368
|
+
return { expression };
|
|
5369
|
+
return {
|
|
5370
|
+
expression: null,
|
|
5371
|
+
diagnostic: {
|
|
5372
|
+
severity: "error",
|
|
5373
|
+
code: "primitive-default-value-invalid",
|
|
5374
|
+
input: "default",
|
|
5375
|
+
failureScope: "source-change",
|
|
5376
|
+
message: `Default value for ${normalizedType} must be a numeric literal. Received: ${JSON.stringify(defaultValue)}.`
|
|
5377
|
+
}
|
|
5378
|
+
};
|
|
5379
|
+
}
|
|
5380
|
+
if (normalizedType === "Boolean") {
|
|
5381
|
+
const lowered = defaultValue.trim().toLowerCase();
|
|
5382
|
+
if (lowered === "true" || lowered === "false")
|
|
5383
|
+
return { expression: lowered };
|
|
5384
|
+
return {
|
|
5385
|
+
expression: null,
|
|
5386
|
+
diagnostic: {
|
|
5387
|
+
severity: "error",
|
|
5388
|
+
code: "primitive-default-value-invalid",
|
|
5389
|
+
input: "default",
|
|
5390
|
+
failureScope: "source-change",
|
|
5391
|
+
message: `Default value for Boolean must be true or false. Received: ${JSON.stringify(defaultValue)}.`
|
|
5392
|
+
}
|
|
5393
|
+
};
|
|
5394
|
+
}
|
|
5395
|
+
return { expression: JSON.stringify(defaultValue) };
|
|
5396
|
+
};
|
|
5601
5397
|
var fieldExpression = (typeName, defaultValue) => {
|
|
5602
5398
|
const typeExpression = normalizeFieldType(typeName);
|
|
5603
|
-
const
|
|
5399
|
+
const defaultExpression = coerceFieldDefault(typeExpression, defaultValue).expression;
|
|
5400
|
+
const defaultOption = defaultExpression ? `, { default: ${defaultExpression} }` : "";
|
|
5604
5401
|
return `field(${typeExpression}${defaultOption})`;
|
|
5605
5402
|
};
|
|
5606
5403
|
var insertIntoObject = (content, className, line) => {
|
|
@@ -5686,6 +5483,327 @@ ${values.map((value) => ` ${value}: t([${JSON.stringify(titleize(value))}, ${
|
|
|
5686
5483
|
};
|
|
5687
5484
|
var parseValues = (value) => value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
|
|
5688
5485
|
|
|
5486
|
+
// pkgs/@akanjs/devkit/workflow/plan.ts
|
|
5487
|
+
var surfaceModes = new Set(["infer", "include", "skip"]);
|
|
5488
|
+
var parseStringList = (value) => {
|
|
5489
|
+
if (Array.isArray(value)) {
|
|
5490
|
+
const values = value.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
5491
|
+
return values.length === value.length ? values : null;
|
|
5492
|
+
}
|
|
5493
|
+
if (typeof value !== "string")
|
|
5494
|
+
return null;
|
|
5495
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
5496
|
+
};
|
|
5497
|
+
var normalizeInputValue = (name, spec, value) => {
|
|
5498
|
+
if (spec.type === "string")
|
|
5499
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
5500
|
+
if (spec.type === "string-list") {
|
|
5501
|
+
const values = parseStringList(value);
|
|
5502
|
+
return values && values.length > 0 ? values : null;
|
|
5503
|
+
}
|
|
5504
|
+
if (typeof value === "string" && surfaceModes.has(value))
|
|
5505
|
+
return value;
|
|
5506
|
+
throw new Error(`Unsupported workflow input value for ${name}`);
|
|
5507
|
+
};
|
|
5508
|
+
var listWorkflowSpecs = (specs) => [...specs].sort((a, b) => a.name.localeCompare(b.name));
|
|
5509
|
+
var getWorkflowSpec = (specs, name) => specs.find((spec) => spec.name === name) ?? null;
|
|
5510
|
+
var compactWorkflowInputs = (inputs) => Object.fromEntries(Object.entries(inputs).filter(([, value]) => value !== null && value !== ""));
|
|
5511
|
+
var addFieldComponentForType = (typeName) => {
|
|
5512
|
+
const normalizedType = normalizeFieldType(typeName);
|
|
5513
|
+
if (normalizedType === "Boolean")
|
|
5514
|
+
return "Field.ToggleSelect";
|
|
5515
|
+
if (normalizedType === "Date")
|
|
5516
|
+
return "Field.Date";
|
|
5517
|
+
if (normalizedType === "Int" || normalizedType === "Float")
|
|
5518
|
+
return "manual numeric input review";
|
|
5519
|
+
if (typeName.toLowerCase() === "enum")
|
|
5520
|
+
return "Field.ToggleSelect";
|
|
5521
|
+
return "Field.Text";
|
|
5522
|
+
};
|
|
5523
|
+
var createAddFieldRecommendations = (inputs) => {
|
|
5524
|
+
const app = typeof inputs.app === "string" ? inputs.app : "<app-or-lib>";
|
|
5525
|
+
const module = typeof inputs.module === "string" ? inputs.module : "<module>";
|
|
5526
|
+
const field = typeof inputs.field === "string" ? inputs.field : "<field>";
|
|
5527
|
+
const typeName = typeof inputs.type === "string" ? inputs.type : null;
|
|
5528
|
+
if (!typeName)
|
|
5529
|
+
return [];
|
|
5530
|
+
const normalizedType = typeName.toLowerCase() === "enum" ? "enum" : normalizeFieldType(typeName);
|
|
5531
|
+
const constantPath = `*/lib/${module}/${module}.constant.ts`;
|
|
5532
|
+
const dictionaryPath = `*/lib/${module}/${module}.dictionary.ts`;
|
|
5533
|
+
const templatePath = `*/lib/${module}/${capitalize3(module)}.Template.tsx`;
|
|
5534
|
+
return [
|
|
5535
|
+
...normalizedType === "Int" || normalizedType === "Float" ? [
|
|
5536
|
+
{
|
|
5537
|
+
code: "add-field-import",
|
|
5538
|
+
kind: "import",
|
|
5539
|
+
target: constantPath,
|
|
5540
|
+
confidence: "high",
|
|
5541
|
+
message: `Import ${normalizedType} from "akanjs/base" before writing field(${normalizedType}).`
|
|
5542
|
+
}
|
|
5543
|
+
] : [],
|
|
5544
|
+
{
|
|
5545
|
+
code: "add-field-placement-constant",
|
|
5546
|
+
kind: "placement",
|
|
5547
|
+
target: constantPath,
|
|
5548
|
+
confidence: "high",
|
|
5549
|
+
message: `Insert ${field}: field(${normalizedType}) in ${capitalize3(module)}Input.`
|
|
5550
|
+
},
|
|
5551
|
+
{
|
|
5552
|
+
code: "add-field-placement-dictionary",
|
|
5553
|
+
kind: "placement",
|
|
5554
|
+
target: dictionaryPath,
|
|
5555
|
+
confidence: "high",
|
|
5556
|
+
message: `Add dictionary labels for ${module}.${field}.`
|
|
5557
|
+
},
|
|
5558
|
+
{
|
|
5559
|
+
code: "add-field-component",
|
|
5560
|
+
kind: "ui-component",
|
|
5561
|
+
target: templatePath,
|
|
5562
|
+
confidence: normalizedType === "Int" || normalizedType === "Float" ? "low" : "high",
|
|
5563
|
+
action: normalizedType === "Int" || normalizedType === "Float" ? "Do not auto-edit UI. Check local Template/Unit/View patterns for Field.Text parsing, formatting, validation rules, and dictionary labels before adding a numeric input." : undefined,
|
|
5564
|
+
message: normalizedType === "Int" || normalizedType === "Float" ? `Numeric UI for ${field} (${normalizedType}) requires manual review; a safe numeric input component pattern is not yet detected.` : `Recommended UI component for ${field} (${normalizedType}): ${addFieldComponentForType(typeName)}.`
|
|
5565
|
+
},
|
|
5566
|
+
{
|
|
5567
|
+
code: "add-field-ui-manual-review",
|
|
5568
|
+
kind: "manual-action",
|
|
5569
|
+
target: templatePath,
|
|
5570
|
+
action: `Review ${app}:${module} Template/Unit/View/Store surfaces and add ${field} only where the existing pattern is clear. For numeric fields, confirm parser/formatter behavior and validation before using Field.Text.`,
|
|
5571
|
+
confidence: "medium",
|
|
5572
|
+
message: normalizedType === "Int" || normalizedType === "Float" ? "UI surface edits stay manual because a safe numeric input component pattern is not yet detected." : "UI surface edits are planned as manual-review unless a safe existing field-list pattern is detected."
|
|
5573
|
+
}
|
|
5574
|
+
];
|
|
5575
|
+
};
|
|
5576
|
+
var createWorkflowPlanRecommendations = (spec, inputs) => [
|
|
5577
|
+
{
|
|
5578
|
+
code: "workflow-apply-first",
|
|
5579
|
+
kind: "auto-apply",
|
|
5580
|
+
confidence: "high",
|
|
5581
|
+
action: "Call apply_workflow with the MCP planPath before editing source files directly.",
|
|
5582
|
+
message: `Apply the ${spec.name} plan through apply_workflow when MCP returns planPath or next.tool=apply_workflow.`
|
|
5583
|
+
},
|
|
5584
|
+
{
|
|
5585
|
+
code: "workflow-validate-apply-report",
|
|
5586
|
+
kind: "validation",
|
|
5587
|
+
confidence: "high",
|
|
5588
|
+
action: "After apply_workflow, call run_validation with validationTarget when present; otherwise use applyReportPath.",
|
|
5589
|
+
message: "Validate the apply report artifact so diagnostics and recommendations follow the actual apply result."
|
|
5590
|
+
},
|
|
5591
|
+
...spec.name === "add-field" ? createAddFieldRecommendations(inputs) : []
|
|
5592
|
+
];
|
|
5593
|
+
var createWorkflowPlan = (spec, rawInputs) => {
|
|
5594
|
+
const inputs = {};
|
|
5595
|
+
const diagnostics = [];
|
|
5596
|
+
for (const [name, inputSpec] of Object.entries(spec.inputs)) {
|
|
5597
|
+
const rawValue = rawInputs[name];
|
|
5598
|
+
if (rawValue === undefined || rawValue === null || rawValue === "") {
|
|
5599
|
+
if (inputSpec.required) {
|
|
5600
|
+
diagnostics.push({
|
|
5601
|
+
severity: "error",
|
|
5602
|
+
code: "workflow-input-missing",
|
|
5603
|
+
input: name,
|
|
5604
|
+
message: `Workflow ${spec.name} requires input "${name}".`
|
|
5605
|
+
});
|
|
5606
|
+
}
|
|
5607
|
+
continue;
|
|
5608
|
+
}
|
|
5609
|
+
const value = normalizeInputValue(name, inputSpec, rawValue);
|
|
5610
|
+
if (value === null) {
|
|
5611
|
+
diagnostics.push({
|
|
5612
|
+
severity: "error",
|
|
5613
|
+
code: "workflow-input-invalid",
|
|
5614
|
+
input: name,
|
|
5615
|
+
message: `Workflow ${spec.name} input "${name}" must be ${inputSpec.type}.`
|
|
5616
|
+
});
|
|
5617
|
+
continue;
|
|
5618
|
+
}
|
|
5619
|
+
if (inputSpec.allowedValues && typeof value === "string" && !inputSpec.allowedValues.includes(value)) {
|
|
5620
|
+
diagnostics.push({
|
|
5621
|
+
severity: "error",
|
|
5622
|
+
code: "workflow-input-not-allowed",
|
|
5623
|
+
input: name,
|
|
5624
|
+
message: `Workflow ${spec.name} input "${name}" must be one of: ${inputSpec.allowedValues.join(", ")}.`
|
|
5625
|
+
});
|
|
5626
|
+
continue;
|
|
5627
|
+
}
|
|
5628
|
+
inputs[name] = value;
|
|
5629
|
+
}
|
|
5630
|
+
const fieldType = inputs.type;
|
|
5631
|
+
if (spec.name === "add-field" && typeof fieldType === "string" && (fieldType.toLowerCase() === "number" || fieldType.toLowerCase() === "numeric")) {
|
|
5632
|
+
diagnostics.push({
|
|
5633
|
+
severity: "error",
|
|
5634
|
+
code: "primitive-field-type-unsupported",
|
|
5635
|
+
input: "type",
|
|
5636
|
+
message: `Field type "${fieldType}" is ambiguous in Akan. Use Int for integer fields or Float for decimal fields.`
|
|
5637
|
+
});
|
|
5638
|
+
}
|
|
5639
|
+
return {
|
|
5640
|
+
schemaVersion: 1,
|
|
5641
|
+
workflow: spec.name,
|
|
5642
|
+
mode: "plan",
|
|
5643
|
+
inputs,
|
|
5644
|
+
optionalSurfaces: spec.optionalSurfaces ?? {},
|
|
5645
|
+
steps: spec.steps,
|
|
5646
|
+
predictedChanges: spec.predictedChanges,
|
|
5647
|
+
validation: spec.validation,
|
|
5648
|
+
diagnostics,
|
|
5649
|
+
recommendations: createWorkflowPlanRecommendations(spec, inputs),
|
|
5650
|
+
requiresApproval: true
|
|
5651
|
+
};
|
|
5652
|
+
};
|
|
5653
|
+
// pkgs/@akanjs/devkit/workflow/render.ts
|
|
5654
|
+
var renderWorkflowList = (specs) => [
|
|
5655
|
+
"# Akan Workflows",
|
|
5656
|
+
"",
|
|
5657
|
+
...specs.flatMap((spec) => [`- \`${spec.name}\`: ${spec.description}`, ` - When: ${spec.whenToUse}`]),
|
|
5658
|
+
""
|
|
5659
|
+
].join(`
|
|
5660
|
+
`);
|
|
5661
|
+
var renderWorkflowExplain = (spec) => [
|
|
5662
|
+
`# Workflow: ${spec.name}`,
|
|
5663
|
+
"",
|
|
5664
|
+
spec.description,
|
|
5665
|
+
"",
|
|
5666
|
+
"## When To Use",
|
|
5667
|
+
spec.whenToUse,
|
|
5668
|
+
"",
|
|
5669
|
+
"## Inputs",
|
|
5670
|
+
...Object.entries(spec.inputs).map(([name, input2]) => `- \`${name}\`${input2.required ? " (required)" : ""}: ${input2.description}${input2.allowedValues ? ` Allowed: ${input2.allowedValues.join(", ")}.` : ""}`),
|
|
5671
|
+
"",
|
|
5672
|
+
"## Optional Surfaces",
|
|
5673
|
+
...Object.entries(spec.optionalSurfaces ?? {}).map(([name, mode]) => `- \`${name}\`: ${mode}`),
|
|
5674
|
+
"",
|
|
5675
|
+
"## Steps",
|
|
5676
|
+
...spec.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
|
|
5677
|
+
"",
|
|
5678
|
+
"## Validation",
|
|
5679
|
+
...spec.validation.map((validation) => `- \`${validation.command}\`: ${validation.reason}`),
|
|
5680
|
+
""
|
|
5681
|
+
].join(`
|
|
5682
|
+
`);
|
|
5683
|
+
var renderWorkflowPlan = (plan) => [
|
|
5684
|
+
`# Workflow Plan: ${plan.workflow}`,
|
|
5685
|
+
"",
|
|
5686
|
+
`- Mode: ${plan.mode}`,
|
|
5687
|
+
`- Requires approval: ${plan.requiresApproval}`,
|
|
5688
|
+
"",
|
|
5689
|
+
"## Inputs",
|
|
5690
|
+
...Object.entries(plan.inputs).map(([name, value]) => `- \`${name}\`: ${Array.isArray(value) ? value.join(", ") : value}`),
|
|
5691
|
+
"",
|
|
5692
|
+
"## Optional Surfaces",
|
|
5693
|
+
...Object.entries(plan.optionalSurfaces).map(([name, mode]) => `- \`${name}\`: ${mode}`),
|
|
5694
|
+
"",
|
|
5695
|
+
"## Steps",
|
|
5696
|
+
...plan.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
|
|
5697
|
+
"",
|
|
5698
|
+
"## Predicted Changes",
|
|
5699
|
+
...plan.predictedChanges.map((change) => {
|
|
5700
|
+
const scope = change.applyScope ? ` (${change.applyScope})` : "";
|
|
5701
|
+
return `- \`${change.action}\`${scope} ${change.target}: ${change.reason}`;
|
|
5702
|
+
}),
|
|
5703
|
+
"",
|
|
5704
|
+
"## Validation",
|
|
5705
|
+
...plan.validation.map((validation) => `- \`${validation.command}\`: ${validation.reason}`),
|
|
5706
|
+
"",
|
|
5707
|
+
"## Diagnostics",
|
|
5708
|
+
...plan.diagnostics.length ? plan.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5709
|
+
"",
|
|
5710
|
+
"## Recommendations",
|
|
5711
|
+
...plan.recommendations.length ? plan.recommendations.map((recommendation) => `- [${recommendation.kind}] ${recommendation.message}`) : ["- none"],
|
|
5712
|
+
""
|
|
5713
|
+
].join(`
|
|
5714
|
+
`);
|
|
5715
|
+
var renderWorkflowApplyReport = (report) => [
|
|
5716
|
+
`# Workflow Apply: ${report.workflow}`,
|
|
5717
|
+
"",
|
|
5718
|
+
`- Mode: ${report.mode}`,
|
|
5719
|
+
`- Status: ${report.status}`,
|
|
5720
|
+
"",
|
|
5721
|
+
"## Changed Files",
|
|
5722
|
+
...report.changedFiles.length ? report.changedFiles.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
|
|
5723
|
+
"",
|
|
5724
|
+
"## Generated Files",
|
|
5725
|
+
...report.generatedFiles.length ? report.generatedFiles.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
|
|
5726
|
+
"",
|
|
5727
|
+
"## Applied Commands",
|
|
5728
|
+
...report.appliedCommands.length ? report.appliedCommands.map((command) => `- \`${command.command}\`: ${command.reason}`) : ["- none"],
|
|
5729
|
+
"",
|
|
5730
|
+
"## Recommended Validation Commands",
|
|
5731
|
+
...report.recommendedValidationCommands.length ? report.recommendedValidationCommands.map((command) => `- \`${command.command}\`: ${command.reason}`) : ["- none"],
|
|
5732
|
+
"",
|
|
5733
|
+
"## Diagnostics",
|
|
5734
|
+
...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5735
|
+
"",
|
|
5736
|
+
"## Recommendations",
|
|
5737
|
+
...report.recommendations.length ? report.recommendations.map((recommendation) => `- [${recommendation.kind}] ${recommendation.message}`) : ["- none"],
|
|
5738
|
+
"",
|
|
5739
|
+
"## Next Actions",
|
|
5740
|
+
...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5741
|
+
""
|
|
5742
|
+
].join(`
|
|
5743
|
+
`);
|
|
5744
|
+
var renderWorkflowApply = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowApplyReport(report);
|
|
5745
|
+
var renderWorkflowValidationRunReport = (report) => [
|
|
5746
|
+
`# Workflow Validation: ${report.workflow}`,
|
|
5747
|
+
"",
|
|
5748
|
+
`- Run: ${report.runId}`,
|
|
5749
|
+
`- Status: ${report.status}`,
|
|
5750
|
+
`- Source status: ${report.sourceStatus}`,
|
|
5751
|
+
`- Workspace status: ${report.workspaceStatus}`,
|
|
5752
|
+
`- Overall status: ${report.overallStatus}`,
|
|
5753
|
+
"",
|
|
5754
|
+
"## Known Blockers",
|
|
5755
|
+
...report.knownBlockers.length ? report.knownBlockers.map((blocker) => {
|
|
5756
|
+
const command = blocker.command ? ` \`${blocker.command}\`` : "";
|
|
5757
|
+
const count = blocker.count > 1 ? ` (${blocker.count}x)` : "";
|
|
5758
|
+
return `- [${blocker.failureScope}]${command}${count}: ${blocker.message}`;
|
|
5759
|
+
}) : ["- none"],
|
|
5760
|
+
"",
|
|
5761
|
+
"## Commands",
|
|
5762
|
+
...report.commands.length ? report.commands.map((command) => {
|
|
5763
|
+
const scope = command.failureScope ? ` (${command.failureScope})` : "";
|
|
5764
|
+
return `- [${command.status}] \`${command.command}\`${scope}: ${command.reason}`;
|
|
5765
|
+
}) : ["- none"],
|
|
5766
|
+
"",
|
|
5767
|
+
"## Diagnostics",
|
|
5768
|
+
...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5769
|
+
"",
|
|
5770
|
+
"## Repair Actions",
|
|
5771
|
+
...report.repairActions.length ? report.repairActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5772
|
+
"",
|
|
5773
|
+
"## Next Actions",
|
|
5774
|
+
...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5775
|
+
""
|
|
5776
|
+
].join(`
|
|
5777
|
+
`);
|
|
5778
|
+
var renderWorkflowValidation = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowValidationRunReport(report);
|
|
5779
|
+
var renderRepairReportMarkdown = (report) => [
|
|
5780
|
+
`# Akan Repair: ${report.kind}`,
|
|
5781
|
+
"",
|
|
5782
|
+
`- Status: ${report.status}`,
|
|
5783
|
+
`- Target: ${report.target ?? "none"}`,
|
|
5784
|
+
"",
|
|
5785
|
+
"## Commands",
|
|
5786
|
+
...report.commands.length ? report.commands.map((command) => `- [${command.status}] \`${command.command}\`: ${command.reason}`) : ["- none"],
|
|
5787
|
+
"",
|
|
5788
|
+
"## Diagnostics",
|
|
5789
|
+
...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
|
|
5790
|
+
"",
|
|
5791
|
+
"## Next Actions",
|
|
5792
|
+
...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
|
|
5793
|
+
""
|
|
5794
|
+
].join(`
|
|
5795
|
+
`);
|
|
5796
|
+
var renderRepairReport = (report, format = "markdown") => format === "json" ? jsonText(report) : renderRepairReportMarkdown(report);
|
|
5797
|
+
var renderWorkflowRunArtifact = (artifact, format = "markdown") => {
|
|
5798
|
+
if ("kind" in artifact)
|
|
5799
|
+
return renderRepairReport(artifact, format);
|
|
5800
|
+
if ("mode" in artifact && artifact.mode === "validate")
|
|
5801
|
+
return renderWorkflowValidation(artifact, format);
|
|
5802
|
+
if ("mode" in artifact && (artifact.mode === "apply" || artifact.mode === "dry-run")) {
|
|
5803
|
+
return renderWorkflowApply(artifact, format);
|
|
5804
|
+
}
|
|
5805
|
+
return jsonText(artifact);
|
|
5806
|
+
};
|
|
5689
5807
|
// pkgs/@akanjs/devkit/akanContext.ts
|
|
5690
5808
|
var resourceList = [
|
|
5691
5809
|
{ uri: "akan://docs/framework", name: "Akan framework guide", mimeType: "text/markdown" },
|
|
@@ -5821,17 +5939,17 @@ var safeReadJson = async (filePath) => {
|
|
|
5821
5939
|
var isWorkflowPlan = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && value.mode === "plan";
|
|
5822
5940
|
var isWorkflowApplyReport = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && (value.mode === "apply" || value.mode === "dry-run");
|
|
5823
5941
|
var isWorkflowRunArtifact = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1;
|
|
5824
|
-
var planInputString = (
|
|
5825
|
-
const value =
|
|
5942
|
+
var planInputString = (plan2, key) => {
|
|
5943
|
+
const value = plan2.inputs[key];
|
|
5826
5944
|
return typeof value === "string" ? value : "";
|
|
5827
5945
|
};
|
|
5828
|
-
var expandWorkflowTarget = (target,
|
|
5829
|
-
const app = planInputString(
|
|
5830
|
-
const module = planInputString(
|
|
5831
|
-
const moduleClass = module ?
|
|
5946
|
+
var expandWorkflowTarget = (target, plan2) => {
|
|
5947
|
+
const app = planInputString(plan2, "app");
|
|
5948
|
+
const module = planInputString(plan2, "module");
|
|
5949
|
+
const moduleClass = module ? capitalize4(module) : "<Module>";
|
|
5832
5950
|
return target.replace(/^\*\//, app ? `apps/${app}/` : "").replaceAll("<module>", module || "<module>").replaceAll("<Module>", moduleClass);
|
|
5833
5951
|
};
|
|
5834
|
-
var workflowPathsForPlan = (
|
|
5952
|
+
var workflowPathsForPlan = (plan2) => plan2.predictedChanges.map((change) => expandWorkflowTarget(change.target, plan2));
|
|
5835
5953
|
var workflowPathsForArtifact = (artifact) => {
|
|
5836
5954
|
if (isWorkflowPlan(artifact))
|
|
5837
5955
|
return workflowPathsForPlan(artifact);
|
|
@@ -6046,7 +6164,7 @@ class AkanContextAnalyzer {
|
|
|
6046
6164
|
severity: strict ? "error" : "warning",
|
|
6047
6165
|
code: "module-abstract-missing",
|
|
6048
6166
|
path: module.abstract.path,
|
|
6049
|
-
message: `${
|
|
6167
|
+
message: `${capitalize4(module.kind)} module ${sys2.name}:${module.name} should include ${module.abstract.path}`,
|
|
6050
6168
|
repairActions: [action]
|
|
6051
6169
|
});
|
|
6052
6170
|
repairActions.push(action);
|
|
@@ -6058,7 +6176,7 @@ class AkanContextAnalyzer {
|
|
|
6058
6176
|
severity: "error",
|
|
6059
6177
|
code: "module-shape-invalid",
|
|
6060
6178
|
path: module.path,
|
|
6061
|
-
message: `${
|
|
6179
|
+
message: `${capitalize4(module.kind)} module ${sys2.name}:${module.name} is missing required files: ${missingFiles.join(", ")}`,
|
|
6062
6180
|
repairActions: [action]
|
|
6063
6181
|
});
|
|
6064
6182
|
repairActions.push(action);
|
|
@@ -6109,8 +6227,8 @@ class AkanContextAnalyzer {
|
|
|
6109
6227
|
...workflowPaths.length ? { baselineDiagnostics, workflowDiagnostics } : {}
|
|
6110
6228
|
};
|
|
6111
6229
|
}
|
|
6112
|
-
static findModules(context, moduleName) {
|
|
6113
|
-
const modules = [...context.apps, ...context.libs].flatMap((sys2) => sys2.modules);
|
|
6230
|
+
static findModules(context, moduleName, { app = null } = {}) {
|
|
6231
|
+
const modules = [...context.apps, ...context.libs].filter((sys2) => !app || sys2.name === app).flatMap((sys2) => sys2.modules);
|
|
6114
6232
|
return moduleName ? modules.filter((module) => module.name === moduleName || module.folderName === moduleName) : modules;
|
|
6115
6233
|
}
|
|
6116
6234
|
static renderMarkdown(context, { module: moduleName } = {}) {
|
|
@@ -6300,7 +6418,7 @@ void st;
|
|
|
6300
6418
|
` : `const UserLayout = ({ children }) => children;
|
|
6301
6419
|
const userLayout = {};
|
|
6302
6420
|
`;
|
|
6303
|
-
const
|
|
6421
|
+
const source2 = opts.includeSystemProvider ? `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
6304
6422
|
import { loadFonts } from "akanjs/client";
|
|
6305
6423
|
import { System } from "akanjs/ui";
|
|
6306
6424
|
import { env } from "@apps/${opts.appName}/env/env.client";
|
|
@@ -6376,7 +6494,7 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
|
|
|
6376
6494
|
return <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>;
|
|
6377
6495
|
}
|
|
6378
6496
|
`;
|
|
6379
|
-
await Bun.write(absPath,
|
|
6497
|
+
await Bun.write(absPath, source2);
|
|
6380
6498
|
return absPath;
|
|
6381
6499
|
}
|
|
6382
6500
|
async function resolveSsrPageEntries(opts) {
|
|
@@ -6533,23 +6651,23 @@ class BarrelAnalyzer {
|
|
|
6533
6651
|
if (visited.has(absFile))
|
|
6534
6652
|
return;
|
|
6535
6653
|
visited.add(absFile);
|
|
6536
|
-
const
|
|
6537
|
-
if (
|
|
6654
|
+
const source2 = await readIfExists(absFile);
|
|
6655
|
+
if (source2 === null)
|
|
6538
6656
|
return;
|
|
6539
6657
|
const currentSubpath = this.#subpathFor(pkg, absFile);
|
|
6540
6658
|
if (!currentSubpath)
|
|
6541
6659
|
return;
|
|
6542
|
-
const authoritative = this.#scanExports(
|
|
6660
|
+
const authoritative = this.#scanExports(source2, absFile);
|
|
6543
6661
|
authoritative.delete("default");
|
|
6544
6662
|
const attributed = new Set;
|
|
6545
6663
|
REEXPORT_RE.lastIndex = 0;
|
|
6546
|
-
let m = REEXPORT_RE.exec(
|
|
6664
|
+
let m = REEXPORT_RE.exec(source2);
|
|
6547
6665
|
while (m !== null) {
|
|
6548
6666
|
const star = m[1];
|
|
6549
6667
|
const nsAs = m[2];
|
|
6550
6668
|
const namedList = m[3];
|
|
6551
6669
|
const spec = m[5] ?? "";
|
|
6552
|
-
m = REEXPORT_RE.exec(
|
|
6670
|
+
m = REEXPORT_RE.exec(source2);
|
|
6553
6671
|
if (!isRelative(spec))
|
|
6554
6672
|
continue;
|
|
6555
6673
|
if (star) {
|
|
@@ -6585,10 +6703,10 @@ class BarrelAnalyzer {
|
|
|
6585
6703
|
}
|
|
6586
6704
|
}
|
|
6587
6705
|
LOCAL_NAMED_RE.lastIndex = 0;
|
|
6588
|
-
let n = LOCAL_NAMED_RE.exec(
|
|
6706
|
+
let n = LOCAL_NAMED_RE.exec(source2);
|
|
6589
6707
|
while (n !== null) {
|
|
6590
6708
|
const body = n[1] ?? "";
|
|
6591
|
-
n = LOCAL_NAMED_RE.exec(
|
|
6709
|
+
n = LOCAL_NAMED_RE.exec(source2);
|
|
6592
6710
|
for (const item of parseNamedList(body)) {
|
|
6593
6711
|
if (item.isType)
|
|
6594
6712
|
continue;
|
|
@@ -6610,10 +6728,10 @@ class BarrelAnalyzer {
|
|
|
6610
6728
|
map.set(name, { subpath: currentSubpath, originalName: name });
|
|
6611
6729
|
}
|
|
6612
6730
|
}
|
|
6613
|
-
#scanExports(
|
|
6731
|
+
#scanExports(source2, absFile) {
|
|
6614
6732
|
try {
|
|
6615
6733
|
const transpiler = [".tsx", ".jsx"].includes(path13.extname(absFile)) ? this.#tsxTranspiler : this.#tsTranspiler;
|
|
6616
|
-
const { exports } = transpiler.scan(
|
|
6734
|
+
const { exports } = transpiler.scan(source2);
|
|
6617
6735
|
return new Set(exports);
|
|
6618
6736
|
} catch (err) {
|
|
6619
6737
|
this.#logger.error(`scan failed: ${err.message}`);
|
|
@@ -6725,28 +6843,28 @@ var createBarrelImportsPlugin = async (app, { skipPath = defaultSkipPath, pipeAf
|
|
|
6725
6843
|
const raw = await Bun.file(realPath).text();
|
|
6726
6844
|
return { contents: raw, loader };
|
|
6727
6845
|
}
|
|
6728
|
-
let
|
|
6729
|
-
const hasMacroAttr = MACRO_ATTR_RE.test(
|
|
6846
|
+
let source2 = await Bun.file(realPath).text();
|
|
6847
|
+
const hasMacroAttr = MACRO_ATTR_RE.test(source2);
|
|
6730
6848
|
if (!hasMacroAttr && barrels.length > 0) {
|
|
6731
6849
|
let maybe = false;
|
|
6732
6850
|
for (const b of barrels) {
|
|
6733
|
-
if (
|
|
6851
|
+
if (source2.includes(b)) {
|
|
6734
6852
|
maybe = true;
|
|
6735
6853
|
break;
|
|
6736
6854
|
}
|
|
6737
6855
|
}
|
|
6738
6856
|
if (maybe) {
|
|
6739
|
-
const rewritten = await rewriteBarrelImports(
|
|
6857
|
+
const rewritten = await rewriteBarrelImports(source2, barrels, analyzer);
|
|
6740
6858
|
if (rewritten !== null)
|
|
6741
|
-
|
|
6859
|
+
source2 = rewritten;
|
|
6742
6860
|
}
|
|
6743
6861
|
}
|
|
6744
6862
|
if (pipeAfter) {
|
|
6745
|
-
const piped = await pipeAfter(
|
|
6863
|
+
const piped = await pipeAfter(source2, { path: realPath });
|
|
6746
6864
|
if (piped !== null)
|
|
6747
|
-
|
|
6865
|
+
source2 = piped;
|
|
6748
6866
|
}
|
|
6749
|
-
return { contents:
|
|
6867
|
+
return { contents: source2, loader };
|
|
6750
6868
|
});
|
|
6751
6869
|
}
|
|
6752
6870
|
};
|
|
@@ -6922,12 +7040,12 @@ var resolveFileCandidate = async (candidate) => {
|
|
|
6922
7040
|
return null;
|
|
6923
7041
|
};
|
|
6924
7042
|
var MACRO_ATTR_RE = /with\s*\{\s*type\s*:\s*["']macro["']\s*\}/;
|
|
6925
|
-
var rewriteBarrelImports = async (
|
|
6926
|
-
const statements = findImportStatements(
|
|
7043
|
+
var rewriteBarrelImports = async (source2, barrels, analyzer) => {
|
|
7044
|
+
const statements = findImportStatements(source2);
|
|
6927
7045
|
if (statements.length === 0)
|
|
6928
7046
|
return null;
|
|
6929
7047
|
let changed = false;
|
|
6930
|
-
let out =
|
|
7048
|
+
let out = source2;
|
|
6931
7049
|
for (let i = statements.length - 1;i >= 0; i--) {
|
|
6932
7050
|
const stmt = statements[i];
|
|
6933
7051
|
if (!stmt)
|
|
@@ -6945,9 +7063,9 @@ var rewriteBarrelImports = async (source, barrels, analyzer) => {
|
|
|
6945
7063
|
}
|
|
6946
7064
|
return changed ? out : null;
|
|
6947
7065
|
};
|
|
6948
|
-
var findImportStatements = (
|
|
7066
|
+
var findImportStatements = (source2) => {
|
|
6949
7067
|
const statements = [];
|
|
6950
|
-
const sourceFile2 = ts4.createSourceFile("barrel-imports.tsx",
|
|
7068
|
+
const sourceFile2 = ts4.createSourceFile("barrel-imports.tsx", source2, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TSX);
|
|
6951
7069
|
for (const statement of sourceFile2.statements) {
|
|
6952
7070
|
if (!ts4.isImportDeclaration(statement))
|
|
6953
7071
|
continue;
|
|
@@ -6961,10 +7079,10 @@ var findImportStatements = (source) => {
|
|
|
6961
7079
|
statements.push({
|
|
6962
7080
|
start: statementStart,
|
|
6963
7081
|
end: statementEnd,
|
|
6964
|
-
clause:
|
|
7082
|
+
clause: source2.slice(importClause.getStart(sourceFile2), importClause.end).trim(),
|
|
6965
7083
|
specifier: statement.moduleSpecifier.text,
|
|
6966
|
-
trailingSemicolon:
|
|
6967
|
-
raw:
|
|
7084
|
+
trailingSemicolon: source2.slice(statement.moduleSpecifier.end, statement.end).includes(";"),
|
|
7085
|
+
raw: source2.slice(statementStart, statementEnd)
|
|
6968
7086
|
});
|
|
6969
7087
|
}
|
|
6970
7088
|
return statements;
|
|
@@ -7214,13 +7332,13 @@ class GraphClientEntryDiscovery {
|
|
|
7214
7332
|
}
|
|
7215
7333
|
return cached;
|
|
7216
7334
|
}
|
|
7217
|
-
async#getImports(file,
|
|
7335
|
+
async#getImports(file, source2) {
|
|
7218
7336
|
const absPath = path15.resolve(file);
|
|
7219
7337
|
let cached = this.#importCache.get(absPath);
|
|
7220
7338
|
if (!cached) {
|
|
7221
7339
|
cached = Promise.resolve().then(() => {
|
|
7222
7340
|
try {
|
|
7223
|
-
return this.#tsTranspiler.scanImports(
|
|
7341
|
+
return this.#tsTranspiler.scanImports(source2);
|
|
7224
7342
|
} catch {
|
|
7225
7343
|
return [];
|
|
7226
7344
|
}
|
|
@@ -7245,8 +7363,8 @@ class GraphClientEntryDiscovery {
|
|
|
7245
7363
|
entries.add(absPath);
|
|
7246
7364
|
return this.#finishDiscovery(absPath, visiting, entries);
|
|
7247
7365
|
}
|
|
7248
|
-
const
|
|
7249
|
-
const imports = await this.#getImports(absPath,
|
|
7366
|
+
const source2 = await this.#getRewrittenSource(absPath, content);
|
|
7367
|
+
const imports = await this.#getImports(absPath, source2);
|
|
7250
7368
|
const importerDir = path15.dirname(absPath);
|
|
7251
7369
|
for (const imp of imports) {
|
|
7252
7370
|
const spec = imp.path;
|
|
@@ -7282,13 +7400,13 @@ var IMPLICIT_ROOT_LAYOUT_RE = /[/\\]\.akan[/\\]generated[/\\](?:implicit-root-la
|
|
|
7282
7400
|
function toClientReferencePath(absPath, workspaceRoot) {
|
|
7283
7401
|
return path16.relative(path16.resolve(workspaceRoot), path16.resolve(absPath)).split(path16.sep).join("/");
|
|
7284
7402
|
}
|
|
7285
|
-
function transformUseClient(
|
|
7286
|
-
if (!USE_CLIENT_RE2.test(
|
|
7403
|
+
function transformUseClient(source2, args) {
|
|
7404
|
+
if (!USE_CLIENT_RE2.test(source2))
|
|
7287
7405
|
return null;
|
|
7288
7406
|
if (IMPLICIT_ROOT_LAYOUT_RE.test(args.path))
|
|
7289
7407
|
return null;
|
|
7290
7408
|
const transpiler = new Bun.Transpiler({ loader: loaderFor2(args.path) });
|
|
7291
|
-
const { exports } = transpiler.scan(
|
|
7409
|
+
const { exports } = transpiler.scan(source2);
|
|
7292
7410
|
if (exports.length === 0)
|
|
7293
7411
|
return null;
|
|
7294
7412
|
const referencePath = args.workspaceRoot ? toClientReferencePath(args.path, args.workspaceRoot) : args.path;
|
|
@@ -7434,9 +7552,9 @@ ${absEntry}`).toString(36);
|
|
|
7434
7552
|
`;
|
|
7435
7553
|
}
|
|
7436
7554
|
async#scanEntryExportNames(absEntry) {
|
|
7437
|
-
const
|
|
7555
|
+
const source2 = await Bun.file(absEntry).text();
|
|
7438
7556
|
const transpiler = new Bun.Transpiler({ loader: this.#loaderForEntry(absEntry) });
|
|
7439
|
-
return transpiler.scan(
|
|
7557
|
+
return transpiler.scan(source2).exports;
|
|
7440
7558
|
}
|
|
7441
7559
|
#loaderForEntry(absPath) {
|
|
7442
7560
|
if (absPath.endsWith(".tsx"))
|
|
@@ -7483,14 +7601,14 @@ ${absEntry}`).toString(36);
|
|
|
7483
7601
|
if (Object.keys(this.#externalAliases).length === 0)
|
|
7484
7602
|
return;
|
|
7485
7603
|
await Promise.all(outputs.filter((output) => output.path.endsWith(".js")).map(async (output) => {
|
|
7486
|
-
const
|
|
7487
|
-
const rewritten = ClientEntriesBundler.rewriteExternalImportSpecifiers(
|
|
7488
|
-
if (rewritten !==
|
|
7604
|
+
const source2 = await Bun.file(output.path).text();
|
|
7605
|
+
const rewritten = ClientEntriesBundler.rewriteExternalImportSpecifiers(source2, this.#externalAliases);
|
|
7606
|
+
if (rewritten !== source2)
|
|
7489
7607
|
await Bun.write(output.path, rewritten);
|
|
7490
7608
|
}));
|
|
7491
7609
|
}
|
|
7492
|
-
static rewriteExternalImportSpecifiers(
|
|
7493
|
-
let rewritten =
|
|
7610
|
+
static rewriteExternalImportSpecifiers(source2, aliases) {
|
|
7611
|
+
let rewritten = source2;
|
|
7494
7612
|
for (const [specifier, alias] of Object.entries(aliases)) {
|
|
7495
7613
|
if (!alias)
|
|
7496
7614
|
continue;
|
|
@@ -7745,9 +7863,9 @@ ${absEntry}`).toString(36);
|
|
|
7745
7863
|
return { buildEntries, originalByBuildEntry };
|
|
7746
7864
|
}
|
|
7747
7865
|
async#scanExportNames(absEntry) {
|
|
7748
|
-
const
|
|
7866
|
+
const source2 = await Bun.file(absEntry).text();
|
|
7749
7867
|
const transpiler = new Bun.Transpiler({ loader: this.#loaderFor(absEntry) });
|
|
7750
|
-
return transpiler.scan(
|
|
7868
|
+
return transpiler.scan(source2).exports;
|
|
7751
7869
|
}
|
|
7752
7870
|
#loaderFor(absPath) {
|
|
7753
7871
|
if (absPath.endsWith(".tsx"))
|
|
@@ -7758,10 +7876,10 @@ ${absEntry}`).toString(36);
|
|
|
7758
7876
|
return "ts";
|
|
7759
7877
|
return "js";
|
|
7760
7878
|
}
|
|
7761
|
-
static normalizeNamedDefaultFunctionForFastRefresh(
|
|
7879
|
+
static normalizeNamedDefaultFunctionForFastRefresh(source2) {
|
|
7762
7880
|
let changed = false;
|
|
7763
7881
|
const defaultNames = [];
|
|
7764
|
-
const next =
|
|
7882
|
+
const next = source2.replace(/(^|\n)(\s*)export\s+default\s+(async\s+)?function\s+([A-Za-z_$][\w$]*)(?=\s*(?:<|\())/g, (match, lineStart, indent, asyncKeyword, name) => {
|
|
7765
7883
|
changed = true;
|
|
7766
7884
|
defaultNames.push(name);
|
|
7767
7885
|
return `${lineStart}${indent}${asyncKeyword ?? ""}function ${name}`;
|
|
@@ -7989,8 +8107,8 @@ ${entries.join(`
|
|
|
7989
8107
|
}
|
|
7990
8108
|
static #hasAsyncDefaultExport(moduleAbsPath) {
|
|
7991
8109
|
try {
|
|
7992
|
-
const
|
|
7993
|
-
const sourceFile2 = ts5.createSourceFile(moduleAbsPath,
|
|
8110
|
+
const source2 = fs3.readFileSync(path21.resolve(moduleAbsPath), "utf8");
|
|
8111
|
+
const sourceFile2 = ts5.createSourceFile(moduleAbsPath, source2, ts5.ScriptTarget.Latest, true, PagesEntrySourceGenerator.#scriptKind(moduleAbsPath));
|
|
7994
8112
|
return PagesEntrySourceGenerator.#sourceFileHasAsyncDefaultExport(sourceFile2);
|
|
7995
8113
|
} catch {
|
|
7996
8114
|
return false;
|
|
@@ -8250,8 +8368,8 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
|
|
|
8250
8368
|
return html;
|
|
8251
8369
|
return result + html.slice(lastIndex);
|
|
8252
8370
|
}
|
|
8253
|
-
static escapeInlineScript(
|
|
8254
|
-
return
|
|
8371
|
+
static escapeInlineScript(source2) {
|
|
8372
|
+
return source2.replace(/<\/script/gi, "<\\/script");
|
|
8255
8373
|
}
|
|
8256
8374
|
static resolveHtmlAssetPath(htmlPath, src) {
|
|
8257
8375
|
if (/^[a-z][a-z0-9+.-]*:/i.test(src) || src.startsWith("//")) {
|
|
@@ -8482,17 +8600,17 @@ class CssCompiler {
|
|
|
8482
8600
|
} catch {
|
|
8483
8601
|
continue;
|
|
8484
8602
|
}
|
|
8485
|
-
let
|
|
8603
|
+
let source2 = content;
|
|
8486
8604
|
if (akanConfig2.barrelImports.length > 0) {
|
|
8487
8605
|
try {
|
|
8488
8606
|
const rewritten = await rewriteBarrelImports(content, akanConfig2.barrelImports, analyzer);
|
|
8489
8607
|
if (rewritten !== null)
|
|
8490
|
-
|
|
8608
|
+
source2 = rewritten;
|
|
8491
8609
|
} catch {}
|
|
8492
8610
|
}
|
|
8493
8611
|
let imports;
|
|
8494
8612
|
try {
|
|
8495
|
-
imports = this.#transpiler.scanImports(
|
|
8613
|
+
imports = this.#transpiler.scanImports(source2);
|
|
8496
8614
|
} catch {
|
|
8497
8615
|
continue;
|
|
8498
8616
|
}
|
|
@@ -8931,7 +9049,7 @@ class DevGeneratedIndexSync {
|
|
|
8931
9049
|
const rawModel = moduleSegment.startsWith("_") ? moduleSegment.slice(1) : moduleSegment;
|
|
8932
9050
|
if (!rawModel)
|
|
8933
9051
|
return null;
|
|
8934
|
-
const modelName =
|
|
9052
|
+
const modelName = capitalize5(rawModel);
|
|
8935
9053
|
const allowedTypes = isScalar ? SCALAR_UI_TYPES : moduleSegment.startsWith("_") ? SERVICE_UI_TYPES : MODULE_UI_TYPES;
|
|
8936
9054
|
const fileTypes = [];
|
|
8937
9055
|
for (const type of allowedTypes) {
|
|
@@ -8948,7 +9066,7 @@ export const ${modelName} = { ${fileTypes.join(", ")} };`;
|
|
|
8948
9066
|
}
|
|
8949
9067
|
}
|
|
8950
9068
|
var exists = async (file) => stat3(file).then(() => true).catch(() => false);
|
|
8951
|
-
var
|
|
9069
|
+
var capitalize5 = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
8952
9070
|
var formatError = (err) => err instanceof Error ? err.message : String(err);
|
|
8953
9071
|
// pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
|
|
8954
9072
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
@@ -9025,8 +9143,8 @@ class FontOptimizer {
|
|
|
9025
9143
|
if (faceCss.length > 0)
|
|
9026
9144
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
9027
9145
|
}
|
|
9028
|
-
#extractFontsExport(
|
|
9029
|
-
const sourceFile2 = ts6.createSourceFile(filePath,
|
|
9146
|
+
#extractFontsExport(source2, filePath) {
|
|
9147
|
+
const sourceFile2 = ts6.createSourceFile(filePath, source2, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TSX);
|
|
9030
9148
|
const fonts = [];
|
|
9031
9149
|
for (const statement of sourceFile2.statements) {
|
|
9032
9150
|
if (!ts6.isVariableStatement(statement))
|
|
@@ -9582,13 +9700,13 @@ function createUseClientBundlePlugin(options = {}) {
|
|
|
9582
9700
|
build.onLoad({ filter: /\.(tsx|ts|jsx|js)$/ }, async (args) => {
|
|
9583
9701
|
if (args.path.includes("/node_modules/"))
|
|
9584
9702
|
return;
|
|
9585
|
-
let
|
|
9703
|
+
let source2;
|
|
9586
9704
|
try {
|
|
9587
|
-
|
|
9705
|
+
source2 = await Bun.file(args.path).text();
|
|
9588
9706
|
} catch {
|
|
9589
9707
|
return;
|
|
9590
9708
|
}
|
|
9591
|
-
const stubbed = transformUseClient(
|
|
9709
|
+
const stubbed = transformUseClient(source2, {
|
|
9592
9710
|
path: args.path,
|
|
9593
9711
|
workspaceRoot: options.workspaceRoot
|
|
9594
9712
|
});
|
|
@@ -9646,7 +9764,7 @@ class PagesBundleBuilder {
|
|
|
9646
9764
|
PagesBundleBuilder.createServerUseClientFetchPlugin(),
|
|
9647
9765
|
await createExternalizeFrameworkPlugin({ app: this.#app, extra: akanConfig2.externalLibs }),
|
|
9648
9766
|
akanConfig2.barrelImports.length > 0 ? await createBarrelImportsPlugin(this.#app, {
|
|
9649
|
-
pipeAfter: (
|
|
9767
|
+
pipeAfter: (source2, args) => transformUseClient(source2, {
|
|
9650
9768
|
path: args.path,
|
|
9651
9769
|
workspaceRoot
|
|
9652
9770
|
})
|
|
@@ -9687,7 +9805,7 @@ class PagesBundleBuilder {
|
|
|
9687
9805
|
...Object.fromEntries(Object.entries(this.#app.getPublicEnv()).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]))
|
|
9688
9806
|
};
|
|
9689
9807
|
}
|
|
9690
|
-
static createPagesEntryPlugin(
|
|
9808
|
+
static createPagesEntryPlugin(source2) {
|
|
9691
9809
|
return {
|
|
9692
9810
|
name: "akan-pages-entry",
|
|
9693
9811
|
setup(build) {
|
|
@@ -9696,7 +9814,7 @@ class PagesBundleBuilder {
|
|
|
9696
9814
|
namespace: "akan-virtual"
|
|
9697
9815
|
}));
|
|
9698
9816
|
build.onLoad({ filter: /^akan-pages-entry$/, namespace: "akan-virtual" }, () => ({
|
|
9699
|
-
contents:
|
|
9817
|
+
contents: source2,
|
|
9700
9818
|
loader: "tsx"
|
|
9701
9819
|
}));
|
|
9702
9820
|
}
|
|
@@ -9718,19 +9836,19 @@ class PagesBundleBuilder {
|
|
|
9718
9836
|
name: "akan-server-use-client-fetch",
|
|
9719
9837
|
setup(build) {
|
|
9720
9838
|
build.onLoad({ filter: /[/\\]lib[/\\]useClient\.(ts|tsx|js|jsx)$/ }, async (args) => {
|
|
9721
|
-
const
|
|
9722
|
-
const transformed = PagesBundleBuilder.transformServerUseClientFetchSource(
|
|
9723
|
-
if (transformed ===
|
|
9839
|
+
const source2 = await Bun.file(args.path).text();
|
|
9840
|
+
const transformed = PagesBundleBuilder.transformServerUseClientFetchSource(source2);
|
|
9841
|
+
if (transformed === source2)
|
|
9724
9842
|
return;
|
|
9725
9843
|
return { contents: transformed, loader: loaderFor4(args.path) };
|
|
9726
9844
|
});
|
|
9727
9845
|
}
|
|
9728
9846
|
};
|
|
9729
9847
|
}
|
|
9730
|
-
static transformServerUseClientFetchSource(
|
|
9731
|
-
if (!
|
|
9732
|
-
return
|
|
9733
|
-
return
|
|
9848
|
+
static transformServerUseClientFetchSource(source2) {
|
|
9849
|
+
if (!source2.includes(`with { type: "macro" }`) || !source2.includes("FetchClient.build"))
|
|
9850
|
+
return source2;
|
|
9851
|
+
return source2.replace(/import\s+\{\s*getSerializedSignal\s*\}\s+from\s+["']\.\/sig["']\s+with\s+\{\s*type\s*:\s*["']macro["']\s*\};/, `import { fetch as serverFetch } from "./sig";`).replace(/const\s+fetchProto\s*=\s*FetchClient\.build<[^;]+;/, "const fetchProto = FetchClient.build<typeof signal>(cnst, serverFetch.serializedSignal, { Err: pageProto.Err, base: serverFetch });");
|
|
9734
9852
|
}
|
|
9735
9853
|
}
|
|
9736
9854
|
function loaderFor4(absPath) {
|
|
@@ -10496,8 +10614,8 @@ class Builder {
|
|
|
10496
10614
|
#executor;
|
|
10497
10615
|
#distExecutor;
|
|
10498
10616
|
#pkgJson;
|
|
10499
|
-
constructor({ executor, distExecutor, pkgJson }) {
|
|
10500
|
-
this.#executor =
|
|
10617
|
+
constructor({ executor: executor2, distExecutor, pkgJson }) {
|
|
10618
|
+
this.#executor = executor2;
|
|
10501
10619
|
this.#distExecutor = distExecutor;
|
|
10502
10620
|
this.#pkgJson = pkgJson;
|
|
10503
10621
|
}
|
|
@@ -10623,7 +10741,7 @@ import os from "os";
|
|
|
10623
10741
|
import path38 from "path";
|
|
10624
10742
|
import { select as select2 } from "@inquirer/prompts";
|
|
10625
10743
|
import { MobileProject } from "@trapezedev/project";
|
|
10626
|
-
import { capitalize as
|
|
10744
|
+
import { capitalize as capitalize6 } from "akanjs/common";
|
|
10627
10745
|
|
|
10628
10746
|
// pkgs/@akanjs/devkit/fileEditor.ts
|
|
10629
10747
|
class FileEditor {
|
|
@@ -11714,7 +11832,7 @@ ${error.message}`;
|
|
|
11714
11832
|
this.#setPermissionsInAndroid(["POST_NOTIFICATIONS"]);
|
|
11715
11833
|
}
|
|
11716
11834
|
async#setPermissionInIos(permissions) {
|
|
11717
|
-
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${
|
|
11835
|
+
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${capitalize6(key)}`, value]));
|
|
11718
11836
|
await Promise.all([
|
|
11719
11837
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Debug", updateNs),
|
|
11720
11838
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Release", updateNs)
|
|
@@ -11806,8 +11924,8 @@ import chalk6 from "chalk";
|
|
|
11806
11924
|
import { program } from "commander";
|
|
11807
11925
|
|
|
11808
11926
|
// pkgs/@akanjs/devkit/commandDecorators/dependencyBuilder.ts
|
|
11809
|
-
var
|
|
11810
|
-
var createDependencyKey = (refName, kind) => `${refName}${
|
|
11927
|
+
var capitalize7 = (value) => value.slice(0, 1).toUpperCase() + value.slice(1);
|
|
11928
|
+
var createDependencyKey = (refName, kind) => `${refName}${capitalize7(kind)}`;
|
|
11811
11929
|
|
|
11812
11930
|
class CommandContainer {
|
|
11813
11931
|
static #instances = new Map;
|
|
@@ -12287,13 +12405,13 @@ var getInternalArgumentValue = async (argMeta, value, workspace) => {
|
|
|
12287
12405
|
...libNames.map((name2) => ({ name: name2, value: { type: "lib", name: name2 } }))
|
|
12288
12406
|
]
|
|
12289
12407
|
});
|
|
12290
|
-
const
|
|
12291
|
-
const modules = await
|
|
12408
|
+
const executor2 = type === "app" ? AppExecutor.from(workspace, name) : LibExecutor.from(workspace, name);
|
|
12409
|
+
const modules = await executor2.getModules();
|
|
12292
12410
|
const moduleName = await select3({
|
|
12293
12411
|
message: `Select the module name`,
|
|
12294
|
-
choices: modules.map((name2) => ({ name: `${
|
|
12412
|
+
choices: modules.map((name2) => ({ name: `${executor2.name}:${name2}`, value: name2 }))
|
|
12295
12413
|
});
|
|
12296
|
-
return ModuleExecutor.from(
|
|
12414
|
+
return ModuleExecutor.from(executor2, moduleName);
|
|
12297
12415
|
} else
|
|
12298
12416
|
throw new Error(`Invalid system type: ${argMeta.type}`);
|
|
12299
12417
|
};
|
|
@@ -12552,18 +12670,18 @@ import * as ts7 from "typescript";
|
|
|
12552
12670
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
12553
12671
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
12554
12672
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
12555
|
-
var scanModuleSpecifiers = (
|
|
12556
|
-
const scannedImports = getTranspiler(filePath).scanImports(
|
|
12673
|
+
var scanModuleSpecifiers = (source2, filePath, includeExports) => {
|
|
12674
|
+
const scannedImports = getTranspiler(filePath).scanImports(source2).map((imp) => imp.path).filter(Boolean);
|
|
12557
12675
|
if (includeExports) {
|
|
12558
12676
|
const specifiers = new Set(scannedImports);
|
|
12559
12677
|
const typeOnlyModuleRegex = /\b(?:import|export)\s+type\s+[\s\S]*?\s+from\s*["']([^"']+)["']/g;
|
|
12560
|
-
for (const match of
|
|
12678
|
+
for (const match of source2.matchAll(typeOnlyModuleRegex)) {
|
|
12561
12679
|
const importPath = match[1];
|
|
12562
12680
|
if (importPath)
|
|
12563
12681
|
specifiers.add(importPath);
|
|
12564
12682
|
}
|
|
12565
12683
|
const exportFromRegex = /\bexport\s+(?:type\s+)?(?:\*|{[\s\S]*?})\s+from\s*["']([^"']+)["']/g;
|
|
12566
|
-
for (const match of
|
|
12684
|
+
for (const match of source2.matchAll(exportFromRegex)) {
|
|
12567
12685
|
const importPath = match[1];
|
|
12568
12686
|
if (importPath)
|
|
12569
12687
|
specifiers.add(importPath);
|
|
@@ -12572,7 +12690,7 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
12572
12690
|
}
|
|
12573
12691
|
const importSpecifiers = new Set;
|
|
12574
12692
|
const importDeclarationRegex = /\bimport\s+(?:type\s+)?(?:["']([^"']+)["']|[\s\S]*?\s+from\s*["']([^"']+)["'])/g;
|
|
12575
|
-
for (const match of
|
|
12693
|
+
for (const match of source2.matchAll(importDeclarationRegex)) {
|
|
12576
12694
|
const importPath = match[1] ?? match[2];
|
|
12577
12695
|
if (importPath && (scannedImports.includes(importPath) || match[0].startsWith("import type"))) {
|
|
12578
12696
|
importSpecifiers.add(importPath);
|
|
@@ -12595,8 +12713,8 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
12595
12713
|
if (analyzedFiles.has(filePath))
|
|
12596
12714
|
return;
|
|
12597
12715
|
analyzedFiles.add(filePath);
|
|
12598
|
-
const
|
|
12599
|
-
for (const importPath of scanModuleSpecifiers(
|
|
12716
|
+
const source2 = readFileSync4(filePath, "utf-8");
|
|
12717
|
+
for (const importPath of scanModuleSpecifiers(source2, filePath, false)) {
|
|
12600
12718
|
if (!importPath.startsWith("."))
|
|
12601
12719
|
continue;
|
|
12602
12720
|
const resolved = ts7.resolveModuleName(importPath, filePath, parsedConfig.options, ts7.sys).resolvedModule?.resolvedFileName;
|
|
@@ -12645,21 +12763,21 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
12645
12763
|
if (analyzedFiles.has(filePath))
|
|
12646
12764
|
return;
|
|
12647
12765
|
analyzedFiles.add(filePath);
|
|
12648
|
-
const
|
|
12649
|
-
if (!
|
|
12766
|
+
const source2 = program2.getSourceFile(filePath);
|
|
12767
|
+
if (!source2)
|
|
12650
12768
|
return;
|
|
12651
12769
|
if (!sourceLineCache.has(filePath)) {
|
|
12652
|
-
sourceLineCache.set(filePath,
|
|
12770
|
+
sourceLineCache.set(filePath, source2.getFullText().split(`
|
|
12653
12771
|
`));
|
|
12654
12772
|
}
|
|
12655
12773
|
const sourceLines = sourceLineCache.get(filePath);
|
|
12656
12774
|
function visit(node) {
|
|
12657
|
-
if (!
|
|
12775
|
+
if (!source2)
|
|
12658
12776
|
return;
|
|
12659
12777
|
if (ts7.isPropertyAccessExpression(node)) {
|
|
12660
12778
|
const left = node.expression;
|
|
12661
12779
|
const right = node.name;
|
|
12662
|
-
const { line } = ts7.getLineAndCharacterOfPosition(
|
|
12780
|
+
const { line } = ts7.getLineAndCharacterOfPosition(source2, node.getStart());
|
|
12663
12781
|
if (ts7.isIdentifier(left) && sourceLines && sourceLines.length > line && sourceLines[line] && (sourceLines[line]?.includes(`@Field.Prop(() => ${left.text}.${right.text}`) || sourceLines[line].includes(`base.Filter(${left.text}.${right.text},`))) {
|
|
12664
12782
|
const symbol = getCachedSymbol(right);
|
|
12665
12783
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
@@ -12710,7 +12828,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
12710
12828
|
}
|
|
12711
12829
|
ts7.forEachChild(node, visit);
|
|
12712
12830
|
}
|
|
12713
|
-
visit(
|
|
12831
|
+
visit(source2);
|
|
12714
12832
|
}
|
|
12715
12833
|
for (const filePath of filesToAnalyze) {
|
|
12716
12834
|
analyzeFileProperties(filePath);
|