eva4j 1.0.16 ā 1.0.18
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/AGENTS.md +220 -5
- package/DOMAIN_YAML_GUIDE.md +188 -3
- package/FUTURE_FEATURES.md +33 -52
- package/QUICK_REFERENCE.md +8 -4
- package/bin/eva4j.js +70 -2
- package/config/defaults.json +1 -0
- package/docs/CAMUNDA_DMN_GUIDE.md +1380 -0
- package/docs/KAFKA_PRODUCTION_CONFIG.md +441 -0
- package/docs/RABBITMQ_PRODUCTION_CONFIG.md +227 -0
- package/docs/commands/ADD_RABBITMQ_CLIENT.md +192 -0
- package/docs/commands/EVALUATE_SYSTEM.md +290 -10
- package/docs/commands/GENERATE_RABBITMQ_EVENT.md +341 -0
- package/docs/commands/GENERATE_RABBITMQ_LISTENER.md +595 -0
- package/docs/commands/GENERATE_TEMPORAL_FLOW.md +52 -12
- package/docs/commands/INDEX.md +27 -3
- package/docs/prototype/TEMPORAL_COMMUNICATION_PATTERNS.md +731 -0
- package/docs/prototype/TEMPORAL_DESIGN_METHODOLOGY.md +740 -0
- package/docs/prototype/system/RISKS.md +277 -0
- package/docs/prototype/system/customers.yaml +133 -0
- package/docs/prototype/system/inventory.yaml +109 -0
- package/docs/prototype/system/notifications.yaml +131 -0
- package/docs/prototype/system/orders.yaml +241 -0
- package/docs/prototype/system/payments.yaml +256 -0
- package/docs/prototype/system/products.yaml +168 -0
- package/docs/prototype/system/system.yaml +269 -0
- package/examples/domain-endpoints-multi-aggregate.yaml +140 -0
- package/examples/domain-events.yaml +26 -0
- package/examples/domain-read-models.yaml +113 -0
- package/examples/system/customer.yaml +89 -0
- package/examples/system/orders.yaml +119 -0
- package/examples/system/product.yaml +27 -0
- package/examples/system/system.yaml +80 -0
- package/package.json +1 -1
- package/read-model-spec.md +664 -0
- package/src/agents/design-gap-analyst-temporal.agent.md +452 -0
- package/src/agents/design-gap-analyst.agent.md +383 -0
- package/src/agents/design-reviewer-temporal.agent.md +412 -0
- package/src/agents/design-reviewer.agent.md +34 -5
- package/src/agents/implement-use-cases.prompt.md +179 -0
- package/src/agents/ux-gap-analyst.agent.md +412 -0
- package/src/commands/add-rabbitmq-client.js +261 -0
- package/src/commands/add-temporal-client.js +22 -2
- package/src/commands/build.js +267 -11
- package/src/commands/evaluate-system.js +700 -13
- package/src/commands/generate-entities.js +560 -24
- package/src/commands/generate-http-exchange.js +3 -0
- package/src/commands/generate-kafka-event.js +3 -0
- package/src/commands/generate-kafka-listener.js +3 -0
- package/src/commands/generate-rabbitmq-event.js +665 -0
- package/src/commands/generate-rabbitmq-listener.js +205 -0
- package/src/commands/generate-record.js +2 -2
- package/src/commands/generate-resource.js +4 -1
- package/src/commands/generate-temporal-activity.js +970 -33
- package/src/commands/generate-temporal-flow.js +98 -38
- package/src/commands/generate-temporal-system.js +708 -0
- package/src/commands/generate-usecase.js +4 -1
- package/src/skills/build-system-yaml/SKILL.md +343 -2
- package/src/skills/build-system-yaml/references/domain-yaml-spec.md +253 -26
- package/src/skills/build-system-yaml/references/module-spec.md +90 -9
- package/src/skills/build-system-yaml/references/system-yaml-spec.md +36 -0
- package/src/skills/build-temporal-system/SKILL.md +752 -0
- package/src/skills/build-temporal-system/references/temporal-communication-patterns.md +167 -0
- package/src/skills/build-temporal-system/references/temporal-domain-yaml-spec.md +449 -0
- package/src/skills/build-temporal-system/references/temporal-module-spec.md +353 -0
- package/src/skills/build-temporal-system/references/temporal-system-yaml-spec.md +326 -0
- package/src/skills/implement-use-case/SKILL.md +350 -0
- package/src/skills/implement-use-case/references/use-case-patterns.md +980 -0
- package/src/skills/requirements-elicitation/SKILL.md +228 -0
- package/src/skills/requirements-elicitation/references/interview-framework.md +260 -0
- package/src/skills/requirements-elicitation/references/output-templates.md +368 -0
- package/src/utils/bounded-context-diagram.js +844 -0
- package/src/utils/config-manager.js +4 -2
- package/src/utils/domain-validator.js +495 -17
- package/src/utils/naming.js +20 -0
- package/src/utils/system-validator.js +169 -11
- package/src/utils/system-yaml-parser.js +318 -0
- package/src/utils/temporal-validator.js +497 -0
- package/src/utils/validator.js +3 -1
- package/src/utils/yaml-to-entity.js +281 -9
- package/templates/aggregate/AggregateRepository.java.ejs +4 -0
- package/templates/aggregate/AggregateRepositoryImpl.java.ejs +8 -0
- package/templates/aggregate/AggregateRoot.java.ejs +38 -4
- package/templates/aggregate/DomainEventHandler.java.ejs +116 -22
- package/templates/aggregate/JpaAggregateRoot.java.ejs +4 -4
- package/templates/aggregate/JpaEntity.java.ejs +2 -2
- package/templates/base/docker/rabbitmq-services.yaml.ejs +12 -0
- package/templates/base/resources/parameters/develop/kafka.yaml.ejs +5 -0
- package/templates/base/resources/parameters/develop/rabbitmq.yaml.ejs +15 -0
- package/templates/base/resources/parameters/develop/temporal.yaml.ejs +0 -3
- package/templates/base/resources/parameters/local/kafka.yaml.ejs +5 -0
- package/templates/base/resources/parameters/local/rabbitmq.yaml.ejs +15 -0
- package/templates/base/resources/parameters/local/temporal.yaml.ejs +0 -3
- package/templates/base/resources/parameters/production/kafka.yaml.ejs +39 -8
- package/templates/base/resources/parameters/production/rabbitmq.yaml.ejs +32 -0
- package/templates/base/resources/parameters/production/temporal.yaml.ejs +0 -3
- package/templates/base/resources/parameters/test/kafka.yaml.ejs +12 -6
- package/templates/base/resources/parameters/test/rabbitmq.yaml.ejs +15 -0
- package/templates/base/resources/parameters/test/temporal.yaml.ejs +0 -3
- package/templates/base/root/AGENTS.md.ejs +1 -1
- package/templates/crud/DeleteCommandHandler.java.ejs +19 -1
- package/templates/crud/EndpointsController.java.ejs +1 -1
- package/templates/crud/ScaffoldCommand.java.ejs +5 -2
- package/templates/crud/ScaffoldCommandHandler.java.ejs +3 -1
- package/templates/crud/ScaffoldQuery.java.ejs +5 -2
- package/templates/crud/ScaffoldQueryHandler.java.ejs +3 -1
- package/templates/crud/SubEntityRemoveCommand.java.ejs +1 -1
- package/templates/crud/UpdateCommandHandler.java.ejs +53 -2
- package/templates/evaluate/report.html.ejs +1447 -90
- package/templates/kafka-event/KafkaConfigBean.java.ejs +1 -1
- package/templates/kafka-event/KafkaMessageBroker.java.ejs +3 -3
- package/templates/ports/PortAclMapper.java.ejs +35 -0
- package/templates/ports/PortFeignAdapter.java.ejs +7 -22
- package/templates/ports/PortFeignClient.java.ejs +4 -0
- package/templates/ports/PortResponseDto.java.ejs +1 -1
- package/templates/rabbitmq-event/RabbitConfigBean.java.ejs +33 -0
- package/templates/rabbitmq-event/RabbitConfigExchange.java.ejs +12 -0
- package/templates/rabbitmq-event/RabbitMessageBroker.java.ejs +35 -0
- package/templates/rabbitmq-event/RabbitMessageBrokerMethod.java.ejs +9 -0
- package/templates/rabbitmq-listener/RabbitConfigConsumerBean.java.ejs +33 -0
- package/templates/rabbitmq-listener/RabbitConfigConsumerExchange.java.ejs +12 -0
- package/templates/rabbitmq-listener/RabbitListenerClass.java.ejs +82 -0
- package/templates/rabbitmq-listener/RabbitListenerSimple.java.ejs +56 -0
- package/templates/read-model/ReadModelDomain.java.ejs +46 -0
- package/templates/read-model/ReadModelJpa.java.ejs +58 -0
- package/templates/read-model/ReadModelJpaRepository.java.ejs +13 -0
- package/templates/read-model/ReadModelKafkaListener.java.ejs +64 -0
- package/templates/read-model/ReadModelRabbitListener.java.ejs +71 -0
- package/templates/read-model/ReadModelRepository.java.ejs +42 -0
- package/templates/read-model/ReadModelRepositoryImpl.java.ejs +85 -0
- package/templates/read-model/ReadModelSyncHandler.java.ejs +54 -0
- package/templates/shared/configurations/kafkaConfig/KafkaConfig.java.ejs +18 -4
- package/templates/shared/configurations/rabbitmqConfig/RabbitMQConfig.java.ejs +100 -0
- package/templates/shared/configurations/temporalConfig/TemporalConfig.java.ejs +2 -64
- package/templates/shared/configurations/temporalConfig/TemporalWorkerFactoryLifecycle.java.ejs +41 -0
- package/templates/temporal-activity/ActivityImpl.java.ejs +68 -2
- package/templates/temporal-activity/ActivityInput.java.ejs +14 -0
- package/templates/temporal-activity/ActivityInterface.java.ejs +7 -1
- package/templates/temporal-activity/ActivityOutput.java.ejs +14 -0
- package/templates/temporal-activity/NestedType.java.ejs +12 -0
- package/templates/temporal-activity/SharedActivityInput.java.ejs +14 -0
- package/templates/temporal-activity/SharedActivityInterface.java.ejs +15 -0
- package/templates/temporal-activity/SharedActivityOutput.java.ejs +14 -0
- package/templates/temporal-activity/SharedNestedType.java.ejs +12 -0
- package/templates/temporal-flow/ModuleHeavyActivity.java.ejs +6 -0
- package/templates/temporal-flow/ModuleLightActivity.java.ejs +6 -0
- package/templates/temporal-flow/ModuleTemporalWorkerConfig.java.ejs +58 -0
- package/templates/temporal-flow/WorkFlowImpl.java.ejs +172 -12
- package/templates/temporal-flow/WorkFlowInput.java.ejs +11 -0
- package/templates/temporal-flow/WorkFlowInterface.java.ejs +5 -4
- package/templates/temporal-flow/WorkFlowService.java.ejs +42 -12
- package/COMMAND_EVALUATION.md +0 -911
|
@@ -5,7 +5,7 @@ const path = require('path');
|
|
|
5
5
|
const fs = require('fs-extra');
|
|
6
6
|
const ConfigManager = require('../utils/config-manager');
|
|
7
7
|
const { isEva4jProject, moduleExists } = require('../utils/validator');
|
|
8
|
-
const { toPackagePath, toPascalCase } = require('../utils/naming');
|
|
8
|
+
const { toPackagePath, toPascalCase, toCamelCase, toScreamingSnakeCase } = require('../utils/naming');
|
|
9
9
|
const { renderAndWrite } = require('../utils/template-engine');
|
|
10
10
|
const ChecksumManager = require('../utils/checksum-manager');
|
|
11
11
|
|
|
@@ -48,6 +48,9 @@ async function generateTemporalFlowCommand(moduleName, flowName, options = {}) {
|
|
|
48
48
|
const { packageName } = projectConfig;
|
|
49
49
|
const packagePath = toPackagePath(packageName);
|
|
50
50
|
|
|
51
|
+
// Normalise module name to camelCase (system.yaml uses kebab-case, .eva4j.json stores camelCase)
|
|
52
|
+
moduleName = toCamelCase(moduleName);
|
|
53
|
+
|
|
51
54
|
if (!(await configManager.moduleExists(moduleName))) {
|
|
52
55
|
console.error(chalk.red(`ā Module '${moduleName}' does not exist`));
|
|
53
56
|
console.error(chalk.gray(`Create it first using: eva add module ${moduleName}`));
|
|
@@ -72,6 +75,8 @@ async function generateTemporalFlowCommand(moduleName, flowName, options = {}) {
|
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
const flowPascalCase = toPascalCase(flowName);
|
|
78
|
+
const modulePascalCase = toPascalCase(moduleName);
|
|
79
|
+
const moduleScreamingSnake = toScreamingSnakeCase(moduleName);
|
|
75
80
|
|
|
76
81
|
const moduleBasePath = path.join(
|
|
77
82
|
projectDir,
|
|
@@ -92,6 +97,9 @@ async function generateTemporalFlowCommand(moduleName, flowName, options = {}) {
|
|
|
92
97
|
packageName,
|
|
93
98
|
moduleName,
|
|
94
99
|
flowPascalCase,
|
|
100
|
+
modulePascalCase,
|
|
101
|
+
moduleCamelCase: moduleName,
|
|
102
|
+
moduleScreamingSnake,
|
|
95
103
|
};
|
|
96
104
|
|
|
97
105
|
const templatesDir = path.join(__dirname, '..', '..', 'templates', 'temporal-flow');
|
|
@@ -125,9 +133,42 @@ async function generateTemporalFlowCommand(moduleName, flowName, options = {}) {
|
|
|
125
133
|
writeOptions
|
|
126
134
|
);
|
|
127
135
|
|
|
128
|
-
// 4.
|
|
129
|
-
spinner.text =
|
|
130
|
-
|
|
136
|
+
// 4. Generate module-scoped marker interfaces (idempotent)
|
|
137
|
+
spinner.text = `Generating ${modulePascalCase} Temporal interfaces...`;
|
|
138
|
+
const interfacesDir = path.join(moduleBasePath, 'domain', 'interfaces');
|
|
139
|
+
await renderAndWrite(
|
|
140
|
+
path.join(templatesDir, 'ModuleHeavyActivity.java.ejs'),
|
|
141
|
+
path.join(interfacesDir, `${modulePascalCase}HeavyActivity.java`),
|
|
142
|
+
context,
|
|
143
|
+
writeOptions
|
|
144
|
+
);
|
|
145
|
+
await renderAndWrite(
|
|
146
|
+
path.join(templatesDir, 'ModuleLightActivity.java.ejs'),
|
|
147
|
+
path.join(interfacesDir, `${modulePascalCase}LightActivity.java`),
|
|
148
|
+
context,
|
|
149
|
+
writeOptions
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// 5. Generate ModuleTemporalWorkerConfig (idempotent)
|
|
153
|
+
spinner.text = `Generating ${modulePascalCase}TemporalWorkerConfig...`;
|
|
154
|
+
const configDir = path.join(moduleBasePath, 'infrastructure', 'configurations');
|
|
155
|
+
await renderAndWrite(
|
|
156
|
+
path.join(templatesDir, 'ModuleTemporalWorkerConfig.java.ejs'),
|
|
157
|
+
path.join(configDir, `${modulePascalCase}TemporalWorkerConfig.java`),
|
|
158
|
+
context,
|
|
159
|
+
writeOptions
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
// 6. Register workflow in module worker config
|
|
163
|
+
spinner.text = 'Registering workflow in module worker config...';
|
|
164
|
+
await registerWorkflowInModuleWorkerConfig(
|
|
165
|
+
path.join(configDir, `${modulePascalCase}TemporalWorkerConfig.java`),
|
|
166
|
+
packageName, moduleName, flowPascalCase, modulePascalCase
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// 7. Append module queue section to temporal.yaml (idempotent)
|
|
170
|
+
spinner.text = 'Updating temporal.yaml with module queues...';
|
|
171
|
+
await appendModuleQueues(projectDir, moduleName, moduleScreamingSnake);
|
|
131
172
|
|
|
132
173
|
spinner.succeed(chalk.green(`ā
${flowPascalCase}WorkFlow generated successfully`));
|
|
133
174
|
|
|
@@ -135,8 +176,13 @@ async function generateTemporalFlowCommand(moduleName, flowName, options = {}) {
|
|
|
135
176
|
console.log(chalk.gray(` ${moduleName}/application/usecases/${flowPascalCase}WorkFlow.java`));
|
|
136
177
|
console.log(chalk.gray(` ${moduleName}/application/usecases/${flowPascalCase}WorkFlowImpl.java`));
|
|
137
178
|
console.log(chalk.gray(` ${moduleName}/application/usecases/${flowPascalCase}WorkFlowService.java`));
|
|
138
|
-
console.log(chalk.
|
|
139
|
-
console.log(chalk.gray(
|
|
179
|
+
console.log(chalk.gray(` ${moduleName}/domain/interfaces/${modulePascalCase}HeavyActivity.java`));
|
|
180
|
+
console.log(chalk.gray(` ${moduleName}/domain/interfaces/${modulePascalCase}LightActivity.java`));
|
|
181
|
+
console.log(chalk.gray(` ${moduleName}/infrastructure/configurations/${modulePascalCase}TemporalWorkerConfig.java`));
|
|
182
|
+
console.log(chalk.blue('\nš Queue names:'));
|
|
183
|
+
console.log(chalk.gray(` Flow: ${moduleScreamingSnake}_WORKFLOW_QUEUE`));
|
|
184
|
+
console.log(chalk.gray(` Heavy: ${moduleScreamingSnake}_HEAVY_TASK_QUEUE`));
|
|
185
|
+
console.log(chalk.gray(` Light: ${moduleScreamingSnake}_LIGHT_TASK_QUEUE`));
|
|
140
186
|
|
|
141
187
|
await checksumManager.save();
|
|
142
188
|
} catch (error) {
|
|
@@ -146,22 +192,9 @@ async function generateTemporalFlowCommand(moduleName, flowName, options = {}) {
|
|
|
146
192
|
}
|
|
147
193
|
}
|
|
148
194
|
|
|
149
|
-
async function
|
|
150
|
-
const configPath = path.join(
|
|
151
|
-
projectDir,
|
|
152
|
-
'src',
|
|
153
|
-
'main',
|
|
154
|
-
'java',
|
|
155
|
-
packagePath,
|
|
156
|
-
'shared',
|
|
157
|
-
'infrastructure',
|
|
158
|
-
'configurations',
|
|
159
|
-
'temporalConfig',
|
|
160
|
-
'TemporalConfig.java'
|
|
161
|
-
);
|
|
162
|
-
|
|
195
|
+
async function registerWorkflowInModuleWorkerConfig(configPath, packageName, moduleName, flowPascalCase, modulePascalCase) {
|
|
163
196
|
if (!(await fs.pathExists(configPath))) {
|
|
164
|
-
console.warn(chalk.yellow(
|
|
197
|
+
console.warn(chalk.yellow(`\nā ļø ${modulePascalCase}TemporalWorkerConfig.java not found ā skipping auto-registration`));
|
|
165
198
|
return;
|
|
166
199
|
}
|
|
167
200
|
|
|
@@ -172,40 +205,31 @@ async function registerWorkflowInTemporalConfig(projectDir, packagePath, package
|
|
|
172
205
|
|
|
173
206
|
// Add import if not already present
|
|
174
207
|
if (!content.includes(importLine)) {
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
const lastImport = allImports[allImports.length - 1];
|
|
181
|
-
const insertPos = lastImport.index + lastImport[0].length;
|
|
182
|
-
content = content.slice(0, insertPos) + '\n' + importLine + content.slice(insertPos);
|
|
183
|
-
}
|
|
208
|
+
const allImports = [...content.matchAll(/^import .+;/gm)];
|
|
209
|
+
if (allImports.length > 0) {
|
|
210
|
+
const lastImport = allImports[allImports.length - 1];
|
|
211
|
+
const insertPos = lastImport.index + lastImport[0].length;
|
|
212
|
+
content = content.slice(0, insertPos) + '\n' + importLine + content.slice(insertPos);
|
|
184
213
|
}
|
|
185
214
|
}
|
|
186
215
|
|
|
187
|
-
// Remove TODO comment and commented-out example placeholder
|
|
188
|
-
content = content.replace(/[ \t]*\/\/ TODO: register your workflow implementation types here\r?\n/g, '');
|
|
189
|
-
content = content.replace(/[ \t]*\/\/ workflowWorker\.registerWorkflowImplementationTypes\(MyWorkflowImpl\.class\);\r?\n?/g, '');
|
|
190
|
-
|
|
191
216
|
// Check if there is already an active registerWorkflowImplementationTypes call
|
|
192
217
|
const activeRegisterRegex = /workflowWorker\.registerWorkflowImplementationTypes\(([^)]+)\);/;
|
|
193
218
|
if (activeRegisterRegex.test(content)) {
|
|
194
|
-
// Add the new class, filtering out the stale MyWorkflowImpl example if still present
|
|
195
219
|
content = content.replace(activeRegisterRegex, (match, classes) => {
|
|
196
220
|
const classList = classes
|
|
197
221
|
.split(',')
|
|
198
222
|
.map((c) => c.trim())
|
|
199
|
-
.filter((c) => c
|
|
223
|
+
.filter((c) => c.length > 0);
|
|
200
224
|
if (!classList.includes(`${implClass}.class`)) {
|
|
201
225
|
classList.push(`${implClass}.class`);
|
|
202
226
|
}
|
|
203
227
|
return `workflowWorker.registerWorkflowImplementationTypes(${classList.join(', ')});`;
|
|
204
228
|
});
|
|
205
229
|
} else {
|
|
206
|
-
// Insert active registration after the
|
|
230
|
+
// Insert active registration after the comment marker
|
|
207
231
|
content = content.replace(
|
|
208
|
-
/(
|
|
232
|
+
/(\/\/ registered by eva g temporal-flow\r?\n)/,
|
|
209
233
|
`$1 workflowWorker.registerWorkflowImplementationTypes(${implClass}.class);\n`
|
|
210
234
|
);
|
|
211
235
|
}
|
|
@@ -213,4 +237,40 @@ async function registerWorkflowInTemporalConfig(projectDir, packagePath, package
|
|
|
213
237
|
await fs.writeFile(configPath, content, 'utf-8');
|
|
214
238
|
}
|
|
215
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Append module-specific queue configuration to temporal.yaml files (idempotent)
|
|
242
|
+
*/
|
|
243
|
+
async function appendModuleQueues(projectDir, moduleName, moduleScreamingSnake) {
|
|
244
|
+
const environments = ['local', 'develop', 'test', 'production'];
|
|
245
|
+
const resourcesDir = path.join(projectDir, 'src', 'main', 'resources', 'parameters');
|
|
246
|
+
|
|
247
|
+
const moduleSection = [
|
|
248
|
+
` ${moduleName}:`,
|
|
249
|
+
` flow-queue: ${moduleScreamingSnake}_WORKFLOW_QUEUE`,
|
|
250
|
+
` heavy-queue: ${moduleScreamingSnake}_HEAVY_TASK_QUEUE`,
|
|
251
|
+
` light-queue: ${moduleScreamingSnake}_LIGHT_TASK_QUEUE`,
|
|
252
|
+
].join('\n');
|
|
253
|
+
|
|
254
|
+
for (const env of environments) {
|
|
255
|
+
const yamlPath = path.join(resourcesDir, env, 'temporal.yaml');
|
|
256
|
+
|
|
257
|
+
if (!(await fs.pathExists(yamlPath))) continue;
|
|
258
|
+
|
|
259
|
+
let content = await fs.readFile(yamlPath, 'utf-8');
|
|
260
|
+
|
|
261
|
+
// Skip if module already registered
|
|
262
|
+
if (content.includes(`${moduleName}:`)) continue;
|
|
263
|
+
|
|
264
|
+
// Add modules: section if not present
|
|
265
|
+
if (!content.includes('modules:')) {
|
|
266
|
+
content = content.trimEnd() + '\n modules:\n' + moduleSection + '\n';
|
|
267
|
+
} else {
|
|
268
|
+
// Append under existing modules: section
|
|
269
|
+
content = content.trimEnd() + '\n' + moduleSection + '\n';
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
await fs.writeFile(yamlPath, content, 'utf-8');
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
216
276
|
module.exports = generateTemporalFlowCommand;
|