diff --git a/.projenrc.ts b/.projenrc.ts index 7ba917552..827f4ec99 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -688,9 +688,18 @@ const tmpToolkitHelpers = configureProject( parent: repo, name: '@aws-cdk/tmp-toolkit-helpers', description: 'A temporary package to hold code shared between aws-cdk and @aws-cdk/toolkit-lib', - deps: [], devDeps: [ cdkBuildTools, + '@types/archiver', + '@types/glob', + '@types/semver', + 'fast-check', + ], + deps: [ + 'archiver', + 'glob', + 'semver', + 'yaml@^1', ], tsconfig: { compilerOptions: { @@ -708,6 +717,7 @@ tmpToolkitHelpers.package.addField('exports', { '.': './lib/index.js', './package.json': './package.json', './api': './lib/api/index.js', + './util': './lib/util/index.js', }); ////////////////////////////////////////////////////////////////////// @@ -1245,6 +1255,8 @@ toolkitLib.postCompileTask.exec('node build-tools/bundle.mjs'); // Smoke test built JS files toolkitLib.postCompileTask.exec('node ./lib/index.js >/dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null = T & Brand; * values which are branded by construction (really just an elaborate * way to write 'as'). */ +/* c8 ignore next 3 */ export function createBranded>(value: TypeUnderlyingBrand): A { return value as A; } diff --git a/packages/aws-cdk/lib/util/types.ts b/packages/@aws-cdk/tmp-toolkit-helpers/src/util/types.ts similarity index 100% rename from packages/aws-cdk/lib/util/types.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/src/util/types.ts diff --git a/packages/aws-cdk/lib/util/version-range.ts b/packages/@aws-cdk/tmp-toolkit-helpers/src/util/version-range.ts similarity index 96% rename from packages/aws-cdk/lib/util/version-range.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/src/util/version-range.ts index 333031049..69fd5d980 100644 --- a/packages/aws-cdk/lib/util/version-range.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/src/util/version-range.ts @@ -1,5 +1,5 @@ import * as semver from 'semver'; -import { ToolkitError } from '../toolkit/error'; +import { ToolkitError } from '../api/toolkit-error'; // bracket - https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN401 // pep - https://www.python.org/dev/peps/pep-0440/#version-specifiers diff --git a/packages/aws-cdk/lib/util/yaml-cfn.ts b/packages/@aws-cdk/tmp-toolkit-helpers/src/util/yaml-cfn.ts similarity index 100% rename from packages/aws-cdk/lib/util/yaml-cfn.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/src/util/yaml-cfn.ts diff --git a/packages/@aws-cdk/tmp-toolkit-helpers/test/_helpers/sleep.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/_helpers/sleep.ts new file mode 100644 index 000000000..430da15f5 --- /dev/null +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/_helpers/sleep.ts @@ -0,0 +1,3 @@ +export async function sleep(ms: number) { + return new Promise((ok) => setTimeout(ok, ms)); +} diff --git a/packages/@aws-cdk/tmp-toolkit-helpers/test/util/archive.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/archive.test.ts new file mode 100644 index 000000000..717dfda9d --- /dev/null +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/archive.test.ts @@ -0,0 +1,169 @@ +import { exec as _exec } from 'child_process'; +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import { promisify } from 'util'; +import { zipDirectory } from '../../src/util/archive'; + +const exec = promisify(_exec); + +describe('zipDirectory', () => { + let tempDir: string; + let outputZipPath: string; + + beforeEach(async () => { + // Create a temporary directory + tempDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'zipDirectory-test-'), + ); + outputZipPath = path.join(os.tmpdir(), 'output.zip'); + + // Clean up any existing test files + try { + await fs.promises.unlink(outputZipPath); + } catch (e) { + // Ignore errors if file doesn't exist + } + }); + + afterEach(async () => { + // Clean up + try { + await fs.promises.rm(tempDir, { recursive: true }); + await fs.promises.unlink(outputZipPath); + } catch (e) { + // Ignore errors during cleanup + } + }); + + test('creates a zip file with expected files', async () => { + // Setup + const testFileContent = 'test content'; + const testFilePath = path.join(tempDir, 'testfile.txt'); + await fs.promises.writeFile(testFilePath, testFileContent); + + // Create a nested directory + const nestedDir = path.join(tempDir, 'nested'); + await fs.promises.mkdir(nestedDir, { recursive: true }); + const nestedFilePath = path.join(nestedDir, 'nestedfile.txt'); + await fs.promises.writeFile(nestedFilePath, 'nested content'); + + // Act + await zipDirectory(tempDir, outputZipPath); + + // Assert + const stats = await fs.promises.stat(outputZipPath); + expect(stats.isFile()).toBe(true); + + // Verify content using unzip + const { stdout: fileList } = await exec(`unzip -l ${outputZipPath}`); + + // Check file list contains the expected files + expect(fileList).toContain('testfile.txt'); + expect(fileList).toContain('nested/nestedfile.txt'); + + // Create a temporary directory to extract files + const extractDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'extract-test-'), + ); + + try { + // Extract files + await exec(`unzip ${outputZipPath} -d ${extractDir}`); + + // Verify content of files + const mainFileContent = await fs.promises.readFile( + path.join(extractDir, 'testfile.txt'), + { encoding: 'utf-8' }, + ); + expect(mainFileContent).toBe(testFileContent); + + const nestedFileContent = await fs.promises.readFile( + path.join(extractDir, 'nested/nestedfile.txt'), + { encoding: 'utf-8' }, + ); + expect(nestedFileContent).toBe('nested content'); + } finally { + // Clean up the extract directory + await fs.promises.rm(extractDir, { recursive: true }); + } + }); + + test('preserves file permissions', async () => { + // Setup - create a file with specific permissions + const testFilePath = path.join(tempDir, 'executable.sh'); + await fs.promises.writeFile(testFilePath, '#!/bin/sh\necho "Hello"'); + + // Set executable permissions (0755) + await fs.promises.chmod(testFilePath, 0o755); + + // Act + await zipDirectory(tempDir, outputZipPath); + + // Assert - extract the file and check permissions + // Create a temporary directory to extract files + const extractDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'extract-permissions-test-'), + ); + + try { + // Extract files + await exec(`unzip ${outputZipPath} -d ${extractDir}`); + + // Check the extracted file permissions + const stats = await fs.promises.stat(path.join(extractDir, 'executable.sh')); + + // Check executable bit is set (0o111 = ---x--x--x) + // eslint-disable-next-line no-bitwise + const isExecutable = !!(stats.mode & 0o111); // Check if any executable bit is set + expect(isExecutable).toBeTruthy(); + } finally { + // Clean up the extract directory + await fs.promises.rm(extractDir, { recursive: true }); + } + }); + + test('follows symlinks as expected', async () => { + // Skip test on Windows as symlinks might not be properly supported + if (os.platform() === 'win32') { + return; + } + + // Setup - create a file and a symlink to it + const targetFile = path.join(tempDir, 'target.txt'); + await fs.promises.writeFile(targetFile, 'target content'); + + const symlinkPath = path.join(tempDir, 'link.txt'); + await fs.promises.symlink(targetFile, symlinkPath); + + // Act + await zipDirectory(tempDir, outputZipPath); + + // Assert - extract the file and check content + // Create a temporary directory to extract files + const extractDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'extract-symlink-test-'), + ); + + try { + // Extract files + await exec(`unzip ${outputZipPath} -d ${extractDir}`); + + // Check that the link.txt file exists in the zip + const linkExists = await fs.promises.stat(path.join(extractDir, 'link.txt')) + .then(() => true) + .catch(() => false); + expect(linkExists).toBeTruthy(); + + // Check that the content is the same as the target file + const linkedContent = await fs.promises.readFile( + path.join(extractDir, 'link.txt'), + { encoding: 'utf-8' }, + ); + expect(linkedContent).toBe('target content'); + } finally { + // Clean up the extract directory + await fs.promises.rm(extractDir, { recursive: true }); + } + }); +}); diff --git a/packages/aws-cdk/test/util/arrays.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/arrays.test.ts similarity index 85% rename from packages/aws-cdk/test/util/arrays.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/arrays.test.ts index b9d09c2b1..4551d3608 100644 --- a/packages/aws-cdk/test/util/arrays.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/arrays.test.ts @@ -1,5 +1,4 @@ -/* eslint-disable import/order */ -import { flatMap, flatten, partition } from '../../lib/util'; +import { flatMap, flatten, partition } from '../../src/util'; test('flatten combines arrays', () => { const output = flatten([ diff --git a/packages/@aws-cdk/tmp-toolkit-helpers/test/util/bool.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/bool.test.ts new file mode 100644 index 000000000..093a50f6c --- /dev/null +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/bool.test.ts @@ -0,0 +1,8 @@ +import { numberFromBool } from '../../src/util/bool'; + +test.each([ + [true, 1], + [false, 0], +])('for %s returns %s', (value, expected) => { + expect(numberFromBool(value)).toBe(expected); +}); diff --git a/packages/aws-cdk/test/util/bytes.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/bytes.test.ts similarity index 89% rename from packages/aws-cdk/test/util/bytes.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/bytes.test.ts index 9292af4f3..7612b404c 100644 --- a/packages/aws-cdk/test/util/bytes.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/bytes.test.ts @@ -1,4 +1,4 @@ -import { formatBytes } from '../../lib/util/bytes'; +import { formatBytes } from '../../src/util/bytes'; test.each([ [0, '0 Bytes'], diff --git a/packages/aws-cdk/test/util/cloudformation.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/cloudformation.test.ts similarity index 92% rename from packages/aws-cdk/test/util/cloudformation.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/cloudformation.test.ts index 4ebec25c2..03fce5f47 100644 --- a/packages/aws-cdk/test/util/cloudformation.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/cloudformation.test.ts @@ -1,5 +1,4 @@ -/* eslint-disable import/order */ -import { validateSnsTopicArn, stackEventHasErrorMessage, maxResourceTypeLength } from '../../lib/util/cloudformation'; +import { validateSnsTopicArn, stackEventHasErrorMessage, maxResourceTypeLength } from '../../src/util/cloudformation'; describe('validateSnsTopicArn', () => { test('empty string', () => { @@ -68,8 +67,8 @@ describe('maxResourceTypeLength', () => { const template = { Resources: { Resource1: { Type: 'AWS::S3::Bucket' }, - Resource2: { Type: 'AWS::IAM::Role' } - } + Resource2: { Type: 'AWS::IAM::Role' }, + }, }; expect(maxResourceTypeLength(template)).toBe('AWS::CloudFormation::Stack'.length); }); @@ -79,8 +78,8 @@ describe('maxResourceTypeLength', () => { const template = { Resources: { Resource1: { Type: 'AWS::S3::Bucket' }, - Resource2: { Type: longType } - } + Resource2: { Type: longType }, + }, }; expect(maxResourceTypeLength(template)).toBe(longType.length); }); @@ -89,8 +88,8 @@ describe('maxResourceTypeLength', () => { const template = { Resources: { Resource1: { Type: 'AWS::S3::Bucket' }, - Resource2: {} - } + Resource2: {}, + }, }; expect(maxResourceTypeLength(template)).toBe('AWS::CloudFormation::Stack'.length); }); @@ -98,8 +97,8 @@ describe('maxResourceTypeLength', () => { test('accepts custom startWidth', () => { const template = { Resources: { - Resource1: { Type: 'AWS::S3::Bucket' } - } + Resource1: { Type: 'AWS::S3::Bucket' }, + }, }; expect(maxResourceTypeLength(template, 50)).toBe(50); }); diff --git a/packages/@aws-cdk/tmp-toolkit-helpers/test/util/content-hash.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/content-hash.test.ts new file mode 100644 index 000000000..9398b0913 --- /dev/null +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/content-hash.test.ts @@ -0,0 +1,118 @@ +import * as crypto from 'crypto'; +import { contentHash, contentHashAny } from '../../src/util/content-hash'; + +describe('contentHash', () => { + test('hashes string data correctly', () => { + const data = 'test string'; + const expected = crypto.createHash('sha256').update(data).digest('hex'); + expect(contentHash(data)).toEqual(expected); + }); + + test('hashes Buffer data correctly', () => { + const data = Buffer.from('test buffer'); + const expected = crypto.createHash('sha256').update(data).digest('hex'); + expect(contentHash(data)).toEqual(expected); + }); + + test('hashes DataView data correctly', () => { + const buffer = new ArrayBuffer(4); + const view = new DataView(buffer); + view.setUint32(0, 42); + const expected = crypto.createHash('sha256').update(view).digest('hex'); + expect(contentHash(view)).toEqual(expected); + }); + + test('produces consistent output for identical inputs', () => { + const data = 'consistent data'; + expect(contentHash(data)).toEqual(contentHash(data)); + }); + + test('produces different output for different inputs', () => { + expect(contentHash('data1')).not.toEqual(contentHash('data2')); + }); +}); + +describe('contentHashAny', () => { + test('hashes primitive string correctly', () => { + const value = 'test string'; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); // sha256 produces 64 hex chars + }); + + test('hashes primitive number correctly', () => { + const value = 123; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes primitive boolean correctly', () => { + const value = true; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes null and undefined correctly', () => { + expect(contentHashAny(null)).toMatch(/^[a-f0-9]{64}$/); + expect(contentHashAny(undefined)).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes arrays correctly', () => { + const value = ['a', 'b', 'c']; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes nested arrays correctly', () => { + const value = ['a', ['b', 'c'], 'd']; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes objects correctly', () => { + const value = { a: 1, b: 2, c: 3 }; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes nested objects correctly', () => { + const value = { a: 1, b: { c: 2, d: 3 }, e: 4 }; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('hashes complex mixed structures correctly', () => { + const value = { + a: 1, + b: ['x', 'y', 'z'], + c: { d: true, e: [1, 2, { f: 'g' }] }, + h: null, + }; + const result = contentHashAny(value); + expect(result).toMatch(/^[a-f0-9]{64}$/); + }); + + test('produces consistent output for identical inputs', () => { + const value = { a: 1, b: [2, 3], c: { d: 4 } }; + expect(contentHashAny(value)).toEqual(contentHashAny(value)); + }); + + test('produces different output for different inputs', () => { + const value1 = { a: 1, b: 2 }; + const value2 = { a: 1, b: 3 }; + expect(contentHashAny(value1)).not.toEqual(contentHashAny(value2)); + }); + + test('produces same hash regardless of object property order', () => { + const value1 = { a: 1, b: 2, c: 3 }; + const value2 = { c: 3, a: 1, b: 2 }; + expect(contentHashAny(value1)).toEqual(contentHashAny(value2)); + }); + + test('distinguishes between string and number values', () => { + expect(contentHashAny('123')).not.toEqual(contentHashAny(123)); + }); + + test('distinguishes between empty arrays and objects', () => { + expect(contentHashAny([])).not.toEqual(contentHashAny({})); + }); +}); diff --git a/packages/aws-cdk/test/util/error.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/format-error.test.ts similarity index 93% rename from packages/aws-cdk/test/util/error.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/format-error.test.ts index 3735357fc..29753add0 100644 --- a/packages/aws-cdk/test/util/error.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/format-error.test.ts @@ -1,4 +1,4 @@ -import { formatErrorMessage } from '../../lib/util/format-error'; +import { formatErrorMessage } from '../../src/util/format-error'; describe('formatErrorMessage', () => { test('should return the formatted message for a regular Error object', () => { diff --git a/packages/aws-cdk/test/util/json.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/json.test.ts similarity index 96% rename from packages/aws-cdk/test/util/json.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/json.test.ts index 21d600a76..53eff0b6f 100644 --- a/packages/aws-cdk/test/util/json.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/json.test.ts @@ -1,4 +1,4 @@ -import { findJsonValue, getResultObj } from '../../lib/util/json'; +import { findJsonValue, getResultObj } from '../../src/util/json'; const jsonObj = { DBInstanceArn: 'arn:aws:rds:us-east-1:123456789012:db:test-instance-1', diff --git a/packages/aws-cdk/test/util/objects.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/objects.test.ts similarity index 82% rename from packages/aws-cdk/test/util/objects.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/objects.test.ts index 836741aaf..7aa9d0dd5 100644 --- a/packages/aws-cdk/test/util/objects.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/objects.test.ts @@ -1,6 +1,5 @@ -/* eslint-disable import/order */ import * as fc from 'fast-check'; -import { deepClone, deepGet, deepMerge, deepSet, splitBySize } from '../../lib/util'; +import { applyDefaults, deepClone, deepGet, deepMerge, deepSet, splitBySize } from '../../src/util'; test('deepSet can set deeply', () => { const obj = {}; @@ -63,3 +62,14 @@ describe('splitBySize', () => { } }); }); + +describe('applyDefaults', () => { + test('applyDefaults() works', () => { + const given = { a: 1 }; + const defaults = { a: 2, b: 2 }; + + const output = applyDefaults(given, defaults); + + expect(output).toEqual({ a: 1, b: 2 }); + }); +}); diff --git a/packages/aws-cdk/test/util/parallel.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/parallel.test.ts similarity index 86% rename from packages/aws-cdk/test/util/parallel.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/parallel.test.ts index 65dca423a..e76171c6e 100644 --- a/packages/aws-cdk/test/util/parallel.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/parallel.test.ts @@ -1,5 +1,5 @@ -import { parallelPromises } from '../../lib/util/parallel'; -import { sleep } from '../util'; +import { parallelPromises } from '../../src/util/parallel'; +import { sleep } from '../_helpers/sleep'; test('parallelPromises', async () => { const N = 4; diff --git a/packages/aws-cdk/test/util/serialize.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/serialize.test.ts similarity index 98% rename from packages/aws-cdk/test/util/serialize.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/serialize.test.ts index a5b605c21..e1f01b99d 100644 --- a/packages/aws-cdk/test/util/serialize.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/serialize.test.ts @@ -1,4 +1,4 @@ -import { toYAML, obscureTemplate, replacerBufferWithInfo } from '../../lib/util/serialize'; +import { toYAML, obscureTemplate, replacerBufferWithInfo } from '../../src/util/serialize'; describe(toYAML, () => { test('does not wrap lines', () => { diff --git a/packages/@aws-cdk/tmp-toolkit-helpers/test/util/string-manipulation.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/string-manipulation.test.ts new file mode 100644 index 000000000..15cb7d0b7 --- /dev/null +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/string-manipulation.test.ts @@ -0,0 +1,73 @@ +import { padLeft, padRight, formatTime } from '../../src/util/string-manipulation'; + +describe('string-manipulation', () => { + describe('padLeft', () => { + test('adds padding to the left of a string', () => { + expect(padLeft(5, 'abc')).toBe(' abc'); + }); + + test('returns the string unchanged if it is already at the target length', () => { + expect(padLeft(3, 'abc')).toBe('abc'); + }); + + test('returns the string unchanged if it exceeds the target length', () => { + expect(padLeft(2, 'abc')).toBe('abc'); + }); + + test('uses the specified padding character', () => { + expect(padLeft(5, 'abc', '*')).toBe('**abc'); + }); + + test('handles empty strings', () => { + expect(padLeft(3, '')).toBe(' '); + }); + }); + + describe('padRight', () => { + test('adds padding to the right of a string', () => { + expect(padRight(5, 'abc')).toBe('abc '); + }); + + test('returns the string unchanged if it is already at the target length', () => { + expect(padRight(3, 'abc')).toBe('abc'); + }); + + test('returns the string unchanged if it exceeds the target length', () => { + expect(padRight(2, 'abc')).toBe('abc'); + }); + + test('uses the specified padding character', () => { + expect(padRight(5, 'abc', '*')).toBe('abc**'); + }); + + test('handles empty strings', () => { + expect(padRight(3, '')).toBe(' '); + }); + }); + + describe('formatTime', () => { + test('converts milliseconds to seconds and rounds to 2 decimal places', () => { + expect(formatTime(1234)).toBe(1.23); + }); + + test('rounds up correctly', () => { + expect(formatTime(1235)).toBe(1.24); + }); + + test('rounds down correctly', () => { + expect(formatTime(1234.4)).toBe(1.23); + }); + + test('handles zero', () => { + expect(formatTime(0)).toBe(0); + }); + + test('handles large numbers', () => { + expect(formatTime(60000)).toBe(60); + }); + + test('handles decimal precision correctly', () => { + expect(formatTime(1500)).toBe(1.5); + }); + }); +}); diff --git a/packages/aws-cdk/test/util/version-range.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/version-range.test.ts similarity index 89% rename from packages/aws-cdk/test/util/version-range.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/version-range.test.ts index 840e50489..309fc7673 100644 --- a/packages/aws-cdk/test/util/version-range.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/version-range.test.ts @@ -1,5 +1,4 @@ -/* eslint-disable import/order */ -import { rangeFromSemver } from '../../lib/util/version-range'; +import { rangeFromSemver } from '../../src/util/version-range'; describe('rangeFromSemver', () => { describe('bracket', () => { diff --git a/packages/aws-cdk/test/util/yaml.test.ts b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/yaml.test.ts similarity index 94% rename from packages/aws-cdk/test/util/yaml.test.ts rename to packages/@aws-cdk/tmp-toolkit-helpers/test/util/yaml.test.ts index 33a7b66c7..eb8943c6c 100644 --- a/packages/aws-cdk/test/util/yaml.test.ts +++ b/packages/@aws-cdk/tmp-toolkit-helpers/test/util/yaml.test.ts @@ -1,5 +1,4 @@ -/* eslint-disable import/order */ -import { deserializeStructure, toYAML } from '../../lib/util/serialize'; +import { deserializeStructure, toYAML } from '../../src/util/serialize'; // Preferred quote of the YAML library const q = '"'; diff --git a/packages/@aws-cdk/toolkit-lib/.projen/tasks.json b/packages/@aws-cdk/toolkit-lib/.projen/tasks.json index 90245fbbc..f7b8e95da 100644 --- a/packages/@aws-cdk/toolkit-lib/.projen/tasks.json +++ b/packages/@aws-cdk/toolkit-lib/.projen/tasks.json @@ -181,6 +181,12 @@ }, { "exec": "node ./lib/api/aws-cdk.js >/dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null >; diff --git a/packages/aws-cdk/lib/api/aws-auth/sdk.ts b/packages/aws-cdk/lib/api/aws-auth/sdk.ts index 3ede58e63..3d0dd1b43 100644 --- a/packages/aws-cdk/lib/api/aws-auth/sdk.ts +++ b/packages/aws-cdk/lib/api/aws-auth/sdk.ts @@ -330,7 +330,7 @@ import { traceMemberMethods } from './tracing'; import { defaultCliUserAgent } from './user-agent'; import { debug } from '../../logging'; import { AuthenticationError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; export interface S3ClientOptions { /** diff --git a/packages/aws-cdk/lib/api/aws-auth/user-agent.ts b/packages/aws-cdk/lib/api/aws-auth/user-agent.ts index 98e2f716d..a63601234 100644 --- a/packages/aws-cdk/lib/api/aws-auth/user-agent.ts +++ b/packages/aws-cdk/lib/api/aws-auth/user-agent.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import { readIfPossible } from './util'; -import { rootDir } from '../../util/directories'; +import { cliRootDir } from '../../cli/root-dir'; /** * Find the package.json from the main toolkit. @@ -9,7 +9,7 @@ import { rootDir } from '../../util/directories'; * Fall back to argv[1], or a standard string if that is undefined for some reason. */ export function defaultCliUserAgent() { - const root = rootDir(false); + const root = cliRootDir(false); const pkg = JSON.parse((root ? readIfPossible(path.join(root, 'package.json')) : undefined) ?? '{}'); const name = pkg.name ?? path.basename(process.argv[1] ?? 'cdk-cli'); const version = pkg.version ?? ''; diff --git a/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts b/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts index fd3e45a2c..ec04e15d0 100644 --- a/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts +++ b/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts @@ -5,10 +5,10 @@ import type { BootstrapEnvironmentOptions, BootstrappingParameters } from './boo import { BootstrapStack, bootstrapVersionFromTemplate } from './deploy-bootstrap'; import { legacyBootstrapTemplate } from './legacy-template'; import { warn } from '../../cli/messages'; +import { cliRootDir } from '../../cli/root-dir'; import { IoMessaging } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { rootDir } from '../../util/directories'; -import { loadStructuredFile, serializeStructure } from '../../util/serialize'; +import { loadStructuredFile, serializeStructure } from '../../util'; import type { SDK, SdkProvider } from '../aws-auth'; import type { SuccessfulDeployStackResult } from '../deployments'; import { Mode } from '../plugin/mode'; @@ -375,7 +375,7 @@ export class Bootstrapper { case 'custom': return loadStructuredFile(this.source.templateFile); case 'default': - return loadStructuredFile(path.join(rootDir(), 'lib', 'api', 'bootstrap', 'bootstrap-template.yaml')); + return loadStructuredFile(path.join(cliRootDir(), 'lib', 'api', 'bootstrap', 'bootstrap-template.yaml')); case 'legacy': return legacyBootstrapTemplate(params); } diff --git a/packages/aws-cdk/lib/api/cxapp/exec.ts b/packages/aws-cdk/lib/api/cxapp/exec.ts index e5782e1d3..6b2e6ba8b 100644 --- a/packages/aws-cdk/lib/api/cxapp/exec.ts +++ b/packages/aws-cdk/lib/api/cxapp/exec.ts @@ -10,7 +10,7 @@ import { versionNumber } from '../../cli/version'; import { debug, warning } from '../../logging'; import { ToolkitError } from '../../toolkit/error'; import { loadTree, some } from '../../tree'; -import { splitBySize } from '../../util/objects'; +import { splitBySize } from '../../util'; import { SdkProvider } from '../aws-auth'; import { Settings } from '../settings'; import { RWLock, ILock } from '../util/rwlock'; diff --git a/packages/aws-cdk/lib/api/deployments/cloudformation.ts b/packages/aws-cdk/lib/api/deployments/cloudformation.ts index 56a16830a..e2a2bf030 100644 --- a/packages/aws-cdk/lib/api/deployments/cloudformation.ts +++ b/packages/aws-cdk/lib/api/deployments/cloudformation.ts @@ -16,8 +16,7 @@ import type { Deployments } from './deployments'; import { debug } from '../../cli/messages'; import { IoMessaging } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; -import { deserializeStructure } from '../../util/serialize'; +import { formatErrorMessage, deserializeStructure } from '../../util'; import type { ICloudFormationClient, SdkProvider } from '../aws-auth'; import { StackStatus } from '../stack-events'; import { makeBodyParameter, TemplateBodyParameter } from '../util/template-body-parameter'; diff --git a/packages/aws-cdk/lib/api/deployments/deploy-stack.ts b/packages/aws-cdk/lib/api/deployments/deploy-stack.ts index 898c6f732..9e2bfbb62 100644 --- a/packages/aws-cdk/lib/api/deployments/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deployments/deploy-stack.ts @@ -31,7 +31,7 @@ import { tryHotswapDeployment } from './hotswap-deployments'; import { debug, info, warn } from '../../cli/messages'; import { IIoHost, IoMessaging, ToolkitAction } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import type { SDK, SdkProvider, ICloudFormationClient } from '../aws-auth'; import type { EnvironmentResources } from '../environment'; import { CfnEvaluationException } from '../evaluate-cloudformation-template'; diff --git a/packages/aws-cdk/lib/api/deployments/deployments.ts b/packages/aws-cdk/lib/api/deployments/deployments.ts index 6bd75b798..0184f07bc 100644 --- a/packages/aws-cdk/lib/api/deployments/deployments.ts +++ b/packages/aws-cdk/lib/api/deployments/deployments.ts @@ -27,7 +27,7 @@ import { import { debug, warn } from '../../cli/messages'; import { IIoHost, IoMessaging, ToolkitAction } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import type { SdkProvider } from '../aws-auth/sdk-provider'; import { type EnvironmentResources, EnvironmentAccess } from '../environment'; import { HotswapMode, HotswapPropertyOverrides } from '../hotswap/common'; diff --git a/packages/aws-cdk/lib/api/deployments/hotswap-deployments.ts b/packages/aws-cdk/lib/api/deployments/hotswap-deployments.ts index 2066ea82a..0ea64cad0 100644 --- a/packages/aws-cdk/lib/api/deployments/hotswap-deployments.ts +++ b/packages/aws-cdk/lib/api/deployments/hotswap-deployments.ts @@ -8,7 +8,7 @@ import type { CloudFormationStack } from './cloudformation'; import { NestedStackTemplates, loadCurrentTemplateWithNestedStacks } from './nested-stack-helpers'; import { info } from '../../cli/messages'; import { ToolkitError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import { EvaluateCloudFormationTemplate } from '../evaluate-cloudformation-template'; import { isHotswappableAppSyncChange } from '../hotswap/appsync-mapping-templates'; import { isHotswappableCodeBuildProjectChange } from '../hotswap/code-build-projects'; diff --git a/packages/aws-cdk/lib/api/deployments/nested-stack-helpers.ts b/packages/aws-cdk/lib/api/deployments/nested-stack-helpers.ts index 09d6445f8..ac251f307 100644 --- a/packages/aws-cdk/lib/api/deployments/nested-stack-helpers.ts +++ b/packages/aws-cdk/lib/api/deployments/nested-stack-helpers.ts @@ -3,7 +3,7 @@ import type { CloudFormationStackArtifact } from '@aws-cdk/cx-api'; import * as fs from 'fs-extra'; import type { SDK } from '../aws-auth'; import { CloudFormationStack, type Template } from './cloudformation'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import { LazyListStackResources, type ListStackResources } from '../evaluate-cloudformation-template'; export interface NestedStackTemplates { diff --git a/packages/aws-cdk/lib/api/environment/environment-access.ts b/packages/aws-cdk/lib/api/environment/environment-access.ts index 2d3fe1288..1d86f030a 100644 --- a/packages/aws-cdk/lib/api/environment/environment-access.ts +++ b/packages/aws-cdk/lib/api/environment/environment-access.ts @@ -4,7 +4,7 @@ import { EnvironmentResources, EnvironmentResourcesRegistry } from './environmen import { warn } from '../../cli/messages'; import { IoMessaging } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import { CredentialsOptions, SdkForEnvironment, SdkProvider } from '../aws-auth/sdk-provider'; import { Mode } from '../plugin/mode'; import { replaceEnvPlaceholders, StringWithoutPlaceholders } from '../util/placeholders'; diff --git a/packages/aws-cdk/lib/api/environment/environment-resources.ts b/packages/aws-cdk/lib/api/environment/environment-resources.ts index df4155592..f9fbd4324 100644 --- a/packages/aws-cdk/lib/api/environment/environment-resources.ts +++ b/packages/aws-cdk/lib/api/environment/environment-resources.ts @@ -3,7 +3,7 @@ import { debug, warn } from '../../cli/messages'; import { Notices } from '../../notices'; import { IoMessaging } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import type { SDK } from '../aws-auth'; import { type EcrRepositoryInfo, ToolkitInfo } from '../toolkit-info'; diff --git a/packages/aws-cdk/lib/api/logs/find-cloudwatch-logs.ts b/packages/aws-cdk/lib/api/logs/find-cloudwatch-logs.ts index 194a8003b..df98d279b 100644 --- a/packages/aws-cdk/lib/api/logs/find-cloudwatch-logs.ts +++ b/packages/aws-cdk/lib/api/logs/find-cloudwatch-logs.ts @@ -2,7 +2,7 @@ import type { CloudFormationStackArtifact, Environment } from '@aws-cdk/cx-api'; import type { StackResourceSummary } from '@aws-sdk/client-cloudformation'; import { debug } from '../../logging'; import { IoMessaging } from '../../toolkit/cli-io-host'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import type { SDK, SdkProvider } from '../aws-auth'; import { EnvironmentAccess } from '../environment'; import { EvaluateCloudFormationTemplate, LazyListStackResources } from '../evaluate-cloudformation-template'; diff --git a/packages/aws-cdk/lib/api/logs/logs-monitor.ts b/packages/aws-cdk/lib/api/logs/logs-monitor.ts index a64a0d93d..b8a0000f4 100644 --- a/packages/aws-cdk/lib/api/logs/logs-monitor.ts +++ b/packages/aws-cdk/lib/api/logs/logs-monitor.ts @@ -2,7 +2,7 @@ import * as util from 'util'; import * as cxapi from '@aws-cdk/cx-api'; import * as chalk from 'chalk'; import { info, error } from '../../logging'; -import { flatten } from '../../util/arrays'; +import { flatten } from '../../util'; import type { SDK } from '../aws-auth'; /** diff --git a/packages/aws-cdk/lib/api/resource-import/migrator.ts b/packages/aws-cdk/lib/api/resource-import/migrator.ts index 0180fd6f4..8365c7ceb 100644 --- a/packages/aws-cdk/lib/api/resource-import/migrator.ts +++ b/packages/aws-cdk/lib/api/resource-import/migrator.ts @@ -4,7 +4,7 @@ import * as fs from 'fs-extra'; import { ImportDeploymentOptions, ResourceImporter } from './importer'; import { info } from '../../cli/messages'; import type { IIoHost, ToolkitAction } from '../../toolkit/cli-io-host'; -import { formatTime } from '../../util/string-manipulation'; +import { formatTime } from '../../util'; import { StackCollection } from '../cxapp/cloud-assembly'; import type { Deployments, ResourcesToImport } from '../deployments'; diff --git a/packages/aws-cdk/lib/api/settings.ts b/packages/aws-cdk/lib/api/settings.ts index 2d5c1ee13..c00550ab4 100644 --- a/packages/aws-cdk/lib/api/settings.ts +++ b/packages/aws-cdk/lib/api/settings.ts @@ -3,7 +3,7 @@ import * as fs_path from 'path'; import * as fs from 'fs-extra'; import { warning } from '../logging'; import { ToolkitError } from '../toolkit/error'; -import * as util from '../util/objects'; +import * as util from '../util'; export type SettingsMap = { [key: string]: any }; diff --git a/packages/aws-cdk/lib/api/stack-events/stack-event-poller.ts b/packages/aws-cdk/lib/api/stack-events/stack-event-poller.ts index e86fcc730..a8859888e 100644 --- a/packages/aws-cdk/lib/api/stack-events/stack-event-poller.ts +++ b/packages/aws-cdk/lib/api/stack-events/stack-event-poller.ts @@ -1,5 +1,5 @@ import type { StackEvent } from '@aws-sdk/client-cloudformation'; -import { formatErrorMessage } from '../../util/format-error'; +import { formatErrorMessage } from '../../util'; import type { ICloudFormationClient } from '../aws-auth'; export interface StackEventPollerProps { diff --git a/packages/aws-cdk/lib/api/stack-events/stack-progress-monitor.ts b/packages/aws-cdk/lib/api/stack-events/stack-progress-monitor.ts index 5a92bfeb9..ee8876172 100644 --- a/packages/aws-cdk/lib/api/stack-events/stack-progress-monitor.ts +++ b/packages/aws-cdk/lib/api/stack-events/stack-progress-monitor.ts @@ -1,7 +1,7 @@ import * as util from 'util'; import { StackEvent } from '@aws-sdk/client-cloudformation'; -import { padLeft } from '../../util/string-manipulation'; +import { padLeft } from '../../util'; export interface StackProgress { /** diff --git a/packages/aws-cdk/lib/api/util/placeholders.ts b/packages/aws-cdk/lib/api/util/placeholders.ts index 28814a31a..ef17bae17 100644 --- a/packages/aws-cdk/lib/api/util/placeholders.ts +++ b/packages/aws-cdk/lib/api/util/placeholders.ts @@ -1,5 +1,5 @@ import { type Environment, EnvironmentPlaceholders } from '@aws-cdk/cx-api'; -import { Branded } from '../../util/type-brands'; +import type { Branded } from '../../util'; import type { SdkProvider } from '../aws-auth/sdk-provider'; import { Mode } from '../plugin/mode'; diff --git a/packages/aws-cdk/lib/api/util/template-body-parameter.ts b/packages/aws-cdk/lib/api/util/template-body-parameter.ts index ca9b5ab02..582477a60 100644 --- a/packages/aws-cdk/lib/api/util/template-body-parameter.ts +++ b/packages/aws-cdk/lib/api/util/template-body-parameter.ts @@ -6,8 +6,7 @@ import * as chalk from 'chalk'; import * as fs from 'fs-extra'; import { debug, error } from '../../logging'; import { ToolkitError } from '../../toolkit/error'; -import { contentHash } from '../../util/content-hash'; -import { toYAML } from '../../util/serialize'; +import { contentHash, toYAML } from '../../util'; import { type AssetManifestBuilder } from '../deployments'; import { EnvironmentResources } from '../environment'; diff --git a/packages/aws-cdk/lib/api/work-graph/work-graph-builder.ts b/packages/aws-cdk/lib/api/work-graph/work-graph-builder.ts index ca3f1acc5..7711a1501 100644 --- a/packages/aws-cdk/lib/api/work-graph/work-graph-builder.ts +++ b/packages/aws-cdk/lib/api/work-graph/work-graph-builder.ts @@ -4,7 +4,7 @@ import { WorkGraph } from './work-graph'; import { DeploymentState, AssetBuildNode, WorkNode } from './work-graph-types'; import { IoMessaging } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { contentHashAny } from '../../util/content-hash'; +import { contentHashAny } from '../../util'; export class WorkGraphBuilder { /** diff --git a/packages/aws-cdk/lib/api/work-graph/work-graph.ts b/packages/aws-cdk/lib/api/work-graph/work-graph.ts index 45565bfe3..4c1e04207 100644 --- a/packages/aws-cdk/lib/api/work-graph/work-graph.ts +++ b/packages/aws-cdk/lib/api/work-graph/work-graph.ts @@ -2,7 +2,7 @@ import { WorkNode, DeploymentState, StackNode, AssetBuildNode, AssetPublishNode import { debug, trace } from '../../cli/messages'; import { IoMessaging } from '../../toolkit/cli-io-host'; import { ToolkitError } from '../../toolkit/error'; -import { parallelPromises } from '../../util/parallel'; +import { parallelPromises } from '../../util'; export type Concurrency = number | Record; diff --git a/packages/aws-cdk/lib/cli/cdk-toolkit.ts b/packages/aws-cdk/lib/cli/cdk-toolkit.ts index bcd112cef..92b1d8174 100644 --- a/packages/aws-cdk/lib/cli/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cli/cdk-toolkit.ts @@ -52,11 +52,7 @@ import { listStacks } from '../list-stacks'; import { result as logResult, debug, error, highlight, info, success, warning } from '../logging'; import { CliIoHost } from '../toolkit/cli-io-host'; import { ToolkitError } from '../toolkit/error'; -import { numberFromBool, partition } from '../util'; -import { validateSnsTopicArn } from '../util/cloudformation'; -import { formatErrorMessage } from '../util/format-error'; -import { deserializeStructure, obscureTemplate, serializeStructure } from '../util/serialize'; -import { formatTime } from '../util/string-manipulation'; +import { numberFromBool, partition, validateSnsTopicArn, formatErrorMessage, deserializeStructure, obscureTemplate, serializeStructure, formatTime } from '../util'; // Must use a require() otherwise esbuild complains about calling a namespace // eslint-disable-next-line @typescript-eslint/no-require-imports diff --git a/packages/aws-cdk/lib/cli/root-dir.ts b/packages/aws-cdk/lib/cli/root-dir.ts new file mode 100644 index 000000000..c522ff956 --- /dev/null +++ b/packages/aws-cdk/lib/cli/root-dir.ts @@ -0,0 +1,31 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { ToolkitError } from '../toolkit/error'; + +/** + * From the current file, find the directory that contains the CLI's package.json + * + * Can't use `__dirname` in production code, as the CLI will get bundled as it's + * released and `__dirname` will refer to a different location in the `.ts` form + * as it will in the final executing form. + */ +export function cliRootDir(): string; +export function cliRootDir(fail: true): string; +export function cliRootDir(fail: false): string | undefined; +export function cliRootDir(fail?: boolean) { + function _rootDir(dirname: string): string | undefined { + const manifestPath = path.join(dirname, 'package.json'); + if (fs.existsSync(manifestPath)) { + return dirname; + } + if (path.dirname(dirname) === dirname) { + if (fail ?? true) { + throw new ToolkitError('Unable to find package manifest'); + } + return undefined; + } + return _rootDir(path.dirname(dirname)); + } + + return _rootDir(__dirname); +} diff --git a/packages/aws-cdk/lib/cli/version.ts b/packages/aws-cdk/lib/cli/version.ts index f950a8f31..b6c58c861 100644 --- a/packages/aws-cdk/lib/cli/version.ts +++ b/packages/aws-cdk/lib/cli/version.ts @@ -5,8 +5,9 @@ import * as fs from 'fs-extra'; import * as semver from 'semver'; import { debug, info } from '../logging'; import { ToolkitError } from '../toolkit/error'; +import { cdkCacheDir } from '../util'; +import { cliRootDir } from './root-dir'; import { formatAsBanner } from './util/console-formatters'; -import { cdkCacheDir, rootDir } from '../util/directories'; import { getLatestVersionFromNpm } from './util/npm'; const ONE_DAY_IN_SECONDS = 1 * 24 * 60 * 60; @@ -25,12 +26,12 @@ export function isDeveloperBuild(): boolean { export function versionNumber(): string { // eslint-disable-next-line @typescript-eslint/no-require-imports - return require(path.join(rootDir(), 'package.json')).version.replace(/\+[0-9a-f]+$/, ''); + return require(path.join(cliRootDir(), 'package.json')).version.replace(/\+[0-9a-f]+$/, ''); } function commit(): string { // eslint-disable-next-line @typescript-eslint/no-require-imports - return require(path.join(rootDir(), 'build-info.json')).commit; + return require(path.join(cliRootDir(), 'build-info.json')).commit; } export class VersionCheckTTL { diff --git a/packages/aws-cdk/lib/commands/migrate.ts b/packages/aws-cdk/lib/commands/migrate.ts index 668c5230f..49721ed5c 100644 --- a/packages/aws-cdk/lib/commands/migrate.ts +++ b/packages/aws-cdk/lib/commands/migrate.ts @@ -23,7 +23,7 @@ import { info } from '../../lib/logging'; import type { ICloudFormationClient, SdkProvider } from '../api/aws-auth'; import { CloudFormationStack } from '../api/deployments'; import { ToolkitError } from '../toolkit/error'; -import { zipDirectory } from '../util/archive'; +import { zipDirectory } from '../util'; const camelCase = require('camelcase'); const decamelize = require('decamelize'); /** The list of languages supported by the built-in noctilucent binary. */ diff --git a/packages/aws-cdk/lib/context-providers/cc-api-provider.ts b/packages/aws-cdk/lib/context-providers/cc-api-provider.ts index 90631538d..607baaee9 100644 --- a/packages/aws-cdk/lib/context-providers/cc-api-provider.ts +++ b/packages/aws-cdk/lib/context-providers/cc-api-provider.ts @@ -3,7 +3,7 @@ import { ICloudControlClient } from '../api'; import { type SdkProvider, initContextProviderSdk } from '../api/aws-auth/sdk-provider'; import { ContextProviderPlugin } from '../api/plugin'; import { ContextProviderError } from '../toolkit/error'; -import { findJsonValue, getResultObj } from '../util/json'; +import { findJsonValue, getResultObj } from '../util'; export class CcApiContextProviderPlugin implements ContextProviderPlugin { constructor(private readonly aws: SdkProvider) { diff --git a/packages/aws-cdk/lib/context-providers/index.ts b/packages/aws-cdk/lib/context-providers/index.ts index 4f377676a..04d8babaa 100644 --- a/packages/aws-cdk/lib/context-providers/index.ts +++ b/packages/aws-cdk/lib/context-providers/index.ts @@ -17,7 +17,7 @@ import { ContextProviderPlugin } from '../api/plugin/context-provider-plugin'; import { replaceEnvPlaceholders } from '../api/util/placeholders'; import { debug } from '../logging'; import { ContextProviderError } from '../toolkit/error'; -import { formatErrorMessage } from '../util/format-error'; +import { formatErrorMessage } from '../util'; export type ContextProviderFactory = ((sdk: SdkProvider) => ContextProviderPlugin); export type ProviderMap = {[name: string]: ContextProviderFactory}; diff --git a/packages/aws-cdk/lib/init-hooks.ts b/packages/aws-cdk/lib/init-hooks.ts index ec2306150..fc3cc27f4 100644 --- a/packages/aws-cdk/lib/init-hooks.ts +++ b/packages/aws-cdk/lib/init-hooks.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import { shell } from './os'; import { ToolkitError } from './toolkit/error'; -import { formatErrorMessage } from './util/format-error'; +import { formatErrorMessage } from './util'; export type SubstitutePlaceholders = (...fileNames: string[]) => Promise; diff --git a/packages/aws-cdk/lib/init.ts b/packages/aws-cdk/lib/init.ts index 59577bc4c..5e11debc0 100644 --- a/packages/aws-cdk/lib/init.ts +++ b/packages/aws-cdk/lib/init.ts @@ -2,13 +2,12 @@ import * as childProcess from 'child_process'; import * as path from 'path'; import * as chalk from 'chalk'; import * as fs from 'fs-extra'; +import { cliRootDir } from './cli/root-dir'; import { versionNumber } from './cli/version'; import { invokeBuiltinHooks } from './init-hooks'; import { error, info, warning } from './logging'; import { ToolkitError } from './toolkit/error'; -import { cdkHomeDir, rootDir } from './util/directories'; -import { formatErrorMessage } from './util/format-error'; -import { rangeFromSemver } from './util/version-range'; +import { cdkHomeDir, formatErrorMessage, rangeFromSemver } from './util'; /* eslint-disable @typescript-eslint/no-var-requires */ // Packages don't have @types module // eslint-disable-next-line @typescript-eslint/no-require-imports @@ -268,7 +267,7 @@ interface ProjectInfo { export async function availableInitTemplates(): Promise { return new Promise(async (resolve) => { try { - const templatesDir = path.join(rootDir(), 'lib', 'init-templates'); + const templatesDir = path.join(cliRootDir(), 'lib', 'init-templates'); const templateNames = await listDirectory(templatesDir); const templates = new Array(); for (const templateName of templateNames) { diff --git a/packages/aws-cdk/lib/legacy-exports-source.ts b/packages/aws-cdk/lib/legacy-exports-source.ts index dd8255b5a..81c7b85a2 100644 --- a/packages/aws-cdk/lib/legacy-exports-source.ts +++ b/packages/aws-cdk/lib/legacy-exports-source.ts @@ -5,26 +5,23 @@ // Note: All type exports are in `legacy-exports.ts` export * from './legacy-logging-source'; -export { deepClone, flatten, ifDefined, isArray, isEmpty, numberFromBool, partition } from './util'; +export { deepClone, flatten, ifDefined, isArray, isEmpty, numberFromBool, partition, padLeft as leftPad, contentHash, deepMerge } from './util'; export { deployStack } from './api/deployments/deploy-stack'; export { cli, exec } from './cli/cli'; export { SdkProvider } from './api/aws-auth'; export { PluginHost } from './api/plugin'; -export { contentHash } from './util/content-hash'; export { Command, Configuration, PROJECT_CONTEXT } from './cli/user-configuration'; export { Settings } from './api/settings'; export { Bootstrapper } from './api/bootstrap'; export { CloudExecutable } from './api/cxapp/cloud-executable'; export { execProgram } from './api/cxapp/exec'; export { RequireApproval } from './diff'; -export { padLeft as leftPad } from './util/string-manipulation'; export { formatAsBanner } from './cli/util/console-formatters'; export { setSdkTracing as enableTracing } from './api/aws-auth/tracing'; export { aliases, command, describe } from './commands/docs'; export { lowerCaseFirstCharacter } from './api/hotswap/common'; -export { deepMerge } from './util/objects'; export { Deployments } from './api/deployments'; -export { rootDir } from './util/directories'; +export { cliRootDir as rootDir } from './cli/root-dir'; export { latestVersionIfHigher, versionNumber } from './cli/version'; export { availableInitTemplates } from './init'; export { cached } from './api/aws-auth/cached'; diff --git a/packages/aws-cdk/lib/notices.ts b/packages/aws-cdk/lib/notices.ts index 0a7d34b42..93175fbb0 100644 --- a/packages/aws-cdk/lib/notices.ts +++ b/packages/aws-cdk/lib/notices.ts @@ -12,8 +12,7 @@ import { versionNumber } from './cli/version'; import { debug, info, warning, error } from './logging'; import { ToolkitError } from './toolkit/error'; import { ConstructTreeNode, loadTreeFromDir } from './tree'; -import { cdkCacheDir } from './util/directories'; -import { formatErrorMessage } from './util/format-error'; +import { cdkCacheDir, formatErrorMessage } from './util'; const CACHE_FILE_PATH = path.join(cdkCacheDir(), 'notices.json'); diff --git a/packages/aws-cdk/lib/util.ts b/packages/aws-cdk/lib/util.ts new file mode 100644 index 000000000..263d2311e --- /dev/null +++ b/packages/aws-cdk/lib/util.ts @@ -0,0 +1 @@ +export * from '../../@aws-cdk/tmp-toolkit-helpers/src/util'; diff --git a/packages/aws-cdk/test/api/aws-auth/fake-sts.ts b/packages/aws-cdk/test/api/aws-auth/fake-sts.ts index d93a7ff77..0b97f7bfe 100644 --- a/packages/aws-cdk/test/api/aws-auth/fake-sts.ts +++ b/packages/aws-cdk/test/api/aws-auth/fake-sts.ts @@ -2,7 +2,7 @@ import { Tag } from '@aws-sdk/client-sts'; import * as nock from 'nock'; import * as uuid from 'uuid'; import * as xmlJs from 'xml-js'; -import { formatErrorMessage } from '../../../lib/util/format-error'; +import { formatErrorMessage } from '../../../lib/util'; interface RegisteredIdentity { readonly account: string; diff --git a/packages/aws-cdk/test/api/bootstrap/bootstrap.test.ts b/packages/aws-cdk/test/api/bootstrap/bootstrap.test.ts index 6c0777dae..b8c49505f 100644 --- a/packages/aws-cdk/test/api/bootstrap/bootstrap.test.ts +++ b/packages/aws-cdk/test/api/bootstrap/bootstrap.test.ts @@ -12,7 +12,7 @@ import { import { parse } from 'yaml'; import { Bootstrapper } from '../../../lib/api/bootstrap'; import { legacyBootstrapTemplate } from '../../../lib/api/bootstrap/legacy-template'; -import { deserializeStructure, serializeStructure, toYAML } from '../../../lib/util/serialize'; +import { deserializeStructure, serializeStructure, toYAML } from '../../../lib/util'; import { CliIoHost } from '../../../lib/toolkit/cli-io-host'; import { MockSdkProvider, mockCloudFormationClient, restoreSdkMocksToDefault } from '../../util/mock-sdk'; diff --git a/packages/aws-cdk/test/util/console-formatters.test.ts b/packages/aws-cdk/test/cli/console-formatters.test.ts similarity index 95% rename from packages/aws-cdk/test/util/console-formatters.test.ts rename to packages/aws-cdk/test/cli/console-formatters.test.ts index 744870730..0c823a4ff 100644 --- a/packages/aws-cdk/test/util/console-formatters.test.ts +++ b/packages/aws-cdk/test/cli/console-formatters.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable import/order */ import * as chalk from 'chalk'; import { formatAsBanner } from '../../lib/cli/util/console-formatters'; diff --git a/packages/aws-cdk/test/util/applydefaults.test.ts b/packages/aws-cdk/test/util/applydefaults.test.ts deleted file mode 100644 index 925adf753..000000000 --- a/packages/aws-cdk/test/util/applydefaults.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-disable import/order */ -import { applyDefaults } from '../../lib/util'; - -test('applyDefaults() works', () => { - const given = { a: 1 }; - const defaults = { a: 2, b: 2 }; - - const output = applyDefaults(given, defaults); - - expect(output).toEqual({ a: 1, b: 2 }); -});