jsii 5.9.5 → 5.9.6

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.
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+
3
+ ###
4
+ # Uses esbuild to minify the built aws-cdk-lib Javascript files to reduce module size
5
+ # and speed up loading times.
6
+ #
7
+ # In local testing, this changed the average time for loading `aws-cdk-lib` from
8
+ # 1112ms to 832ms (25% reduction).
9
+ #
10
+ # There are potentially even more savings available if we were to bundle each submodule
11
+ # into a single file; however, experiments with this (so far) have not worked due to circular
12
+ # dependencies in imports that lead to errors like "... is not a constructor". There are also
13
+ # potentially concerns with relative file usage (e.g., `__dirname`) in source. For now, this helps a bit.
14
+ ###
15
+
16
+ scriptdir=$(cd $(dirname $0) && pwd)
17
+ cd ${scriptdir}/..
18
+
19
+ find . -name '*.js' ! -name '.eslintrc.js' ! -path '*node_modules*' | xargs npx esbuild \
20
+ --platform=node \
21
+ --format=cjs \
22
+ --minify-whitespace \
23
+ --minify-syntax \
24
+ --tsconfig=tsconfig.json \
25
+ --allow-overwrite \
26
+ --outdir=.
@@ -0,0 +1,142 @@
1
+ /* eslint-disable no-console */
2
+ /**
3
+ * Verify that the two styles of imports we support:
4
+ *
5
+ * import { aws_ec2 } from 'aws-cdk-lib';
6
+ * import * as aws_ec2 from 'aws-cdk-lib/aws-ec2';
7
+ *
8
+ * Resolve to the same source file when analyzed using the TypeScript compiler.
9
+ *
10
+ * This is necessary for Rosetta's analysis and translation of examples: we need
11
+ * to know what submodule we're importing here, and we need to be able to deal
12
+ * with both styles since both are used interchangeably.
13
+ */
14
+ import * as os from 'os';
15
+ import * as path from 'path';
16
+ import * as fs from 'fs-extra';
17
+
18
+ // eslint-disable-next-line import/no-extraneous-dependencies
19
+ import * as ts from 'typescript';
20
+
21
+ async function main() {
22
+ // First make a tempdir and symlink `aws-cdk-lib` into it so we can refer to it
23
+ // as if it was an installed module.
24
+ await withTemporaryDirectory(async (tmpDir) => {
25
+ await fs.mkdirp(path.join(tmpDir, 'node_modules'));
26
+ await fs.symlink(path.resolve(__dirname, '..'), path.join(tmpDir, 'node_modules', 'aws-cdk-lib'));
27
+
28
+ const import1 = 'import { aws_ec2 } from "aws-cdk-lib";';
29
+ const import2 = 'import * as aws_ec2 from "aws-cdk-lib/aws-ec2";';
30
+
31
+ const src1 = await compileAndResolve(path.join(tmpDir, 'program1.ts'), import1, 'aws_ec2');
32
+ const src2 = await compileAndResolve(path.join(tmpDir, 'program2.ts'), import2, 'aws_ec2');
33
+
34
+ if (src1 !== src2) {
35
+ console.error('Import mismatch!');
36
+ console.error('\n ', import1, '\n');
37
+ console.error('resolves to', src1);
38
+ console.error('\n ', import2, '\n');
39
+ console.error('resolves to', src2);
40
+ process.exitCode = 1;
41
+ }
42
+ });
43
+ }
44
+
45
+ async function compileAndResolve(fileName: string, contents: string, symbolName: string) {
46
+ await fs.writeFile(fileName, contents + `\n\nconsole.log(${symbolName});`, { encoding: 'utf-8' });
47
+ const program = ts.createProgram({ rootNames: [fileName], options: STANDARD_COMPILER_OPTIONS });
48
+
49
+ const sourceFile = program.getSourceFile(fileName);
50
+ if (!sourceFile) {
51
+ throw new Error(`Could not find sourcefile back: ${fileName}`);
52
+ }
53
+
54
+ const diags = [
55
+ ...program.getGlobalDiagnostics(),
56
+ ...program.getDeclarationDiagnostics(sourceFile),
57
+ ...program.getSyntacticDiagnostics(sourceFile),
58
+ ...program.getSemanticDiagnostics(sourceFile),
59
+ ];
60
+ if (diags.length > 0) {
61
+ console.error(ts.formatDiagnostics(diags, {
62
+ getNewLine: () => '\n',
63
+ getCurrentDirectory: () => path.dirname(fileName),
64
+ getCanonicalFileName: (f) => path.resolve(f),
65
+ }));
66
+ throw new Error('Compilation failed');
67
+ }
68
+
69
+ // Find the 'console.log()' back and resolve the symbol inside
70
+ const logStmt = assertNode(sourceFile.statements[1], ts.isExpressionStatement);
71
+ const logCall = assertNode(logStmt.expression, ts.isCallExpression);
72
+ const ident = assertNode(logCall.arguments[0], ts.isIdentifier);
73
+
74
+ let sym = program.getTypeChecker().getSymbolAtLocation(ident);
75
+
76
+ // Resolve alias if applicable
77
+ // eslint-disable-next-line no-bitwise
78
+ while (sym && ((sym.flags & ts.SymbolFlags.Alias) !== 0)) {
79
+ sym = program.getTypeChecker().getAliasedSymbol(sym);
80
+ }
81
+
82
+ if (!sym) {
83
+ throw new Error(`Could not resolve: ${symbolName} in '${contents}'`);
84
+ }
85
+
86
+ // Return the filename
87
+ const srcFile = sym.declarations?.[0].getSourceFile().fileName.replace(/[.](ts|js|d\.ts)$/, '');
88
+ if (!srcFile) {
89
+ console.log(sym);
90
+ throw new Error(`Symbol ${symbolName} in '${contents}' does not resolve to a source location`);
91
+ }
92
+ return srcFile;
93
+ }
94
+
95
+ export async function withTemporaryDirectory<T>(callback: (dir: string) => Promise<T>): Promise<T> {
96
+ const tmpdir = await fs.mkdtemp(path.join(os.tmpdir(), path.basename(__filename)));
97
+ try {
98
+ return await callback(tmpdir);
99
+ } finally {
100
+ await fs.remove(tmpdir);
101
+ }
102
+ }
103
+
104
+ function assertNode<A extends ts.Node>(x: ts.Node, assert: (x: ts.Node) => x is A): A {
105
+ if (!assert(x)) {
106
+ throw new Error(`Not the right type of node, expecting ${assert.name}, got ${ts.SyntaxKind[x.kind]}`);
107
+ }
108
+ return x;
109
+ }
110
+
111
+ export const STANDARD_COMPILER_OPTIONS: ts.CompilerOptions = {
112
+ alwaysStrict: true,
113
+ charset: 'utf8',
114
+ declaration: true,
115
+ experimentalDecorators: true,
116
+ inlineSourceMap: true,
117
+ inlineSources: true,
118
+ lib: ['lib.es2016.d.ts', 'lib.es2017.object.d.ts', 'lib.es2017.string.d.ts'],
119
+ module: ts.ModuleKind.CommonJS,
120
+ noEmitOnError: true,
121
+ noFallthroughCasesInSwitch: true,
122
+ noImplicitAny: true,
123
+ noImplicitReturns: true,
124
+ noImplicitThis: true,
125
+ noUnusedLocals: false, // Important, becomes super annoying without this
126
+ noUnusedParameters: false, // Important, becomes super annoying without this
127
+ resolveJsonModule: true,
128
+ strict: true,
129
+ strictNullChecks: true,
130
+ strictPropertyInitialization: true,
131
+ stripInternal: true,
132
+ target: ts.ScriptTarget.ES2019,
133
+ // Incremental builds
134
+ incremental: true,
135
+ tsBuildInfoFile: '.tsbuildinfo',
136
+ };
137
+
138
+ main().catch((e) => {
139
+ // eslint-disable-next-line no-console
140
+ console.error(e);
141
+ process.exitCode = 1;
142
+ });
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Check that the imports from 'aws-cdk-lib' we expect to work, work, and those we have shielded off don't work.
3
+ */
4
+ import * as os from 'os';
5
+ import * as path from 'path';
6
+ import * as fs from 'fs-extra';
7
+
8
+ async function main() {
9
+ // First make a tempdir and symlink `aws-cdk-lib` into it so we can refer to it
10
+ // as if it was an installed module.
11
+ await withTemporaryDirectory(async (tmpDir) => {
12
+ await fs.mkdirp(path.join(tmpDir, 'node_modules'));
13
+ await fs.symlink(path.resolve(__dirname, '..'), path.join(tmpDir, 'node_modules', 'aws-cdk-lib'));
14
+
15
+ assertImportSucceeds('aws-cdk-lib');
16
+ assertImportFails('aws-cdk-lib/LICENSE', 'ERR_PACKAGE_PATH_NOT_EXPORTED');
17
+ assertImportFails('aws-cdk-lib/aws-s3/lib/bucket', 'ERR_PACKAGE_PATH_NOT_EXPORTED');
18
+ assertImportSucceeds('aws-cdk-lib/aws-s3');
19
+
20
+ function assertImportSucceeds(name: string) {
21
+ require.resolve(name, { paths: [tmpDir] });
22
+ }
23
+
24
+ function assertImportFails(name: string, code: string) {
25
+ try {
26
+ require.resolve(name, { paths: [tmpDir] });
27
+
28
+ // eslint-disable-next-line no-console
29
+ console.error(`Import of '${name}' should have produced an error, but didn't.`);
30
+ process.exitCode = 1;
31
+ } catch (e: any) {
32
+ if (e.code !== code) {
33
+ // eslint-disable-next-line no-console
34
+ console.error(`Import of '${name}' should have produced error ${code}, but got ${(e as any).code}.`);
35
+ process.exitCode = 1;
36
+ }
37
+ }
38
+ }
39
+ });
40
+ }
41
+
42
+
43
+ export async function withTemporaryDirectory<T>(callback: (dir: string) => Promise<T>): Promise<T> {
44
+ const tmpdir = await fs.mkdtemp(path.join(os.tmpdir(), path.basename(__filename)));
45
+ try {
46
+ return await callback(tmpdir);
47
+ } finally {
48
+ await fs.remove(tmpdir);
49
+ }
50
+ }
51
+
52
+
53
+ main().catch((e) => {
54
+ // eslint-disable-next-line no-console
55
+ console.error(e);
56
+ process.exitCode = 1;
57
+ });
@@ -0,0 +1,158 @@
1
+ // +------------------------------------------------------------------------------------------------
2
+ // | this script is executed post packaging to verify that experimental modules in aws-cdk-lib includes **only** L1 autogenerated files.
3
+ // | The purpose is to avoid publishing L2 of experimental modules with aws-cdk-lib
4
+ // |
5
+ import { spawnSync } from 'child_process';
6
+ import * as console from 'console';
7
+ import * as os from 'os';
8
+ import * as path from 'path';
9
+ import * as fs from 'fs-extra';
10
+
11
+ async function main(tempDir: string) {
12
+ console.log('🧐 Verifying all experimental modules includes only L1s files...');
13
+ const cwd = process.cwd();
14
+ const awsCdkModulesRepoPath = path.join(findWorkspacePath(), 'packages', '@aws-cdk');
15
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
16
+ const version = require('./../package.json').version;
17
+ const tarFullPath = path.join(cwd, 'dist', 'js', `aws-cdk-lib@${version}.jsii.tgz`);
18
+
19
+ const invalidCfnModules = new Map<string, Array<String>>();
20
+ const invalidModules = new Array<string>();
21
+
22
+ // install the tarball in a temp directory
23
+ console.log(`installing aws-cdk-lib from dist/js into ${tempDir}`);
24
+ exec('npm', ['install', '--prefix', tempDir, tarFullPath]);
25
+ const installedAwsCdkLibPath = path.join(tempDir, 'node_modules', 'aws-cdk-lib', 'lib');
26
+
27
+ for (const module of fs.readdirSync(awsCdkModulesRepoPath)) {
28
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
29
+ const pkgJson = require(path.join(awsCdkModulesRepoPath, module, 'package.json'));
30
+ if (pkgJson.stability !== 'experimental') {
31
+ continue;
32
+ }
33
+ if (pkgJson['cdk-build']?.cloudformation) {
34
+ // if a cfn module, verify only the allowed files exists
35
+ const files = await listAllFiles(path.join(installedAwsCdkLibPath, module));
36
+ const invalidFiles = new Array();
37
+ files.forEach(file => {
38
+ if (!isAllowedFile(file)) {
39
+ invalidFiles.push(file);
40
+ }
41
+ });
42
+ if (invalidFiles.length > 0) {
43
+ invalidCfnModules.set(module, invalidFiles);
44
+ }
45
+ } else {
46
+ // not a cfn module, verify it was entirely removed
47
+ if (fs.existsSync(path.join(installedAwsCdkLibPath, module))) {
48
+ invalidModules.push(module);
49
+ }
50
+ }
51
+ }
52
+
53
+ if (invalidCfnModules.size > 0 || invalidModules.length > 0) {
54
+ if (invalidCfnModules.size > 0 ) {
55
+ console.log('cfn module with invalid files:');
56
+ for (let [module, files] of invalidCfnModules.entries()) {
57
+ console.log(`${module}:`);
58
+ files.forEach(file => console.log(`\t ${file}`));
59
+ }
60
+ }
61
+ console.log('---------------------------------------------');
62
+ if (invalidModules.length > 0) {
63
+ console.log('non-cfn experimental modules:');
64
+ invalidModules.forEach(m => console.log(`\t ${m}`));
65
+ }
66
+ throw new Error('Verification Error');
67
+ }
68
+ }
69
+
70
+ const tempDir = fs.mkdtempSync(os.tmpdir());
71
+
72
+ main(tempDir).then(
73
+ () => {
74
+ fs.removeSync(tempDir);
75
+ console.log('✅ All experimental modules includes only L1s files!');
76
+ process.exit(0);
77
+ },
78
+ (err) => {
79
+ process.stderr.write(`${err}\n`);
80
+ process.stderr.write(`❌ Verification failed, Some experimental modules includes non L1 files, see details above. Inspect working directory: '${tempDir}'`);
81
+ process.exit(1);
82
+ },
83
+ );
84
+
85
+
86
+ /**
87
+ * Spawn sync with error handling
88
+ */
89
+ function exec(cmd: string, args: string[]) {
90
+ const proc = spawnSync(cmd, args);
91
+
92
+ if (proc.error) {
93
+ throw proc.error;
94
+ }
95
+
96
+ if (proc.status !== 0) {
97
+ if (proc.stdout || proc.stderr) {
98
+ throw new Error(`${cmd} exited with status ${proc.status}; stdout: ${proc.stdout?.toString().trim()}\n\n\nstderr: ${proc.stderr?.toString().trim()}`);
99
+ }
100
+ throw new Error(`${cmd} exited with status ${proc.status}`);
101
+ }
102
+
103
+ return proc;
104
+ }
105
+
106
+ const GENERATED_SUFFIX_REGEX = new RegExp(/generated\.(js|d\.ts)$/);
107
+ const ALLOWED_FILES = ['.jsiirc.json', 'index.ts', 'index.js', 'index.d.ts'];
108
+
109
+ /**
110
+ * Recursively collect all files in dir
111
+ */
112
+ async function listAllFiles(dir: string) {
113
+ const ret = new Array();
114
+
115
+ async function recurse(part: string) {
116
+ const files = await fs.readdir(part);
117
+ for (const file of files) {
118
+ const fullPath = path.join(part, file);
119
+ if ((await fs.stat(fullPath)).isDirectory()) {
120
+ await recurse(fullPath);
121
+ } else {
122
+ ret.push(file);
123
+ }
124
+ }
125
+ }
126
+ await recurse(dir);
127
+ return ret;
128
+ }
129
+
130
+ /**
131
+ * Find the workspace root path. Walk up the directory tree until you find lerna.json
132
+ */
133
+ function findWorkspacePath() {
134
+
135
+ return _findRootPath(process.cwd());
136
+
137
+ function _findRootPath(part: string): string {
138
+ if (part === path.resolve(part, '..')) {
139
+ throw new Error('couldn\'t find a \'lerna.json\' file when walking up the directory tree, are you in a aws-cdk project?');
140
+ }
141
+
142
+ if (fs.existsSync(path.resolve(part, 'lerna.json'))) {
143
+ return part;
144
+ }
145
+ return _findRootPath(path.resolve(part, '..'));
146
+ }
147
+ }
148
+
149
+ /**
150
+ * @param file
151
+ * @returns true if the file allowed in an L1 only modules, otherwise false
152
+ */
153
+ function isAllowedFile(file: string) {
154
+ if (GENERATED_SUFFIX_REGEX.test(file)) {
155
+ return true;
156
+ }
157
+ return ALLOWED_FILES.includes(file);
158
+ }