swallowkit 2.0.0-alpha.1 → 2.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +14 -0
- package/README.md +14 -0
- package/dist/cli/commands/add-auth.js +37 -6
- package/dist/cli/commands/add-auth.js.map +1 -1
- package/dist/cli/commands/configure-mcp.d.ts +12 -0
- package/dist/cli/commands/configure-mcp.d.ts.map +1 -0
- package/dist/cli/commands/configure-mcp.js +42 -0
- package/dist/cli/commands/configure-mcp.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +2 -2
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +39 -27
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/init.d.ts +8 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +67 -132
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/migrations.d.ts.map +1 -1
- package/dist/cli/commands/migrations.js +25 -0
- package/dist/cli/commands/migrations.js.map +1 -1
- package/dist/cli/commands/provision.d.ts +5 -0
- package/dist/cli/commands/provision.d.ts.map +1 -1
- package/dist/cli/commands/provision.js +278 -55
- package/dist/cli/commands/provision.js.map +1 -1
- package/dist/cli/commands/scaffold.d.ts +4 -0
- package/dist/cli/commands/scaffold.d.ts.map +1 -1
- package/dist/cli/commands/scaffold.js +85 -3
- package/dist/cli/commands/scaffold.js.map +1 -1
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +43 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/core/operations/create-model.d.ts +2 -0
- package/dist/core/operations/create-model.d.ts.map +1 -1
- package/dist/core/operations/create-model.js +60 -8
- package/dist/core/operations/create-model.js.map +1 -1
- package/dist/core/operations/migration-generator.d.ts.map +1 -1
- package/dist/core/operations/migration-generator.js +12 -1
- package/dist/core/operations/migration-generator.js.map +1 -1
- package/dist/core/operations/model-migration.d.ts +22 -0
- package/dist/core/operations/model-migration.d.ts.map +1 -0
- package/dist/core/operations/model-migration.js +36 -0
- package/dist/core/operations/model-migration.js.map +1 -0
- package/dist/core/operations/provision-deployment.d.ts +52 -0
- package/dist/core/operations/provision-deployment.d.ts.map +1 -0
- package/dist/core/operations/provision-deployment.js +164 -0
- package/dist/core/operations/provision-deployment.js.map +1 -0
- package/dist/core/operations/provision-operations.d.ts +62 -6
- package/dist/core/operations/provision-operations.d.ts.map +1 -1
- package/dist/core/operations/provision-operations.js +653 -115
- package/dist/core/operations/provision-operations.js.map +1 -1
- package/dist/core/operations/scaffold-apply.d.ts +1 -0
- package/dist/core/operations/scaffold-apply.d.ts.map +1 -1
- package/dist/core/operations/scaffold-apply.js +1 -0
- package/dist/core/operations/scaffold-apply.js.map +1 -1
- package/dist/core/operations/scaffold-machine.d.ts +1 -0
- package/dist/core/operations/scaffold-machine.d.ts.map +1 -1
- package/dist/core/operations/scaffold-machine.js.map +1 -1
- package/dist/core/operations/scaffold-plan.d.ts +2 -0
- package/dist/core/operations/scaffold-plan.d.ts.map +1 -1
- package/dist/core/operations/scaffold-plan.js +3 -1
- package/dist/core/operations/scaffold-plan.js.map +1 -1
- package/dist/core/project/agent-instructions.d.ts.map +1 -1
- package/dist/core/project/agent-instructions.js +4 -1
- package/dist/core/project/agent-instructions.js.map +1 -1
- package/dist/core/project/boundaries.d.ts +5 -2
- package/dist/core/project/boundaries.d.ts.map +1 -1
- package/dist/core/project/boundaries.js +51 -20
- package/dist/core/project/boundaries.js.map +1 -1
- package/dist/core/project/capabilities.d.ts +10 -0
- package/dist/core/project/capabilities.d.ts.map +1 -1
- package/dist/core/project/capabilities.js +38 -6
- package/dist/core/project/capabilities.js.map +1 -1
- package/dist/core/project/home-page.d.ts +4 -0
- package/dist/core/project/home-page.d.ts.map +1 -0
- package/dist/core/project/home-page.js +113 -0
- package/dist/core/project/home-page.js.map +1 -0
- package/dist/core/project/mcp-config.d.ts +26 -0
- package/dist/core/project/mcp-config.d.ts.map +1 -0
- package/dist/core/project/mcp-config.js +117 -0
- package/dist/core/project/mcp-config.js.map +1 -0
- package/dist/core/project/react-project.d.ts +1 -1
- package/dist/core/project/react-project.d.ts.map +1 -1
- package/dist/core/project/react-project.js +46 -25
- package/dist/core/project/react-project.js.map +1 -1
- package/dist/core/project/state.d.ts +7 -0
- package/dist/core/project/state.d.ts.map +1 -1
- package/dist/core/project/state.js +86 -0
- package/dist/core/project/state.js.map +1 -1
- package/dist/core/project/workflows.d.ts.map +1 -1
- package/dist/core/project/workflows.js +53 -7
- package/dist/core/project/workflows.js.map +1 -1
- package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
- package/dist/core/scaffold/auth-generator.js +26 -27
- package/dist/core/scaffold/auth-generator.js.map +1 -1
- package/dist/core/scaffold/model-parser.d.ts +23 -0
- package/dist/core/scaffold/model-parser.d.ts.map +1 -1
- package/dist/core/scaffold/model-parser.js +407 -137
- package/dist/core/scaffold/model-parser.js.map +1 -1
- package/dist/core/scaffold/native-schema-generator.d.ts +13 -0
- package/dist/core/scaffold/native-schema-generator.d.ts.map +1 -1
- package/dist/core/scaffold/native-schema-generator.js +294 -91
- package/dist/core/scaffold/native-schema-generator.js.map +1 -1
- package/dist/core/scaffold/openapi-generator.d.ts +5 -0
- package/dist/core/scaffold/openapi-generator.d.ts.map +1 -1
- package/dist/core/scaffold/openapi-generator.js +53 -3
- package/dist/core/scaffold/openapi-generator.js.map +1 -1
- package/dist/core/scaffold/ui-generator.d.ts +0 -3
- package/dist/core/scaffold/ui-generator.d.ts.map +1 -1
- package/dist/core/scaffold/ui-generator.js +68 -7
- package/dist/core/scaffold/ui-generator.js.map +1 -1
- package/dist/core/verify/index.d.ts +4 -3
- package/dist/core/verify/index.d.ts.map +1 -1
- package/dist/core/verify/index.js +122 -5
- package/dist/core/verify/index.js.map +1 -1
- package/dist/machine/contracts.d.ts +1 -0
- package/dist/machine/contracts.d.ts.map +1 -1
- package/dist/machine/errors.d.ts +3 -2
- package/dist/machine/errors.d.ts.map +1 -1
- package/dist/machine/errors.js +2 -1
- package/dist/machine/errors.js.map +1 -1
- package/dist/machine/index.d.ts.map +1 -1
- package/dist/machine/index.js +59 -28
- package/dist/machine/index.js.map +1 -1
- package/dist/mcp/index.d.ts +6 -4
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +210 -25
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/version-selection.d.ts +55 -0
- package/dist/mcp/version-selection.d.ts.map +1 -0
- package/dist/mcp/version-selection.js +152 -0
- package/dist/mcp/version-selection.js.map +1 -0
- package/dist/utils/azure-cli.d.ts +56 -0
- package/dist/utils/azure-cli.d.ts.map +1 -0
- package/dist/utils/azure-cli.js +326 -0
- package/dist/utils/azure-cli.js.map +1 -0
- package/dist/utils/azure-diagnostics.d.ts +16 -0
- package/dist/utils/azure-diagnostics.d.ts.map +1 -0
- package/dist/utils/azure-diagnostics.js +68 -0
- package/dist/utils/azure-diagnostics.js.map +1 -0
- package/dist/utils/package-manager.js +2 -2
- package/dist/utils/package-manager.js.map +1 -1
- package/dist/utils/python-uv.d.ts +5 -7
- package/dist/utils/python-uv.d.ts.map +1 -1
- package/dist/utils/python-uv.js +50 -24
- package/dist/utils/python-uv.js.map +1 -1
- package/dist/utils/react-dev.d.ts +4 -0
- package/dist/utils/react-dev.d.ts.map +1 -0
- package/dist/utils/react-dev.js +35 -0
- package/dist/utils/react-dev.js.map +1 -0
- package/dist/utils/semver.d.ts +14 -0
- package/dist/utils/semver.d.ts.map +1 -0
- package/dist/utils/semver.js +61 -0
- package/dist/utils/semver.js.map +1 -0
- package/package.json +6 -3
- package/src/__tests__/__snapshots__/boundaries.test.ts.snap +154 -0
- package/src/__tests__/agent-instructions.test.ts +5 -0
- package/src/__tests__/agent-loop-phase34.test.ts +143 -8
- package/src/__tests__/auth.test.ts +9 -0
- package/src/__tests__/azure-cli.test.ts +202 -0
- package/src/__tests__/boundaries.test.ts +42 -0
- package/src/__tests__/csharp-schema.test.ts +261 -0
- package/src/__tests__/dev.test.ts +13 -6
- package/src/__tests__/fixtures/az wrapper.cmd +2 -0
- package/src/__tests__/fixtures/azure-cli.cjs +153 -0
- package/src/__tests__/fixtures/provision-runner.cjs +28 -0
- package/src/__tests__/generated-project-matrix.test.ts +789 -0
- package/src/__tests__/home-page.test.ts +50 -0
- package/src/__tests__/init.test.ts +116 -0
- package/src/__tests__/mcp-version.test.ts +262 -0
- package/src/__tests__/mcp.test.ts +120 -3
- package/src/__tests__/multi-auth.test.ts +115 -4
- package/src/__tests__/package-manager.test.ts +17 -2
- package/src/__tests__/plan-apply.test.ts +179 -0
- package/src/__tests__/provision-runtime.test.ts +722 -0
- package/src/__tests__/python-uv.test.ts +50 -14
- package/src/__tests__/python-venv.test.ts +48 -0
- package/src/__tests__/react-dev.test.ts +72 -0
- package/src/__tests__/react.test.ts +19 -0
- package/src/__tests__/schema-analysis.test.ts +329 -0
- package/src/cli/commands/add-auth.ts +36 -6
- package/src/cli/commands/configure-mcp.ts +54 -0
- package/src/cli/commands/dev.ts +40 -31
- package/src/cli/commands/init.ts +73 -138
- package/src/cli/commands/migrations.ts +22 -0
- package/src/cli/commands/provision.ts +294 -56
- package/src/cli/commands/scaffold.ts +105 -3
- package/src/cli/index.ts +40 -7
- package/src/core/operations/create-model.ts +51 -13
- package/src/core/operations/migration-generator.ts +14 -1
- package/src/core/operations/model-migration.ts +52 -0
- package/src/core/operations/provision-deployment.ts +183 -0
- package/src/core/operations/provision-operations.ts +662 -154
- package/src/core/operations/scaffold-apply.ts +2 -0
- package/src/core/operations/scaffold-machine.ts +1 -0
- package/src/core/operations/scaffold-plan.ts +5 -1
- package/src/core/project/agent-instructions.ts +4 -1
- package/src/core/project/agent-templates/AGENTS.md +89 -6
- package/src/core/project/agent-templates/CLAUDE.md +14 -1
- package/src/core/project/agent-templates/copilot-instructions.md +15 -1
- package/src/core/project/agent-templates/shared-models.instructions.md +11 -3
- package/src/core/project/boundaries.ts +62 -20
- package/src/core/project/capabilities.ts +49 -6
- package/src/core/project/home-page.ts +114 -0
- package/src/core/project/mcp-config.ts +84 -0
- package/src/core/project/react-project.ts +50 -28
- package/src/core/project/state.ts +70 -0
- package/src/core/project/workflows.ts +53 -7
- package/src/core/scaffold/auth-generator.ts +26 -27
- package/src/core/scaffold/model-parser.ts +413 -129
- package/src/core/scaffold/native-schema-generator.ts +319 -103
- package/src/core/scaffold/openapi-generator.ts +63 -5
- package/src/core/scaffold/ui-generator.ts +70 -8
- package/src/core/verify/index.ts +118 -6
- package/src/machine/contracts.ts +1 -0
- package/src/machine/errors.ts +4 -2
- package/src/machine/index.ts +65 -34
- package/src/mcp/index.ts +221 -31
- package/src/mcp/version-selection.ts +163 -0
- package/src/utils/azure-cli.ts +315 -0
- package/src/utils/azure-diagnostics.ts +75 -0
- package/src/utils/package-manager.ts +2 -2
- package/src/utils/python-uv.ts +53 -33
- package/src/utils/react-dev.ts +31 -0
- package/src/utils/semver.ts +59 -0
|
@@ -4,10 +4,144 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.provisionCommand = void 0;
|
|
7
|
+
exports.formatProvisionError = formatProvisionError;
|
|
8
|
+
exports.describeProvisionAction = describeProvisionAction;
|
|
9
|
+
exports.formatProvisionResult = formatProvisionResult;
|
|
10
|
+
exports.createProvisionCommand = createProvisionCommand;
|
|
7
11
|
const commander_1 = require("commander");
|
|
8
12
|
const prompts_1 = __importDefault(require("prompts"));
|
|
9
13
|
const config_1 = require("../../core/config");
|
|
10
14
|
const provision_operations_1 = require("../../core/operations/provision-operations");
|
|
15
|
+
const errors_1 = require("../../machine/errors");
|
|
16
|
+
const azure_diagnostics_1 = require("../../utils/azure-diagnostics");
|
|
17
|
+
const azure_cli_1 = require("../../utils/azure-cli");
|
|
18
|
+
function humanProvisionMessage(message) {
|
|
19
|
+
return message
|
|
20
|
+
.replace(/swallowkit machine inspect provision --plan/g, "swallowkit provision --status")
|
|
21
|
+
.replace(/swallowkit machine apply provision --plan/g, "swallowkit provision --resume")
|
|
22
|
+
.replace(/plan provision/g, "swallowkit provision")
|
|
23
|
+
.replace(/\b[Pp]lan\b/g, "Execution")
|
|
24
|
+
.replace(/preview/g, "deployment preparation")
|
|
25
|
+
.replace(/after approval/g, "")
|
|
26
|
+
.replace(/--approve/g, "")
|
|
27
|
+
.replace(/ {2,}/g, " ");
|
|
28
|
+
}
|
|
29
|
+
function formatProvisionError(error) {
|
|
30
|
+
if (!(error instanceof errors_1.MachineCommandError))
|
|
31
|
+
return error instanceof Error ? error.message : String(error);
|
|
32
|
+
const message = error.code === "azure-deployment-failed" ? error.message : humanProvisionMessage(error.message);
|
|
33
|
+
const lines = [...new Set(message.split("\n"))];
|
|
34
|
+
const details = error.details;
|
|
35
|
+
if (details?.deployment) {
|
|
36
|
+
lines.push(`Deployment: ${details.deployment.reference.name}; state: ${details.deployment.state}`);
|
|
37
|
+
}
|
|
38
|
+
for (const diagnostic of details?.diagnostics ?? []) {
|
|
39
|
+
if (diagnostic.failureKind || diagnostic.outputTruncated)
|
|
40
|
+
lines.push((0, azure_diagnostics_1.formatAzureDiagnostic)(diagnostic));
|
|
41
|
+
}
|
|
42
|
+
const runId = details?.runId;
|
|
43
|
+
if (runId) {
|
|
44
|
+
lines.push(`Check: swallowkit provision --status ${runId}`);
|
|
45
|
+
if (error.code !== "azure-deployment-failed")
|
|
46
|
+
lines.push(`Resume: swallowkit provision --resume ${runId}`);
|
|
47
|
+
else
|
|
48
|
+
lines.push("Azure reported a terminal failure. Resuming only observes that failed deployment; correct its cause before explicitly deploying again.");
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
for (const action of error.nextActions ?? []) {
|
|
52
|
+
const command = humanProvisionMessage(action.command);
|
|
53
|
+
if (!command.includes("machine "))
|
|
54
|
+
lines.push(command);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return lines.join("\n");
|
|
58
|
+
}
|
|
59
|
+
async function printProvisionSetup(result) {
|
|
60
|
+
if (!result.deployment || result.status !== "complete")
|
|
61
|
+
return;
|
|
62
|
+
const reference = result.deployment.reference;
|
|
63
|
+
const fields = ["staticWebAppName", "staticWebAppUrl", "functionsAppName", "functionsAppUrl", "cosmosDbAccountName", "cosmosDatabaseName"];
|
|
64
|
+
let outputs;
|
|
65
|
+
try {
|
|
66
|
+
const response = await (0, azure_cli_1.runAzCliAsync)([
|
|
67
|
+
"deployment",
|
|
68
|
+
"group",
|
|
69
|
+
"show",
|
|
70
|
+
"--name",
|
|
71
|
+
reference.name.startsWith("swallowkit-migration-") ? "swallowkit-baseline" : reference.name,
|
|
72
|
+
"--resource-group",
|
|
73
|
+
reference.resourceGroup,
|
|
74
|
+
"--subscription",
|
|
75
|
+
reference.subscription,
|
|
76
|
+
"--query",
|
|
77
|
+
`{${fields.map((field) => `${field}:properties.outputs.${field}.value`).join(",")}}`,
|
|
78
|
+
"-o",
|
|
79
|
+
"json",
|
|
80
|
+
], { timeout: 30000 });
|
|
81
|
+
if (response.status !== 0 || response.failureKind || response.stdoutTruncated)
|
|
82
|
+
throw new Error("Output query did not complete.");
|
|
83
|
+
const parsed = JSON.parse(response.stdout);
|
|
84
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
85
|
+
throw new Error("Invalid resource output.");
|
|
86
|
+
outputs = parsed;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
console.warn("Deployment succeeded, but resource information could not be read. Inspect the deployment's named outputs in Azure Portal; do not redeploy just to retrieve them.");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
console.log("\nResource information:");
|
|
93
|
+
for (const field of fields) {
|
|
94
|
+
if (typeof outputs[field] === "string")
|
|
95
|
+
console.log(` ${field}: ${outputs[field]}`);
|
|
96
|
+
}
|
|
97
|
+
const swaName = typeof outputs.staticWebAppName === "string" ? outputs.staticWebAppName : "<swa-name>";
|
|
98
|
+
const functionsAppName = typeof outputs.functionsAppName === "string" ? outputs.functionsAppName : "<functions-app-name>";
|
|
99
|
+
const target = ["--resource-group", reference.resourceGroup, "--subscription", reference.subscription];
|
|
100
|
+
const swaTokenArgs = ["staticwebapp", "secrets", "list", "--name", swaName, ...target, "--query", "properties.apiKey", "-o", "tsv"];
|
|
101
|
+
const publishProfileArgs = ["webapp", "deployment", "list-publishing-profiles", "--name", functionsAppName, ...target, "--xml"];
|
|
102
|
+
console.log("\nCI/CD settings (save these as secrets in GitHub Actions or Azure Pipelines):\n");
|
|
103
|
+
console.log(" [AZURE_STATIC_WEB_APPS_API_TOKEN]");
|
|
104
|
+
console.log(await readCiCdSecret(swaTokenArgs, typeof outputs.staticWebAppName === "string"));
|
|
105
|
+
console.log(" [AZURE_FUNCTIONAPP_NAME]");
|
|
106
|
+
console.log(` ${functionsAppName}\n`);
|
|
107
|
+
console.log(" [AZURE_FUNCTIONAPP_PUBLISH_PROFILE]");
|
|
108
|
+
console.log(await readCiCdSecret(publishProfileArgs, typeof outputs.functionsAppName === "string"));
|
|
109
|
+
console.log(" These values are shown only in this terminal; SwallowKit does not store them. Treat them as secrets.");
|
|
110
|
+
console.log(" Next: configure your CI/CD pipeline and manually trigger the first deployment (later pushes deploy automatically).");
|
|
111
|
+
}
|
|
112
|
+
// Reads a CI/CD credential for display in the human terminal only. The value is
|
|
113
|
+
// never written to checkpoints, the ledger, or machine/MCP responses.
|
|
114
|
+
async function readCiCdSecret(args, resourceKnown) {
|
|
115
|
+
const manual = ` Run manually: az ${args.map((arg) => (/[\s"]/.test(arg) ? `"${arg}"` : arg)).join(" ")}\n`;
|
|
116
|
+
if (!resourceKnown)
|
|
117
|
+
return ` ⚠️ The resource name was not in the deployment outputs.\n${manual}`;
|
|
118
|
+
try {
|
|
119
|
+
const response = await (0, azure_cli_1.runAzCliAsync)(args, { timeout: 60000 });
|
|
120
|
+
const value = response.stdout.trim();
|
|
121
|
+
if (response.status === 0 && !response.failureKind && !response.stdoutTruncated && value)
|
|
122
|
+
return ` ${value}\n`;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Fall through to the manual command; deployment itself already succeeded.
|
|
126
|
+
}
|
|
127
|
+
return ` ⚠️ Could not retrieve automatically.\n${manual}`;
|
|
128
|
+
}
|
|
129
|
+
function describeProvisionAction(plan) {
|
|
130
|
+
switch (plan.mode) {
|
|
131
|
+
case "bootstrap":
|
|
132
|
+
return `Resource group ${plan.resourceGroup} does not exist yet. It will be created in ${plan.location} and the infrastructure in infra/main.bicep will be deployed.`;
|
|
133
|
+
case "migrate":
|
|
134
|
+
return `${plan.pendingMigrations.length} infrastructure migration(s) will be deployed to ${plan.resourceGroup}: ${plan.pendingMigrations.map((migration) => `${migration.version}-${migration.slug}`).join(", ")}.`;
|
|
135
|
+
case "adopt":
|
|
136
|
+
return `The existing resource group ${plan.resourceGroup} will be recorded as SwallowKit baseline 0. Nothing will be deployed.`;
|
|
137
|
+
case "reconcile":
|
|
138
|
+
return `infra/main.bicep will be redeployed to ${plan.resourceGroup}. Template-managed settings may be reset.`;
|
|
139
|
+
case "recover":
|
|
140
|
+
return `The existing baseline deployment in ${plan.resourceGroup} will be observed and its migration tag/ledger completed after Azure Succeeded. Bicep will not be submitted again.`;
|
|
141
|
+
default:
|
|
142
|
+
return `Resource group ${plan.resourceGroup}:`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
11
145
|
const PRIMARY_REGIONS = [
|
|
12
146
|
{ title: "Japan East (japaneast)", value: "japaneast" },
|
|
13
147
|
{ title: "Japan West (japanwest)", value: "japanwest" },
|
|
@@ -26,6 +160,39 @@ const SWA_REGIONS = [
|
|
|
26
160
|
{ title: "East US 2 (eastus2)", value: "eastus2" },
|
|
27
161
|
{ title: "West Europe (westeurope)", value: "westeurope" },
|
|
28
162
|
];
|
|
163
|
+
function formatProvisionResult(result) {
|
|
164
|
+
const outcome = result.outcome === "succeeded"
|
|
165
|
+
? "✅ Provisioning completed, including migration tags and the local ledger."
|
|
166
|
+
: result.outcome === "in-progress"
|
|
167
|
+
? "⏳ Azure deployment is still in progress. The local wait ended; this is not an Azure failure."
|
|
168
|
+
: result.outcome === "partial"
|
|
169
|
+
? "⚠️ Provisioning is partially complete. Finish migration bookkeeping from the checkpoint; do not redeploy the baseline."
|
|
170
|
+
: result.outcome === "failed"
|
|
171
|
+
? "❌ Azure deployment reached a failed/cancelled terminal state."
|
|
172
|
+
: "⚠️ Azure deployment result is unknown. A local az interruption does not prove an Azure failure.";
|
|
173
|
+
const lines = [outcome, `Resource group: ${result.resourceGroup}`];
|
|
174
|
+
if (result.deployment) {
|
|
175
|
+
const reference = result.deployment.reference;
|
|
176
|
+
lines.push(`Deployment: ${reference.name}; subscription: ${reference.subscription}; state: ${result.deployment.state}${reference.id ? `; ID: ${reference.id}` : ""}`);
|
|
177
|
+
for (const error of result.deployment.errors)
|
|
178
|
+
lines.push(`${error.code}: ${error.message}`);
|
|
179
|
+
}
|
|
180
|
+
for (const warning of result.warnings)
|
|
181
|
+
lines.push(`Warning: ${humanProvisionMessage(warning)}`);
|
|
182
|
+
for (const diagnostic of result.diagnostics.filter((entry) => entry.failureKind || entry.outputTruncated)) {
|
|
183
|
+
lines.push((0, azure_diagnostics_1.formatAzureDiagnostic)(diagnostic));
|
|
184
|
+
}
|
|
185
|
+
if (result.status !== "complete") {
|
|
186
|
+
lines.push(`Check status: swallowkit provision --status ${result.runId}`);
|
|
187
|
+
if (result.outcome !== "failed")
|
|
188
|
+
lines.push(`Resume and wait until completion: swallowkit provision --resume ${result.runId}`);
|
|
189
|
+
if (result.outcome !== "failed")
|
|
190
|
+
lines.push("Azure may continue after Ctrl+C or process termination. No Azure cancellation or deletion is performed.");
|
|
191
|
+
else
|
|
192
|
+
lines.push("Azure reported a terminal failure. Correct its cause before explicitly deploying again; resuming does not repair a failed deployment.");
|
|
193
|
+
}
|
|
194
|
+
return lines.join("\n");
|
|
195
|
+
}
|
|
29
196
|
async function resolveLocations(options) {
|
|
30
197
|
if (options.location && options.swaLocation) {
|
|
31
198
|
return { location: options.location, swaLocation: options.swaLocation };
|
|
@@ -55,60 +222,116 @@ async function resolveLocations(options) {
|
|
|
55
222
|
throw new Error("Region selection cancelled.");
|
|
56
223
|
return { location, swaLocation };
|
|
57
224
|
}
|
|
58
|
-
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
225
|
+
function createProvisionCommand() {
|
|
226
|
+
return new commander_1.Command("provision")
|
|
227
|
+
.description("Deploy Azure infrastructure and show resource information and CI/CD setup")
|
|
228
|
+
.option("-g, --resource-group <name>", "Resource group name (required for deployment)")
|
|
229
|
+
.option("--subscription <id>", "Azure subscription ID")
|
|
230
|
+
.option("--location <region>", "Primary location for Functions and Cosmos DB")
|
|
231
|
+
.option("--swa-location <region>", "Static Web App location")
|
|
232
|
+
.option("--what-if", "Check Azure what-if before deployment", false)
|
|
233
|
+
.option("--adopt-existing", "Adopt an existing untagged resource group without deploying main.bicep", false)
|
|
234
|
+
.option("--baseline <version>", "Baseline version for adoption (currently 0)")
|
|
235
|
+
.option("--reconcile", "Explicitly redeploy infra/main.bicep", false)
|
|
236
|
+
.addOption(new commander_1.Option("--approve", "Compatibility option; invoking provision already requests execution").hideHelp())
|
|
237
|
+
.option("--status <runId>", "Read an existing execution checkpoint and Azure deployment state without writes")
|
|
238
|
+
.option("--resume <runId>", "Continue the original execution without resubmitting attempted deployments")
|
|
239
|
+
.option("--resume-deployment <name>", "Recover an older untracked baseline deployment after verifying its template and parameters")
|
|
240
|
+
.addOption(new commander_1.Option("--wait-seconds <seconds>", "Optional limit on waiting, 0-3600 seconds (default: wait until Azure finishes; status: 0)").hideHelp())
|
|
241
|
+
.action(async (options) => {
|
|
242
|
+
try {
|
|
243
|
+
(0, config_1.ensureSwallowKitProject)("provision");
|
|
244
|
+
const waitSeconds = options.waitSeconds === undefined ? undefined : Number(options.waitSeconds);
|
|
245
|
+
if ((options.resume && options.status) ||
|
|
246
|
+
((options.resume || options.status) &&
|
|
247
|
+
(options.resourceGroup ||
|
|
248
|
+
options.resumeDeployment ||
|
|
249
|
+
options.reconcile ||
|
|
250
|
+
options.adoptExisting ||
|
|
251
|
+
options.subscription ||
|
|
252
|
+
options.location ||
|
|
253
|
+
options.swaLocation ||
|
|
254
|
+
options.whatIf ||
|
|
255
|
+
options.baseline !== undefined))) {
|
|
256
|
+
throw new errors_1.MachineCommandError("invalid-arguments", "Use --status or --resume with the checkpoint ID alone; its original Azure target and reviewed files are preserved.", undefined, "blocked");
|
|
257
|
+
}
|
|
258
|
+
if (options.status) {
|
|
259
|
+
const result = await (0, provision_operations_1.inspectProvisionOperation)({
|
|
260
|
+
planId: options.status,
|
|
261
|
+
waitSeconds,
|
|
262
|
+
});
|
|
263
|
+
console.log(formatProvisionResult(result));
|
|
264
|
+
if (result.status === "blocked" || result.status === "failed")
|
|
265
|
+
process.exitCode = 1;
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (options.resume) {
|
|
269
|
+
const result = await (0, provision_operations_1.applyProvisionOperation)({
|
|
270
|
+
planId: options.resume,
|
|
271
|
+
approve: true,
|
|
272
|
+
waitSeconds,
|
|
273
|
+
waitUntilComplete: waitSeconds === undefined,
|
|
274
|
+
});
|
|
275
|
+
console.log(formatProvisionResult(result));
|
|
276
|
+
await printProvisionSetup(result);
|
|
277
|
+
if (result.status === "blocked" || result.status === "failed")
|
|
278
|
+
process.exitCode = 1;
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (!options.resourceGroup)
|
|
282
|
+
throw new errors_1.MachineCommandError("invalid-arguments", "Provision requires --resource-group.", undefined, "blocked");
|
|
283
|
+
const locations = await resolveLocations(options);
|
|
284
|
+
const baseline = options.baseline === undefined ? undefined : Number(options.baseline);
|
|
285
|
+
// Preview in memory: the same Azure checks as the agent workflow, but no saved plan file.
|
|
286
|
+
const preview = await (0, provision_operations_1.planProvisionOperation)({
|
|
287
|
+
resourceGroup: options.resourceGroup,
|
|
288
|
+
subscription: options.subscription,
|
|
289
|
+
location: locations.location,
|
|
290
|
+
swaLocation: locations.swaLocation,
|
|
291
|
+
whatIf: options.whatIf,
|
|
292
|
+
adoptExisting: options.adoptExisting,
|
|
293
|
+
baseline,
|
|
294
|
+
reconcile: options.reconcile,
|
|
295
|
+
resumeDeployment: options.resumeDeployment,
|
|
296
|
+
}, { persist: false });
|
|
297
|
+
for (const warning of preview.warnings)
|
|
298
|
+
console.warn(`Warning: ${warning}`);
|
|
299
|
+
if (preview.mode === "offline") {
|
|
300
|
+
console.log([
|
|
301
|
+
"",
|
|
302
|
+
"❌ Azure CLI is unavailable, so the current state of Azure could not be checked. Nothing was changed in Azure.",
|
|
303
|
+
" 1. Make sure `az --version` works in this terminal (install: https://aka.ms/azure-cli).",
|
|
304
|
+
" 2. Sign in with `az login` (and `az account set --subscription <id>` if needed).",
|
|
305
|
+
" 3. Run this command again.",
|
|
306
|
+
].join("\n"));
|
|
307
|
+
process.exitCode = 1;
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (preview.mode === "adoption-required") {
|
|
311
|
+
throw new Error("The existing resource group has no migration tag. For an interrupted baseline use --resume-deployment <original-name> to verify/observe it without redeploying. Legacy adoption applies only to a legacy manifest; do not replace an existing manifest.");
|
|
312
|
+
}
|
|
313
|
+
if (preview.mode === "noop") {
|
|
314
|
+
console.log(`Resource group ${preview.resourceGroup} is already up to date. Nothing to do.`);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
console.log(`\n${describeProvisionAction(preview)}`);
|
|
318
|
+
console.log("Deploying Azure infrastructure. Azure resources may incur charges.");
|
|
319
|
+
console.log("Waiting for the Azure deployment to finish. This often takes 10-20 minutes; resource information and CI/CD settings are shown when it completes.");
|
|
320
|
+
const result = await (0, provision_operations_1.executeProvisionPlan)(preview, {
|
|
321
|
+
approve: true,
|
|
322
|
+
retryHint: provision_operations_1.INTERACTIVE_PROVISION_RETRY_HINT,
|
|
323
|
+
waitSeconds,
|
|
324
|
+
waitUntilComplete: waitSeconds === undefined,
|
|
325
|
+
});
|
|
326
|
+
console.log(formatProvisionResult(result));
|
|
327
|
+
await printProvisionSetup(result);
|
|
328
|
+
if (result.status === "blocked" || result.status === "failed")
|
|
329
|
+
process.exitCode = 1;
|
|
98
330
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
approved = answer.approved === true;
|
|
106
|
-
}
|
|
107
|
-
if (!approved) {
|
|
108
|
-
console.log("Provision cancelled.");
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const result = await (0, provision_operations_1.applyProvisionOperation)({ planId: plan.planId, approve: true });
|
|
112
|
-
console.log(`Provision completed (${plan.mode}). ${result.executedCommands.length} command(s) executed.`);
|
|
113
|
-
});
|
|
331
|
+
catch (error) {
|
|
332
|
+
throw new Error(formatProvisionError(error));
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
exports.provisionCommand = createProvisionCommand();
|
|
114
337
|
//# sourceMappingURL=provision.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provision.js","sourceRoot":"","sources":["../../../src/cli/commands/provision.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"provision.js","sourceRoot":"","sources":["../../../src/cli/commands/provision.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,12 @@ interface ScaffoldOptions {
|
|
|
11
11
|
functionsDir?: string;
|
|
12
12
|
apiDir?: string;
|
|
13
13
|
apiOnly?: boolean;
|
|
14
|
+
skipInfra?: boolean;
|
|
14
15
|
expectedSchemaAnalysis?: SchemaAnalysisSnapshot;
|
|
15
16
|
}
|
|
17
|
+
export declare function buildInfraSkippedWarning(modelName: string, modelArgument: string): string;
|
|
18
|
+
/** Warn when a model looks per-user (partition key or owner-like id field) but no authentication is configured. */
|
|
19
|
+
export declare function buildUserScopedDataWarning(modelInfo: ModelInfo, authConfig: AuthConfig | undefined): string | undefined;
|
|
16
20
|
export declare function scaffoldCommand(options: ScaffoldOptions): Promise<void>;
|
|
17
21
|
/**
|
|
18
22
|
* モデルの authPolicy と auth config から実効的な認可ポリシーを解決
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scaffold.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,SAAS,EAA4C,MAAM,kCAAkC,CAAC;AAgBvG,OAAO,EAOL,aAAa,EACd,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAML,eAAe,EACf,UAAU,EACX,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,oBAAoB,EAEpB,sBAAsB,EACvB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scaffold.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,SAAS,EAA4C,MAAM,kCAAkC,CAAC;AAgBvG,OAAO,EAOL,aAAa,EACd,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAML,eAAe,EACf,UAAU,EACX,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,oBAAoB,EAEpB,sBAAsB,EACvB,MAAM,oCAAoC,CAAC;AAO5C,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzF;AASD,mHAAmH;AACnH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUvH;AAsBD,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,iBAkM7D;AAyBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CA6DvH;AAsBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA4C3D;AAqID,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,GAAG,aAAa,CAYlG;AA4VD;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,GAAE,oBAAyD,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/I;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,oBAAyD,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C1M"}
|
|
@@ -37,6 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
};
|
|
38
38
|
})();
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.buildInfraSkippedWarning = buildInfraSkippedWarning;
|
|
41
|
+
exports.buildUserScopedDataWarning = buildUserScopedDataWarning;
|
|
40
42
|
exports.scaffoldCommand = scaffoldCommand;
|
|
41
43
|
exports.resolveAuthPolicy = resolveAuthPolicy;
|
|
42
44
|
exports.resolveModelPath = resolveModelPath;
|
|
@@ -62,7 +64,32 @@ const auth_generator_1 = require("../../core/scaffold/auth-generator");
|
|
|
62
64
|
const file_session_1 = require("../../core/operations/file-session");
|
|
63
65
|
const migration_generator_1 = require("../../core/operations/migration-generator");
|
|
64
66
|
const artifacts_1 = require("../../core/project/artifacts");
|
|
67
|
+
const create_model_1 = require("../../core/operations/create-model");
|
|
65
68
|
const SCAFFOLD_GENERATOR = "scaffold";
|
|
69
|
+
function buildInfraSkippedWarning(modelName, modelArgument) {
|
|
70
|
+
return `infra-skipped: The Cosmos DB container migration for ${modelName} was not generated (--skip-infra); infra/ was left unchanged. ` +
|
|
71
|
+
`Generate it later with "swallowkit migrations add-model ${modelArgument}", or re-plan scaffold without --skip-infra.`;
|
|
72
|
+
}
|
|
73
|
+
const USER_SCOPE_FIELD = /^(user|owner|learner|member|account|customer|student|author|creator|profile|person|employee|patient)Id$/i;
|
|
74
|
+
function isAuthenticationConfigured(authConfig) {
|
|
75
|
+
if (!authConfig || authConfig.provider === "none")
|
|
76
|
+
return false;
|
|
77
|
+
return Boolean(authConfig.provider) || Object.keys(authConfig.schemes ?? {}).length > 0;
|
|
78
|
+
}
|
|
79
|
+
/** Warn when a model looks per-user (partition key or owner-like id field) but no authentication is configured. */
|
|
80
|
+
function buildUserScopedDataWarning(modelInfo, authConfig) {
|
|
81
|
+
if (isAuthenticationConfigured(authConfig))
|
|
82
|
+
return undefined;
|
|
83
|
+
const partitionField = modelInfo.partitionKey.replace(/^\//, "");
|
|
84
|
+
const fieldNames = modelInfo.fields.filter((field) => field.type === "string" && !field.isArray).map((field) => field.name);
|
|
85
|
+
const ownerField = [partitionField, ...fieldNames].find((name) => USER_SCOPE_FIELD.test(name) && fieldNames.includes(name));
|
|
86
|
+
if (!ownerField)
|
|
87
|
+
return undefined;
|
|
88
|
+
const reason = ownerField === partitionField ? `is the partition key and looks like a per-user owner id` : `looks like a per-user owner id`;
|
|
89
|
+
return `user-scoped-data-without-auth: ${modelInfo.name}.${ownerField} ${reason}, but authentication is not configured. ` +
|
|
90
|
+
`Generated CRUD does not scope data to a principal, so any caller can read and write every ${modelInfo.name} document. ` +
|
|
91
|
+
`Add authentication with "plan auth", restrict or remove the generated write endpoints, and add ai-authored endpoints that derive ${ownerField} from the verified principal instead of the request body.`;
|
|
92
|
+
}
|
|
66
93
|
function getMachineAwareStdio() {
|
|
67
94
|
return process.env.SWALLOWKIT_MACHINE_OUTPUT === "1" ? "pipe" : "inherit";
|
|
68
95
|
}
|
|
@@ -116,6 +143,16 @@ async function scaffoldCommand(options) {
|
|
|
116
143
|
}
|
|
117
144
|
session.setSchemaAnalysis(schemaAnalysis);
|
|
118
145
|
console.log(`✅ Model parsed: ${modelInfo.name} (${modelInfo.schemaName})`);
|
|
146
|
+
// Validate policy prerequisites before any generated artifacts are written.
|
|
147
|
+
resolveAuthPolicy(modelInfo, (0, config_1.getAuthConfig)());
|
|
148
|
+
for (const configName of ["swallowkit.config.js", "swallowkit.config.json", ".swallowkitrc.json"]) {
|
|
149
|
+
session.registerInput(path.join(process.cwd(), configName));
|
|
150
|
+
}
|
|
151
|
+
const userScopeWarning = buildUserScopedDataWarning(modelInfo, (0, config_1.getAuthConfig)());
|
|
152
|
+
if (userScopeWarning) {
|
|
153
|
+
session.addWarning(userScopeWarning);
|
|
154
|
+
console.warn(`⚠️ ${userScopeWarning}`);
|
|
155
|
+
}
|
|
119
156
|
const backendLanguage = (0, config_1.getBackendLanguage)();
|
|
120
157
|
const frontend = (0, config_1.getFrontendFramework)();
|
|
121
158
|
const apiDir = options.apiDir || (frontend === "react" ? "bff" : "app/api");
|
|
@@ -155,6 +192,7 @@ async function scaffoldCommand(options) {
|
|
|
155
192
|
if (options.apiOnly) {
|
|
156
193
|
console.log("ℹ️ --api-only skips UI generation only; Functions, BFF routes, OpenAPI, and native schema assets are still updated.");
|
|
157
194
|
}
|
|
195
|
+
(0, create_model_1.updateSharedIndex)(modelPath, modelInfo.schemaName, session);
|
|
158
196
|
// 5. Generate BFF callFunction helper
|
|
159
197
|
await generateCallFunctionHelper(session, apiDir);
|
|
160
198
|
// 6. Generate Azure Functions code
|
|
@@ -179,9 +217,16 @@ async function scaffoldCommand(options) {
|
|
|
179
217
|
else {
|
|
180
218
|
await generateBFFRoutes(modelInfo, apiDir, sharedPackageName, session);
|
|
181
219
|
}
|
|
182
|
-
// 8. Generate Cosmos DB container Bicep file (skip for connector models)
|
|
220
|
+
// 8. Generate Cosmos DB container Bicep file (skip for connector models or when infra changes are excluded)
|
|
183
221
|
if (!isConnectorModel) {
|
|
184
|
-
|
|
222
|
+
if (options.skipInfra) {
|
|
223
|
+
const warning = buildInfraSkippedWarning(modelInfo.name, (0, model_parser_1.toKebabCase)(modelInfo.name));
|
|
224
|
+
session.addWarning(warning);
|
|
225
|
+
console.warn(`\n⚠️ ${warning}`);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
await generateCosmosContainer(modelInfo, session);
|
|
229
|
+
}
|
|
185
230
|
}
|
|
186
231
|
// 9. Generate UI components (unless --api-only)
|
|
187
232
|
if (!options.apiOnly) {
|
|
@@ -254,11 +299,32 @@ function applyExternalTokenFetchToGeneratedUi(modelInfo, session, importPath = '
|
|
|
254
299
|
function resolveAuthPolicy(modelInfo, authConfig) {
|
|
255
300
|
// モデルに明示的な authPolicy がある場合はそれを使用
|
|
256
301
|
if (modelInfo.authPolicy) {
|
|
302
|
+
if (!isAuthenticationConfigured(authConfig)) {
|
|
303
|
+
throw new errors_1.MachineCommandError("auth-policy-without-auth", `Model '${modelInfo.name}' declares authPolicy, but authentication is not configured. No artifacts were written. Run plan auth and apply auth before scaffolding this model.`, { model: modelInfo.name }, "blocked", [{
|
|
304
|
+
command: "swallowkit machine plan auth --provider <custom-jwt|swa|external-token>",
|
|
305
|
+
description: "Choose an authentication provider, review and apply its plan, then re-plan scaffold.",
|
|
306
|
+
}]);
|
|
307
|
+
}
|
|
257
308
|
const normalized = (0, config_1.normalizeAuthConfig)(authConfig);
|
|
309
|
+
const usesNamedPolicy = Boolean(modelInfo.authPolicy.policy ||
|
|
310
|
+
typeof modelInfo.authPolicy.read === "string" || typeof modelInfo.authPolicy.write === "string");
|
|
311
|
+
// Guards resolve each operation independently: a string selects the named router, an array (or
|
|
312
|
+
// the roles fallback) selects the single-provider helper. Named schemes only have the router.
|
|
313
|
+
const operationIsNamed = (selected) => typeof selected === "string" || (selected === undefined && Boolean(modelInfo.authPolicy.policy));
|
|
314
|
+
const everyOperationNamed = operationIsNamed(modelInfo.authPolicy.read) && operationIsNamed(modelInfo.authPolicy.write) &&
|
|
315
|
+
!modelInfo.authPolicy.roles;
|
|
316
|
+
if (authConfig?.schemes && !authConfig.provider && !everyOperationNamed) {
|
|
317
|
+
throw new errors_1.MachineCommandError("auth-policy-requires-named-policy", `Model '${modelInfo.name}' declares an authPolicy whose read or write operation does not resolve to a named policy, but authentication uses named schemes. Use authPolicy = { policy: '<name>' } or name both read and write policies (role arrays are not supported with named schemes); no artifacts were written.`, { model: modelInfo.name }, "blocked", [{
|
|
318
|
+
command: "swallowkit machine inspect capabilities",
|
|
319
|
+
description: "Define a named authorization policy selecting the required schemes/roles, reference it from the model, then re-plan scaffold.",
|
|
320
|
+
}]);
|
|
321
|
+
}
|
|
258
322
|
for (const policyName of [modelInfo.authPolicy.policy, typeof modelInfo.authPolicy.read === 'string' ? modelInfo.authPolicy.read : undefined, typeof modelInfo.authPolicy.write === 'string' ? modelInfo.authPolicy.write : undefined].filter((value) => Boolean(value))) {
|
|
259
323
|
if (!normalized?.authorization.policies[policyName])
|
|
260
324
|
throw new Error(`Model '${modelInfo.name}' references undefined auth policy '${policyName}'. Define auth.authorization.policies.${policyName}.`);
|
|
261
325
|
}
|
|
326
|
+
if (usesNamedPolicy)
|
|
327
|
+
assertNamedSchemesConfigured(modelInfo.name, "authPolicy", authConfig);
|
|
262
328
|
return modelInfo.authPolicy;
|
|
263
329
|
}
|
|
264
330
|
// auth 設定がない場合はガードなし
|
|
@@ -270,11 +336,27 @@ function resolveAuthPolicy(modelInfo, authConfig) {
|
|
|
270
336
|
if (defaultPolicy === 'authenticated') {
|
|
271
337
|
return {}; // 空のポリシー = 認証のみ、ロール制限なし
|
|
272
338
|
}
|
|
273
|
-
if (defaultPolicy !== 'anonymous')
|
|
339
|
+
if (defaultPolicy !== 'anonymous') {
|
|
340
|
+
assertNamedSchemesConfigured(modelInfo.name, `auth.authorization.defaultPolicy '${defaultPolicy}'`, authConfig);
|
|
274
341
|
return { policy: defaultPolicy };
|
|
342
|
+
}
|
|
275
343
|
// defaultPolicy が 'anonymous' なら認証不要
|
|
276
344
|
return undefined;
|
|
277
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Named authorization policies are enforced by the generated multi-scheme router and scheme-specific
|
|
348
|
+
* client contexts, which exist only for named auth.schemes. A single-provider configuration
|
|
349
|
+
* (auth.provider) has no router, so referencing a named policy would generate code that cannot build.
|
|
350
|
+
*/
|
|
351
|
+
function assertNamedSchemesConfigured(modelName, source, authConfig) {
|
|
352
|
+
if (Object.keys(authConfig?.schemes ?? {}).some((name) => name !== "default"))
|
|
353
|
+
return;
|
|
354
|
+
throw new errors_1.MachineCommandError("auth-named-policy-requires-named-scheme", `Model '${modelName}' uses a named authorization policy via ${source}, but authentication is configured with a single auth.provider. ` +
|
|
355
|
+
`Named policies require named auth.schemes; no artifacts were written. Use role lists (authPolicy = { roles: [...] } or read/write role arrays) with auth.provider, or add a named scheme.`, { model: modelName, source }, "blocked", [{
|
|
356
|
+
command: "swallowkit machine plan auth --provider <swa|external-token|custom-jwt> --scheme <name>",
|
|
357
|
+
description: "Add a named scheme and reference it from auth.authorization.policies, or switch the model to role lists; then re-plan scaffold.",
|
|
358
|
+
}]);
|
|
359
|
+
}
|
|
278
360
|
/**
|
|
279
361
|
* モデルファイルのパスを解決
|
|
280
362
|
*/
|