@friggframework/devtools 2.0.0-next.45 → 2.0.0-next.46
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/infrastructure/ARCHITECTURE.md +487 -0
- package/infrastructure/HEALTH.md +468 -0
- package/infrastructure/README.md +51 -0
- package/infrastructure/__tests__/postgres-config.test.js +914 -0
- package/infrastructure/__tests__/template-generation.test.js +687 -0
- package/infrastructure/create-frigg-infrastructure.js +1 -1
- package/infrastructure/docs/POSTGRES-CONFIGURATION.md +630 -0
- package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
- package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
- package/infrastructure/domains/database/aurora-builder.js +809 -0
- package/infrastructure/domains/database/aurora-builder.test.js +950 -0
- package/infrastructure/domains/database/aurora-discovery.js +87 -0
- package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
- package/infrastructure/domains/database/aurora-resolver.js +210 -0
- package/infrastructure/domains/database/aurora-resolver.test.js +347 -0
- package/infrastructure/domains/database/migration-builder.js +633 -0
- package/infrastructure/domains/database/migration-builder.test.js +294 -0
- package/infrastructure/domains/database/migration-resolver.js +163 -0
- package/infrastructure/domains/database/migration-resolver.test.js +337 -0
- package/infrastructure/domains/health/application/ports/IPropertyReconciler.js +164 -0
- package/infrastructure/domains/health/application/ports/IResourceDetector.js +129 -0
- package/infrastructure/domains/health/application/ports/IResourceImporter.js +142 -0
- package/infrastructure/domains/health/application/ports/IStackRepository.js +131 -0
- package/infrastructure/domains/health/application/ports/index.js +26 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/execute-resource-import-use-case.test.js +679 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/mismatch-analyzer-method-name.test.js +167 -0
- package/infrastructure/domains/health/application/use-cases/__tests__/repair-via-import-use-case.test.js +1130 -0
- package/infrastructure/domains/health/application/use-cases/execute-resource-import-use-case.js +221 -0
- package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.js +152 -0
- package/infrastructure/domains/health/application/use-cases/reconcile-properties-use-case.test.js +343 -0
- package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.js +535 -0
- package/infrastructure/domains/health/application/use-cases/repair-via-import-use-case.test.js +376 -0
- package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.js +213 -0
- package/infrastructure/domains/health/application/use-cases/run-health-check-use-case.test.js +441 -0
- package/infrastructure/domains/health/docs/ACME-DEV-DRIFT-ANALYSIS.md +267 -0
- package/infrastructure/domains/health/docs/BUILD-VS-DEPLOYED-TEMPLATE-ANALYSIS.md +324 -0
- package/infrastructure/domains/health/docs/ORPHAN-DETECTION-ANALYSIS.md +386 -0
- package/infrastructure/domains/health/docs/SPEC-CLEANUP-COMMAND.md +1419 -0
- package/infrastructure/domains/health/docs/TDD-IMPLEMENTATION-SUMMARY.md +391 -0
- package/infrastructure/domains/health/docs/TEMPLATE-COMPARISON-IMPLEMENTATION.md +551 -0
- package/infrastructure/domains/health/domain/entities/issue.js +299 -0
- package/infrastructure/domains/health/domain/entities/issue.test.js +528 -0
- package/infrastructure/domains/health/domain/entities/property-mismatch.js +108 -0
- package/infrastructure/domains/health/domain/entities/property-mismatch.test.js +275 -0
- package/infrastructure/domains/health/domain/entities/resource.js +159 -0
- package/infrastructure/domains/health/domain/entities/resource.test.js +432 -0
- package/infrastructure/domains/health/domain/entities/stack-health-report.js +306 -0
- package/infrastructure/domains/health/domain/entities/stack-health-report.test.js +601 -0
- package/infrastructure/domains/health/domain/services/__tests__/health-score-percentage-based.test.js +380 -0
- package/infrastructure/domains/health/domain/services/__tests__/import-progress-monitor.test.js +971 -0
- package/infrastructure/domains/health/domain/services/__tests__/import-template-generator.test.js +1150 -0
- package/infrastructure/domains/health/domain/services/__tests__/logical-id-mapper.test.js +672 -0
- package/infrastructure/domains/health/domain/services/__tests__/template-parser.test.js +496 -0
- package/infrastructure/domains/health/domain/services/__tests__/update-progress-monitor.test.js +419 -0
- package/infrastructure/domains/health/domain/services/health-score-calculator.js +248 -0
- package/infrastructure/domains/health/domain/services/health-score-calculator.test.js +504 -0
- package/infrastructure/domains/health/domain/services/import-progress-monitor.js +195 -0
- package/infrastructure/domains/health/domain/services/import-template-generator.js +435 -0
- package/infrastructure/domains/health/domain/services/logical-id-mapper.js +345 -0
- package/infrastructure/domains/health/domain/services/mismatch-analyzer.js +234 -0
- package/infrastructure/domains/health/domain/services/mismatch-analyzer.test.js +431 -0
- package/infrastructure/domains/health/domain/services/property-mutability-config.js +382 -0
- package/infrastructure/domains/health/domain/services/template-parser.js +245 -0
- package/infrastructure/domains/health/domain/services/update-progress-monitor.js +192 -0
- package/infrastructure/domains/health/domain/value-objects/health-score.js +138 -0
- package/infrastructure/domains/health/domain/value-objects/health-score.test.js +267 -0
- package/infrastructure/domains/health/domain/value-objects/property-mutability.js +161 -0
- package/infrastructure/domains/health/domain/value-objects/property-mutability.test.js +198 -0
- package/infrastructure/domains/health/domain/value-objects/resource-state.js +167 -0
- package/infrastructure/domains/health/domain/value-objects/resource-state.test.js +196 -0
- package/infrastructure/domains/health/domain/value-objects/stack-identifier.js +192 -0
- package/infrastructure/domains/health/domain/value-objects/stack-identifier.test.js +262 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-cfn-tagged.test.js +312 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-multi-stack.test.js +367 -0
- package/infrastructure/domains/health/infrastructure/adapters/__tests__/orphan-detection-relationship-analysis.test.js +432 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.js +784 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-property-reconciler.test.js +1133 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.js +565 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-detector.test.js +554 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.js +318 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-resource-importer.test.js +398 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.js +777 -0
- package/infrastructure/domains/health/infrastructure/adapters/aws-stack-repository.test.js +580 -0
- package/infrastructure/domains/integration/integration-builder.js +397 -0
- package/infrastructure/domains/integration/integration-builder.test.js +593 -0
- package/infrastructure/domains/integration/integration-resolver.js +170 -0
- package/infrastructure/domains/integration/integration-resolver.test.js +369 -0
- package/infrastructure/domains/integration/websocket-builder.js +69 -0
- package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
- package/infrastructure/domains/networking/vpc-builder.js +1829 -0
- package/infrastructure/domains/networking/vpc-builder.test.js +1262 -0
- package/infrastructure/domains/networking/vpc-discovery.js +177 -0
- package/infrastructure/domains/networking/vpc-discovery.test.js +350 -0
- package/infrastructure/domains/networking/vpc-resolver.js +324 -0
- package/infrastructure/domains/networking/vpc-resolver.test.js +501 -0
- package/infrastructure/domains/parameters/ssm-builder.js +79 -0
- package/infrastructure/domains/parameters/ssm-builder.test.js +189 -0
- package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
- package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
- package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
- package/infrastructure/domains/security/kms-builder.js +366 -0
- package/infrastructure/domains/security/kms-builder.test.js +374 -0
- package/infrastructure/domains/security/kms-discovery.js +80 -0
- package/infrastructure/domains/security/kms-discovery.test.js +177 -0
- package/infrastructure/domains/security/kms-resolver.js +96 -0
- package/infrastructure/domains/security/kms-resolver.test.js +216 -0
- package/infrastructure/domains/shared/base-builder.js +112 -0
- package/infrastructure/domains/shared/base-resolver.js +186 -0
- package/infrastructure/domains/shared/base-resolver.test.js +305 -0
- package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
- package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
- package/infrastructure/domains/shared/cloudformation-discovery-v2.js +334 -0
- package/infrastructure/domains/shared/cloudformation-discovery.js +375 -0
- package/infrastructure/domains/shared/cloudformation-discovery.test.js +590 -0
- package/infrastructure/domains/shared/environment-builder.js +119 -0
- package/infrastructure/domains/shared/environment-builder.test.js +247 -0
- package/infrastructure/domains/shared/providers/aws-provider-adapter.js +544 -0
- package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +377 -0
- package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
- package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
- package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
- package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
- package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
- package/infrastructure/domains/shared/resource-discovery.js +192 -0
- package/infrastructure/domains/shared/resource-discovery.test.js +552 -0
- package/infrastructure/domains/shared/types/app-definition.js +205 -0
- package/infrastructure/domains/shared/types/discovery-result.js +106 -0
- package/infrastructure/domains/shared/types/discovery-result.test.js +258 -0
- package/infrastructure/domains/shared/types/index.js +46 -0
- package/infrastructure/domains/shared/types/resource-ownership.js +108 -0
- package/infrastructure/domains/shared/types/resource-ownership.test.js +101 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.js +380 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
- package/infrastructure/domains/shared/utilities/handler-path-resolver.js +134 -0
- package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +268 -0
- package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
- package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +138 -0
- package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +2 -1
- package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
- package/infrastructure/esbuild.config.js +53 -0
- package/infrastructure/infrastructure-composer.js +87 -0
- package/infrastructure/{serverless-template.test.js → infrastructure-composer.test.js} +115 -24
- package/infrastructure/scripts/build-prisma-layer.js +553 -0
- package/infrastructure/scripts/build-prisma-layer.test.js +102 -0
- package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +80 -48
- package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
- package/layers/prisma/nodejs/package.json +8 -0
- package/management-ui/server/utils/cliIntegration.js +1 -1
- package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
- package/package.json +11 -11
- package/frigg-cli/.eslintrc.js +0 -141
- package/frigg-cli/__tests__/unit/commands/build.test.js +0 -251
- package/frigg-cli/__tests__/unit/commands/db-setup.test.js +0 -548
- package/frigg-cli/__tests__/unit/commands/install.test.js +0 -400
- package/frigg-cli/__tests__/unit/commands/ui.test.js +0 -346
- package/frigg-cli/__tests__/unit/utils/database-validator.test.js +0 -366
- package/frigg-cli/__tests__/unit/utils/error-messages.test.js +0 -304
- package/frigg-cli/__tests__/unit/utils/prisma-runner.test.js +0 -486
- package/frigg-cli/__tests__/utils/mock-factory.js +0 -270
- package/frigg-cli/__tests__/utils/prisma-mock.js +0 -194
- package/frigg-cli/__tests__/utils/test-fixtures.js +0 -463
- package/frigg-cli/__tests__/utils/test-setup.js +0 -287
- package/frigg-cli/build-command/index.js +0 -65
- package/frigg-cli/db-setup-command/index.js +0 -193
- package/frigg-cli/deploy-command/index.js +0 -175
- package/frigg-cli/generate-command/__tests__/generate-command.test.js +0 -301
- package/frigg-cli/generate-command/azure-generator.js +0 -43
- package/frigg-cli/generate-command/gcp-generator.js +0 -47
- package/frigg-cli/generate-command/index.js +0 -332
- package/frigg-cli/generate-command/terraform-generator.js +0 -555
- package/frigg-cli/generate-iam-command.js +0 -118
- package/frigg-cli/index.js +0 -75
- package/frigg-cli/index.test.js +0 -158
- package/frigg-cli/init-command/backend-first-handler.js +0 -756
- package/frigg-cli/init-command/index.js +0 -93
- package/frigg-cli/init-command/template-handler.js +0 -143
- package/frigg-cli/install-command/backend-js.js +0 -33
- package/frigg-cli/install-command/commit-changes.js +0 -16
- package/frigg-cli/install-command/environment-variables.js +0 -127
- package/frigg-cli/install-command/environment-variables.test.js +0 -136
- package/frigg-cli/install-command/index.js +0 -54
- package/frigg-cli/install-command/install-package.js +0 -13
- package/frigg-cli/install-command/integration-file.js +0 -30
- package/frigg-cli/install-command/logger.js +0 -12
- package/frigg-cli/install-command/template.js +0 -90
- package/frigg-cli/install-command/validate-package.js +0 -75
- package/frigg-cli/jest.config.js +0 -124
- package/frigg-cli/package.json +0 -54
- package/frigg-cli/start-command/index.js +0 -149
- package/frigg-cli/start-command/start-command.test.js +0 -297
- package/frigg-cli/test/init-command.test.js +0 -180
- package/frigg-cli/test/npm-registry.test.js +0 -319
- package/frigg-cli/ui-command/index.js +0 -154
- package/frigg-cli/utils/app-resolver.js +0 -319
- package/frigg-cli/utils/backend-path.js +0 -25
- package/frigg-cli/utils/database-validator.js +0 -161
- package/frigg-cli/utils/error-messages.js +0 -257
- package/frigg-cli/utils/npm-registry.js +0 -167
- package/frigg-cli/utils/prisma-runner.js +0 -280
- package/frigg-cli/utils/process-manager.js +0 -199
- package/frigg-cli/utils/repo-detection.js +0 -405
- package/infrastructure/aws-discovery.js +0 -1176
- package/infrastructure/aws-discovery.test.js +0 -1220
- package/infrastructure/serverless-template.js +0 -2094
- /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
- /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
- /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
- /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
- /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
- /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
- /package/infrastructure/{run-discovery.js → scripts/run-discovery.js} +0 -0
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const { spawn } = require('child_process');
|
|
3
|
-
const readline = require('readline');
|
|
4
|
-
|
|
5
|
-
class ProcessManager {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.processes = new Map();
|
|
8
|
-
this.isShuttingDown = false;
|
|
9
|
-
this.outputBuffer = new Map();
|
|
10
|
-
this.setupShutdownHandlers();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
setupShutdownHandlers() {
|
|
14
|
-
const shutdown = async () => {
|
|
15
|
-
if (this.isShuttingDown) return;
|
|
16
|
-
this.isShuttingDown = true;
|
|
17
|
-
|
|
18
|
-
console.log('\n' + chalk.yellow('⏹ Shutting down...'));
|
|
19
|
-
|
|
20
|
-
const shutdownPromises = [];
|
|
21
|
-
for (const [name, proc] of this.processes) {
|
|
22
|
-
shutdownPromises.push(this.killProcess(name, proc));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
await Promise.all(shutdownPromises);
|
|
26
|
-
|
|
27
|
-
console.log(chalk.green('✓ All processes stopped cleanly'));
|
|
28
|
-
process.exit(0);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
process.on('SIGINT', shutdown);
|
|
32
|
-
process.on('SIGTERM', shutdown);
|
|
33
|
-
process.on('exit', () => {
|
|
34
|
-
for (const [, proc] of this.processes) {
|
|
35
|
-
try {
|
|
36
|
-
proc.kill('SIGKILL');
|
|
37
|
-
} catch (e) {
|
|
38
|
-
// Process already dead
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async killProcess(name, proc) {
|
|
45
|
-
return new Promise((resolve) => {
|
|
46
|
-
if (!proc || proc.killed) {
|
|
47
|
-
resolve();
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const timeout = setTimeout(() => {
|
|
52
|
-
try {
|
|
53
|
-
proc.kill('SIGKILL');
|
|
54
|
-
} catch (e) {
|
|
55
|
-
// Process already dead
|
|
56
|
-
}
|
|
57
|
-
resolve();
|
|
58
|
-
}, 5000);
|
|
59
|
-
|
|
60
|
-
proc.once('exit', () => {
|
|
61
|
-
clearTimeout(timeout);
|
|
62
|
-
this.processes.delete(name);
|
|
63
|
-
resolve();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
proc.kill('SIGTERM');
|
|
68
|
-
} catch (e) {
|
|
69
|
-
clearTimeout(timeout);
|
|
70
|
-
resolve();
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
spawnProcess(name, command, args, options = {}) {
|
|
76
|
-
const proc = spawn(command, args, {
|
|
77
|
-
...options,
|
|
78
|
-
stdio: ['inherit', 'pipe', 'pipe'],
|
|
79
|
-
shell: true
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
this.processes.set(name, proc);
|
|
83
|
-
this.outputBuffer.set(name, []);
|
|
84
|
-
|
|
85
|
-
// Create readline interfaces for better line handling
|
|
86
|
-
const stdoutReader = readline.createInterface({
|
|
87
|
-
input: proc.stdout,
|
|
88
|
-
crlfDelay: Infinity
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
const stderrReader = readline.createInterface({
|
|
92
|
-
input: proc.stderr,
|
|
93
|
-
crlfDelay: Infinity
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
stdoutReader.on('line', (line) => {
|
|
97
|
-
if (!this.isShuttingDown) {
|
|
98
|
-
this.handleOutput(name, line, 'stdout');
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
stderrReader.on('line', (line) => {
|
|
103
|
-
if (!this.isShuttingDown) {
|
|
104
|
-
this.handleOutput(name, line, 'stderr');
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
proc.on('error', (error) => {
|
|
109
|
-
if (!this.isShuttingDown) {
|
|
110
|
-
console.error(chalk.red(`[${name}] Process error:`), error.message);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
proc.on('exit', (code, signal) => {
|
|
115
|
-
this.processes.delete(name);
|
|
116
|
-
if (!this.isShuttingDown && code !== 0 && code !== null) {
|
|
117
|
-
console.error(chalk.red(`[${name}] Process exited with code ${code}`));
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
return proc;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
handleOutput(processName, line, stream) {
|
|
125
|
-
// Filter out noisy/redundant messages
|
|
126
|
-
const filters = [
|
|
127
|
-
/VITE v\d+\.\d+\.\d+/,
|
|
128
|
-
/ready in \d+ ms/,
|
|
129
|
-
/Local:/,
|
|
130
|
-
/Network:/,
|
|
131
|
-
/press h \+ enter to show help/,
|
|
132
|
-
/\[nodemon\]/,
|
|
133
|
-
/watching for file changes/,
|
|
134
|
-
/restarting due to changes/,
|
|
135
|
-
/starting/,
|
|
136
|
-
/clean exit/,
|
|
137
|
-
/waiting for changes before restart/,
|
|
138
|
-
/^$/ // empty lines
|
|
139
|
-
];
|
|
140
|
-
|
|
141
|
-
if (filters.some(filter => filter.test(line))) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Format output based on process
|
|
146
|
-
const prefix = this.getProcessPrefix(processName);
|
|
147
|
-
const coloredLine = this.colorizeOutput(line, stream);
|
|
148
|
-
|
|
149
|
-
console.log(`${prefix} ${coloredLine}`);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
getProcessPrefix(processName) {
|
|
153
|
-
const prefixes = {
|
|
154
|
-
'frontend': chalk.blue('[Frontend]'),
|
|
155
|
-
'backend': chalk.green('[Backend]'),
|
|
156
|
-
'vite': chalk.blue('[Vite]'),
|
|
157
|
-
'server': chalk.green('[Server]')
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
return prefixes[processName.toLowerCase()] || chalk.gray(`[${processName}]`);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
colorizeOutput(line, stream) {
|
|
164
|
-
// Error detection
|
|
165
|
-
if (stream === 'stderr' || /error|fail|exception/i.test(line)) {
|
|
166
|
-
return chalk.red(line);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Warning detection
|
|
170
|
-
if (/warn|warning/i.test(line)) {
|
|
171
|
-
return chalk.yellow(line);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Success detection
|
|
175
|
-
if (/success|ready|started|listening|compiled/i.test(line)) {
|
|
176
|
-
return chalk.green(line);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Info detection
|
|
180
|
-
if (/info|starting/i.test(line)) {
|
|
181
|
-
return chalk.blue(line);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return chalk.gray(line);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
printStatus(frontendUrl, backendUrl, repoName) {
|
|
188
|
-
console.log('\n' + chalk.bold.green('✨ Frigg Management UI is ready!'));
|
|
189
|
-
console.log('');
|
|
190
|
-
console.log(chalk.cyan(' Frontend: ') + chalk.white(frontendUrl));
|
|
191
|
-
console.log(chalk.cyan(' Backend: ') + chalk.white(backendUrl));
|
|
192
|
-
console.log(chalk.cyan(' Repository:') + chalk.white(` ${repoName}`));
|
|
193
|
-
console.log('');
|
|
194
|
-
console.log(chalk.gray(' Press ' + chalk.bold('Ctrl+C') + ' to stop all servers'));
|
|
195
|
-
console.log('');
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
module.exports = ProcessManager;
|
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2024 Frigg Integration Framework
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use strict';
|
|
9
|
-
|
|
10
|
-
const fs = require('fs-extra');
|
|
11
|
-
const path = require('path');
|
|
12
|
-
const os = require('os');
|
|
13
|
-
const chalk = require('chalk');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Checks if a directory is a Frigg repository
|
|
17
|
-
* @param {string} directory - Path to check
|
|
18
|
-
* @returns {Promise<{isFriggRepo: boolean, repoInfo: object|null}>}
|
|
19
|
-
*/
|
|
20
|
-
async function isFriggRepository(directory) {
|
|
21
|
-
try {
|
|
22
|
-
const packageJsonPath = path.join(directory, 'package.json');
|
|
23
|
-
|
|
24
|
-
// Check if package.json exists
|
|
25
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
26
|
-
return { isFriggRepo: false, repoInfo: null };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const packageJson = await fs.readJson(packageJsonPath);
|
|
30
|
-
|
|
31
|
-
// Primary indicators of a Frigg repository
|
|
32
|
-
const indicators = {
|
|
33
|
-
hasFriggDependencies: false,
|
|
34
|
-
hasBackendWorkspace: false,
|
|
35
|
-
hasFrontendWorkspace: false,
|
|
36
|
-
hasServerlessConfig: false,
|
|
37
|
-
friggDependencies: []
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Check for @friggframework dependencies
|
|
41
|
-
const allDeps = {
|
|
42
|
-
...packageJson.dependencies,
|
|
43
|
-
...packageJson.devDependencies,
|
|
44
|
-
...packageJson.peerDependencies
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
for (const dep in allDeps) {
|
|
48
|
-
if (dep.startsWith('@friggframework/')) {
|
|
49
|
-
indicators.hasFriggDependencies = true;
|
|
50
|
-
indicators.friggDependencies.push(dep);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Check for Frigg-specific files
|
|
55
|
-
const friggConfigFiles = [
|
|
56
|
-
'frigg.config.js',
|
|
57
|
-
'frigg.config.json',
|
|
58
|
-
'.friggrc',
|
|
59
|
-
'.friggrc.json',
|
|
60
|
-
'.friggrc.js'
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
indicators.hasFriggConfig = friggConfigFiles.some(file =>
|
|
64
|
-
fs.existsSync(path.join(directory, file))
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
// Check for Frigg-specific directories
|
|
68
|
-
const friggDirs = [
|
|
69
|
-
'.frigg',
|
|
70
|
-
'frigg-modules',
|
|
71
|
-
'api-modules'
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
indicators.hasFriggDirectories = friggDirs.some(dir =>
|
|
75
|
-
fs.existsSync(path.join(directory, dir))
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// Check for Frigg-specific scripts in package.json
|
|
79
|
-
indicators.hasFriggScripts = false;
|
|
80
|
-
if (packageJson.scripts) {
|
|
81
|
-
const friggScriptPatterns = ['frigg', 'frigg-dev', 'frigg-build', 'frigg-deploy'];
|
|
82
|
-
indicators.hasFriggScripts = Object.keys(packageJson.scripts).some(script =>
|
|
83
|
-
friggScriptPatterns.some(pattern => script.includes(pattern)) ||
|
|
84
|
-
Object.values(packageJson.scripts).some(cmd =>
|
|
85
|
-
typeof cmd === 'string' && cmd.includes('frigg ')
|
|
86
|
-
)
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Check for workspace structure
|
|
91
|
-
if (packageJson.workspaces) {
|
|
92
|
-
const workspaces = Array.isArray(packageJson.workspaces)
|
|
93
|
-
? packageJson.workspaces
|
|
94
|
-
: packageJson.workspaces.packages || [];
|
|
95
|
-
|
|
96
|
-
indicators.hasBackendWorkspace = workspaces.some(ws =>
|
|
97
|
-
ws.includes('backend') || ws === 'backend'
|
|
98
|
-
);
|
|
99
|
-
indicators.hasFrontendWorkspace = workspaces.some(ws =>
|
|
100
|
-
ws.includes('frontend') || ws === 'frontend'
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Check for backend/serverless.yml
|
|
105
|
-
const serverlessPath = path.join(directory, 'backend', 'serverless.yml');
|
|
106
|
-
indicators.hasServerlessConfig = fs.existsSync(serverlessPath);
|
|
107
|
-
|
|
108
|
-
// Check for individual frontend directories (React, Vue, etc.)
|
|
109
|
-
const frontendDirs = ['frontend', 'react', 'vue', 'svelte', 'angular'];
|
|
110
|
-
const existingFrontendDirs = frontendDirs.filter(dir =>
|
|
111
|
-
fs.existsSync(path.join(directory, dir))
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
// Skip @friggframework packages (they're framework packages, not Frigg apps)
|
|
115
|
-
if (packageJson.name && packageJson.name.startsWith('@friggframework/')) {
|
|
116
|
-
return { isFriggRepo: false, repoInfo: null };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Additional check for Zapier apps that shouldn't be detected as Frigg repos
|
|
120
|
-
const isZapierApp = packageJson.name && (
|
|
121
|
-
packageJson.name.includes('zapier-public') ||
|
|
122
|
-
packageJson.name.includes('zapier-app') ||
|
|
123
|
-
(packageJson.scripts && packageJson.scripts.zapier)
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
// Check for specific Frigg indicators in serverless.yml
|
|
127
|
-
let hasFriggServerlessIndicators = false;
|
|
128
|
-
if (indicators.hasServerlessConfig) {
|
|
129
|
-
try {
|
|
130
|
-
const serverlessContent = fs.readFileSync(serverlessPath, 'utf8');
|
|
131
|
-
hasFriggServerlessIndicators = serverlessContent.includes('frigg') ||
|
|
132
|
-
serverlessContent.includes('FriggHandler') ||
|
|
133
|
-
serverlessContent.includes('@friggframework');
|
|
134
|
-
} catch (error) {
|
|
135
|
-
// Ignore read errors
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// A directory is considered a Frigg repo if it has:
|
|
140
|
-
// 1. Frigg dependencies (MANDATORY - most reliable indicator) OR
|
|
141
|
-
// 2. Frigg-specific configuration files OR
|
|
142
|
-
// 3. Frigg-specific directories OR
|
|
143
|
-
// 4. Frigg-specific scripts in package.json OR
|
|
144
|
-
// 5. Serverless config with explicit Frigg references AND proper structure
|
|
145
|
-
//
|
|
146
|
-
// For Zapier apps, we require explicit Frigg indicators
|
|
147
|
-
const hasFriggIndicators = indicators.hasFriggDependencies ||
|
|
148
|
-
indicators.hasFriggConfig ||
|
|
149
|
-
indicators.hasFriggDirectories ||
|
|
150
|
-
indicators.hasFriggScripts ||
|
|
151
|
-
hasFriggServerlessIndicators;
|
|
152
|
-
|
|
153
|
-
// Determine if it's a Frigg repository
|
|
154
|
-
let isFriggRepo = false;
|
|
155
|
-
|
|
156
|
-
if (isZapierApp) {
|
|
157
|
-
// For Zapier apps, require explicit Frigg dependencies or config
|
|
158
|
-
isFriggRepo = indicators.hasFriggDependencies || indicators.hasFriggConfig;
|
|
159
|
-
} else {
|
|
160
|
-
// For non-Zapier apps, any Frigg indicator is sufficient
|
|
161
|
-
isFriggRepo = hasFriggIndicators;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Additional validation for edge cases
|
|
165
|
-
if (isZapierApp && !indicators.hasFriggDependencies && !indicators.hasFriggConfig) {
|
|
166
|
-
return { isFriggRepo: false, repoInfo: null };
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (isFriggRepo) {
|
|
170
|
-
return {
|
|
171
|
-
isFriggRepo: true,
|
|
172
|
-
repoInfo: {
|
|
173
|
-
name: packageJson.name || path.basename(directory),
|
|
174
|
-
path: directory,
|
|
175
|
-
version: packageJson.version,
|
|
176
|
-
framework: detectFramework(directory, existingFrontendDirs),
|
|
177
|
-
hasBackend: fs.existsSync(path.join(directory, 'backend')),
|
|
178
|
-
friggDependencies: indicators.friggDependencies,
|
|
179
|
-
workspaces: packageJson.workspaces,
|
|
180
|
-
hasFriggConfig: indicators.hasFriggConfig,
|
|
181
|
-
hasFriggDirectories: indicators.hasFriggDirectories,
|
|
182
|
-
isZapierApp: isZapierApp,
|
|
183
|
-
...indicators
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return { isFriggRepo: false, repoInfo: null };
|
|
189
|
-
|
|
190
|
-
} catch (error) {
|
|
191
|
-
return { isFriggRepo: false, repoInfo: null };
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Detects the frontend framework used in the Frigg repository
|
|
197
|
-
* @param {string} directory - Repository directory
|
|
198
|
-
* @param {string[]} existingFrontendDirs - List of existing frontend directories
|
|
199
|
-
* @returns {string} Framework name
|
|
200
|
-
*/
|
|
201
|
-
function detectFramework(directory, existingFrontendDirs) {
|
|
202
|
-
// Check for framework-specific directories
|
|
203
|
-
const frameworkDirs = {
|
|
204
|
-
'react': 'React',
|
|
205
|
-
'vue': 'Vue',
|
|
206
|
-
'svelte': 'Svelte',
|
|
207
|
-
'angular': 'Angular'
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
for (const dir of existingFrontendDirs) {
|
|
211
|
-
if (frameworkDirs[dir]) {
|
|
212
|
-
return frameworkDirs[dir];
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Check frontend directory for framework indicators
|
|
217
|
-
const frontendPath = path.join(directory, 'frontend');
|
|
218
|
-
if (fs.existsSync(frontendPath)) {
|
|
219
|
-
try {
|
|
220
|
-
const frontendPackageJson = path.join(frontendPath, 'package.json');
|
|
221
|
-
if (fs.existsSync(frontendPackageJson)) {
|
|
222
|
-
const frontendPkg = fs.readJsonSync(frontendPackageJson);
|
|
223
|
-
const deps = { ...frontendPkg.dependencies, ...frontendPkg.devDependencies };
|
|
224
|
-
|
|
225
|
-
if (deps.react) return 'React';
|
|
226
|
-
if (deps.vue) return 'Vue';
|
|
227
|
-
if (deps.svelte) return 'Svelte';
|
|
228
|
-
if (deps['@angular/core']) return 'Angular';
|
|
229
|
-
}
|
|
230
|
-
} catch (error) {
|
|
231
|
-
// Ignore errors
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return 'Unknown';
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Searches for Frigg repositories in common locations
|
|
240
|
-
* @param {Object} options - Search options
|
|
241
|
-
* @returns {Promise<Array>} Array of discovered repositories
|
|
242
|
-
*/
|
|
243
|
-
async function discoverFriggRepositories(options = {}) {
|
|
244
|
-
const {
|
|
245
|
-
searchPaths = [
|
|
246
|
-
process.cwd(),
|
|
247
|
-
path.join(os.homedir(), 'Documents'),
|
|
248
|
-
path.join(os.homedir(), 'Projects'),
|
|
249
|
-
path.join(os.homedir(), 'Development'),
|
|
250
|
-
path.join(os.homedir(), 'dev'),
|
|
251
|
-
path.join(os.homedir(), 'Code')
|
|
252
|
-
],
|
|
253
|
-
maxDepth = 3,
|
|
254
|
-
excludePatterns = ['node_modules', '.git', 'dist', 'build', '.next', 'coverage']
|
|
255
|
-
} = options;
|
|
256
|
-
|
|
257
|
-
const discoveredRepos = [];
|
|
258
|
-
const visited = new Set();
|
|
259
|
-
|
|
260
|
-
for (const searchPath of searchPaths) {
|
|
261
|
-
if (fs.existsSync(searchPath)) {
|
|
262
|
-
await searchDirectory(searchPath, 0, maxDepth, excludePatterns, discoveredRepos, visited);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Remove duplicates and sort by name
|
|
267
|
-
const uniqueRepos = Array.from(
|
|
268
|
-
new Map(discoveredRepos.map(repo => [repo.path, repo])).values()
|
|
269
|
-
);
|
|
270
|
-
|
|
271
|
-
return uniqueRepos.sort((a, b) => a.name.localeCompare(b.name));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Recursively searches a directory for Frigg repositories
|
|
276
|
-
*/
|
|
277
|
-
async function searchDirectory(dirPath, currentDepth, maxDepth, excludePatterns, results, visited) {
|
|
278
|
-
// Avoid infinite loops from symlinks
|
|
279
|
-
const realPath = fs.realpathSync(dirPath);
|
|
280
|
-
if (visited.has(realPath)) return;
|
|
281
|
-
visited.add(realPath);
|
|
282
|
-
|
|
283
|
-
if (currentDepth > maxDepth) return;
|
|
284
|
-
|
|
285
|
-
try {
|
|
286
|
-
// Check if current directory is a Frigg repo
|
|
287
|
-
const { isFriggRepo, repoInfo } = await isFriggRepository(dirPath);
|
|
288
|
-
if (isFriggRepo) {
|
|
289
|
-
results.push(repoInfo);
|
|
290
|
-
return; // Don't search inside Frigg repos
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Continue searching subdirectories
|
|
294
|
-
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
295
|
-
|
|
296
|
-
for (const entry of entries) {
|
|
297
|
-
if (entry.isDirectory()) {
|
|
298
|
-
const entryName = entry.name;
|
|
299
|
-
|
|
300
|
-
// Skip excluded patterns
|
|
301
|
-
if (excludePatterns.some(pattern => entryName.includes(pattern))) {
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Skip hidden directories except .git for workspace detection
|
|
306
|
-
if (entryName.startsWith('.') && entryName !== '.git') {
|
|
307
|
-
continue;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const entryPath = path.join(dirPath, entryName);
|
|
311
|
-
await searchDirectory(entryPath, currentDepth + 1, maxDepth, excludePatterns, results, visited);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
} catch (error) {
|
|
315
|
-
// Silently skip directories we can't access
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Gets the current directory's Frigg repository status
|
|
321
|
-
* @returns {Promise<Object>} Current repository info
|
|
322
|
-
*/
|
|
323
|
-
async function getCurrentRepositoryInfo() {
|
|
324
|
-
const currentDir = process.cwd();
|
|
325
|
-
|
|
326
|
-
// Check current directory
|
|
327
|
-
let { isFriggRepo, repoInfo } = await isFriggRepository(currentDir);
|
|
328
|
-
|
|
329
|
-
if (isFriggRepo) {
|
|
330
|
-
return { ...repoInfo, isCurrent: true };
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Check parent directories up to 3 levels
|
|
334
|
-
let checkDir = currentDir;
|
|
335
|
-
for (let i = 0; i < 3; i++) {
|
|
336
|
-
const parentDir = path.dirname(checkDir);
|
|
337
|
-
if (parentDir === checkDir) break; // Reached root
|
|
338
|
-
|
|
339
|
-
const result = await isFriggRepository(parentDir);
|
|
340
|
-
if (result.isFriggRepo) {
|
|
341
|
-
return { ...result.repoInfo, isCurrent: false, currentSubPath: path.relative(parentDir, currentDir) };
|
|
342
|
-
}
|
|
343
|
-
checkDir = parentDir;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return null;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Prompts user to select a repository from discovered repos
|
|
351
|
-
* @param {Array} repositories - List of discovered repositories
|
|
352
|
-
* @returns {Promise<Object|null>} Selected repository or null
|
|
353
|
-
*/
|
|
354
|
-
async function promptRepositorySelection(repositories) {
|
|
355
|
-
if (repositories.length === 0) {
|
|
356
|
-
console.log(chalk.yellow('No Frigg repositories found.'));
|
|
357
|
-
console.log(chalk.gray('To create a new Frigg project, run: frigg init <project-name>'));
|
|
358
|
-
return null;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (repositories.length === 1) {
|
|
362
|
-
console.log(chalk.green(`Found 1 Frigg repository: ${repositories[0].name}`));
|
|
363
|
-
return repositories[0];
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
console.log(chalk.blue(`Found ${repositories.length} Frigg repositories:`));
|
|
367
|
-
console.log();
|
|
368
|
-
|
|
369
|
-
repositories.forEach((repo, index) => {
|
|
370
|
-
const framework = repo.framework !== 'Unknown' ? chalk.gray(`(${repo.framework})`) : '';
|
|
371
|
-
console.log(` ${chalk.cyan((index + 1).toString().padStart(2))}. ${chalk.white(repo.name)} ${framework}`);
|
|
372
|
-
console.log(` ${chalk.gray(repo.path)}`);
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
console.log();
|
|
376
|
-
|
|
377
|
-
// For now, return the first one. In a full implementation, you'd use a prompt library
|
|
378
|
-
console.log(chalk.yellow('Auto-selecting first repository. Use interactive selection in future versions.'));
|
|
379
|
-
return repositories[0];
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Formats repository information for display
|
|
384
|
-
* @param {Object} repoInfo - Repository information
|
|
385
|
-
* @returns {string} Formatted display string
|
|
386
|
-
*/
|
|
387
|
-
function formatRepositoryInfo(repoInfo) {
|
|
388
|
-
const parts = [
|
|
389
|
-
chalk.white(repoInfo.name),
|
|
390
|
-
repoInfo.version ? chalk.gray(`v${repoInfo.version}`) : '',
|
|
391
|
-
repoInfo.framework !== 'Unknown' ? chalk.blue(`[${repoInfo.framework}]`) : '',
|
|
392
|
-
repoInfo.hasBackend ? chalk.green('[Backend]') : ''
|
|
393
|
-
].filter(Boolean);
|
|
394
|
-
|
|
395
|
-
return parts.join(' ');
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
module.exports = {
|
|
399
|
-
isFriggRepository,
|
|
400
|
-
discoverFriggRepositories,
|
|
401
|
-
getCurrentRepositoryInfo,
|
|
402
|
-
promptRepositorySelection,
|
|
403
|
-
formatRepositoryInfo,
|
|
404
|
-
detectFramework
|
|
405
|
-
};
|