swallowkit 1.0.0-beta.6 → 1.0.0-beta.61

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.
Files changed (296) hide show
  1. package/README.ja.md +87 -175
  2. package/README.md +87 -176
  3. package/dist/__tests__/fixtures.d.ts +12 -0
  4. package/dist/__tests__/fixtures.d.ts.map +1 -1
  5. package/dist/__tests__/fixtures.js +101 -0
  6. package/dist/__tests__/fixtures.js.map +1 -1
  7. package/dist/cli/commands/add-auth.d.ts +15 -0
  8. package/dist/cli/commands/add-auth.d.ts.map +1 -0
  9. package/dist/cli/commands/add-auth.js +790 -0
  10. package/dist/cli/commands/add-auth.js.map +1 -0
  11. package/dist/cli/commands/add-connector.d.ts +20 -0
  12. package/dist/cli/commands/add-connector.d.ts.map +1 -0
  13. package/dist/cli/commands/add-connector.js +164 -0
  14. package/dist/cli/commands/add-connector.js.map +1 -0
  15. package/dist/cli/commands/cosmos-worktree-isolation.d.ts +25 -0
  16. package/dist/cli/commands/cosmos-worktree-isolation.d.ts.map +1 -0
  17. package/dist/cli/commands/cosmos-worktree-isolation.js +124 -0
  18. package/dist/cli/commands/cosmos-worktree-isolation.js.map +1 -0
  19. package/dist/cli/commands/create-model.d.ts +1 -4
  20. package/dist/cli/commands/create-model.d.ts.map +1 -1
  21. package/dist/cli/commands/create-model.js +20 -82
  22. package/dist/cli/commands/create-model.js.map +1 -1
  23. package/dist/cli/commands/dev-seeds.d.ts +62 -0
  24. package/dist/cli/commands/dev-seeds.d.ts.map +1 -0
  25. package/dist/cli/commands/dev-seeds.js +474 -0
  26. package/dist/cli/commands/dev-seeds.js.map +1 -0
  27. package/dist/cli/commands/dev.d.ts +38 -0
  28. package/dist/cli/commands/dev.d.ts.map +1 -1
  29. package/dist/cli/commands/dev.js +733 -155
  30. package/dist/cli/commands/dev.js.map +1 -1
  31. package/dist/cli/commands/index.d.ts +1 -0
  32. package/dist/cli/commands/index.d.ts.map +1 -1
  33. package/dist/cli/commands/index.js +3 -1
  34. package/dist/cli/commands/index.js.map +1 -1
  35. package/dist/cli/commands/init.d.ts +74 -0
  36. package/dist/cli/commands/init.d.ts.map +1 -1
  37. package/dist/cli/commands/init.js +1376 -930
  38. package/dist/cli/commands/init.js.map +1 -1
  39. package/dist/cli/commands/scaffold.d.ts +24 -0
  40. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  41. package/dist/cli/commands/scaffold.js +473 -90
  42. package/dist/cli/commands/scaffold.js.map +1 -1
  43. package/dist/cli/index.d.ts +5 -1
  44. package/dist/cli/index.d.ts.map +1 -1
  45. package/dist/cli/index.js +335 -55
  46. package/dist/cli/index.js.map +1 -1
  47. package/dist/core/config.d.ts +14 -3
  48. package/dist/core/config.d.ts.map +1 -1
  49. package/dist/core/config.js +179 -8
  50. package/dist/core/config.js.map +1 -1
  51. package/dist/core/mock/connector-mock-server.d.ts +101 -0
  52. package/dist/core/mock/connector-mock-server.d.ts.map +1 -0
  53. package/dist/core/mock/connector-mock-server.js +480 -0
  54. package/dist/core/mock/connector-mock-server.js.map +1 -0
  55. package/dist/core/mock/zod-mock-generator.d.ts +14 -0
  56. package/dist/core/mock/zod-mock-generator.d.ts.map +1 -0
  57. package/dist/core/mock/zod-mock-generator.js +163 -0
  58. package/dist/core/mock/zod-mock-generator.js.map +1 -0
  59. package/dist/core/operations/auth-operations.d.ts +61 -0
  60. package/dist/core/operations/auth-operations.d.ts.map +1 -0
  61. package/dist/core/operations/auth-operations.js +272 -0
  62. package/dist/core/operations/auth-operations.js.map +1 -0
  63. package/dist/core/operations/create-model.d.ts +15 -0
  64. package/dist/core/operations/create-model.d.ts.map +1 -0
  65. package/dist/core/operations/create-model.js +185 -0
  66. package/dist/core/operations/create-model.js.map +1 -0
  67. package/dist/core/operations/file-session.d.ts +56 -0
  68. package/dist/core/operations/file-session.d.ts.map +1 -0
  69. package/dist/core/operations/file-session.js +203 -0
  70. package/dist/core/operations/file-session.js.map +1 -0
  71. package/dist/core/operations/provision-operations.d.ts +52 -0
  72. package/dist/core/operations/provision-operations.d.ts.map +1 -0
  73. package/dist/core/operations/provision-operations.js +211 -0
  74. package/dist/core/operations/provision-operations.js.map +1 -0
  75. package/dist/core/operations/runtime.d.ts +37 -0
  76. package/dist/core/operations/runtime.d.ts.map +1 -0
  77. package/dist/core/operations/runtime.js +248 -0
  78. package/dist/core/operations/runtime.js.map +1 -0
  79. package/dist/core/operations/scaffold-apply.d.ts +21 -0
  80. package/dist/core/operations/scaffold-apply.d.ts.map +1 -0
  81. package/dist/core/operations/scaffold-apply.js +57 -0
  82. package/dist/core/operations/scaffold-apply.js.map +1 -0
  83. package/dist/core/operations/scaffold-machine.d.ts +16 -0
  84. package/dist/core/operations/scaffold-machine.d.ts.map +1 -0
  85. package/dist/core/operations/scaffold-machine.js +51 -0
  86. package/dist/core/operations/scaffold-machine.js.map +1 -0
  87. package/dist/core/operations/scaffold-plan.d.ts +43 -0
  88. package/dist/core/operations/scaffold-plan.d.ts.map +1 -0
  89. package/dist/core/operations/scaffold-plan.js +187 -0
  90. package/dist/core/operations/scaffold-plan.js.map +1 -0
  91. package/dist/core/project/agent-instructions.d.ts +29 -0
  92. package/dist/core/project/agent-instructions.d.ts.map +1 -0
  93. package/dist/core/project/agent-instructions.js +160 -0
  94. package/dist/core/project/agent-instructions.js.map +1 -0
  95. package/dist/core/project/artifacts.d.ts +58 -0
  96. package/dist/core/project/artifacts.d.ts.map +1 -0
  97. package/dist/core/project/artifacts.js +179 -0
  98. package/dist/core/project/artifacts.js.map +1 -0
  99. package/dist/core/project/boundaries.d.ts +50 -0
  100. package/dist/core/project/boundaries.d.ts.map +1 -0
  101. package/dist/core/project/boundaries.js +117 -0
  102. package/dist/core/project/boundaries.js.map +1 -0
  103. package/dist/core/project/capabilities.d.ts +58 -0
  104. package/dist/core/project/capabilities.d.ts.map +1 -0
  105. package/dist/core/project/capabilities.js +135 -0
  106. package/dist/core/project/capabilities.js.map +1 -0
  107. package/dist/core/project/drift.d.ts +29 -0
  108. package/dist/core/project/drift.d.ts.map +1 -0
  109. package/dist/core/project/drift.js +188 -0
  110. package/dist/core/project/drift.js.map +1 -0
  111. package/dist/core/project/infra.d.ts +49 -0
  112. package/dist/core/project/infra.d.ts.map +1 -0
  113. package/dist/core/project/infra.js +167 -0
  114. package/dist/core/project/infra.js.map +1 -0
  115. package/dist/core/project/manifest.d.ts +92 -0
  116. package/dist/core/project/manifest.d.ts.map +1 -0
  117. package/dist/core/project/manifest.js +321 -0
  118. package/dist/core/project/manifest.js.map +1 -0
  119. package/dist/core/project/state.d.ts +15 -0
  120. package/dist/core/project/state.d.ts.map +1 -0
  121. package/dist/core/project/state.js +106 -0
  122. package/dist/core/project/state.js.map +1 -0
  123. package/dist/core/project/validation.d.ts +20 -0
  124. package/dist/core/project/validation.d.ts.map +1 -0
  125. package/dist/core/project/validation.js +274 -0
  126. package/dist/core/project/validation.js.map +1 -0
  127. package/dist/core/project/workflows.d.ts +43 -0
  128. package/dist/core/project/workflows.d.ts.map +1 -0
  129. package/dist/core/project/workflows.js +299 -0
  130. package/dist/core/project/workflows.js.map +1 -0
  131. package/dist/core/scaffold/auth-generator.d.ts +63 -0
  132. package/dist/core/scaffold/auth-generator.d.ts.map +1 -0
  133. package/dist/core/scaffold/auth-generator.js +1774 -0
  134. package/dist/core/scaffold/auth-generator.js.map +1 -0
  135. package/dist/core/scaffold/connector-functions-generator.d.ts +41 -0
  136. package/dist/core/scaffold/connector-functions-generator.d.ts.map +1 -0
  137. package/dist/core/scaffold/connector-functions-generator.js +1029 -0
  138. package/dist/core/scaffold/connector-functions-generator.js.map +1 -0
  139. package/dist/core/scaffold/functions-generator.d.ts +7 -1
  140. package/dist/core/scaffold/functions-generator.d.ts.map +1 -1
  141. package/dist/core/scaffold/functions-generator.js +771 -69
  142. package/dist/core/scaffold/functions-generator.js.map +1 -1
  143. package/dist/core/scaffold/model-parser.d.ts +21 -1
  144. package/dist/core/scaffold/model-parser.d.ts.map +1 -1
  145. package/dist/core/scaffold/model-parser.js +230 -79
  146. package/dist/core/scaffold/model-parser.js.map +1 -1
  147. package/dist/core/scaffold/native-schema-generator.d.ts +19 -0
  148. package/dist/core/scaffold/native-schema-generator.d.ts.map +1 -0
  149. package/dist/core/scaffold/native-schema-generator.js +753 -0
  150. package/dist/core/scaffold/native-schema-generator.js.map +1 -0
  151. package/dist/core/scaffold/nextjs-generator.d.ts +8 -0
  152. package/dist/core/scaffold/nextjs-generator.d.ts.map +1 -1
  153. package/dist/core/scaffold/nextjs-generator.js +153 -9
  154. package/dist/core/scaffold/nextjs-generator.js.map +1 -1
  155. package/dist/core/scaffold/openapi-generator.d.ts +3 -0
  156. package/dist/core/scaffold/openapi-generator.d.ts.map +1 -0
  157. package/dist/core/scaffold/openapi-generator.js +190 -0
  158. package/dist/core/scaffold/openapi-generator.js.map +1 -0
  159. package/dist/core/scaffold/ui-generator.d.ts +17 -4
  160. package/dist/core/scaffold/ui-generator.d.ts.map +1 -1
  161. package/dist/core/scaffold/ui-generator.js +174 -34
  162. package/dist/core/scaffold/ui-generator.js.map +1 -1
  163. package/dist/core/verify/index.d.ts +69 -0
  164. package/dist/core/verify/index.d.ts.map +1 -0
  165. package/dist/core/verify/index.js +412 -0
  166. package/dist/core/verify/index.js.map +1 -0
  167. package/dist/database/base-model.d.ts +3 -3
  168. package/dist/database/base-model.js +3 -3
  169. package/dist/index.d.ts +2 -2
  170. package/dist/index.d.ts.map +1 -1
  171. package/dist/index.js +2 -1
  172. package/dist/index.js.map +1 -1
  173. package/dist/machine/contracts.d.ts +24 -0
  174. package/dist/machine/contracts.d.ts.map +1 -0
  175. package/dist/machine/contracts.js +3 -0
  176. package/dist/machine/contracts.js.map +1 -0
  177. package/dist/machine/errors.d.ts +14 -0
  178. package/dist/machine/errors.d.ts.map +1 -0
  179. package/dist/machine/errors.js +42 -0
  180. package/dist/machine/errors.js.map +1 -0
  181. package/dist/machine/index.d.ts +3 -0
  182. package/dist/machine/index.d.ts.map +1 -0
  183. package/dist/machine/index.js +566 -0
  184. package/dist/machine/index.js.map +1 -0
  185. package/dist/mcp/index.d.ts +25 -0
  186. package/dist/mcp/index.d.ts.map +1 -0
  187. package/dist/mcp/index.js +425 -0
  188. package/dist/mcp/index.js.map +1 -0
  189. package/dist/types/index.d.ts +109 -0
  190. package/dist/types/index.d.ts.map +1 -1
  191. package/dist/utils/package-manager.d.ts +9 -12
  192. package/dist/utils/package-manager.d.ts.map +1 -1
  193. package/dist/utils/package-manager.js +51 -22
  194. package/dist/utils/package-manager.js.map +1 -1
  195. package/dist/utils/python-uv.d.ts +21 -0
  196. package/dist/utils/python-uv.d.ts.map +1 -0
  197. package/dist/utils/python-uv.js +111 -0
  198. package/dist/utils/python-uv.js.map +1 -0
  199. package/dist/version.d.ts +2 -0
  200. package/dist/version.d.ts.map +1 -0
  201. package/dist/version.js +49 -0
  202. package/dist/version.js.map +1 -0
  203. package/package.json +16 -17
  204. package/src/__tests__/__snapshots__/functions-generator.test.ts.snap +1139 -0
  205. package/src/__tests__/__snapshots__/nextjs-generator.test.ts.snap +206 -0
  206. package/src/__tests__/__snapshots__/ui-generator.test.ts.snap +532 -0
  207. package/src/__tests__/agent-instructions.test.ts +237 -0
  208. package/src/__tests__/agent-loop-phase34.test.ts +513 -0
  209. package/src/__tests__/auth.test.ts +770 -0
  210. package/src/__tests__/bff-swa-auth.test.ts +275 -0
  211. package/src/__tests__/config.test.ts +295 -0
  212. package/src/__tests__/connector-functions-generator.test.ts +288 -0
  213. package/src/__tests__/connector-mock-server.test.ts +459 -0
  214. package/src/__tests__/connector-model-bff.test.ts +162 -0
  215. package/src/__tests__/cosmos-worktree-isolation.test.ts +149 -0
  216. package/src/__tests__/dev-seeds.test.ts +236 -0
  217. package/src/__tests__/dev.test.ts +296 -0
  218. package/src/__tests__/file-session.test.ts +98 -0
  219. package/src/__tests__/fixtures.ts +184 -0
  220. package/src/__tests__/functions-generator.test.ts +237 -0
  221. package/src/__tests__/init.test.ts +363 -0
  222. package/src/__tests__/jest-globals.d.ts +8 -0
  223. package/src/__tests__/machine.test.ts +371 -0
  224. package/src/__tests__/mcp.test.ts +253 -0
  225. package/src/__tests__/model-parser.test.ts +142 -0
  226. package/src/__tests__/multi-auth.test.ts +160 -0
  227. package/src/__tests__/nextjs-generator.test.ts +105 -0
  228. package/src/__tests__/openapi-generator.test.ts +43 -0
  229. package/src/__tests__/package-manager.test.ts +244 -0
  230. package/src/__tests__/plan-apply.test.ts +499 -0
  231. package/src/__tests__/python-uv.test.ts +48 -0
  232. package/src/__tests__/scaffold.test.ts +302 -0
  233. package/src/__tests__/string-utils.test.ts +75 -0
  234. package/src/__tests__/tsconfig.json +15 -0
  235. package/src/__tests__/ui-generator.test.ts +248 -0
  236. package/src/__tests__/zod-mock-generator.test.ts +132 -0
  237. package/src/cli/commands/add-auth.ts +853 -0
  238. package/src/cli/commands/add-connector.ts +159 -0
  239. package/src/cli/commands/cosmos-worktree-isolation.ts +130 -0
  240. package/src/cli/commands/create-model.ts +62 -0
  241. package/src/cli/commands/dev-seeds.ts +629 -0
  242. package/src/cli/commands/dev.ts +1252 -0
  243. package/src/cli/commands/index.ts +9 -0
  244. package/src/cli/commands/init.ts +3414 -0
  245. package/src/cli/commands/provision.ts +193 -0
  246. package/src/cli/commands/scaffold.ts +1081 -0
  247. package/src/cli/index.ts +352 -0
  248. package/src/core/config.ts +380 -0
  249. package/src/core/mock/connector-mock-server.ts +555 -0
  250. package/src/core/mock/zod-mock-generator.ts +205 -0
  251. package/src/core/operations/auth-operations.ts +360 -0
  252. package/src/core/operations/create-model.ts +191 -0
  253. package/src/core/operations/file-session.ts +222 -0
  254. package/src/core/operations/provision-operations.ts +297 -0
  255. package/src/core/operations/runtime.ts +258 -0
  256. package/src/core/operations/scaffold-apply.ts +106 -0
  257. package/src/core/operations/scaffold-machine.ts +77 -0
  258. package/src/core/operations/scaffold-plan.ts +215 -0
  259. package/src/core/project/agent-instructions.ts +167 -0
  260. package/src/core/project/agent-templates/AGENTS.md +504 -0
  261. package/src/core/project/agent-templates/CLAUDE.md +31 -0
  262. package/src/core/project/agent-templates/azure-functions.instructions.md +22 -0
  263. package/src/core/project/agent-templates/bff-routes.instructions.md +18 -0
  264. package/src/core/project/agent-templates/copilot-instructions.md +27 -0
  265. package/src/core/project/agent-templates/shared-models.instructions.md +72 -0
  266. package/src/core/project/artifacts.ts +205 -0
  267. package/src/core/project/boundaries.ts +170 -0
  268. package/src/core/project/capabilities.ts +193 -0
  269. package/src/core/project/drift.ts +202 -0
  270. package/src/core/project/infra.ts +196 -0
  271. package/src/core/project/manifest.ts +402 -0
  272. package/src/core/project/state.ts +77 -0
  273. package/src/core/project/validation.ts +295 -0
  274. package/src/core/project/workflows.ts +295 -0
  275. package/src/core/scaffold/auth-generator.ts +1824 -0
  276. package/src/core/scaffold/connector-functions-generator.ts +1133 -0
  277. package/src/core/scaffold/functions-generator.ts +972 -0
  278. package/src/core/scaffold/model-parser.ts +781 -0
  279. package/src/core/scaffold/native-schema-generator.ts +904 -0
  280. package/src/core/scaffold/nextjs-generator.ts +382 -0
  281. package/src/core/scaffold/openapi-generator.ts +212 -0
  282. package/src/core/scaffold/ui-generator.ts +1100 -0
  283. package/src/core/verify/index.ts +468 -0
  284. package/src/database/base-model.ts +184 -0
  285. package/src/database/client.ts +140 -0
  286. package/src/database/repository.ts +104 -0
  287. package/src/database/runtime-check.ts +25 -0
  288. package/src/index.ts +27 -0
  289. package/src/machine/contracts.ts +33 -0
  290. package/src/machine/errors.ts +45 -0
  291. package/src/machine/index.ts +690 -0
  292. package/src/mcp/index.ts +423 -0
  293. package/src/types/index.ts +182 -0
  294. package/src/utils/package-manager.ts +251 -0
  295. package/src/utils/python-uv.ts +96 -0
  296. package/src/version.ts +13 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * SwallowKit Add-Connector コマンド
3
+ * swallowkit.config.js にコネクタ設定を追加する
4
+ */
5
+
6
+ import * as fs from "fs";
7
+ import { detectFromProject, getCommands } from "../../utils/package-manager";
8
+ import * as path from "path";
9
+ import { ensureSwallowKitProject } from "../../core/config";
10
+ import { ApiConnectorConfig, ConnectorDefinition } from "../../types";
11
+ import { syncProjectManifest } from "../../core/project/manifest";
12
+
13
+ interface AddConnectorOptions {
14
+ name: string;
15
+ type: "rdb" | "api";
16
+ provider?: "mysql" | "postgres" | "sqlserver";
17
+ }
18
+
19
+ /**
20
+ * add-connector コマンド
21
+ */
22
+ export async function addConnectorCommand(options: AddConnectorOptions) {
23
+ ensureSwallowKitProject("add-connector");
24
+
25
+ console.log(`🔌 SwallowKit Add-Connector: Adding '${options.name}' connector...\n`);
26
+
27
+ const configPath = findConfigFile();
28
+ if (!configPath) {
29
+ console.error("❌ swallowkit.config.js not found. Run 'swallowkit init' first.");
30
+ process.exit(1);
31
+ }
32
+
33
+ // Build connector definition
34
+ const connectorDef = buildConnectorDefinition(options);
35
+
36
+ // Update config file
37
+ updateConfigWithConnector(configPath, options.name, connectorDef);
38
+ await syncProjectManifest();
39
+
40
+ console.log(`\n✅ Connector '${options.name}' added successfully!`);
41
+ console.log("\n📝 Next steps:");
42
+ console.log(` 1. Review the connector settings in ${configPath}`);
43
+ console.log(` 2. Set the required environment variables in functions/local.settings.json`);
44
+ console.log(` 3. Create models with: ${getCommands(detectFromProject()).exec} swallowkit create-model <name> --connector=${options.name}`);
45
+ }
46
+
47
+ function findConfigFile(): string | null {
48
+ const candidates = ["swallowkit.config.js", "swallowkit.config.json", ".swallowkitrc.json"];
49
+ for (const candidate of candidates) {
50
+ const fullPath = path.resolve(process.cwd(), candidate);
51
+ if (fs.existsSync(fullPath)) {
52
+ return fullPath;
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ function buildConnectorDefinition(options: AddConnectorOptions): ConnectorDefinition {
59
+ const name = options.name.toUpperCase().replace(/[^A-Z0-9]/g, "_");
60
+
61
+ if (options.type === "rdb") {
62
+ return {
63
+ type: "rdb",
64
+ provider: options.provider || "mysql",
65
+ connectionEnvVar: `${name}_CONNECTION_STRING`,
66
+ };
67
+ }
68
+
69
+ return {
70
+ type: "api",
71
+ baseUrlEnvVar: `${name}_API_BASE_URL`,
72
+ auth: {
73
+ type: "apiKey",
74
+ envVar: `${name}_API_KEY`,
75
+ placement: "query",
76
+ paramName: "apiKey",
77
+ },
78
+ };
79
+ }
80
+
81
+ /**
82
+ * swallowkit.config.js にコネクタ設定を追加
83
+ */
84
+ export function updateConfigWithConnector(
85
+ configPath: string,
86
+ connectorName: string,
87
+ connectorDef: ConnectorDefinition
88
+ ): void {
89
+ const content = fs.readFileSync(configPath, "utf-8");
90
+
91
+ if (configPath.endsWith(".json")) {
92
+ // JSON config
93
+ const config = JSON.parse(content);
94
+ if (!config.connectors) {
95
+ config.connectors = {};
96
+ }
97
+ config.connectors[connectorName] = connectorDef;
98
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
99
+ console.log(`✅ Updated: ${configPath}`);
100
+ return;
101
+ }
102
+
103
+ // JS config — append connectors section
104
+ if (content.includes("connectors:") || content.includes("connectors :")) {
105
+ console.log(`⚠️ 'connectors' section already exists in ${configPath}. Please add the connector manually:`);
106
+ console.log(formatConnectorSnippet(connectorName, connectorDef));
107
+ return;
108
+ }
109
+
110
+ // Find the last property before the closing of module.exports
111
+ const closingBraceIdx = content.lastIndexOf("}");
112
+ if (closingBraceIdx === -1) {
113
+ console.error("❌ Could not parse config file structure. Please add the connector manually:");
114
+ console.log(formatConnectorSnippet(connectorName, connectorDef));
115
+ return;
116
+ }
117
+
118
+ // Check if we need a comma before inserting
119
+ const beforeClosing = content.substring(0, closingBraceIdx).trimEnd();
120
+ const needsComma = !beforeClosing.endsWith(",") && !beforeClosing.endsWith("{");
121
+
122
+ const connectorBlock = generateConnectorJSBlock(connectorName, connectorDef);
123
+ const insertion = `${needsComma ? "," : ""}\n // コネクタ定義\n connectors: {\n${connectorBlock}\n },\n`;
124
+
125
+ const newContent = content.substring(0, closingBraceIdx) + insertion + content.substring(closingBraceIdx);
126
+ fs.writeFileSync(configPath, newContent, "utf-8");
127
+ console.log(`✅ Updated: ${configPath}`);
128
+ }
129
+
130
+ function generateConnectorJSBlock(name: string, def: ConnectorDefinition): string {
131
+ if (def.type === "rdb") {
132
+ return ` ${name}: {
133
+ type: 'rdb',
134
+ provider: '${def.provider}',
135
+ connectionEnvVar: '${def.connectionEnvVar}',
136
+ },`;
137
+ }
138
+
139
+ const apiDef: ApiConnectorConfig = def;
140
+ let authBlock = "";
141
+ if (apiDef.auth) {
142
+ authBlock = `
143
+ auth: {
144
+ type: '${apiDef.auth.type}',
145
+ envVar: '${apiDef.auth.envVar}',
146
+ placement: '${apiDef.auth.placement || "query"}',
147
+ paramName: '${apiDef.auth.paramName || "apiKey"}',
148
+ },`;
149
+ }
150
+
151
+ return ` ${name}: {
152
+ type: 'api',
153
+ baseUrlEnvVar: '${apiDef.baseUrlEnvVar}',${authBlock}
154
+ },`;
155
+ }
156
+
157
+ function formatConnectorSnippet(name: string, def: ConnectorDefinition): string {
158
+ return `\n ${name}: ${JSON.stringify(def, null, 4)}\n`;
159
+ }
@@ -0,0 +1,130 @@
1
+ import { execFileSync } from "child_process";
2
+ import { createHash } from "crypto";
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+
6
+ const WORKTREE_HASH_LENGTH = 8;
7
+
8
+ export interface GitWorktreeInfo {
9
+ worktreeRoot: string;
10
+ gitDir: string;
11
+ gitCommonDir: string;
12
+ isLinkedWorktree: boolean;
13
+ }
14
+
15
+ export interface CosmosDatabaseNameResolution {
16
+ databaseName: string;
17
+ worktreeIsolationEnabled: boolean;
18
+ worktreeRoot?: string;
19
+ }
20
+
21
+ export type GitCommandRunner = (args: string[], cwd: string) => string;
22
+
23
+ const runGitCommand: GitCommandRunner = (args, cwd) =>
24
+ execFileSync("git", args, {
25
+ cwd,
26
+ encoding: "utf-8",
27
+ stdio: ["ignore", "pipe", "ignore"],
28
+ windowsHide: true,
29
+ });
30
+
31
+ /**
32
+ * Resolve Git's worktree metadata without relying on whether .git is a file or
33
+ * directory. A linked worktree has a per-worktree Git directory that differs
34
+ * from the repository's common Git directory.
35
+ */
36
+ export function resolveGitWorktreeInfo(
37
+ cwd: string = process.cwd(),
38
+ runGit: GitCommandRunner = runGitCommand
39
+ ): GitWorktreeInfo | null {
40
+ try {
41
+ const output = runGit(
42
+ [
43
+ "rev-parse",
44
+ "--show-toplevel",
45
+ "--absolute-git-dir",
46
+ "--git-common-dir",
47
+ ],
48
+ cwd
49
+ );
50
+ const lines = output.split(/\r?\n/).map((line) => line.trim());
51
+ const [worktreeRootOutput, gitDirOutput, gitCommonDirOutput] = lines;
52
+
53
+ if (!worktreeRootOutput || !gitDirOutput || !gitCommonDirOutput) {
54
+ return null;
55
+ }
56
+
57
+ const worktreeRoot = canonicalizePath(worktreeRootOutput, cwd);
58
+ const gitDir = canonicalizePath(gitDirOutput, cwd);
59
+ const gitCommonDir = canonicalizePath(gitCommonDirOutput, cwd);
60
+
61
+ return {
62
+ worktreeRoot,
63
+ gitDir,
64
+ gitCommonDir,
65
+ isLinkedWorktree: gitDir !== gitCommonDir,
66
+ };
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Produce a stable, database-safe identifier for a canonical worktree path.
74
+ */
75
+ export function createWorktreePathHash(worktreeRoot: string): string {
76
+ return createHash("sha256")
77
+ .update(canonicalizePath(worktreeRoot), "utf-8")
78
+ .digest("hex")
79
+ .slice(0, WORKTREE_HASH_LENGTH);
80
+ }
81
+
82
+ export function applyCosmosDatabaseWorktreeIsolation(
83
+ baseDatabaseName: string,
84
+ worktreeInfo: GitWorktreeInfo | null
85
+ ): CosmosDatabaseNameResolution {
86
+ if (!worktreeInfo?.isLinkedWorktree) {
87
+ return {
88
+ databaseName: baseDatabaseName,
89
+ worktreeIsolationEnabled: false,
90
+ };
91
+ }
92
+
93
+ const suffix = createWorktreePathHash(worktreeInfo.worktreeRoot);
94
+ return {
95
+ databaseName: `${baseDatabaseName}_${suffix}`,
96
+ worktreeIsolationEnabled: true,
97
+ worktreeRoot: worktreeInfo.worktreeRoot,
98
+ };
99
+ }
100
+
101
+ export function resolveCosmosDatabaseNameForWorktree(
102
+ baseDatabaseName: string,
103
+ cwd: string = process.cwd(),
104
+ runGit: GitCommandRunner = runGitCommand
105
+ ): CosmosDatabaseNameResolution {
106
+ return applyCosmosDatabaseWorktreeIsolation(
107
+ baseDatabaseName,
108
+ resolveGitWorktreeInfo(cwd, runGit)
109
+ );
110
+ }
111
+
112
+ function canonicalizePath(
113
+ value: string,
114
+ basePath: string = process.cwd()
115
+ ): string {
116
+ const absolutePath = path.resolve(basePath, value);
117
+ let canonicalPath = absolutePath;
118
+
119
+ try {
120
+ canonicalPath = fs.realpathSync.native(absolutePath);
121
+ } catch {
122
+ // Git metadata can disappear between discovery and normalization. The
123
+ // normalized absolute path remains a stable fallback for this invocation.
124
+ }
125
+
126
+ const normalizedPath = path.normalize(canonicalPath).normalize("NFC");
127
+ return process.platform === "win32"
128
+ ? normalizedPath.toLowerCase()
129
+ : normalizedPath;
130
+ }
@@ -0,0 +1,62 @@
1
+ import * as readline from "readline";
2
+ import { createModelOperation } from "../../core/operations/create-model";
3
+ import { detectFromProject, getCommands } from "../../utils/package-manager";
4
+
5
+ interface CreateModelOptions {
6
+ names: string[]; // モデル名のリスト(例: ["todo", "user", "post"])
7
+ modelsDir?: string; // モデルディレクトリ(デフォルト: "shared/models")
8
+ connector?: string; // コネクタ名(例: "mysql", "backlog")
9
+ }
10
+
11
+ /**
12
+ * ユーザーに確認を求める
13
+ */
14
+ function askConfirmation(question: string): Promise<boolean> {
15
+ const rl = readline.createInterface({
16
+ input: process.stdin,
17
+ output: process.stdout,
18
+ });
19
+
20
+ return new Promise((resolve) => {
21
+ rl.question(question, (answer) => {
22
+ rl.close();
23
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
24
+ });
25
+ });
26
+ }
27
+
28
+ /**
29
+ * create-model コマンド
30
+ */
31
+ export async function createModelCommand(options: CreateModelOptions) {
32
+ console.log("🏗️ SwallowKit Create-Model: Generating model templates...\n");
33
+
34
+ const result = await createModelOperation({
35
+ names: options.names,
36
+ modelsDir: options.modelsDir,
37
+ connector: options.connector,
38
+ overwriteMode: "prompt",
39
+ confirmOverwrite: async (filePath) => askConfirmation(`⚠️ File ${filePath} already exists. Overwrite? (y/N): `),
40
+ });
41
+
42
+ // サマリー表示
43
+ console.log("\n📋 Summary:");
44
+ if (result.connectorType && options.connector) {
45
+ console.log(` 🔌 Connector: ${options.connector} (${result.connectorType})`);
46
+ }
47
+ if (result.createdFiles.length > 0) {
48
+ console.log(` ✅ Created ${result.createdFiles.length} model(s): ${result.createdFiles.join(", ")}`);
49
+ }
50
+ if (result.skippedFiles.length > 0) {
51
+ console.log(` ⏭️ Skipped ${result.skippedFiles.length} model(s): ${result.skippedFiles.join(", ")}`);
52
+ }
53
+ if (result.updatedIndex) {
54
+ console.log(" 📦 Updated shared/index.ts");
55
+ }
56
+
57
+ if (result.createdFiles.length > 0) {
58
+ console.log("\n📝 Next steps:");
59
+ console.log(" 1. Customize the generated model fields in shared/models/");
60
+ console.log(` 2. Run '${getCommands(detectFromProject()).exec} swallowkit scaffold <model>' to generate CRUD code`);
61
+ }
62
+ }