@friggframework/devtools 2.0.0-next.44 → 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 -2074
- /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,297 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test suite for the frigg start command
|
|
3
|
-
*
|
|
4
|
-
* These tests ensure that the start command properly:
|
|
5
|
-
* 1. Sets FRIGG_SKIP_AWS_DISCOVERY=true in the parent process to skip AWS API calls
|
|
6
|
-
* 2. Suppresses AWS SDK maintenance mode warnings
|
|
7
|
-
* 3. Spawns serverless with correct configuration
|
|
8
|
-
* 4. Validates database configuration before starting
|
|
9
|
-
*
|
|
10
|
-
* This fixes the issue where frigg start would attempt AWS discovery during local development,
|
|
11
|
-
* causing unnecessary AWS API calls and potential failures when AWS credentials aren't available.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// Mock dependencies BEFORE importing startCommand
|
|
15
|
-
const mockValidator = {
|
|
16
|
-
validateDatabaseUrl: jest.fn(),
|
|
17
|
-
getDatabaseType: jest.fn(),
|
|
18
|
-
checkPrismaClientGenerated: jest.fn()
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
jest.mock('node:child_process', () => ({
|
|
22
|
-
spawn: jest.fn(),
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
jest.mock('../utils/database-validator', () => mockValidator);
|
|
26
|
-
jest.mock('dotenv');
|
|
27
|
-
|
|
28
|
-
const { spawn } = require('node:child_process');
|
|
29
|
-
const { startCommand } = require('./index');
|
|
30
|
-
const { createMockDatabaseValidator } = require('../__tests__/utils/prisma-mock');
|
|
31
|
-
const dotenv = require('dotenv');
|
|
32
|
-
|
|
33
|
-
describe('startCommand', () => {
|
|
34
|
-
let mockChildProcess;
|
|
35
|
-
let mockProcessExit;
|
|
36
|
-
|
|
37
|
-
beforeEach(() => {
|
|
38
|
-
// Mock process.exit to throw error and stop execution (prevents actual exits)
|
|
39
|
-
const exitError = new Error('process.exit called');
|
|
40
|
-
exitError.code = 'PROCESS_EXIT';
|
|
41
|
-
mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
42
|
-
throw exitError;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// Reset mocks
|
|
46
|
-
jest.clearAllMocks();
|
|
47
|
-
|
|
48
|
-
// Re-apply process.exit mock after clearAllMocks
|
|
49
|
-
mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
50
|
-
throw exitError;
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Set up default database validator mocks for all tests
|
|
54
|
-
const defaultValidator = createMockDatabaseValidator();
|
|
55
|
-
mockValidator.validateDatabaseUrl.mockReturnValue(defaultValidator.validateDatabaseUrl());
|
|
56
|
-
mockValidator.getDatabaseType.mockReturnValue(defaultValidator.getDatabaseType());
|
|
57
|
-
mockValidator.checkPrismaClientGenerated.mockReturnValue(defaultValidator.checkPrismaClientGenerated());
|
|
58
|
-
|
|
59
|
-
// Mock dotenv
|
|
60
|
-
dotenv.config = jest.fn();
|
|
61
|
-
|
|
62
|
-
// Clear environment variables
|
|
63
|
-
delete process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE;
|
|
64
|
-
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
65
|
-
|
|
66
|
-
// Create a mock child process
|
|
67
|
-
mockChildProcess = {
|
|
68
|
-
on: jest.fn(),
|
|
69
|
-
stdout: { on: jest.fn() },
|
|
70
|
-
stderr: { on: jest.fn() },
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
spawn.mockReturnValue(mockChildProcess);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
afterEach(() => {
|
|
77
|
-
// Restore process.exit
|
|
78
|
-
if (mockProcessExit) {
|
|
79
|
-
mockProcessExit.mockRestore();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Clean up environment
|
|
83
|
-
delete process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE;
|
|
84
|
-
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should set FRIGG_SKIP_AWS_DISCOVERY to true in the parent process', async () => {
|
|
88
|
-
const options = { stage: 'dev' };
|
|
89
|
-
|
|
90
|
-
await startCommand(options);
|
|
91
|
-
|
|
92
|
-
// Verify the environment variable is set in the parent process
|
|
93
|
-
expect(process.env.FRIGG_SKIP_AWS_DISCOVERY).toBe('true');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('should set AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE to suppress warnings', async () => {
|
|
97
|
-
const options = { stage: 'dev' };
|
|
98
|
-
|
|
99
|
-
await startCommand(options);
|
|
100
|
-
|
|
101
|
-
expect(process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE).toBe('1');
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('should spawn serverless with correct arguments', async () => {
|
|
105
|
-
const options = { stage: 'prod' };
|
|
106
|
-
|
|
107
|
-
await startCommand(options);
|
|
108
|
-
|
|
109
|
-
expect(spawn).toHaveBeenCalledWith(
|
|
110
|
-
'serverless',
|
|
111
|
-
['offline', '--config', 'infrastructure.js', '--stage', 'prod'],
|
|
112
|
-
expect.objectContaining({
|
|
113
|
-
cwd: expect.any(String),
|
|
114
|
-
stdio: 'inherit',
|
|
115
|
-
env: expect.objectContaining({
|
|
116
|
-
FRIGG_SKIP_AWS_DISCOVERY: 'true',
|
|
117
|
-
}),
|
|
118
|
-
})
|
|
119
|
-
);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should include verbose flag when verbose option is enabled', async () => {
|
|
123
|
-
const options = { stage: 'dev', verbose: true };
|
|
124
|
-
|
|
125
|
-
await startCommand(options);
|
|
126
|
-
|
|
127
|
-
expect(spawn).toHaveBeenCalledWith(
|
|
128
|
-
'serverless',
|
|
129
|
-
['offline', '--config', 'infrastructure.js', '--stage', 'dev', '--verbose'],
|
|
130
|
-
expect.any(Object)
|
|
131
|
-
);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should pass FRIGG_SKIP_AWS_DISCOVERY in spawn environment', async () => {
|
|
135
|
-
const options = { stage: 'dev' };
|
|
136
|
-
|
|
137
|
-
await startCommand(options);
|
|
138
|
-
|
|
139
|
-
const spawnCall = spawn.mock.calls[0];
|
|
140
|
-
const spawnOptions = spawnCall[2];
|
|
141
|
-
|
|
142
|
-
expect(spawnOptions.env).toHaveProperty('FRIGG_SKIP_AWS_DISCOVERY', 'true');
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should handle child process errors', async () => {
|
|
146
|
-
const options = { stage: 'dev' };
|
|
147
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
148
|
-
|
|
149
|
-
await startCommand(options);
|
|
150
|
-
|
|
151
|
-
// Simulate an error
|
|
152
|
-
const errorCallback = mockChildProcess.on.mock.calls.find(call => call[0] === 'error')[1];
|
|
153
|
-
const testError = new Error('Test error');
|
|
154
|
-
errorCallback(testError);
|
|
155
|
-
|
|
156
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Error executing command: Test error');
|
|
157
|
-
|
|
158
|
-
consoleErrorSpy.mockRestore();
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('should handle child process exit with non-zero code', async () => {
|
|
162
|
-
const options = { stage: 'dev' };
|
|
163
|
-
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
164
|
-
|
|
165
|
-
await startCommand(options);
|
|
166
|
-
|
|
167
|
-
// Simulate exit with error code
|
|
168
|
-
const closeCallback = mockChildProcess.on.mock.calls.find(call => call[0] === 'close')[1];
|
|
169
|
-
closeCallback(1);
|
|
170
|
-
|
|
171
|
-
expect(consoleLogSpy).toHaveBeenCalledWith('Child process exited with code 1');
|
|
172
|
-
|
|
173
|
-
consoleLogSpy.mockRestore();
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('should not log on successful exit', async () => {
|
|
177
|
-
const options = { stage: 'dev' };
|
|
178
|
-
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
179
|
-
|
|
180
|
-
await startCommand(options);
|
|
181
|
-
|
|
182
|
-
// Clear the spy calls from startCommand execution
|
|
183
|
-
consoleLogSpy.mockClear();
|
|
184
|
-
|
|
185
|
-
// Simulate successful exit
|
|
186
|
-
const closeCallback = mockChildProcess.on.mock.calls.find(call => call[0] === 'close')[1];
|
|
187
|
-
closeCallback(0);
|
|
188
|
-
|
|
189
|
-
// Should not log anything for successful exit
|
|
190
|
-
expect(consoleLogSpy).not.toHaveBeenCalledWith(expect.stringContaining('exited'));
|
|
191
|
-
|
|
192
|
-
consoleLogSpy.mockRestore();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe('Database Pre-flight Validation', () => {
|
|
196
|
-
let mockConsoleError;
|
|
197
|
-
|
|
198
|
-
beforeEach(() => {
|
|
199
|
-
// Mock console.error (all other mocks are set up in outer beforeEach)
|
|
200
|
-
mockConsoleError = jest.spyOn(console, 'error').mockImplementation();
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
afterEach(() => {
|
|
204
|
-
mockConsoleError.mockRestore();
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it('should pass pre-flight checks when database valid', async () => {
|
|
208
|
-
const options = { stage: 'dev' };
|
|
209
|
-
|
|
210
|
-
await startCommand(options);
|
|
211
|
-
|
|
212
|
-
expect(mockValidator.validateDatabaseUrl).toHaveBeenCalled();
|
|
213
|
-
expect(mockValidator.getDatabaseType).toHaveBeenCalled();
|
|
214
|
-
expect(mockValidator.checkPrismaClientGenerated).toHaveBeenCalled();
|
|
215
|
-
expect(mockProcessExit).not.toHaveBeenCalled();
|
|
216
|
-
expect(spawn).toHaveBeenCalled();
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it('should fail when DATABASE_URL missing', async () => {
|
|
220
|
-
mockValidator.validateDatabaseUrl.mockReturnValue({
|
|
221
|
-
valid: false,
|
|
222
|
-
error: 'DATABASE_URL not found'
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
await expect(startCommand({})).rejects.toThrow('process.exit called');
|
|
226
|
-
|
|
227
|
-
expect(mockConsoleError).toHaveBeenCalled();
|
|
228
|
-
expect(mockProcessExit).toHaveBeenCalledWith(1);
|
|
229
|
-
expect(spawn).not.toHaveBeenCalled();
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it('should fail when database type not configured', async () => {
|
|
233
|
-
mockValidator.getDatabaseType.mockReturnValue({
|
|
234
|
-
error: 'Database not configured'
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
await expect(startCommand({})).rejects.toThrow('process.exit called');
|
|
238
|
-
|
|
239
|
-
expect(mockConsoleError).toHaveBeenCalled();
|
|
240
|
-
expect(mockProcessExit).toHaveBeenCalledWith(1);
|
|
241
|
-
expect(spawn).not.toHaveBeenCalled();
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
it('should fail when Prisma client not generated', async () => {
|
|
245
|
-
mockValidator.checkPrismaClientGenerated.mockReturnValue({
|
|
246
|
-
generated: false,
|
|
247
|
-
error: 'Client not found'
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
await expect(startCommand({})).rejects.toThrow('process.exit called');
|
|
251
|
-
|
|
252
|
-
expect(mockConsoleError).toHaveBeenCalled();
|
|
253
|
-
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('frigg db:setup'));
|
|
254
|
-
expect(mockProcessExit).toHaveBeenCalledWith(1);
|
|
255
|
-
expect(spawn).not.toHaveBeenCalled();
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('should suggest running frigg db:setup when client missing', async () => {
|
|
259
|
-
mockValidator.checkPrismaClientGenerated.mockReturnValue({
|
|
260
|
-
generated: false,
|
|
261
|
-
error: 'Client not generated'
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
await expect(startCommand({})).rejects.toThrow('process.exit called');
|
|
265
|
-
|
|
266
|
-
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('frigg db:setup'));
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it('should exit with code 1 on validation failure', async () => {
|
|
270
|
-
mockValidator.validateDatabaseUrl.mockReturnValue({
|
|
271
|
-
valid: false
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
await expect(startCommand({})).rejects.toThrow('process.exit called');
|
|
275
|
-
|
|
276
|
-
expect(mockProcessExit).toHaveBeenCalledWith(1);
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('should continue to serverless start when validation passes', async () => {
|
|
280
|
-
await startCommand({ stage: 'dev' });
|
|
281
|
-
|
|
282
|
-
expect(spawn).toHaveBeenCalledWith(
|
|
283
|
-
'serverless',
|
|
284
|
-
expect.arrayContaining(['offline']),
|
|
285
|
-
expect.any(Object)
|
|
286
|
-
);
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
it('should load .env before validation', async () => {
|
|
290
|
-
await startCommand({});
|
|
291
|
-
|
|
292
|
-
expect(dotenv.config).toHaveBeenCalledWith(expect.objectContaining({
|
|
293
|
-
path: expect.stringContaining('.env')
|
|
294
|
-
}));
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
});
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const { initCommand } = require('../init-command');
|
|
4
|
-
const BackendFirstHandler = require('../init-command/backend-first-handler');
|
|
5
|
-
|
|
6
|
-
// Mock dependencies
|
|
7
|
-
jest.mock('fs-extra');
|
|
8
|
-
jest.mock('chalk', () => ({
|
|
9
|
-
blue: jest.fn(text => text),
|
|
10
|
-
green: jest.fn(text => text),
|
|
11
|
-
red: jest.fn(text => text),
|
|
12
|
-
yellow: jest.fn(text => text),
|
|
13
|
-
gray: jest.fn(text => text),
|
|
14
|
-
cyan: jest.fn(text => text),
|
|
15
|
-
bold: jest.fn(text => text)
|
|
16
|
-
}));
|
|
17
|
-
jest.mock('@inquirer/prompts');
|
|
18
|
-
jest.mock('child_process');
|
|
19
|
-
jest.mock('cross-spawn');
|
|
20
|
-
jest.mock('../init-command/backend-first-handler');
|
|
21
|
-
jest.mock('validate-npm-package-name');
|
|
22
|
-
|
|
23
|
-
describe('Init Command', () => {
|
|
24
|
-
const mockProjectPath = '/test/project/path';
|
|
25
|
-
const mockProjectName = 'test-project';
|
|
26
|
-
let mockExit;
|
|
27
|
-
let mockConsoleLog;
|
|
28
|
-
const validateProjectName = require('validate-npm-package-name');
|
|
29
|
-
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
jest.clearAllMocks();
|
|
32
|
-
|
|
33
|
-
// Mock process.exit
|
|
34
|
-
mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
35
|
-
throw new Error('process.exit');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Mock console.log and console.error
|
|
39
|
-
mockConsoleLog = jest.spyOn(console, 'log').mockImplementation();
|
|
40
|
-
jest.spyOn(console, 'error').mockImplementation();
|
|
41
|
-
|
|
42
|
-
// Reset fs mocks
|
|
43
|
-
const fs = require('fs-extra');
|
|
44
|
-
fs.ensureDirSync.mockImplementation(() => {});
|
|
45
|
-
fs.pathExists.mockResolvedValue(false);
|
|
46
|
-
fs.readdir.mockResolvedValue([]);
|
|
47
|
-
fs.readdirSync.mockReturnValue([]);
|
|
48
|
-
fs.writeFileSync.mockImplementation(() => {});
|
|
49
|
-
fs.lstatSync.mockReturnValue({ isDirectory: () => false });
|
|
50
|
-
|
|
51
|
-
// Mock BackendFirstHandler
|
|
52
|
-
BackendFirstHandler.mockImplementation(() => ({
|
|
53
|
-
initialize: jest.fn().mockResolvedValue()
|
|
54
|
-
}));
|
|
55
|
-
|
|
56
|
-
// Mock validate-npm-package-name
|
|
57
|
-
validateProjectName.mockReturnValue({
|
|
58
|
-
validForNewPackages: true,
|
|
59
|
-
errors: [],
|
|
60
|
-
warnings: []
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
afterEach(() => {
|
|
65
|
-
mockExit.mockRestore();
|
|
66
|
-
mockConsoleLog.mockRestore();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('Validation', () => {
|
|
70
|
-
it('should validate project name', async () => {
|
|
71
|
-
validateProjectName.mockReturnValue({
|
|
72
|
-
validForNewPackages: false,
|
|
73
|
-
errors: ['Invalid name'],
|
|
74
|
-
warnings: []
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
await expect(initCommand('invalid-name', {})).rejects.toThrow('process.exit');
|
|
78
|
-
expect(mockExit).toHaveBeenCalledWith(1);
|
|
79
|
-
expect(console.error).toHaveBeenCalledWith(expect.stringContaining('npm naming restrictions'));
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should accept valid project names', async () => {
|
|
83
|
-
validateProjectName.mockReturnValue({
|
|
84
|
-
validForNewPackages: true,
|
|
85
|
-
errors: [],
|
|
86
|
-
warnings: []
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
await initCommand('valid-name', {});
|
|
90
|
-
expect(BackendFirstHandler).toHaveBeenCalled();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should check Node.js version compatibility', async () => {
|
|
94
|
-
const originalVersion = process.version;
|
|
95
|
-
Object.defineProperty(process, 'version', {
|
|
96
|
-
value: 'v12.0.0',
|
|
97
|
-
configurable: true
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
101
|
-
await initCommand(mockProjectName, {});
|
|
102
|
-
|
|
103
|
-
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Node 14 or higher'));
|
|
104
|
-
|
|
105
|
-
Object.defineProperty(process, 'version', {
|
|
106
|
-
value: originalVersion,
|
|
107
|
-
configurable: true
|
|
108
|
-
});
|
|
109
|
-
consoleSpy.mockRestore();
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('Project Creation Modes', () => {
|
|
114
|
-
it('should use BackendFirstHandler by default', async () => {
|
|
115
|
-
await initCommand(mockProjectName, {});
|
|
116
|
-
|
|
117
|
-
expect(BackendFirstHandler).toHaveBeenCalledWith(
|
|
118
|
-
expect.stringContaining(mockProjectName),
|
|
119
|
-
expect.objectContaining({
|
|
120
|
-
force: false,
|
|
121
|
-
verbose: false
|
|
122
|
-
})
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should pass options to BackendFirstHandler', async () => {
|
|
127
|
-
const options = {
|
|
128
|
-
force: true,
|
|
129
|
-
verbose: true,
|
|
130
|
-
mode: 'standalone',
|
|
131
|
-
frontend: false
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
await initCommand(mockProjectName, options);
|
|
135
|
-
|
|
136
|
-
expect(BackendFirstHandler).toHaveBeenCalledWith(
|
|
137
|
-
expect.any(String),
|
|
138
|
-
expect.objectContaining(options)
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('should handle initialization errors gracefully', async () => {
|
|
143
|
-
const mockError = new Error('Initialization failed');
|
|
144
|
-
BackendFirstHandler.mockImplementation(() => ({
|
|
145
|
-
initialize: jest.fn().mockRejectedValue(mockError)
|
|
146
|
-
}));
|
|
147
|
-
|
|
148
|
-
await expect(initCommand(mockProjectName, {})).rejects.toThrow('process.exit');
|
|
149
|
-
|
|
150
|
-
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Aborting'));
|
|
151
|
-
expect(mockExit).toHaveBeenCalledWith(1);
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
describe('Directory Safety', () => {
|
|
156
|
-
it('should check if directory is safe to use', async () => {
|
|
157
|
-
BackendFirstHandler.mockImplementation(() => ({
|
|
158
|
-
initialize: jest.fn().mockRejectedValue(new Error('Directory not empty'))
|
|
159
|
-
}));
|
|
160
|
-
|
|
161
|
-
await expect(initCommand(mockProjectName, {})).rejects.toThrow('process.exit');
|
|
162
|
-
|
|
163
|
-
expect(mockExit).toHaveBeenCalledWith(1);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('should allow safe files in directory', async () => {
|
|
167
|
-
await initCommand(mockProjectName, {});
|
|
168
|
-
expect(BackendFirstHandler).toHaveBeenCalled();
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('should force overwrite when --force flag is used', async () => {
|
|
172
|
-
await initCommand(mockProjectName, { force: true });
|
|
173
|
-
expect(BackendFirstHandler).toHaveBeenCalledWith(
|
|
174
|
-
expect.any(String),
|
|
175
|
-
expect.objectContaining({ force: true })
|
|
176
|
-
);
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
});
|