swallowkit 1.1.2 → 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 +61 -7
- package/README.md +61 -7
- package/dist/cli/commands/add-auth.d.ts.map +1 -1
- package/dist/cli/commands/add-auth.js +103 -27
- 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 +5 -2
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +143 -67
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/init.d.ts +14 -7
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +149 -170
- 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 +5 -1
- package/dist/cli/commands/scaffold.d.ts.map +1 -1
- package/dist/cli/commands/scaffold.js +123 -18
- 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 +49 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/core/config.d.ts +2 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +19 -0
- package/dist/core/config.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 +2 -1
- package/dist/core/project/agent-instructions.d.ts.map +1 -1
- package/dist/core/project/agent-instructions.js +15 -0
- 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 +17 -0
- package/dist/core/project/capabilities.d.ts.map +1 -1
- package/dist/core/project/capabilities.js +45 -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/manifest.d.ts +3 -1
- package/dist/core/project/manifest.d.ts.map +1 -1
- package/dist/core/project/manifest.js +47 -25
- package/dist/core/project/manifest.js.map +1 -1
- 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 +26 -0
- package/dist/core/project/react-project.d.ts.map +1 -0
- package/dist/core/project/react-project.js +443 -0
- package/dist/core/project/react-project.js.map +1 -0
- 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/validation.d.ts.map +1 -1
- package/dist/core/project/validation.js +32 -10
- package/dist/core/project/validation.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/react-bff-generator.d.ts +10 -0
- package/dist/core/scaffold/react-bff-generator.d.ts.map +1 -0
- package/dist/core/scaffold/react-bff-generator.js +252 -0
- package/dist/core/scaffold/react-bff-generator.js.map +1 -0
- package/dist/core/scaffold/react-ui-generator.d.ts +6 -0
- package/dist/core/scaffold/react-ui-generator.d.ts.map +1 -0
- package/dist/core/scaffold/react-ui-generator.js +41 -0
- package/dist/core/scaffold/react-ui-generator.js.map +1 -0
- 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/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/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 +61 -30
- 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/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- 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.d.ts +2 -2
- package/dist/utils/package-manager.d.ts.map +1 -1
- package/dist/utils/package-manager.js +6 -3
- 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 +7 -4
- package/src/__tests__/__snapshots__/boundaries.test.ts.snap +154 -0
- package/src/__tests__/agent-instructions.test.ts +6 -1
- 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 +145 -5
- 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 +838 -0
- package/src/__tests__/release-metadata.test.ts +121 -0
- package/src/__tests__/schema-analysis.test.ts +329 -0
- package/src/cli/commands/add-auth.ts +103 -29
- package/src/cli/commands/configure-mcp.ts +54 -0
- package/src/cli/commands/dev.ts +145 -73
- package/src/cli/commands/init.ts +147 -172
- package/src/cli/commands/migrations.ts +22 -0
- package/src/cli/commands/provision.ts +294 -56
- package/src/cli/commands/scaffold.ts +145 -22
- package/src/cli/index.ts +46 -10
- package/src/core/config.ts +21 -1
- 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 +17 -1
- package/src/core/project/agent-templates/AGENTS.md +113 -15
- package/src/core/project/agent-templates/CLAUDE.md +14 -1
- package/src/core/project/agent-templates/bff-routes.instructions.md +5 -3
- 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 +63 -6
- package/src/core/project/home-page.ts +114 -0
- package/src/core/project/manifest.ts +52 -27
- package/src/core/project/mcp-config.ts +84 -0
- package/src/core/project/react-project.ts +529 -0
- package/src/core/project/state.ts +70 -0
- package/src/core/project/validation.ts +32 -10
- 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/react-bff-generator.ts +292 -0
- package/src/core/scaffold/react-ui-generator.ts +51 -0
- package/src/core/scaffold/ui-generator.ts +70 -8
- package/src/core/verify/index.ts +118 -6
- package/src/index.ts +3 -1
- package/src/machine/contracts.ts +1 -0
- package/src/machine/errors.ts +4 -2
- package/src/machine/index.ts +67 -36
- package/src/mcp/index.ts +221 -31
- package/src/mcp/version-selection.ts +163 -0
- package/src/types/index.ts +4 -0
- package/src/utils/azure-cli.ts +315 -0
- package/src/utils/azure-diagnostics.ts +75 -0
- package/src/utils/package-manager.ts +7 -4
- package/src/utils/python-uv.ts +53 -33
- package/src/utils/react-dev.ts +31 -0
- package/src/utils/semver.ts +59 -0
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
import * as fs from "fs";
|
|
7
7
|
import * as path from "path";
|
|
8
|
-
import { ensureSwallowKitProject, getBackendLanguage, getConnectorDefinition, getValidatedFullConfig } from "../../core/config";
|
|
9
|
-
import {
|
|
8
|
+
import { ensureSwallowKitProject, getBackendLanguage, getFrontendFramework, getConnectorDefinition, getValidatedFullConfig } from "../../core/config";
|
|
9
|
+
import { generateManagedFunctionConfig, generateReactAuthBff, generateReactBffHelper } from "../../core/scaffold/react-bff-generator";
|
|
10
|
+
import { adaptReactPage } from "../../core/scaffold/react-ui-generator";
|
|
11
|
+
import { AuthConfig, AuthProvider, BackendLanguage, CustomJwtConfig, RdbConnectorConfig } from "../../types";
|
|
10
12
|
import {
|
|
11
13
|
generateAuthModels,
|
|
12
14
|
generateAuthFunctionsTS,
|
|
@@ -98,6 +100,32 @@ function defaultCustomJwtConfig(): CustomJwtConfig {
|
|
|
98
100
|
};
|
|
99
101
|
}
|
|
100
102
|
|
|
103
|
+
function writeCallFunction(cwd: string, session: FileOperationSession, nextSource: string, auth: AuthConfig): void {
|
|
104
|
+
if (getFrontendFramework() === "react") {
|
|
105
|
+
const name = JSON.parse(session.readFile(path.join(cwd, "package.json"))).name;
|
|
106
|
+
session.writeFile(path.join(cwd, "bff", "src", "lib", "call-function.ts"), generateReactBffHelper(name, auth), managedMeta);
|
|
107
|
+
} else {
|
|
108
|
+
session.writeFile(path.join(cwd, "lib", "api", "call-function.ts"), nextSource, managedMeta);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function writeLoginPage(cwd: string, session: FileOperationSession, source: string): void {
|
|
113
|
+
const react = getFrontendFramework() === "react";
|
|
114
|
+
const destination = react ? path.join(cwd, "src", "pages", "login.tsx") : path.join(cwd, "app", "login", "page.tsx");
|
|
115
|
+
session.writeFile(destination, react ? adaptReactPage(source) : source, managedMeta);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function writeAuthContext(cwd: string, session: FileOperationSession, source: string): void {
|
|
119
|
+
session.writeFile(path.join(cwd, "lib", "auth", "auth-context.tsx"), getFrontendFramework() === "react" ? adaptReactPage(source) : source, managedMeta);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function writeManagedAuthRoute(cwd: string, session: FileOperationSession, customJwt: boolean): void {
|
|
123
|
+
const name = JSON.parse(session.readFile(path.join(cwd, "package.json"))).name;
|
|
124
|
+
const sharedName = JSON.parse(session.readFile(path.join(cwd, "shared", "package.json"))).name;
|
|
125
|
+
session.writeFile(path.join(cwd, "bff", "src", "auth", "index.ts"), generateReactAuthBff(name, sharedName, customJwt), managedMeta);
|
|
126
|
+
session.writeFile(path.join(cwd, "bff", "auth", "function.json"), generateManagedFunctionConfig("auth/{action}", ["GET", "POST"], "auth"), managedMeta);
|
|
127
|
+
}
|
|
128
|
+
|
|
101
129
|
function setupSwaAuth(cwd: string, backendLanguage: BackendLanguage, session: FileOperationSession, allowedProviders?: string[]): void {
|
|
102
130
|
const providers = normalizeSwaProviders(allowedProviders);
|
|
103
131
|
const helperPath = backendLanguage === "typescript"
|
|
@@ -112,14 +140,12 @@ function setupSwaAuth(cwd: string, backendLanguage: BackendLanguage, session: Fi
|
|
|
112
140
|
: generateSwaAuthHelperPython();
|
|
113
141
|
session.writeFile(helperPath, helper, managedMeta);
|
|
114
142
|
|
|
115
|
-
|
|
116
|
-
session.writeFile(callFnPath, generateBFFCallFunctionWithSwaAuth(), managedMeta);
|
|
143
|
+
writeCallFunction(cwd, session, generateBFFCallFunctionWithSwaAuth(), { provider: "swa" });
|
|
117
144
|
|
|
118
145
|
const authDir = path.join(cwd, "lib", "auth");
|
|
119
146
|
session.writeFile(path.join(authDir, "auth-context.tsx"), generateSwaAuthContext(providers), managedMeta);
|
|
120
147
|
updateRootLayoutWithAuthProvider(cwd, session);
|
|
121
|
-
|
|
122
|
-
session.writeFile(path.join(loginDir, "page.tsx"), generateSwaLoginPage(providers), managedMeta);
|
|
148
|
+
writeLoginPage(cwd, session, generateSwaLoginPage(providers));
|
|
123
149
|
updateSwaRouteConfig(cwd, session, providers);
|
|
124
150
|
}
|
|
125
151
|
|
|
@@ -127,10 +153,10 @@ function setupExternalTokenAuth(cwd: string, backendLanguage: BackendLanguage, s
|
|
|
127
153
|
const authDir = path.join(cwd, "lib", "auth");
|
|
128
154
|
writeIfMissing(session, path.join(authDir, "external-token-adapter.ts"), generateExternalTokenAdapter());
|
|
129
155
|
session.writeFile(path.join(authDir, "authenticated-fetch.ts"), generateAuthenticatedFetch(), managedMeta);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
session.writeFile(path.join(
|
|
156
|
+
writeAuthContext(cwd, session, generateExternalTokenAuthContext());
|
|
157
|
+
writeCallFunction(cwd, session, generateBFFCallFunctionWithAuth(), { provider: "external-token" });
|
|
158
|
+
if (getFrontendFramework() === "react") writeManagedAuthRoute(cwd, session, false);
|
|
159
|
+
else session.writeFile(path.join(cwd, "app", "api", "auth", "me", "route.ts"), generateExternalTokenBFFMeRoute(), managedMeta);
|
|
134
160
|
updateRootLayoutWithAuthProvider(cwd, session);
|
|
135
161
|
|
|
136
162
|
if (backendLanguage === "typescript") {
|
|
@@ -240,6 +266,14 @@ export function addAuthProviderToRootLayout(layout: string): string {
|
|
|
240
266
|
}
|
|
241
267
|
|
|
242
268
|
function updateRootLayoutWithAuthProvider(cwd: string, session: FileOperationSession): void {
|
|
269
|
+
if (getFrontendFramework() === "react") {
|
|
270
|
+
const mainPath = path.join(cwd, "src", "main.tsx");
|
|
271
|
+
const main = session.readFile(mainPath);
|
|
272
|
+
if (main.includes("<AuthProvider>")) return;
|
|
273
|
+
if (!main.includes("<App />")) throw new Error("Could not find <App /> in src/main.tsx; cannot install AuthProvider");
|
|
274
|
+
session.writeFile(mainPath, `import { AuthProvider } from '@/lib/auth/auth-context';\n${main.replace("<App />", "<AuthProvider><App /></AuthProvider>")}`, extensionMeta);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
243
277
|
const layoutPath = path.join(cwd, "app", "layout.tsx");
|
|
244
278
|
if (!session.fileExists(layoutPath)) {
|
|
245
279
|
throw new Error("app/layout.tsx was not found; cannot install AuthProvider");
|
|
@@ -364,27 +398,25 @@ export async function addAuthCommand(options: AddAuthOptions) {
|
|
|
364
398
|
|
|
365
399
|
// 4. Generate proxy
|
|
366
400
|
console.log("\n Generating proxy...");
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
401
|
+
if (getFrontendFramework() === "nextjs") {
|
|
402
|
+
const proxyPath = path.join(cwd, "proxy.ts");
|
|
403
|
+
session.writeFile(proxyPath, generateProxy(projectName), managedMeta);
|
|
404
|
+
console.log(` Created: proxy.ts`);
|
|
405
|
+
}
|
|
370
406
|
|
|
371
407
|
// 5. Generate login page
|
|
372
408
|
console.log("\n Generating login page...");
|
|
373
|
-
|
|
374
|
-
session.writeFile(path.join(loginDir, "page.tsx"), generateLoginPage(), managedMeta);
|
|
375
|
-
console.log(` Created: app/login/page.tsx`);
|
|
409
|
+
writeLoginPage(cwd, session, generateLoginPage());
|
|
376
410
|
|
|
377
411
|
// 6. Generate auth context
|
|
378
412
|
console.log("\n Generating auth context...");
|
|
379
|
-
|
|
380
|
-
session.writeFile(path.join(authLibDir, "auth-context.tsx"), generateAuthContext(), managedMeta);
|
|
413
|
+
writeAuthContext(cwd, session, generateAuthContext());
|
|
381
414
|
console.log(`✅ Created: lib/auth/auth-context.tsx`);
|
|
382
415
|
|
|
383
416
|
// 7. Update callFunction with auth support
|
|
384
417
|
console.log("\n Updating callFunction with auth support...");
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
console.log(` Updated: lib/api/call-function.ts`);
|
|
418
|
+
writeCallFunction(cwd, session, generateBFFCallFunctionWithAuth(), { provider: "custom-jwt" });
|
|
419
|
+
console.log(` Updated: ${getFrontendFramework() === "react" ? "bff/src/lib" : "lib/api"}/call-function.ts`);
|
|
388
420
|
|
|
389
421
|
// 8. Update swallowkit.config.js
|
|
390
422
|
console.log("\n Updating configuration...");
|
|
@@ -396,7 +428,7 @@ export async function addAuthCommand(options: AddAuthOptions) {
|
|
|
396
428
|
|
|
397
429
|
// 10. Install dependencies
|
|
398
430
|
console.log("\n Installing auth dependencies...");
|
|
399
|
-
|
|
431
|
+
installAuthDependenciesSync(cwd, backendLanguage, rdbProvider, session);
|
|
400
432
|
await finalize();
|
|
401
433
|
|
|
402
434
|
console.log("\n Authentication setup complete!");
|
|
@@ -426,7 +458,8 @@ function findObjectEnd(content: string, open: number): number {
|
|
|
426
458
|
function updateConfigWithNamedScheme(cwd: string, scheme: string, provider: AuthProvider, session: FileOperationSession, allowedProviders?: string[]): void {
|
|
427
459
|
const jsPath = path.join(cwd, "swallowkit.config.js");
|
|
428
460
|
const jsonPath = path.join(cwd, "swallowkit.config.json");
|
|
429
|
-
|
|
461
|
+
// Match loadConfig precedence: swallowkit.config.json wins when both files exist.
|
|
462
|
+
const configPath = session.fileExists(jsonPath) ? jsonPath : jsPath;
|
|
430
463
|
if (!session.fileExists(configPath)) throw new Error("swallowkit.config.js or swallowkit.config.json is required");
|
|
431
464
|
const swaProviders = provider === "swa" ? normalizeSwaProviders(allowedProviders) : undefined;
|
|
432
465
|
if (configPath.endsWith(".json")) {
|
|
@@ -478,6 +511,11 @@ function addNamedScheme(cwd: string, scheme: string, provider: AuthProvider, lan
|
|
|
478
511
|
// Validate/update config before creating files, so duplicate names stop safely.
|
|
479
512
|
updateConfigWithNamedScheme(cwd, scheme, provider, session, allowedProviders);
|
|
480
513
|
const slug = scheme.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/_/g, "-").toLowerCase();
|
|
514
|
+
if (provider === "custom-jwt") {
|
|
515
|
+
// The scheme's JWT helper needs the same token/password/driver packages as single-provider custom-jwt.
|
|
516
|
+
const connector = getConnectorDefinition(defaultCustomJwtConfig().userConnector) as RdbConnectorConfig | undefined;
|
|
517
|
+
installAuthDependenciesSync(cwd, language, connector?.provider ?? "mysql", session);
|
|
518
|
+
}
|
|
481
519
|
if (language === "typescript") {
|
|
482
520
|
const dir = path.join(cwd, "functions", "src", "auth", "schemes", slug);
|
|
483
521
|
if (provider === "external-token") writeIfMissing(session, path.join(dir, "verifier.ts"), generateExternalTokenVerifierTS());
|
|
@@ -498,11 +536,19 @@ function addNamedScheme(cwd: string, scheme: string, provider: AuthProvider, lan
|
|
|
498
536
|
if (provider === "external-token") {
|
|
499
537
|
writeIfMissing(session, path.join(clientDir, "token-adapter.ts"), generateExternalTokenAdapter());
|
|
500
538
|
writeIfMissing(session, path.join(clientDir, "authenticated-fetch.ts"), generateAuthenticatedFetch().replace("'./external-token-adapter'", "'./token-adapter'"));
|
|
501
|
-
|
|
539
|
+
const source = generateExternalTokenAuthContext().replace(/external-token-adapter/g, "token-adapter");
|
|
540
|
+
writeIfMissing(session, path.join(clientDir, "auth-context.tsx"), getFrontendFramework() === "react" ? adaptReactPage(source) : source);
|
|
502
541
|
} else if (provider === "swa") {
|
|
503
542
|
writeIfMissing(session, path.join(clientDir, "auth-context.tsx"), generateSwaAuthContext(allowedProviders));
|
|
504
543
|
} else if (provider === "custom-jwt") {
|
|
505
|
-
writeIfMissing(session, path.join(clientDir, "auth-context.tsx"), generateAuthContext());
|
|
544
|
+
writeIfMissing(session, path.join(clientDir, "auth-context.tsx"), getFrontendFramework() === "react" ? adaptReactPage(generateAuthContext()) : generateAuthContext());
|
|
545
|
+
}
|
|
546
|
+
if (getFrontendFramework() === "react") {
|
|
547
|
+
const existing = getValidatedFullConfig().auth;
|
|
548
|
+
writeCallFunction(cwd, session, "", {
|
|
549
|
+
...existing, schemes: { ...existing?.schemes, [scheme]: { provider } },
|
|
550
|
+
});
|
|
551
|
+
return;
|
|
506
552
|
}
|
|
507
553
|
const callFunctionPath = path.join(cwd, "lib", "api", "call-function.ts");
|
|
508
554
|
if (!session.fileExists(callFunctionPath)) writeIfMissing(session, callFunctionPath, generateBFFCallFunctionWithMultipleAuth());
|
|
@@ -649,9 +695,14 @@ function generateFunctionsAuth(
|
|
|
649
695
|
const functionAppPath = path.join(functionsDir, "function_app.py");
|
|
650
696
|
if (session.fileExists(functionAppPath)) {
|
|
651
697
|
const content = session.readFile(functionAppPath);
|
|
652
|
-
const authImport = "from blueprints.auth import
|
|
698
|
+
const authImport = "from blueprints.auth import auth_bp";
|
|
653
699
|
const authRegister = "app.register_blueprint(auth_bp)";
|
|
654
|
-
|
|
700
|
+
// Earlier releases imported a non-existent `bp`; repair it in place when re-running.
|
|
701
|
+
const legacyImport = "from blueprints.auth import bp as auth_bp";
|
|
702
|
+
if (content.includes(legacyImport)) {
|
|
703
|
+
session.writeFile(functionAppPath, content.replace(legacyImport, authImport), extensionMeta);
|
|
704
|
+
console.log(` Updated: functions/function_app.py (fixed auth blueprint import)`);
|
|
705
|
+
} else if (!content.includes(authImport)) {
|
|
655
706
|
const marker = "# SwallowKit scaffold registrations";
|
|
656
707
|
if (content.includes(marker)) {
|
|
657
708
|
const updated = content.replace(
|
|
@@ -667,6 +718,10 @@ function generateFunctionsAuth(
|
|
|
667
718
|
}
|
|
668
719
|
|
|
669
720
|
function generateBFFAuth(cwd: string, projectName: string, sharedPackageName: string, session: FileOperationSession): void {
|
|
721
|
+
if (getFrontendFramework() === "react") {
|
|
722
|
+
writeManagedAuthRoute(cwd, session, true);
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
670
725
|
const authApiDir = path.join(cwd, "app", "api", "auth");
|
|
671
726
|
|
|
672
727
|
// Login route
|
|
@@ -698,6 +753,24 @@ function generateBFFAuth(cwd: string, projectName: string, sharedPackageName: st
|
|
|
698
753
|
}
|
|
699
754
|
|
|
700
755
|
function updateConfigWithAuth(cwd: string, provider: AuthProvider, config: CustomJwtConfig, session: FileOperationSession, allowedProviders?: string[]): void {
|
|
756
|
+
const jsonPath = path.join(cwd, "swallowkit.config.json");
|
|
757
|
+
if (session.fileExists(jsonPath)) {
|
|
758
|
+
// loadConfig reads swallowkit.config.json first, so it is the effective configuration.
|
|
759
|
+
const value = JSON.parse(session.readFile(jsonPath));
|
|
760
|
+
if (value.auth) {
|
|
761
|
+
console.log(" 'auth' section already exists in swallowkit.config.json");
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
value.auth = {
|
|
765
|
+
provider,
|
|
766
|
+
...(provider === "custom-jwt" ? { customJwt: { ...config, jwtSecretEnv: config.jwtSecretEnv || "JWT_SECRET", tokenExpiry: config.tokenExpiry || "24h" } } : {}),
|
|
767
|
+
...(provider === "swa" ? { swa: { allowedProviders: normalizeSwaProviders(allowedProviders), roleSource: "swa-roles" } } : {}),
|
|
768
|
+
authorization: { defaultPolicy: provider === "none" ? "anonymous" : "authenticated" },
|
|
769
|
+
};
|
|
770
|
+
session.writeFile(jsonPath, JSON.stringify(value, null, 2) + "\n", extensionMeta);
|
|
771
|
+
console.log(` Updated: swallowkit.config.json`);
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
701
774
|
const configPath = path.join(cwd, "swallowkit.config.js");
|
|
702
775
|
if (!session.fileExists(configPath)) {
|
|
703
776
|
console.warn(" swallowkit.config.js not found. Please add auth config manually.");
|
|
@@ -742,7 +815,8 @@ function updateConfigWithAuth(cwd: string, provider: AuthProvider, config: Custo
|
|
|
742
815
|
provider: '${provider}',
|
|
743
816
|
${providerSettings}
|
|
744
817
|
authorization: {
|
|
745
|
-
|
|
818
|
+
// Disabled auth has no scheme to authenticate against; 'authenticated' would fail validateConfig.
|
|
819
|
+
defaultPolicy: '${provider === "none" ? "anonymous" : "authenticated"}',
|
|
746
820
|
},
|
|
747
821
|
},
|
|
748
822
|
`;
|
|
@@ -777,7 +851,7 @@ function updateEnvironmentFiles(cwd: string, session: FileOperationSession): voi
|
|
|
777
851
|
}
|
|
778
852
|
}
|
|
779
853
|
|
|
780
|
-
|
|
854
|
+
function installAuthDependenciesSync(cwd: string, backendLanguage: BackendLanguage, provider: "mysql" | "postgres" | "sqlserver" = "mysql", session: FileOperationSession): void {
|
|
781
855
|
if (backendLanguage === "typescript") {
|
|
782
856
|
const funcPkgPath = path.join(cwd, "functions", "package.json");
|
|
783
857
|
if (session.fileExists(funcPkgPath)) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { ensureSwallowKitProject } from "../../core/config";
|
|
3
|
+
import {
|
|
4
|
+
MCP_CONFIG_PATH,
|
|
5
|
+
MCP_LATEST,
|
|
6
|
+
lookupPublishedLatestVersion,
|
|
7
|
+
readMcpConfigVersion,
|
|
8
|
+
resolveMcpPinVersion,
|
|
9
|
+
writeMcpConfigVersion,
|
|
10
|
+
} from "../../core/project/mcp-config";
|
|
11
|
+
import { resolveProjectSwallowKit } from "../../mcp/version-selection";
|
|
12
|
+
import { parseSemver } from "../../utils/semver";
|
|
13
|
+
import { getSwallowKitVersion } from "../../version";
|
|
14
|
+
|
|
15
|
+
export interface ConfigureMcpResult {
|
|
16
|
+
previousVersion: string | null;
|
|
17
|
+
version: string;
|
|
18
|
+
reason: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function configureMcp(
|
|
22
|
+
options: { version?: string; cwd?: string },
|
|
23
|
+
lookupLatest: (packageName: string) => string | null = lookupPublishedLatestVersion
|
|
24
|
+
): ConfigureMcpResult {
|
|
25
|
+
const cwd = options.cwd ?? process.cwd();
|
|
26
|
+
const requested = (options.version ?? "auto").trim();
|
|
27
|
+
const previousVersion = readMcpConfigVersion(cwd);
|
|
28
|
+
|
|
29
|
+
let decision: { version: string; reason: string };
|
|
30
|
+
if (requested === "auto") {
|
|
31
|
+
const projectVersion = resolveProjectSwallowKit(cwd)?.version ?? getSwallowKitVersion();
|
|
32
|
+
decision = resolveMcpPinVersion(projectVersion, lookupLatest("swallowkit"));
|
|
33
|
+
} else if (requested === MCP_LATEST) {
|
|
34
|
+
decision = { version: MCP_LATEST, reason: "Explicitly requested latest." };
|
|
35
|
+
} else if (parseSemver(requested)) {
|
|
36
|
+
decision = { version: requested, reason: "Explicitly pinned version." };
|
|
37
|
+
} else {
|
|
38
|
+
throw new Error(`--version must be "auto", "latest", or a semantic version (got "${requested}").`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
writeMcpConfigVersion(cwd, decision.version);
|
|
42
|
+
return { previousVersion, ...decision };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const configureMcpCommand = new Command("configure-mcp")
|
|
46
|
+
.description(`Select the SwallowKit MCP version used by ${MCP_CONFIG_PATH} (auto: latest unless the project is newer)`)
|
|
47
|
+
.option("--version <version>", "auto | latest | <semver>", "auto")
|
|
48
|
+
.action((options: { version?: string }) => {
|
|
49
|
+
ensureSwallowKitProject("configure-mcp");
|
|
50
|
+
const result = configureMcp({ version: options.version });
|
|
51
|
+
console.log(`${MCP_CONFIG_PATH}: SWALLOWKIT_MCP_VERSION ${result.previousVersion ?? "(unset)"} -> ${result.version}`);
|
|
52
|
+
console.log(`Reason: ${result.reason}`);
|
|
53
|
+
console.log("Restart the MCP server (or reload your agent) to apply the change.");
|
|
54
|
+
});
|