-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Flavio Stutz
committed
Jan 11, 2024
1 parent
73652e5
commit 6ffe6f3
Showing
5 changed files
with
113 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* eslint-disable camelcase */ | ||
import { RetentionDays } from 'aws-cdk-lib/aws-logs'; | ||
|
||
import { LambdaConfig } from '..'; | ||
|
||
import { StageConfig, StagesConfig, resolveStageConfig } from './configs'; | ||
|
||
type TestConfig = StageConfig & { | ||
lambda: LambdaConfig; | ||
}; | ||
|
||
const testStageConfigs: StagesConfig<TestConfig> = { | ||
default: { | ||
lambda: { | ||
allowAllOutbound: true, | ||
logRetention: RetentionDays.ONE_WEEK, | ||
}, | ||
}, | ||
dev: { | ||
lambda: { | ||
logRetention: RetentionDays.ONE_DAY, | ||
bundling: { | ||
sourceMap: true, | ||
}, | ||
}, | ||
}, | ||
prd: { | ||
lambda: { | ||
logRetention: RetentionDays.SIX_MONTHS, | ||
}, | ||
}, | ||
}; | ||
|
||
describe('configs', () => { | ||
it('resolve config with dev overrides', async () => { | ||
const stageConfig = resolveStageConfig<TestConfig>('dev', testStageConfigs); | ||
expect(stageConfig.lambda.allowAllOutbound).toBeTruthy(); | ||
expect(stageConfig.lambda.logRetention).toBe(RetentionDays.ONE_DAY); | ||
}); | ||
|
||
it('resolve stage "dev-pr-123" with same contents as stage "dev"', async () => { | ||
const stageConfig = resolveStageConfig<TestConfig>('dev-pr-123', testStageConfigs); | ||
expect(stageConfig.lambda.allowAllOutbound).toBeTruthy(); | ||
expect(stageConfig.lambda.logRetention).toBe(RetentionDays.ONE_DAY); | ||
}); | ||
|
||
it('resolve prd config with defaults', async () => { | ||
const stageConfig = resolveStageConfig<TestConfig>('tst', testStageConfigs); | ||
expect(stageConfig.lambda.allowAllOutbound).toBeTruthy(); | ||
expect(stageConfig.lambda.logRetention).toBe(RetentionDays.ONE_WEEK); | ||
}); | ||
|
||
it('resolve acc config with defaults', async () => { | ||
const stageConfig = resolveStageConfig<TestConfig>('prd', testStageConfigs); | ||
expect(stageConfig.lambda.allowAllOutbound).toBeTruthy(); | ||
expect(stageConfig.lambda.logRetention).toBe(RetentionDays.SIX_MONTHS); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Scoper } from 'scoperjs'; | ||
|
||
// https://stackoverflow.com/questions/43159887/make-a-single-property-optional-in-typescript | ||
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>; | ||
|
||
export type StagesConfig<T extends StageConfig> = { | ||
default: T; | ||
[stage: string]: T; | ||
}; | ||
|
||
export type StageConfig = { | ||
stage?: string; | ||
}; | ||
|
||
/** | ||
* Returns the prefix for a stage name identified by a '-'. e.g: for 'dev-pr-123', it returns 'dev' | ||
* @param stageName Full stage name. e.g: dev-pr-123, dev-testing-deploy, acc-frozen | ||
* @returns Prefix of stage name. e.g: 'dev' | ||
*/ | ||
export const getStagePrefix = (stage: string): string => { | ||
return stage.replaceAll(/-.*/g, ''); | ||
}; | ||
|
||
/** | ||
* Resolves a stage configuration by merging global configs with specific stage configs | ||
* @param {string} stage such as 'dev', 'tst', 'acc', 'prd', 'dev-pr-123'. The actual stage name for getting the config will be the stage name prefixed by "-" if exists. For example, for 'dev-pr-123', it will be used 'dev' | ||
* @param {StagesConfig<T>} stagesConfig Configuration for all stages along with default values if the stage doesn't define a specific value | ||
* @returns {StageConfig} | ||
*/ | ||
export function resolveStageConfig<T extends StageConfig>( | ||
stage: string, | ||
stagesConfig: StagesConfig<T>, | ||
): T { | ||
const contexter = Scoper.create<T>(stagesConfig.default); | ||
// eslint-disable-next-line no-restricted-syntax | ||
for (const [stagek, config] of Object.entries(stagesConfig)) { | ||
contexter.setScopeValue(stagek, config); | ||
} | ||
|
||
// get stage context by stage prefix name. e.g: context 'dev' when stage is 'dev-pr-123' | ||
const stagePrefix = getStagePrefix(stage); | ||
|
||
const stageValue = contexter.getValue(stagePrefix); | ||
stageValue.stage = stage; | ||
return stageValue; | ||
} |