@specverse/engines 4.1.5 → 4.1.7

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 (122) hide show
  1. package/dist/libs/instance-factories/applications/templates/generic/backend-env-generator.js +22 -0
  2. package/dist/libs/instance-factories/applications/templates/generic/backend-package-json-generator.js +66 -0
  3. package/dist/libs/instance-factories/applications/templates/generic/backend-tsconfig-generator.js +54 -0
  4. package/dist/libs/instance-factories/applications/templates/generic/main-generator.js +290 -0
  5. package/dist/libs/instance-factories/applications/templates/react/_view-components-source.js +530 -0
  6. package/dist/libs/instance-factories/applications/templates/react/api-client-generator.js +437 -0
  7. package/dist/libs/instance-factories/applications/templates/react/api-types-generator.js +146 -0
  8. package/dist/libs/instance-factories/applications/templates/react/app-tsx-generator.js +73 -0
  9. package/dist/libs/instance-factories/applications/templates/react/env-example-generator.js +18 -0
  10. package/dist/libs/instance-factories/applications/templates/react/field-helpers-generator.js +99 -0
  11. package/dist/libs/instance-factories/applications/templates/react/gitignore-generator.js +35 -0
  12. package/dist/libs/instance-factories/applications/templates/react/index-css-generator.js +9 -0
  13. package/dist/libs/instance-factories/applications/templates/react/index-html-generator.js +23 -0
  14. package/dist/libs/instance-factories/applications/templates/react/main-tsx-generator.js +29 -0
  15. package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +49 -0
  16. package/dist/libs/instance-factories/applications/templates/react/pattern-adapter-generator.js +156 -0
  17. package/dist/libs/instance-factories/applications/templates/react/react-pattern-adapter.js +935 -0
  18. package/dist/libs/instance-factories/applications/templates/react/relationship-field-generator.js +143 -0
  19. package/dist/libs/instance-factories/applications/templates/react/runtime-app-tsx-generator.js +101 -0
  20. package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js +50 -0
  21. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.js +646 -0
  22. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.js +65 -0
  23. package/dist/libs/instance-factories/applications/templates/react/tsconfig-generator.js +28 -0
  24. package/dist/libs/instance-factories/applications/templates/react/use-api-hooks-generator.js +132 -0
  25. package/dist/libs/instance-factories/applications/templates/react/view-dashboard-generator.js +143 -0
  26. package/dist/libs/instance-factories/applications/templates/react/view-detail-generator.js +143 -0
  27. package/dist/libs/instance-factories/applications/templates/react/view-form-generator.js +355 -0
  28. package/dist/libs/instance-factories/applications/templates/react/view-list-generator.js +91 -0
  29. package/dist/libs/instance-factories/applications/templates/react/view-router-generator.js +79 -0
  30. package/dist/libs/instance-factories/applications/templates/react/vite-config-generator.js +42 -0
  31. package/dist/libs/instance-factories/cli/templates/commander/cli-bin-wrapper-generator.js +11 -0
  32. package/dist/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +111 -0
  33. package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +928 -0
  34. package/dist/libs/instance-factories/communication/templates/eventemitter/bus-generator.js +83 -0
  35. package/dist/libs/instance-factories/communication/templates/eventemitter/publisher-generator.js +91 -0
  36. package/dist/libs/instance-factories/communication/templates/eventemitter/subscriber-generator.js +86 -0
  37. package/dist/libs/instance-factories/controllers/templates/fastify/meta-routes-generator.js +93 -0
  38. package/dist/libs/instance-factories/controllers/templates/fastify/routes-generator.js +280 -0
  39. package/dist/libs/instance-factories/controllers/templates/fastify/server-generator.js +125 -0
  40. package/dist/libs/instance-factories/infrastructure/templates/docker-k8s/infrastructure-generator.js +25 -0
  41. package/dist/libs/instance-factories/orms/templates/prisma/schema-generator.js +371 -0
  42. package/dist/libs/instance-factories/orms/templates/prisma/services-generator.js +266 -0
  43. package/dist/libs/instance-factories/scaffolding/templates/generic/env-example-generator.js +51 -0
  44. package/dist/libs/instance-factories/scaffolding/templates/generic/env-generator.js +61 -0
  45. package/dist/libs/instance-factories/scaffolding/templates/generic/gitignore-generator.js +59 -0
  46. package/dist/libs/instance-factories/scaffolding/templates/generic/package-json-generator.js +126 -0
  47. package/dist/libs/instance-factories/scaffolding/templates/generic/readme-generator.js +159 -0
  48. package/dist/libs/instance-factories/scaffolding/templates/generic/tsconfig-generator.js +56 -0
  49. package/dist/libs/instance-factories/scaffolding/templates/generic/tsconfig-react-generator.js +37 -0
  50. package/dist/libs/instance-factories/sdks/templates/python/sdk-generator.js +29 -0
  51. package/dist/libs/instance-factories/sdks/templates/typescript/sdk-generator.js +28 -0
  52. package/dist/libs/instance-factories/services/templates/memory/generate-interpreter.js +14 -0
  53. package/dist/libs/instance-factories/services/templates/memory/step-conventions-memory.js +415 -0
  54. package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +177 -0
  55. package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +413 -0
  56. package/dist/libs/instance-factories/services/templates/prisma/service-generator.js +243 -0
  57. package/dist/libs/instance-factories/services/templates/prisma/step-conventions.js +264 -0
  58. package/dist/libs/instance-factories/services/templates/shared-patterns.js +24 -0
  59. package/dist/libs/instance-factories/shared/path-resolver.js +59 -0
  60. package/dist/libs/instance-factories/storage/templates/mongodb/config-generator.js +13 -0
  61. package/dist/libs/instance-factories/storage/templates/mongodb/docker-generator.js +16 -0
  62. package/dist/libs/instance-factories/storage/templates/postgresql/config-generator.js +45 -0
  63. package/dist/libs/instance-factories/storage/templates/postgresql/docker-generator.js +46 -0
  64. package/dist/libs/instance-factories/storage/templates/redis/config-generator.js +14 -0
  65. package/dist/libs/instance-factories/storage/templates/redis/docker-generator.js +16 -0
  66. package/dist/libs/instance-factories/test-generation.js +145 -0
  67. package/dist/libs/instance-factories/testing/templates/vitest/tests-generator.js +30 -0
  68. package/dist/libs/instance-factories/tools/templates/mcp/mcp-server-generator.js +149 -0
  69. package/dist/libs/instance-factories/tools/templates/mcp/static/src/controllers/MCPServerController.js +232 -0
  70. package/dist/libs/instance-factories/tools/templates/mcp/static/src/events/EventEmitter.js +49 -0
  71. package/dist/libs/instance-factories/tools/templates/mcp/static/src/index.js +18 -0
  72. package/dist/libs/instance-factories/tools/templates/mcp/static/src/interfaces/ResourceProvider.js +0 -0
  73. package/dist/libs/instance-factories/tools/templates/mcp/static/src/models/LibrarySuggestion.js +97 -0
  74. package/dist/libs/instance-factories/tools/templates/mcp/static/src/models/SpecVerseResource.js +64 -0
  75. package/dist/libs/instance-factories/tools/templates/mcp/static/src/server/mcp-server.js +182 -0
  76. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/CLIProxyService.js +1210 -0
  77. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/EmbeddedResourcesAdapter.js +172 -0
  78. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/EntityModuleService.js +240 -0
  79. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/HybridResourcesProvider.js +147 -0
  80. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/LibraryToolsService.js +281 -0
  81. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorBridge.js +409 -0
  82. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorToolsService.js +414 -0
  83. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/PromptToolsService.js +467 -0
  84. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/ResourcesProviderService.js +135 -0
  85. package/dist/libs/instance-factories/tools/templates/mcp/static/src/types/index.js +0 -0
  86. package/dist/libs/instance-factories/tools/templates/vscode/static/extension.js +965 -0
  87. package/dist/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.js +238 -0
  88. package/dist/libs/instance-factories/validation/templates/zod/validation-generator.js +25 -0
  89. package/dist/libs/instance-factories/views/index.js +48 -0
  90. package/dist/libs/instance-factories/views/templates/react/adapters/antd-adapter.js +742 -0
  91. package/dist/libs/instance-factories/views/templates/react/adapters/mui-adapter.js +824 -0
  92. package/dist/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.js +719 -0
  93. package/dist/libs/instance-factories/views/templates/react/app-generator.js +45 -0
  94. package/dist/libs/instance-factories/views/templates/react/components-generator.js +779 -0
  95. package/dist/libs/instance-factories/views/templates/react/forms-generator.js +285 -0
  96. package/dist/libs/instance-factories/views/templates/react/frontend-package-json-generator.js +46 -0
  97. package/dist/libs/instance-factories/views/templates/react/hooks-generator.js +111 -0
  98. package/dist/libs/instance-factories/views/templates/react/index-css-generator.js +9 -0
  99. package/dist/libs/instance-factories/views/templates/react/index-html-generator.js +23 -0
  100. package/dist/libs/instance-factories/views/templates/react/main-tsx-generator.js +21 -0
  101. package/dist/libs/instance-factories/views/templates/react/react-component-generator.js +299 -0
  102. package/dist/libs/instance-factories/views/templates/react/router-generator.js +136 -0
  103. package/dist/libs/instance-factories/views/templates/react/router-generic-generator.js +107 -0
  104. package/dist/libs/instance-factories/views/templates/react/shared-utils-generator.js +179 -0
  105. package/dist/libs/instance-factories/views/templates/react/spec-json-generator.js +7 -0
  106. package/dist/libs/instance-factories/views/templates/react/types-generator.js +56 -0
  107. package/dist/libs/instance-factories/views/templates/react/views-metadata-generator.js +27 -0
  108. package/dist/libs/instance-factories/views/templates/react/vite-config-generator.js +29 -0
  109. package/dist/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js +261 -0
  110. package/dist/libs/instance-factories/views/templates/shared/adapter-types.js +34 -0
  111. package/dist/libs/instance-factories/views/templates/shared/atomic-components-registry.js +800 -0
  112. package/dist/libs/instance-factories/views/templates/shared/base-generator.js +305 -0
  113. package/dist/libs/instance-factories/views/templates/shared/component-metadata.js +517 -0
  114. package/dist/libs/instance-factories/views/templates/shared/composite-pattern-types.js +0 -0
  115. package/dist/libs/instance-factories/views/templates/shared/composite-patterns.js +445 -0
  116. package/dist/libs/instance-factories/views/templates/shared/index.js +80 -0
  117. package/dist/libs/instance-factories/views/templates/shared/pattern-validator.js +210 -0
  118. package/dist/libs/instance-factories/views/templates/shared/property-mapper.js +492 -0
  119. package/dist/libs/instance-factories/views/templates/shared/syntax-mapper.js +321 -0
  120. package/dist/realize/index.js +36 -12
  121. package/dist/realize/index.js.map +1 -1
  122. package/package.json +3 -2
@@ -0,0 +1,266 @@
1
+ function generatePrismaService(context) {
2
+ const { model, controller, spec, implType } = context;
3
+ if (!model) {
4
+ throw new Error("Model is required in template context");
5
+ }
6
+ const modelName = model.name;
7
+ const serviceName = `${modelName}Service`;
8
+ const prismaModel = modelName.charAt(0).toLowerCase() + modelName.slice(1);
9
+ const imports = generateImports(modelName, implType);
10
+ const methods = generateCRUDEMethods(modelName, prismaModel, model, implType);
11
+ const validateMethod = generateValidationMethod(modelName, model, implType);
12
+ return `${imports}
13
+
14
+ /**
15
+ * ${serviceName}
16
+ * Generated service for ${modelName} model
17
+ *
18
+ * Provides CURED operations (Create, Retrieve, Update, Evolve, Delete)
19
+ * with Prisma ORM integration
20
+ */
21
+ export class ${serviceName} {
22
+ constructor(private prisma: PrismaClient) {}
23
+
24
+ ${methods}
25
+
26
+ ${validateMethod}
27
+ }
28
+ `;
29
+ }
30
+ function generateImports(modelName, implType) {
31
+ const imports = [
32
+ `import { PrismaClient, ${modelName} } from '@prisma/client';`
33
+ ];
34
+ return imports.join("\n");
35
+ }
36
+ function generateCRUDEMethods(modelName, prismaModel, model, implType) {
37
+ const methods = [];
38
+ methods.push(generateCreateMethod(modelName, prismaModel, model));
39
+ methods.push(generateRetrieveMethod(modelName, prismaModel, model));
40
+ methods.push(generateUpdateMethod(modelName, prismaModel, model));
41
+ methods.push(generateEvolveMethod(modelName, prismaModel, model));
42
+ methods.push(generateDeleteMethod(modelName, prismaModel, model));
43
+ methods.push(generateListMethod(modelName, prismaModel, model));
44
+ return methods.join("\n\n");
45
+ }
46
+ function generateCreateMethod(modelName, prismaModel, model) {
47
+ return ` /**
48
+ * Create a new ${modelName}
49
+ */
50
+ async create(data: Omit<${modelName}, 'id' | 'createdAt' | 'updatedAt'>): Promise<${modelName}> {
51
+ // Validate before creating
52
+ const validationResult = this.validate(data, { operation: 'create' });
53
+ if (!validationResult.valid) {
54
+ throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
55
+ }
56
+
57
+ return await this.prisma.${prismaModel}.create({
58
+ data: data as any
59
+ });
60
+ }`;
61
+ }
62
+ function generateRetrieveMethod(modelName, prismaModel, model) {
63
+ return ` /**
64
+ * Retrieve a ${modelName} by ID
65
+ */
66
+ async retrieve(id: string): Promise<${modelName} | null> {
67
+ return await this.prisma.${prismaModel}.findUnique({
68
+ where: { id }
69
+ });
70
+ }`;
71
+ }
72
+ function generateUpdateMethod(modelName, prismaModel, model) {
73
+ return ` /**
74
+ * Update a ${modelName}
75
+ */
76
+ async update(id: string, data: Partial<${modelName}>): Promise<${modelName}> {
77
+ // Validate before updating
78
+ const validationResult = this.validate(data, { operation: 'update' });
79
+ if (!validationResult.valid) {
80
+ throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
81
+ }
82
+
83
+ return await this.prisma.${prismaModel}.update({
84
+ where: { id },
85
+ data: data as any
86
+ });
87
+ }`;
88
+ }
89
+ function generateEvolveMethod(modelName, prismaModel, model) {
90
+ const hasLifecycle = model.lifecycle && model.lifecycle.length > 0;
91
+ if (hasLifecycle) {
92
+ return ` /**
93
+ * Evolve a ${modelName} (lifecycle-aware update)
94
+ * Handles state transitions according to lifecycle rules
95
+ */
96
+ async evolve(id: string, data: Partial<${modelName}>): Promise<${modelName}> {
97
+ // Get current instance to check state
98
+ const current = await this.retrieve(id);
99
+ if (!current) {
100
+ throw new Error('${modelName} not found');
101
+ }
102
+
103
+ // Validate state transition if status is being changed
104
+ if (data.status && data.status !== current.status) {
105
+ // TODO: Add lifecycle validation based on model.lifecycle
106
+ // For now, allow any transition
107
+ }
108
+
109
+ // Validate data
110
+ const validationResult = this.validate(data, { operation: 'evolve' });
111
+ if (!validationResult.valid) {
112
+ throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
113
+ }
114
+
115
+ return await this.prisma.${prismaModel}.update({
116
+ where: { id },
117
+ data: data as any
118
+ });
119
+ }`;
120
+ } else {
121
+ return ` /**
122
+ * Evolve a ${modelName} (same as update for models without lifecycle)
123
+ */
124
+ async evolve(id: string, data: Partial<${modelName}>): Promise<${modelName}> {
125
+ return this.update(id, data);
126
+ }`;
127
+ }
128
+ }
129
+ function generateDeleteMethod(modelName, prismaModel, model) {
130
+ const hasSoftDelete = model.metadata?.softDelete;
131
+ if (hasSoftDelete) {
132
+ return ` /**
133
+ * Delete a ${modelName} (soft delete)
134
+ */
135
+ async delete(id: string): Promise<void> {
136
+ await this.prisma.${prismaModel}.update({
137
+ where: { id },
138
+ data: {
139
+ deletedAt: new Date(),
140
+ isDeleted: true
141
+ }
142
+ });
143
+ }`;
144
+ } else {
145
+ return ` /**
146
+ * Delete a ${modelName}
147
+ */
148
+ async delete(id: string): Promise<void> {
149
+ await this.prisma.${prismaModel}.delete({
150
+ where: { id }
151
+ });
152
+ }`;
153
+ }
154
+ }
155
+ function generateListMethod(modelName, prismaModel, model) {
156
+ const hasSoftDelete = model.metadata?.softDelete;
157
+ const whereClause = hasSoftDelete ? `
158
+ where: { isDeleted: false },` : "";
159
+ return ` /**
160
+ * List all ${modelName}s
161
+ */
162
+ async list(): Promise<${modelName}[]> {
163
+ return await this.prisma.${prismaModel}.findMany({${whereClause}
164
+ orderBy: { createdAt: 'desc' }
165
+ });
166
+ }`;
167
+ }
168
+ function generateValidationMethod(modelName, model, implType) {
169
+ return ` /**
170
+ * Validate ${modelName} data
171
+ * Unified validation method for all operations
172
+ */
173
+ validate(
174
+ data: any,
175
+ context: { operation: 'create' | 'update' | 'evolve' }
176
+ ): { valid: boolean; errors: string[] } {
177
+ const errors: string[] = [];
178
+
179
+ // Required field validation (for create operation)
180
+ if (context.operation === 'create') {
181
+ ${generateRequiredFieldValidation(model)}
182
+ }
183
+
184
+ // Type validation
185
+ ${generateTypeValidation(model)}
186
+
187
+ // Constraint validation
188
+ ${generateConstraintValidation(model)}
189
+
190
+ return {
191
+ valid: errors.length === 0,
192
+ errors
193
+ };
194
+ }`;
195
+ }
196
+ function generateRequiredFieldValidation(model) {
197
+ const requiredFields = model.attributes?.filter(
198
+ (attr) => attr.constraints?.required && !["id", "createdAt", "updatedAt"].includes(attr.name)
199
+ ) || [];
200
+ if (requiredFields.length === 0) {
201
+ return "// No required fields";
202
+ }
203
+ const validations = requiredFields.map(
204
+ (field) => `if (data.${field.name} === undefined || data.${field.name} === null) {
205
+ errors.push('${field.name} is required');
206
+ }`
207
+ ).join("\n ");
208
+ return validations;
209
+ }
210
+ function generateTypeValidation(model) {
211
+ const fields = model.attributes || [];
212
+ if (fields.length === 0) {
213
+ return "// No type validation";
214
+ }
215
+ const validations = fields.filter((field) => !["id", "createdAt", "updatedAt"].includes(field.name)).map((field) => {
216
+ const typeName = inferJsType(field.type);
217
+ if (typeName === "string" || typeName === "number" || typeName === "boolean") {
218
+ return `if (data.${field.name} !== undefined && typeof data.${field.name} !== '${typeName}') {
219
+ errors.push('${field.name} must be a ${typeName}');
220
+ }`;
221
+ }
222
+ return "";
223
+ }).filter((v) => v).join("\n ");
224
+ return validations || "// No type validation needed";
225
+ }
226
+ function generateConstraintValidation(model) {
227
+ const fields = model.attributes?.filter(
228
+ (attr) => attr.constraints && Object.keys(attr.constraints).length > 0
229
+ ) || [];
230
+ if (fields.length === 0) {
231
+ return "// No constraint validation";
232
+ }
233
+ const validations = fields.map((field) => {
234
+ const constraints = [];
235
+ if (field.constraints.unique) {
236
+ constraints.push(`// TODO: Check uniqueness of ${field.name}`);
237
+ }
238
+ if (field.constraints.min !== void 0) {
239
+ constraints.push(
240
+ `if (data.${field.name} !== undefined && data.${field.name} < ${field.constraints.min}) {
241
+ errors.push('${field.name} must be at least ${field.constraints.min}');
242
+ }`
243
+ );
244
+ }
245
+ if (field.constraints.max !== void 0) {
246
+ constraints.push(
247
+ `if (data.${field.name} !== undefined && data.${field.name} > ${field.constraints.max}) {
248
+ errors.push('${field.name} must be at most ${field.constraints.max}');
249
+ }`
250
+ );
251
+ }
252
+ return constraints.join("\n ");
253
+ }).filter((v) => v).join("\n ");
254
+ return validations || "// No constraint validation needed";
255
+ }
256
+ function inferJsType(type) {
257
+ const typeLower = type.toLowerCase();
258
+ if (typeLower.includes("string") || typeLower.includes("text")) return "string";
259
+ if (typeLower.includes("int") || typeLower.includes("number")) return "number";
260
+ if (typeLower.includes("bool")) return "boolean";
261
+ if (typeLower.includes("date")) return "object";
262
+ return "any";
263
+ }
264
+ export {
265
+ generatePrismaService as default
266
+ };
@@ -0,0 +1,51 @@
1
+ function generateEnvExample(context) {
2
+ const { manifest } = context;
3
+ const envVars = aggregateEnvironmentVariables(context.implementationTypes || []);
4
+ const byCategory = {};
5
+ for (const envVar of envVars) {
6
+ const category = envVar.category || "Configuration";
7
+ if (!byCategory[category]) {
8
+ byCategory[category] = [];
9
+ }
10
+ byCategory[category].push(envVar);
11
+ }
12
+ const lines = [
13
+ "# Environment Configuration",
14
+ "# Copy this file to .env and fill in your values",
15
+ ""
16
+ ];
17
+ for (const [category, vars] of Object.entries(byCategory)) {
18
+ lines.push(`# ${category}`);
19
+ for (const envVar of vars) {
20
+ if (envVar.description) {
21
+ lines.push(`# ${envVar.description}`);
22
+ }
23
+ if (envVar.required) {
24
+ lines.push(`# REQUIRED`);
25
+ }
26
+ const value = envVar.example || "";
27
+ lines.push(`${envVar.name}="${value}"`);
28
+ }
29
+ lines.push("");
30
+ }
31
+ return lines.join("\n");
32
+ }
33
+ function aggregateEnvironmentVariables(implementationTypes) {
34
+ const envVarsMap = /* @__PURE__ */ new Map();
35
+ if (!implementationTypes || implementationTypes.length === 0) {
36
+ return [];
37
+ }
38
+ for (const implType of implementationTypes) {
39
+ if (implType.requirements?.environment) {
40
+ for (const envVar of implType.requirements.environment) {
41
+ if (!envVarsMap.has(envVar.name)) {
42
+ envVarsMap.set(envVar.name, envVar);
43
+ }
44
+ }
45
+ }
46
+ }
47
+ return Array.from(envVarsMap.values());
48
+ }
49
+ export {
50
+ generateEnvExample as default
51
+ };
@@ -0,0 +1,61 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ function generateEnv(context) {
4
+ const { manifest } = context;
5
+ const envVars = aggregateEnvironmentVariables(context.implementationTypes || []);
6
+ let parentDatabaseUrl;
7
+ try {
8
+ const parentEnvPath = join(process.cwd(), ".env");
9
+ if (existsSync(parentEnvPath)) {
10
+ const parentEnvContent = readFileSync(parentEnvPath, "utf-8");
11
+ const match = parentEnvContent.match(/DATABASE_URL=["']?([^"'\n]+)["']?/);
12
+ if (match) {
13
+ parentDatabaseUrl = match[1];
14
+ }
15
+ }
16
+ } catch (err) {
17
+ }
18
+ const byCategory = {};
19
+ for (const envVar of envVars) {
20
+ const category = envVar.category || "Configuration";
21
+ if (!byCategory[category]) {
22
+ byCategory[category] = [];
23
+ }
24
+ byCategory[category].push(envVar);
25
+ }
26
+ const lines = [];
27
+ for (const [category, vars] of Object.entries(byCategory)) {
28
+ lines.push(`# ${category}`);
29
+ for (const envVar of vars) {
30
+ if (envVar.description) {
31
+ lines.push(`# ${envVar.description}`);
32
+ }
33
+ let value = envVar.example || "";
34
+ if (envVar.name === "DATABASE_URL" && parentDatabaseUrl) {
35
+ value = parentDatabaseUrl;
36
+ }
37
+ lines.push(`${envVar.name}="${value}"`);
38
+ }
39
+ lines.push("");
40
+ }
41
+ return lines.join("\n");
42
+ }
43
+ function aggregateEnvironmentVariables(implementationTypes) {
44
+ const envVarsMap = /* @__PURE__ */ new Map();
45
+ if (!implementationTypes || implementationTypes.length === 0) {
46
+ return [];
47
+ }
48
+ for (const implType of implementationTypes) {
49
+ if (implType.requirements?.environment) {
50
+ for (const envVar of implType.requirements.environment) {
51
+ if (!envVarsMap.has(envVar.name)) {
52
+ envVarsMap.set(envVar.name, envVar);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ return Array.from(envVarsMap.values());
58
+ }
59
+ export {
60
+ generateEnv as default
61
+ };
@@ -0,0 +1,59 @@
1
+ function generateGitIgnore(context) {
2
+ const { manifest } = context;
3
+ const ignorePatterns = [
4
+ "# Dependencies",
5
+ "node_modules/",
6
+ "",
7
+ "# Build output",
8
+ "dist/",
9
+ "build/",
10
+ "",
11
+ "# Environment",
12
+ ".env",
13
+ ".env.local",
14
+ ".env.*.local",
15
+ "",
16
+ "# TypeScript",
17
+ "*.tsbuildinfo",
18
+ "",
19
+ "# Logs",
20
+ "logs/",
21
+ "*.log",
22
+ "npm-debug.log*",
23
+ ""
24
+ ];
25
+ if (usesPrisma(manifest)) {
26
+ ignorePatterns.push(
27
+ "# Prisma",
28
+ "prisma/migrations/",
29
+ ""
30
+ );
31
+ }
32
+ ignorePatterns.push(
33
+ "# IDE",
34
+ ".vscode/",
35
+ ".idea/",
36
+ "*.swp",
37
+ "*.swo",
38
+ "",
39
+ "# OS",
40
+ ".DS_Store",
41
+ "Thumbs.db",
42
+ "",
43
+ "# Testing",
44
+ "coverage/",
45
+ ".nyc_output/"
46
+ );
47
+ return ignorePatterns.join("\n");
48
+ }
49
+ function usesPrisma(manifest) {
50
+ if (!manifest || !manifest.capabilityMappings) {
51
+ return false;
52
+ }
53
+ return manifest.capabilityMappings.some(
54
+ (m) => m.instanceFactory?.toLowerCase().includes("prisma")
55
+ );
56
+ }
57
+ export {
58
+ generateGitIgnore as default
59
+ };
@@ -0,0 +1,126 @@
1
+ function generatePackageJson(context) {
2
+ const { spec, manifest, configuration } = context;
3
+ const outputStructure = configuration?.outputStructure || "monorepo";
4
+ const isMonorepo = outputStructure === "monorepo";
5
+ const aggregated = aggregateRequirements(context.instanceFactories || context.implementationTypes || []);
6
+ const pkg = {
7
+ name: (spec.metadata?.component || "specverse-app").toLowerCase().replace(/\s+/g, "-"),
8
+ version: spec.metadata?.version || "1.0.0",
9
+ description: spec.metadata?.description || "",
10
+ private: true,
11
+ type: "module"
12
+ };
13
+ if (isMonorepo) {
14
+ const frontendDir = configuration?.frontendDir || "frontend";
15
+ const backendDir = configuration?.backendDir || "backend";
16
+ pkg.workspaces = [backendDir, frontendDir];
17
+ pkg.scripts = {
18
+ // Build all workspaces
19
+ "build": "npm run build --workspaces",
20
+ "build:backend": `npm run build --workspace=${backendDir}`,
21
+ "build:frontend": `npm run build --workspace=${frontendDir}`,
22
+ // Production
23
+ "start": `npm run start --workspace=${backendDir}`,
24
+ // Development
25
+ "dev": "npm run dev --workspaces",
26
+ "dev:backend": `npm run dev --workspace=${backendDir}`,
27
+ "dev:frontend": `npm run dev --workspace=${frontendDir}`,
28
+ // Testing
29
+ "test": "npm test --workspaces",
30
+ "test:backend": `npm test --workspace=${backendDir}`,
31
+ "test:frontend": `npm test --workspace=${frontendDir}`,
32
+ // Database management (backend)
33
+ "db:setup": `npm run db:setup --workspace=${backendDir}`,
34
+ "db:generate": `npm run db:generate --workspace=${backendDir}`,
35
+ "db:push": `npm run db:push --workspace=${backendDir}`,
36
+ "db:migrate": `npm run db:migrate --workspace=${backendDir}`,
37
+ "db:studio": `npm run db:studio --workspace=${backendDir}`,
38
+ // Linting
39
+ "lint": "npm run lint --workspaces",
40
+ "lint:fix": "npm run lint:fix --workspaces"
41
+ };
42
+ } else {
43
+ pkg.scripts = {
44
+ ...aggregated.scripts,
45
+ // Ensure we have build script if TypeScript
46
+ ...aggregated.usesTypeScript && !aggregated.scripts.build && {
47
+ build: "tsc"
48
+ },
49
+ // Add database setup script
50
+ "db:setup": `node -e "const{execSync:e}=require('child_process');const{readFileSync:r}=require('fs');try{const d=r('.env','utf8').match(/DATABASE_URL=.*\\/([^?\\"]+)/)?.[1];if(!d)throw new Error('DATABASE_URL not found');console.log('Creating database:',d);try{e('createdb '+d)}catch(err){const errMsg=err.stderr?err.stderr.toString():err.message;if(errMsg.includes('already exists')){console.log('\u2705 Database already exists')}else throw err}console.log('\u2705 Database created successfully')}catch(err){console.error('\u274C Database setup failed:',err.message);process.exit(1)}"`,
51
+ // Add test script if not provided by implementation types
52
+ ...!aggregated.scripts.test && {
53
+ test: 'echo "Error: no test specified" && exit 1'
54
+ }
55
+ };
56
+ pkg.dependencies = aggregated.dependencies;
57
+ pkg.devDependencies = {
58
+ ...aggregated.devDependencies,
59
+ // Ensure TypeScript is present if needed
60
+ ...aggregated.usesTypeScript && !aggregated.devDependencies.typescript && {
61
+ typescript: "^5.3.0",
62
+ "@types/node": "^20.0.0"
63
+ }
64
+ };
65
+ if (aggregated.usesTypeScript) {
66
+ pkg.main = "dist/main.js";
67
+ pkg.types = "dist/main.d.ts";
68
+ }
69
+ }
70
+ pkg.engines = {
71
+ node: ">=18.0.0"
72
+ };
73
+ return JSON.stringify(pkg, null, 2);
74
+ }
75
+ function aggregateRequirements(implementationTypes) {
76
+ const result = {
77
+ dependencies: {},
78
+ devDependencies: {},
79
+ scripts: {},
80
+ environment: [],
81
+ usesTypeScript: false,
82
+ usesDocker: false
83
+ };
84
+ if (!implementationTypes || implementationTypes.length === 0) {
85
+ return result;
86
+ }
87
+ for (const implType of implementationTypes) {
88
+ if (implType.dependencies) {
89
+ if (implType.dependencies.runtime && Array.isArray(implType.dependencies.runtime)) {
90
+ for (const dep of implType.dependencies.runtime) {
91
+ if (dep.name && dep.version) {
92
+ result.dependencies[dep.name] = dep.version;
93
+ }
94
+ }
95
+ }
96
+ if (implType.dependencies.dev && Array.isArray(implType.dependencies.dev)) {
97
+ for (const dep of implType.dependencies.dev) {
98
+ if (dep.name && dep.version) {
99
+ result.devDependencies[dep.name] = dep.version;
100
+ }
101
+ }
102
+ }
103
+ }
104
+ const requirements = implType.requirements;
105
+ if (requirements) {
106
+ if (requirements.dependencies?.npm) {
107
+ Object.assign(result.dependencies, requirements.dependencies.npm.dependencies || {});
108
+ Object.assign(result.devDependencies, requirements.dependencies.npm.devDependencies || {});
109
+ Object.assign(result.scripts, requirements.dependencies.npm.scripts || {});
110
+ }
111
+ if (requirements.environment) {
112
+ result.environment.push(...requirements.environment);
113
+ }
114
+ }
115
+ if (implType.technology?.language === "typescript") {
116
+ result.usesTypeScript = true;
117
+ }
118
+ if (implType.capabilities?.provides?.includes("container.dev")) {
119
+ result.usesDocker = true;
120
+ }
121
+ }
122
+ return result;
123
+ }
124
+ export {
125
+ generatePackageJson as default
126
+ };