Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2342c49
fix: move reference interfaces to their own submodules
rix0rrr Nov 6, 2025
c1ec13f
Fix semis
rix0rrr Nov 6, 2025
a5b4903
That made us not import `core`
rix0rrr Nov 6, 2025
bc60594
selective imports should be at service submodule level
Nov 6, 2025
6cd0707
Unused ident
rix0rrr Nov 7, 2025
37f1467
Oya le le
rix0rrr Nov 7, 2025
3920f92
Deprecation
rix0rrr Nov 7, 2025
09282a5
Account for kinesisanalyticsv2
rix0rrr Nov 7, 2025
2fa03b2
Add remapped types for use with jsii-diff
rix0rrr Nov 7, 2025
eab8c46
Integrated rmapped types and breaking changes
rix0rrr Nov 7, 2025
8d5acdf
Fix compilation error with newer version of jsii
rix0rrr Nov 7, 2025
48cb0e2
Diff submodule config
rix0rrr Nov 10, 2025
42b9a43
Update to latest jsii
rix0rrr Nov 11, 2025
a337edd
Must use export type
rix0rrr Nov 11, 2025
a4d64bf
Snappies
rix0rrr Nov 11, 2025
f5dac18
Move IEnvironmentAware to avoid another cycle
rix0rrr Nov 11, 2025
dcb6568
Merge remote-tracking branch 'origin/main' into huijbers/centralized-…
mrgrain Nov 11, 2025
32128c0
fix jsiirc
rix0rrr Nov 11, 2025
c168e68
Update snaps
rix0rrr Nov 12, 2025
c7bc292
Merge branch 'main' into huijbers/centralized-l1-interfaces
mrgrain Nov 12, 2025
c3dfc9f
remove files and comments
mrgrain Nov 12, 2025
770d5ff
fix targets
mrgrain Nov 12, 2025
177aa9a
cleanup
mrgrain Nov 12, 2025
615b17b
remove unused import
mrgrain Nov 12, 2025
b50f3ce
better snaps
mrgrain Nov 12, 2025
a601c61
import from core
mrgrain Nov 12, 2025
e3dbb5b
Move more types
rix0rrr Nov 12, 2025
f380758
Merge branch 'huijbers/centralized-l1-interfaces' of github.com:aws/a…
rix0rrr Nov 12, 2025
c32f817
Merge branch 'main' into huijbers/centralized-l1-interfaces
mergify[bot] Nov 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,032 changes: 3,032 additions & 0 deletions allowed-breaking-changes.txt

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
"fs-extra": "^9.1.0",
"graceful-fs": "^4.2.11",
"jest-junit": "^13.2.0",
"jsii-diff": "1.118.0",
"jsii-pacmak": "1.118.0",
"jsii-reflect": "1.118.0",
"jsii-diff": "1.119.0",
"jsii-pacmak": "1.119.0",
"jsii-reflect": "1.119.0",
"lerna": "^8.2.4",
"nx": "^20",
"semver": "^7.7.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/aws-cdk-lib/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*.d.ts
*.generated.ts
*.generated.*
*.js
*.js.map
*.snk
Expand Down
3 changes: 2 additions & 1 deletion packages/aws-cdk-lib/aws-iam/lib/grant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Dependable, IConstruct, IDependable } from 'constructs';
import { PolicyStatement } from './policy-statement';
import { IGrantable, IPrincipal } from './principals';
import * as cdk from '../../core';
import { IEnvironmentAware } from '../../interfaces/environment-aware';

/**
* Basic options for a grant operation
Expand Down Expand Up @@ -421,7 +422,7 @@ interface GrantProps {
/**
* A resource with a resource policy that can be added to
*/
export interface IResourceWithPolicyV2 extends cdk.IEnvironmentAware {
export interface IResourceWithPolicyV2 extends IEnvironmentAware {
/**
* Add a statement to the resource's resource policy
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-stepfunctions/lib/states/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { FieldUtils } from '../fields';
import { noEmptyObject } from '../private/util';
import { StateGraph } from '../state-graph';
import { IStepFunctionsTask, StepFunctionsTaskConfig } from '../step-functions-task';
import { CatchProps, IChainable, INextable, RetryProps } from '../types';
import { CatchProps, IChainable, INextable, QueryLanguage, RetryProps } from '../types';

/**
* Props that are common to all tasks
Expand Down Expand Up @@ -162,7 +162,7 @@ export class Task extends State implements INextable {
/**
* Return the Amazon States Language object for this state
*/
public toStateJson(): object {
public toStateJson(_?: QueryLanguage): object {
return {
...this.renderNextEnd(),
...this.renderRetryCatch(),
Expand Down
45 changes: 2 additions & 43 deletions packages/aws-cdk-lib/core/lib/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,46 +31,5 @@ export interface Environment {
readonly region?: string;
}

/**
* Represents the environment a given resource lives in.
*
* Used as the return value for the `IEnvironmentAware.env` property.
*/
export interface ResourceEnvironment {
/**
* The AWS Account ID that this resource belongs to.
*
* Since this can be a Token (for example, when the account is
* CloudFormation's `AWS::AccountId` intrinsic), make sure to use
* `Token.compareStrings()` instead of comparing the values with direct
* string equality.
*/
readonly account: string;

/**
* The AWS Region that this resource belongs to.
*
* Since this can be a Token (for example, when the region is CloudFormation's
* `AWS::Region` intrinsic), make sure to use `Token.compareStrings()` instead
* of comparing the values with direct string equality.
*/
readonly region: string;
}

/**
* Used to indicate that a particular construct has an resource environment
*/
export interface IEnvironmentAware {
/**
* The environment this resource belongs to.
*
* For resources that are created and managed in a Stack (those created by
* creating new class instances like `new Role()`, `new Bucket()`, etc.), this
* is always the same as the environment of the stack they belong to.
*
* For referenced resources (those obtained from referencing methods like
* `Role.fromRoleArn()`, `Bucket.fromBucketName()`, etc.), they might be
* different than the stack they were imported into.
*/
readonly env: ResourceEnvironment;
}
// For backwards compatibility with TypeScript users
export type { IEnvironmentAware, ResourceEnvironment } from '../../interfaces/environment-aware';
2 changes: 1 addition & 1 deletion packages/aws-cdk-lib/core/lib/resource.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ArnComponents, ArnFormat } from './arn';
import { CfnResource } from './cfn-resource';
import { RESOURCE_SYMBOL } from './constants';
import { IEnvironmentAware, ResourceEnvironment } from './environment';
import { ValidationError } from './errors';
import { IStringProducer, Lazy } from './lazy';
import { generatePhysicalName, isGeneratedWhenNeededMarker } from './private/physical-name-generator';
Expand All @@ -10,6 +9,7 @@ import { RemovalPolicy } from './removal-policy';
import { IResolveContext } from './resolvable';
import { Stack } from './stack';
import { Token, Tokenization } from './token';
import { IEnvironmentAware, ResourceEnvironment } from '../../interfaces/environment-aware';

// v2 - leave this as a separate section so it reduces merge conflicts when compat is removed
// eslint-disable-next-line import/order
Expand Down
1 change: 1 addition & 0 deletions packages/aws-cdk-lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ export * as cloud_assembly_schema from './cloud-assembly-schema';
export * as cloudformation_include from './cloudformation-include';
export * as custom_resources from './custom-resources';
export * as cx_api from './cx-api';
export * as interfaces from './interfaces';
export * as lambda_layer_awscli from './lambda-layer-awscli';
export * as lambda_layer_node_proxy_agent from './lambda-layer-node-proxy-agent';
export * as pipelines from './pipelines';
Expand Down
13 changes: 13 additions & 0 deletions packages/aws-cdk-lib/interfaces/.jsiirc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"targets": {
"java": {
"package": "software.amazon.awscdk.interfaces"
},
"dotnet": {
"namespace": "Amazon.CDK.Interfaces"
},
"python": {
"module": "aws_cdk.interfaces"
}
}
}
33 changes: 33 additions & 0 deletions packages/aws-cdk-lib/interfaces/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
CDK Resource Interfaces
=======================

This module contains resource interfaces for all AWS service resources.

These are interfaces that look like this:

```
/**
* Indicates that this resource can be referenced as a Bucket.
*/
interface IBucketRef {
/**
* A reference to a Bucket resource.
*/
readonly bucketRef: BucketReference;
}
interface BucketReference {
/**
* The BucketName of the Bucket resource.
*/
readonly bucketName: string;
/**
* The ARN of the Bucket resource.
*/
readonly bucketArn: string;
}
```

These are in a separate submodule so that they can be referenced from all other
service submodules without introducing cyclic dependencies between them.
43 changes: 43 additions & 0 deletions packages/aws-cdk-lib/interfaces/environment-aware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Used to indicate that a particular construct has an resource environment
*/
export interface IEnvironmentAware {
/**
* The environment this resource belongs to.
*
* For resources that are created and managed in a Stack (those created by
* creating new class instances like `new Role()`, `new Bucket()`, etc.), this
* is always the same as the environment of the stack they belong to.
*
* For referenced resources (those obtained from referencing methods like
* `Role.fromRoleArn()`, `Bucket.fromBucketName()`, etc.), they might be
* different than the stack they were imported into.
*/
readonly env: ResourceEnvironment;
}

/**
* Represents the environment a given resource lives in.
*
* Used as the return value for the `IEnvironmentAware.env` property.
*/
export interface ResourceEnvironment {
/**
* The AWS Account ID that this resource belongs to.
*
* Since this can be a Token (for example, when the account is
* CloudFormation's `AWS::AccountId` intrinsic), make sure to use
* `Token.compareStrings()` instead of comparing the values with direct
* string equality.
*/
readonly account: string;

/**
* The AWS Region that this resource belongs to.
*
* Since this can be a Token (for example, when the region is CloudFormation's
* `AWS::Region` intrinsic), make sure to use `Token.compareStrings()` instead
* of comparing the values with direct string equality.
*/
readonly region: string;
}
2 changes: 2 additions & 0 deletions packages/aws-cdk-lib/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './environment-aware';
export * from './index.generated';
1 change: 1 addition & 0 deletions packages/aws-cdk-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@
"./custom-resources": "./custom-resources/index.js",
"./custom-resources/lib/helpers-internal": "./custom-resources/lib/helpers-internal/index.js",
"./cx-api": "./cx-api/index.js",
"./interfaces": "./interfaces/index.js",
"./lambda-layer-awscli": "./lambda-layer-awscli/index.js",
"./lambda-layer-kubectl": "./lambda-layer-kubectl/index.js",
"./lambda-layer-node-proxy-agent": "./lambda-layer-node-proxy-agent/index.js",
Expand Down
20 changes: 16 additions & 4 deletions packages/aws-cdk-lib/scripts/gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import * as path from 'node:path';
import { naming, topo } from '@aws-cdk/spec2cdk';
import { generateAll } from '@aws-cdk/spec2cdk/lib/cfn2ts';
import * as fs from 'fs-extra';
import submodulesGen from './submodules';
import generateServiceSubmoduleFiles from './submodules';
import writeCloudFormationIncludeMapping from './submodules/cloudformation-include';

const awsCdkLibDir = path.join(__dirname, '..');
const pkgJsonPath = path.join(awsCdkLibDir, 'package.json');
const topLevelIndexFilePath = path.join(awsCdkLibDir, 'index.ts');
const scopeMapPath = path.join(__dirname, 'scope-map.json');

const NON_SERVICE_SUBMODULES = ['core', 'interfaces'];

main().catch(e => {
// eslint-disable-next-line no-console
console.error(e);
Expand All @@ -19,17 +22,26 @@ async function main() {
// Generate all L1s based on config in scope-map.json

const generated = (await generateAll(awsCdkLibDir, {
coreImport: '../../core',
cloudwatchImport: '../../aws-cloudwatch',
skippedServices: [],
scopeMapPath,
}));

await updateExportsAndEntryPoints(generated);
await topo.writeModuleMap(generated);
await submodulesGen(generated, awsCdkLibDir);
await writeCloudFormationIncludeMapping(generated, awsCdkLibDir);

for (const nss of NON_SERVICE_SUBMODULES) {
delete generated[nss];
}
await generateServiceSubmoduleFiles(generated, awsCdkLibDir);
}

/**
* Make every module in the module map visible
*
* Read `index.ts` and `package.json#exports`, and add exports for every
* submodule that's not in there yet.
*/
async function updateExportsAndEntryPoints(modules: topo.ModuleMap) {
const pkgJson = await fs.readJson(pkgJsonPath);

Expand Down
3 changes: 3 additions & 0 deletions packages/aws-cdk-lib/scripts/scope-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -1934,5 +1934,8 @@
"namespace": "AWS::CloudFormation"
}
]
},
"interfaces": {
"scopes": []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import * as path from 'node:path';
import { topo } from '@aws-cdk/spec2cdk';
import * as fs from 'fs-extra';

export default async function cloudformationInclude(moduleMap: topo.ModuleMap, outPath: string) {
export default async function writeCloudFormationIncludeMapping(moduleMap: topo.ModuleMap, outPath: string) {
const classMap: { [cfnType: string]: string } = {};
Object.entries(moduleMap).forEach(([moduleName, { resources }]) => {
const modulePath = `aws-cdk-lib/${moduleName}`;
Object.entries(resources).forEach(([resourceName, resourceClassName]) => {
Object.entries(resources ?? {}).forEach(([resourceName, resourceClassName]) => {
classMap[resourceName] = `${modulePath}.${resourceClassName}`;
});
});
Expand Down
58 changes: 48 additions & 10 deletions packages/aws-cdk-lib/scripts/submodules/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import * as path from 'node:path';
import { createLibraryReadme } from '@aws-cdk/pkglint';
import { createLibraryReadme, ModuleDefinition } from '@aws-cdk/pkglint';
import { topo } from '@aws-cdk/spec2cdk';
import * as fs from 'fs-extra';
import cloudformationInclude from './cloudformation-include';

export default async function submodulesGen(modules: topo.ModuleMap, outPath: string) {
/**
* Make sure that a number of expected files exist for every service submodule
*
* Non-service submodules should not be passed to this function.
*/
export default async function generateServiceSubmoduleFiles(modules: topo.ModuleMap, outPath: string) {
for (const submodule of Object.values(modules)) {
if (submodule.name === 'core') {
continue;
}

const submodulePath = path.join(outPath, submodule.name);
await ensureSubmodule(submodule, submodulePath);
await ensureInterfaceSubmoduleJsiiJsonRc(submodule, path.join(outPath, 'interfaces'));
}

// Do specific code gen for certain submodules
await cloudformationInclude(modules, outPath);
}

async function ensureSubmodule(submodule: topo.ModuleMapEntry, modulePath: string) {
Expand Down Expand Up @@ -71,3 +69,43 @@ async function ensureSubmodule(submodule: topo.ModuleMapEntry, modulePath: strin
};
await fs.writeJson(path.join(modulePath, '.jsiirc.json'), jsiirc, { spaces: 2 });
}

/**
* Make a jsiirc file for every service-specific interfaces submodule
*
* Do that by taking the namespaces of the parent `interfaces` submodule and concatenating the last part
* of the names corresponding services namespace.
*/
async function ensureInterfaceSubmoduleJsiiJsonRc(submodule: topo.ModuleMapEntry, interfacesModulePath: string) {
if (!submodule.definition) {
throw new Error(`Cannot infer path or namespace for submodule named "${submodule.name}".`);
}

const interfacesModuleJsiiRcPath = path.join(interfacesModulePath, '.jsiirc.json');
const interfacesModuleJsiiRc = JSON.parse(await fs.readFile(interfacesModuleJsiiRcPath, 'utf-8'));

const jsiiRcPath = path.join(interfacesModulePath, 'generated', `${submodule.name}-interfaces.generated.jsiirc.json`);

const jsiirc = {
targets: {
...combineLanguageNamespace('java', 'package', 'javaPackage'),
...combineLanguageNamespace('dotnet', 'namespace', 'dotnetPackage'),
...combineLanguageNamespace('python', 'module', 'pythonModuleName'),
// No Go...
},
};
await fs.writeJson(jsiiRcPath, jsiirc, { spaces: 2 });

function combineLanguageNamespace(language: string, whatName: string, k: keyof ModuleDefinition) {
const ns = `${interfacesModuleJsiiRc.targets[language][whatName]}.${lastPart(submodule.definition?.[k] ?? 'undefined')}`;
if (ns.includes('undefined')) {
throw new Error(`Could not build child namespace for language ${language} from ${JSON.stringify(interfacesModuleJsiiRc.targets[language])} and ${k} from ${JSON.stringify(submodule.definition)}`);
}

return { [language]: { [whatName]: ns } };
}
}

function lastPart(x: string): string {
return x.split('.').slice(-1)[0];
}
4 changes: 2 additions & 2 deletions tools/@aws-cdk/cdk-build-tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
"jest-junit": "^13.2.0",
"jsii": "~5.9.13",
"jsii-rosetta": "~5.9.9",
"jsii-pacmak": "1.118.0",
"jsii-reflect": "1.118.0",
"jsii-pacmak": "1.119.0",
"jsii-reflect": "1.119.0",
"markdownlint-cli": "^0.45.0",
"nyc": "^15.1.0",
"semver": "^7.7.2",
Expand Down
2 changes: 0 additions & 2 deletions tools/@aws-cdk/cfn2ts/README.md

This file was deleted.

2 changes: 0 additions & 2 deletions tools/@aws-cdk/spec2cdk/bin/cfn2ts

This file was deleted.

4 changes: 0 additions & 4 deletions tools/@aws-cdk/spec2cdk/bin/cfn2ts.ts

This file was deleted.

Loading
Loading