@wolsok/nx-aws-cdk-v2 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.babelrc +10 -0
  2. package/README.md +96 -0
  3. package/eslint.config.js +17 -0
  4. package/executors.json +20 -0
  5. package/generators.json +19 -0
  6. package/jest.config.ts +8 -0
  7. package/package.json +24 -0
  8. package/project.json +66 -0
  9. package/src/executors/bootstrap/bootstrap.spec.ts +57 -0
  10. package/src/executors/bootstrap/bootstrap.ts +45 -0
  11. package/src/executors/bootstrap/schema.d.ts +3 -0
  12. package/src/executors/bootstrap/schema.json +8 -0
  13. package/src/executors/deploy/deploy.spec.ts +106 -0
  14. package/src/executors/deploy/deploy.ts +43 -0
  15. package/src/executors/deploy/schema.d.ts +3 -0
  16. package/src/executors/deploy/schema.json +13 -0
  17. package/src/executors/destroy/destroy.spec.ts +56 -0
  18. package/src/executors/destroy/destroy.ts +45 -0
  19. package/src/executors/destroy/schema.d.ts +3 -0
  20. package/src/executors/destroy/schema.json +13 -0
  21. package/src/generators/application/application.spec.ts +30 -0
  22. package/src/generators/application/application.ts +125 -0
  23. package/src/generators/application/files/cdk.json__template__ +36 -0
  24. package/src/generators/application/files/src/main.ts__template__ +5 -0
  25. package/src/generators/application/files/src/stacks/app-stack.ts__template__ +9 -0
  26. package/src/generators/application/files/tsconfig.app.json__template__ +9 -0
  27. package/src/generators/application/files/tsconfig.json__template__ +15 -0
  28. package/src/generators/application/jest-files/src/main.test.ts__template__ +13 -0
  29. package/src/generators/application/schema.d.ts +8 -0
  30. package/src/generators/application/schema.json +44 -0
  31. package/src/generators/init/init.spec.ts +22 -0
  32. package/src/generators/init/init.ts +45 -0
  33. package/src/generators/init/schema.d.ts +4 -0
  34. package/src/generators/init/schema.json +20 -0
  35. package/src/index.ts +0 -0
  36. package/src/interfaces/parsed-executor.interface.ts +7 -0
  37. package/src/utils/cdk-shared.ts +2 -0
  38. package/src/utils/executor.util.ts +120 -0
  39. package/src/utils/testing.ts +28 -0
  40. package/tsconfig.json +13 -0
  41. package/tsconfig.lib.json +11 -0
  42. package/tsconfig.spec.json +20 -0
package/.babelrc ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@nx/js/babel",
5
+ {
6
+ "useBuiltIns": "usage"
7
+ }
8
+ ]
9
+ ]
10
+ }
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
2
+ [![@wolsok/nx-aws-cdk-v2](https://img.shields.io/badge/%40adrian--goe-nx--aws--cdk-green)](https://github.com/WolfSoko/nx-aws-cdk-v2/tree/main/packages/aws-cdk-v2)
3
+ [![Typescript](https://badgen.net/badge/icon/typescript?icon=typescript&label)](https://www.typescriptlang.org/)
4
+ [![LICENSE](https://img.shields.io/npm/l/@wolsok/nx-aws-cdk-v2.svg)](https://www.npmjs.com/package/@wolsok/nx-aws-cdk-v2)
5
+ [![npm version](https://img.shields.io/npm/v/@wolsok/nx-aws-cdk-v2.svg)](https://www.npmjs.com/package/@wolsok/nx-aws-cdk-v2)
6
+ [![Downloads](https://img.shields.io/npm/dm/@wolsok/nx-aws-cdk-v2.svg)](https://www.npmjs.com/package/@wolsok/nx-aws-cdk-v2)
7
+
8
+ <hr>
9
+
10
+ # @wolsok/nx-aws-cdk-v2
11
+
12
+ An Nx plugin for developing [aws-cdk](https://docs.aws.amazon.com/cdk/latest/guide/home.html)
13
+
14
+ ## Table of Contents
15
+
16
+ - [Install](#install)
17
+ - [Usage](#usage)
18
+ - [Generate Application](#generate-application)
19
+ - [Targets](#targets)
20
+ - [Maintainers](#maintainers)
21
+ - [Contributing](#contributing)
22
+ - [License](#license)
23
+
24
+ ## Install
25
+
26
+ ```shell
27
+ # npm
28
+ npm install --save-dev @wolsok/nx-aws-cdk-v2
29
+
30
+ # yarn
31
+ yarn add --dev @wolsok/nx-aws-cdk-v2
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ### Generate Application
37
+
38
+ Create AWS CDK v2 Application
39
+
40
+ More details on AWS CDK v2 can be found on https://docs.aws.amazon.com/cdk/v2/guide/home.html
41
+
42
+ ```shell
43
+ nx generate @wolsok/nx-aws-cdk-v2:application myApp
44
+ ```
45
+
46
+ you can customize it further by passing these options:
47
+
48
+ ```
49
+ nx generate @wolsok/nx-aws-cdk-v2:application [name] [options,...]
50
+
51
+ Options:
52
+ --name
53
+ --tags Add tags to the project (used for linting)
54
+ --directory A directory where the project is placed
55
+ --skipFormat Skip formatting files
56
+ --unitTestRunner Adds the specified unit test runner (default: jest)
57
+ --setParserOptionsProject Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
58
+ --dryRun Runs through and reports activity without writing to disk.
59
+ --skip-nx-cache Skip the use of Nx cache.
60
+ --help Show available options for project target.
61
+ ```
62
+
63
+ ### Targets
64
+
65
+ Generated applications expose several functions to the CLI that allow users to deploy, destroy and bootstrap.
66
+
67
+ ```shell
68
+ nx deploy myApp
69
+ nx destroy myApp
70
+ nx bootstrap myApp --profile=profile
71
+ #see how to use aws environments https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#bootstrapping-howto-cli
72
+ nx bootstrap myApp aws://123456789012/us-east-1
73
+ ```
74
+
75
+ ## Maintainers
76
+
77
+ [@WolfSoko](https://github.com/WolfSoko)
78
+
79
+ ## Contributing
80
+
81
+ See [the contributing file](../../CONTRIBUTING.md)!
82
+
83
+ PRs accepted.
84
+
85
+ If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
86
+
87
+ ## License
88
+
89
+ This project is MIT licensed 2022 Wolfram Sokollek
90
+
91
+ ## Special thanks
92
+
93
+ This Project is based on [@tienne](https://github.com/tienne)'s
94
+ [nx-plugins](https://github.com/codebrewlab/nx-plugins).
95
+
96
+ Also thanks to [@therk](https://github.com/therk) for his work on migrating to cdk v2.
@@ -0,0 +1,17 @@
1
+ const baseConfig = require('../../eslint.config.js');
2
+
3
+ module.exports = [
4
+ ...baseConfig,
5
+ {
6
+ files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
7
+ rules: {},
8
+ },
9
+ {
10
+ files: ['**/*.ts', '**/*.tsx'],
11
+ rules: {},
12
+ },
13
+ {
14
+ files: ['**/*.js', '**/*.jsx'],
15
+ rules: {},
16
+ },
17
+ ];
package/executors.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "executors": {
4
+ "deploy": {
5
+ "implementation": "./src/executors/deploy/deploy",
6
+ "schema": "./src/executors/deploy/schema.json",
7
+ "description": "build executor"
8
+ },
9
+ "destroy": {
10
+ "implementation": "./src/executors/destroy/destroy",
11
+ "schema": "./src/executors/destroy/schema.json",
12
+ "description": "destroy executor"
13
+ },
14
+ "bootstrap": {
15
+ "implementation": "./src/executors/bootstrap/bootstrap",
16
+ "schema": "./src/executors/bootstrap/schema.json",
17
+ "description": "bootstrap executor"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "name": "aws-cdk-v2",
4
+ "version": "0.0.1",
5
+ "generators": {
6
+ "init": {
7
+ "factory": "./src/generators/init/init",
8
+ "schema": "./src/generators/init/schema.json",
9
+ "description": "init generator",
10
+ "aliases": ["ng-add"],
11
+ "hidden": true
12
+ },
13
+ "application": {
14
+ "factory": "./src/generators/application/application",
15
+ "schema": "./src/generators/application/schema.json",
16
+ "description": "create aws-cdk application"
17
+ }
18
+ }
19
+ }
package/jest.config.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { JestConfigWithTsJest } from 'ts-jest';
2
+
3
+ export default {
4
+ displayName: { name: 'aws-cdk-v2', color: 'blue' },
5
+ preset: '../../jest.preset.js',
6
+ testEnvironment: 'node',
7
+ coverageDirectory: '../../coverage/packages/aws-cdk-v2',
8
+ } as JestConfigWithTsJest;
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@wolsok/nx-aws-cdk-v2",
3
+ "version": "1.3.0",
4
+ "main": "src/index.js",
5
+ "generators": "./generators.json",
6
+ "executors": "./executors.json",
7
+ "keywords": [
8
+ "nx",
9
+ "aws-cdk",
10
+ "monorepo",
11
+ "aws cdk",
12
+ "Node"
13
+ ],
14
+ "ng-update": {
15
+ "requirements": {},
16
+ "migrations": "./migrations.json"
17
+ },
18
+ "author": "Wolfram Sokollek",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git@github.com:WolfSoko/nx-aws-cdk-v2"
22
+ },
23
+ "license": "MIT"
24
+ }
package/project.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "aws-cdk-v2",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/aws-cdk-v2/src",
5
+ "projectType": "library",
6
+ "tags": [],
7
+ "targets": {
8
+ "build": {
9
+ "executor": "@nx/js:tsc",
10
+ "outputs": ["{options.outputPath}"],
11
+ "options": {
12
+ "outputPath": "dist/packages/aws-cdk-v2",
13
+ "main": "packages/aws-cdk-v2/src/index.ts",
14
+ "tsConfig": "packages/aws-cdk-v2/tsconfig.lib.json",
15
+ "assets": [
16
+ "packages/aws-cdk-v2/*.md",
17
+ {
18
+ "input": "./packages/aws-cdk-v2/src",
19
+ "glob": "**/!(*.ts)",
20
+ "output": "./src"
21
+ },
22
+ {
23
+ "input": "./packages/aws-cdk-v2/src",
24
+ "glob": "**/*.d.ts",
25
+ "output": "./src"
26
+ },
27
+ {
28
+ "input": "./packages/aws-cdk-v2",
29
+ "glob": "generators.json",
30
+ "output": "."
31
+ },
32
+ {
33
+ "input": "./packages/aws-cdk-v2",
34
+ "glob": "executors.json",
35
+ "output": "."
36
+ }
37
+ ]
38
+ }
39
+ },
40
+ "lint": {
41
+ "options": {
42
+ "args": ["**/*.ts", "generators.json", "executors.json", "package.json"]
43
+ }
44
+ },
45
+ "test": {
46
+ "inputs": [
47
+ "default",
48
+ "^default",
49
+ "{workspaceRoot}/jest.preset.js",
50
+ {
51
+ "externalDependencies": ["jest"]
52
+ }
53
+ ],
54
+ "outputs": ["{workspaceRoot}\\coverage\\packages\\aws-cdk-v2"],
55
+ "options": {
56
+ "passWithNoTests": true
57
+ },
58
+ "configurations": {
59
+ "ci": {
60
+ "ci": true,
61
+ "coverage": true
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,57 @@
1
+ import * as childProcess from 'child_process';
2
+
3
+ import { logger } from '@nx/devkit';
4
+
5
+ import { BootstrapExecutorSchema } from './schema';
6
+ import executor from './bootstrap';
7
+ import { generateCommandString, LARGE_BUFFER } from '../../utils/executor.util';
8
+ import { mockExecutorContext } from '../../utils/testing';
9
+
10
+ const options: BootstrapExecutorSchema = {};
11
+
12
+ const nodeCommandWithRelativePath = generateCommandString('bootstrap', 'apps/proj');
13
+
14
+ describe('aws-cdk-v2 Bootstrap Executor', () => {
15
+ const context = mockExecutorContext('bootstrap');
16
+
17
+ beforeEach(async () => {
18
+ jest.spyOn(logger, 'debug');
19
+ jest.spyOn(childProcess, 'exec');
20
+ });
21
+
22
+ afterEach(() => jest.clearAllMocks());
23
+
24
+ it('run cdk bootstrap command', async () => {
25
+ await executor(options, context);
26
+
27
+ expect(childProcess.exec).toHaveBeenCalledWith(
28
+ nodeCommandWithRelativePath,
29
+ expect.objectContaining({
30
+ cwd: expect.stringContaining(context.root),
31
+ env: process.env,
32
+ maxBuffer: LARGE_BUFFER,
33
+ })
34
+ );
35
+
36
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath}`);
37
+ });
38
+
39
+ it('run cdk bootstrap command profile', async () => {
40
+ const option: BootstrapExecutorSchema = Object.assign({}, options);
41
+ const profile = 'prod';
42
+ option['profile'] = profile;
43
+ await executor(option, context);
44
+
45
+ expect(childProcess.exec).toHaveBeenCalledWith(
46
+ `${nodeCommandWithRelativePath} --profile ${profile}`,
47
+ expect.objectContaining({
48
+ env: process.env,
49
+ maxBuffer: LARGE_BUFFER,
50
+ })
51
+ );
52
+
53
+ expect(logger.debug).toHaveBeenLastCalledWith(
54
+ `Executing command: ${nodeCommandWithRelativePath} --profile ${profile}`
55
+ );
56
+ });
57
+ });
@@ -0,0 +1,45 @@
1
+ import { BootstrapExecutorSchema } from './schema';
2
+ import { createCommand, parseArgs, runCommandProcess } from '../../utils/executor.util';
3
+ import { ParsedExecutorInterface } from '../../interfaces/parsed-executor.interface';
4
+ import { ExecutorContext } from '@nx/devkit';
5
+
6
+ export interface ParsedBootstrapExecutorOption extends ParsedExecutorInterface {
7
+ profile?: string;
8
+ app?: string;
9
+ sourceRoot: string;
10
+ root: string;
11
+ }
12
+
13
+ export default async function runExecutor(options: BootstrapExecutorSchema, context: ExecutorContext) {
14
+ const normalizedOptions = normalizeOptions(options, context);
15
+ const result = await runBootstrap(normalizedOptions, context);
16
+
17
+ return {
18
+ success: result,
19
+ };
20
+ }
21
+
22
+ function runBootstrap(options: ParsedBootstrapExecutorOption, context: ExecutorContext) {
23
+ const command = createCommand('bootstrap', options);
24
+ return runCommandProcess(command, context.root);
25
+ }
26
+
27
+ function normalizeOptions(options: BootstrapExecutorSchema, context: ExecutorContext): ParsedBootstrapExecutorOption {
28
+ const parsedArgs = parseArgs(options);
29
+ let profile;
30
+
31
+ if (Object.prototype.hasOwnProperty.call(options, 'profile')) {
32
+ profile = `--profile ${options.profile}`;
33
+ }
34
+
35
+ // eslint-disable-next-line no-unsafe-optional-chaining
36
+ const { sourceRoot, root } = context?.projectsConfigurations?.projects[context.projectName];
37
+
38
+ return {
39
+ ...options,
40
+ parseArgs: parsedArgs,
41
+ profile,
42
+ sourceRoot,
43
+ root,
44
+ };
45
+ }
@@ -0,0 +1,3 @@
1
+ export interface BootstrapExecutorSchema {
2
+ profile?: string;
3
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "Bootstrap executor",
4
+ "description": "",
5
+ "type": "object",
6
+ "properties": {},
7
+ "required": []
8
+ }
@@ -0,0 +1,106 @@
1
+ import * as childProcess from 'child_process';
2
+ import { logger } from '@nx/devkit';
3
+
4
+ import executor from './deploy';
5
+ import { DeployExecutorSchema } from './schema';
6
+ import { generateCommandString, LARGE_BUFFER } from '../../utils/executor.util';
7
+ import { mockExecutorContext } from '../../utils/testing';
8
+
9
+ const options: DeployExecutorSchema = {};
10
+
11
+ const nodeCommandWithRelativePath = generateCommandString('deploy', 'apps/proj');
12
+
13
+ describe('aws-cdk-v2 deploy Executor', () => {
14
+ const context = mockExecutorContext('deploy');
15
+
16
+ beforeEach(async () => {
17
+ jest.spyOn(logger, 'debug');
18
+ jest.spyOn(childProcess, 'exec');
19
+ });
20
+
21
+ afterEach(() => jest.clearAllMocks());
22
+
23
+ it('run cdk deploy command', async () => {
24
+ await executor(options, context);
25
+
26
+ expect(childProcess.exec).toHaveBeenCalledWith(
27
+ nodeCommandWithRelativePath,
28
+ expect.objectContaining({
29
+ cwd: context.root,
30
+ env: process.env,
31
+ maxBuffer: LARGE_BUFFER,
32
+ })
33
+ );
34
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath}`);
35
+ });
36
+
37
+ it('run cdk deploy command stack', async () => {
38
+ const option: DeployExecutorSchema = Object.assign({}, options);
39
+ const stackName = 'test';
40
+ option['stacks'] = stackName;
41
+ await executor(option, context);
42
+
43
+ expect(childProcess.exec).toHaveBeenCalledWith(
44
+ `${nodeCommandWithRelativePath} ${stackName}`,
45
+ expect.objectContaining({
46
+ env: process.env,
47
+ maxBuffer: LARGE_BUFFER,
48
+ })
49
+ );
50
+
51
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath} ${stackName}`);
52
+ });
53
+
54
+ it('run cdk deploy command context options', async () => {
55
+ const option: DeployExecutorSchema = Object.assign({}, options);
56
+ const contextOptionString = 'key=value';
57
+ option['context'] = contextOptionString;
58
+ await executor(option, context);
59
+
60
+ expect(childProcess.exec).toHaveBeenCalledWith(
61
+ `${nodeCommandWithRelativePath} --context ${contextOptionString}`,
62
+ expect.objectContaining({
63
+ env: process.env,
64
+ maxBuffer: LARGE_BUFFER,
65
+ })
66
+ );
67
+
68
+ expect(logger.debug).toHaveBeenLastCalledWith(
69
+ `Executing command: ${nodeCommandWithRelativePath} --context ${contextOptionString}`
70
+ );
71
+ });
72
+
73
+ it('run cdk deploy command with multiple context options', async () => {
74
+ const option: DeployExecutorSchema = Object.assign({}, options);
75
+ const contextOptions = ['firstKey=firstValue', 'secondKey=secondValue'];
76
+ option['context'] = contextOptions;
77
+ await executor(option, context);
78
+
79
+ const contextCmd = contextOptions.map((option) => `--context ${option}`).join(' ');
80
+ expect(childProcess.exec).toHaveBeenCalledWith(
81
+ `${nodeCommandWithRelativePath} ${contextCmd}`,
82
+ expect.objectContaining({
83
+ env: process.env,
84
+ maxBuffer: LARGE_BUFFER,
85
+ })
86
+ );
87
+
88
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath} ${contextCmd}`);
89
+ });
90
+
91
+ it('run cdk deploy command with boolean context option', async () => {
92
+ const option: DeployExecutorSchema = Object.assign({}, options);
93
+ option['context'] = true;
94
+ await executor(option, context);
95
+
96
+ expect(childProcess.exec).toHaveBeenCalledWith(
97
+ `${nodeCommandWithRelativePath} --context true`,
98
+ expect.objectContaining({
99
+ env: process.env,
100
+ maxBuffer: LARGE_BUFFER,
101
+ })
102
+ );
103
+
104
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath} --context true`);
105
+ });
106
+ });
@@ -0,0 +1,43 @@
1
+ import { DeployExecutorSchema } from './schema';
2
+ import { createCommand, runCommandProcess, parseArgs } from '../../utils/executor.util';
3
+ import { ParsedExecutorInterface } from '../../interfaces/parsed-executor.interface';
4
+ import { ExecutorContext } from '@nx/devkit';
5
+
6
+ export interface ParsedDeployExecutorOption extends ParsedExecutorInterface {
7
+ stacks?: string[];
8
+ sourceRoot: string;
9
+ root: string;
10
+ }
11
+
12
+ export default async function runExecutor(options: DeployExecutorSchema, context: ExecutorContext) {
13
+ const normalizedOptions = normalizeOptions(options, context);
14
+ const result = await runDeploy(normalizedOptions, context);
15
+
16
+ return {
17
+ success: result,
18
+ };
19
+ }
20
+
21
+ async function runDeploy(options: ParsedDeployExecutorOption, context: ExecutorContext) {
22
+ const command = createCommand('deploy', options);
23
+ return runCommandProcess(command, context.root);
24
+ }
25
+
26
+ function normalizeOptions(options: DeployExecutorSchema, context: ExecutorContext): ParsedDeployExecutorOption {
27
+ const parsedArgs = parseArgs(options);
28
+ let stacks;
29
+
30
+ if (Object.prototype.hasOwnProperty.call(options, 'stacks')) {
31
+ stacks = options.stacks;
32
+ }
33
+
34
+ const { sourceRoot, root } = context?.projectsConfigurations?.projects[context.projectName] ?? {};
35
+
36
+ return {
37
+ ...options,
38
+ parseArgs: parsedArgs,
39
+ stacks,
40
+ sourceRoot,
41
+ root,
42
+ };
43
+ }
@@ -0,0 +1,3 @@
1
+ export interface DeployExecutorSchema {
2
+ stacks?: string;
3
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "deploy executor",
4
+ "description": "",
5
+ "type": "object",
6
+ "properties": {
7
+ "stacks": {
8
+ "type": "string",
9
+ "description": "use deploy named STACKS"
10
+ }
11
+ },
12
+ "required": []
13
+ }
@@ -0,0 +1,56 @@
1
+ import * as childProcess from 'child_process';
2
+
3
+ import { logger } from '@nx/devkit';
4
+
5
+ import { DestroyExecutorSchema } from './schema';
6
+ import executor from './destroy';
7
+ import { generateCommandString, LARGE_BUFFER } from '../../utils/executor.util';
8
+ import { mockExecutorContext } from '../../utils/testing';
9
+
10
+ const options: DestroyExecutorSchema = {};
11
+
12
+ const nodeCommandWithRelativePath = generateCommandString('destroy', 'apps/proj');
13
+
14
+ describe('aws-cdk-v2 Destroy Executor', () => {
15
+ const context = mockExecutorContext('destroy');
16
+
17
+ beforeEach(async () => {
18
+ jest.spyOn(logger, 'debug');
19
+ jest.spyOn(childProcess, 'exec');
20
+ });
21
+
22
+ afterEach(() => jest.clearAllMocks());
23
+
24
+ it('run cdk destroy command', async () => {
25
+ await executor(options, context);
26
+
27
+ expect(childProcess.exec).toHaveBeenCalledWith(
28
+ nodeCommandWithRelativePath,
29
+ expect.objectContaining({
30
+ cwd: context.root,
31
+ env: process.env,
32
+ maxBuffer: LARGE_BUFFER,
33
+ })
34
+ );
35
+
36
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath}`);
37
+ });
38
+
39
+ it('run cdk destroy command stack', async () => {
40
+ const option: DestroyExecutorSchema = Object.assign({}, options);
41
+ const stackName = 'test';
42
+ option['stacks'] = stackName;
43
+
44
+ await executor(option, context);
45
+
46
+ expect(childProcess.exec).toHaveBeenCalledWith(
47
+ `${nodeCommandWithRelativePath} ${stackName}`,
48
+ expect.objectContaining({
49
+ env: process.env,
50
+ maxBuffer: LARGE_BUFFER,
51
+ })
52
+ );
53
+
54
+ expect(logger.debug).toHaveBeenLastCalledWith(`Executing command: ${nodeCommandWithRelativePath} ${stackName}`);
55
+ });
56
+ });
@@ -0,0 +1,45 @@
1
+ import { DestroyExecutorSchema } from './schema';
2
+ import { createCommand, parseArgs, runCommandProcess } from '../../utils/executor.util';
3
+ import { ParsedExecutorInterface } from '../../interfaces/parsed-executor.interface';
4
+ import { ExecutorContext } from '@nx/devkit';
5
+
6
+ export interface ParsedDestroyExecutorOption extends ParsedExecutorInterface {
7
+ stacks?: string[];
8
+ app?: string;
9
+ sourceRoot: string;
10
+ root: string;
11
+ }
12
+
13
+ export default async function runExecutor(options: DestroyExecutorSchema, context: ExecutorContext) {
14
+ const normalizedOptions = normalizeOptions(options, context);
15
+ const result = await runDestroy(normalizedOptions, context);
16
+
17
+ return {
18
+ success: result,
19
+ };
20
+ }
21
+
22
+ function runDestroy(options: ParsedDestroyExecutorOption, context: ExecutorContext) {
23
+ const command = createCommand('destroy', options);
24
+ return runCommandProcess(command, context.root);
25
+ }
26
+
27
+ function normalizeOptions(options: DestroyExecutorSchema, context: ExecutorContext): ParsedDestroyExecutorOption {
28
+ const parsedArgs = parseArgs(options);
29
+ let stacks;
30
+
31
+ if (Object.prototype.hasOwnProperty.call(options, 'stacks')) {
32
+ stacks = options.stacks;
33
+ }
34
+
35
+ // eslint-disable-next-line no-unsafe-optional-chaining
36
+ const { sourceRoot, root } = context?.projectsConfigurations?.projects[context.projectName];
37
+
38
+ return {
39
+ ...options,
40
+ parseArgs: parsedArgs,
41
+ stacks,
42
+ sourceRoot,
43
+ root,
44
+ };
45
+ }
@@ -0,0 +1,3 @@
1
+ export interface DestroyExecutorSchema {
2
+ stacks?: string;
3
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "Destroy executor",
4
+ "description": "",
5
+ "type": "object",
6
+ "properties": {
7
+ "stacks": {
8
+ "type": "string",
9
+ "description": "use destroy named STACKS"
10
+ }
11
+ },
12
+ "required": []
13
+ }