@aws-blocks/core 0.1.17 → 0.2.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.
- package/dist/cdk/__fixtures__/import-meta-handler.d.ts +6 -0
- package/dist/cdk/__fixtures__/import-meta-handler.d.ts.map +1 -0
- package/dist/cdk/__fixtures__/import-meta-handler.js +13 -0
- package/dist/cdk/blocks-backend.d.ts +15 -0
- package/dist/cdk/blocks-backend.d.ts.map +1 -1
- package/dist/cdk/blocks-backend.js +41 -3
- package/dist/cdk/blocks-backend.test.js +137 -1
- package/dist/cdk/blocks-defaults.d.ts +44 -0
- package/dist/cdk/blocks-defaults.d.ts.map +1 -0
- package/dist/cdk/blocks-defaults.js +23 -0
- package/dist/cdk/blocks-defaults.test.d.ts +2 -0
- package/dist/cdk/blocks-defaults.test.d.ts.map +1 -0
- package/dist/cdk/blocks-defaults.test.js +22 -0
- package/dist/cdk/blocks-stack.test.js +39 -1
- package/dist/cdk/bundling.d.ts +42 -0
- package/dist/cdk/bundling.d.ts.map +1 -0
- package/dist/cdk/bundling.js +72 -0
- package/dist/cdk/bundling.test.d.ts +2 -0
- package/dist/cdk/bundling.test.d.ts.map +1 -0
- package/dist/cdk/bundling.test.js +80 -0
- package/dist/cdk/compute/compute.d.ts +33 -0
- package/dist/cdk/compute/compute.d.ts.map +1 -0
- package/dist/cdk/compute/compute.js +28 -0
- package/dist/cdk/index.d.ts +52 -0
- package/dist/cdk/index.d.ts.map +1 -1
- package/dist/cdk/index.js +95 -5
- package/dist/cdk/internal.d.ts +24 -0
- package/dist/cdk/internal.d.ts.map +1 -0
- package/dist/cdk/internal.js +27 -0
- package/dist/cdk/mixins.d.ts +18 -4
- package/dist/cdk/mixins.d.ts.map +1 -1
- package/dist/cdk/mixins.js +31 -7
- package/dist/cdk/mixins.test.js +45 -0
- package/dist/common/index.d.ts +9 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/index.cdk.d.ts +2 -1
- package/dist/index.cdk.d.ts.map +1 -1
- package/dist/index.cdk.js +2 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +12 -3
- package/dist/rpc.test.js +20 -0
- package/dist/scripts/telemetry.test.js +2 -0
- package/dist/telemetry/environment.d.ts.map +1 -1
- package/dist/telemetry/environment.js +3 -1
- package/dist/telemetry/telemetry.test.js +10 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -1
- package/src/cdk/__fixtures__/import-meta-handler.ts +16 -0
- package/src/cdk/blocks-backend.test.ts +166 -1
- package/src/cdk/blocks-backend.ts +55 -3
- package/src/cdk/blocks-defaults.test.ts +25 -0
- package/src/cdk/blocks-defaults.ts +49 -0
- package/src/cdk/blocks-stack.test.ts +48 -1
- package/src/cdk/bundling.test.ts +90 -0
- package/src/cdk/bundling.ts +76 -0
- package/src/cdk/compute/compute.ts +37 -0
- package/src/cdk/index.ts +105 -5
- package/src/cdk/internal.ts +29 -0
- package/src/cdk/mixins.test.ts +56 -1
- package/src/cdk/mixins.ts +32 -7
- package/src/common/index.ts +9 -0
- package/src/index.cdk.ts +5 -1
- package/src/rpc.test.ts +22 -0
- package/src/rpc.ts +19 -3
- package/src/scripts/telemetry.test.ts +2 -0
- package/src/telemetry/environment.ts +3 -1
- package/src/telemetry/telemetry.test.ts +12 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Internal CDK entry point — framework- and test-only surface that is
|
|
6
|
+
* intentionally NOT part of the public API (`@aws-blocks/core` /
|
|
7
|
+
* `@aws-blocks/core/cdk`).
|
|
8
|
+
*
|
|
9
|
+
* The compute abstraction lives behind this path while it has no public,
|
|
10
|
+
* customer-facing surface. Importing from here is a signal that you are inside
|
|
11
|
+
* the framework or a test, not a customer.
|
|
12
|
+
*
|
|
13
|
+
* Planned removal: once a customer can assign a compute and have it actually
|
|
14
|
+
* take effect — i.e. `this.compute` resolution and request routing to the
|
|
15
|
+
* chosen compute both exist, plus a synth-time guard that rejects an assignment
|
|
16
|
+
* with no route — these exports move to the public CDK entry point
|
|
17
|
+
* (`@aws-blocks/core/cdk`, re-exported from `index.cdk.ts`) and this file is
|
|
18
|
+
* deleted. It must NOT be made public before then: a compute a customer can
|
|
19
|
+
* declare but that is silently ignored is a worse experience than not having
|
|
20
|
+
* the feature. Until that flip, treat everything here as unstable — no
|
|
21
|
+
* backward-compatibility guarantee.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export { Compute } from './compute/compute.js';
|
|
27
|
+
// Reserved `/aws-blocks` path segment, needed by concrete computes (e.g.
|
|
28
|
+
// LambdaCompute in @aws-blocks/bb-lambda-compute) to build their API route tree.
|
|
29
|
+
export { BLOCKS_NAMESPACE } from '../constants.js';
|
package/src/cdk/mixins.test.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { test, describe } from 'node:test';
|
|
5
|
-
import assert from 'node:assert';
|
|
6
5
|
import * as cdk from 'aws-cdk-lib';
|
|
7
6
|
import { Template, Match } from 'aws-cdk-lib/assertions';
|
|
8
7
|
import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb';
|
|
@@ -110,6 +109,62 @@ describe('sandbox removal policy', () => {
|
|
|
110
109
|
});
|
|
111
110
|
});
|
|
112
111
|
|
|
112
|
+
test('SandboxDisableDeletionProtection mixin: deletionProtection disabled on DynamoDB table', () => {
|
|
113
|
+
const app = new cdk.App({ context: { sandboxMode: 'true' } });
|
|
114
|
+
const stack = new cdk.Stack(app, 'TestStack');
|
|
115
|
+
|
|
116
|
+
new Table(stack, 'MyTable', {
|
|
117
|
+
partitionKey: { name: 'pk', type: AttributeType.STRING },
|
|
118
|
+
billingMode: BillingMode.PAY_PER_REQUEST,
|
|
119
|
+
deletionProtection: true,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
RemovalPolicies.of(stack).destroy();
|
|
123
|
+
Mixins.of(stack).apply(new SandboxDisableDeletionProtection());
|
|
124
|
+
|
|
125
|
+
const template = Template.fromStack(stack);
|
|
126
|
+
// DynamoDB refuses DeleteTable while protection is on, regardless of DeletionPolicy
|
|
127
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
128
|
+
DeletionProtectionEnabled: false,
|
|
129
|
+
});
|
|
130
|
+
template.hasResource('AWS::DynamoDB::Table', {
|
|
131
|
+
DeletionPolicy: 'Delete',
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('production mode: deletionProtection stays enabled on DynamoDB table when mixin is not applied', () => {
|
|
136
|
+
const app = new cdk.App();
|
|
137
|
+
const stack = new cdk.Stack(app, 'TestStack');
|
|
138
|
+
|
|
139
|
+
new Table(stack, 'MyTable', {
|
|
140
|
+
partitionKey: { name: 'pk', type: AttributeType.STRING },
|
|
141
|
+
billingMode: BillingMode.PAY_PER_REQUEST,
|
|
142
|
+
deletionProtection: true,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const template = Template.fromStack(stack);
|
|
146
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
147
|
+
DeletionProtectionEnabled: true,
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('SandboxDisableDeletionProtection mixin: does not set DeletionProtectionEnabled on unprotected tables', () => {
|
|
152
|
+
const app = new cdk.App({ context: { sandboxMode: 'true' } });
|
|
153
|
+
const stack = new cdk.Stack(app, 'TestStack');
|
|
154
|
+
|
|
155
|
+
new Table(stack, 'MyTable', {
|
|
156
|
+
partitionKey: { name: 'pk', type: AttributeType.STRING },
|
|
157
|
+
billingMode: BillingMode.PAY_PER_REQUEST,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
Mixins.of(stack).apply(new SandboxDisableDeletionProtection());
|
|
161
|
+
|
|
162
|
+
const template = Template.fromStack(stack);
|
|
163
|
+
template.hasResourceProperties('AWS::DynamoDB::Table', {
|
|
164
|
+
DeletionProtectionEnabled: Match.absent(),
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
113
168
|
test('SandboxDisableDeletionProtection mixin: skips constructs without deletionProtection', () => {
|
|
114
169
|
const app = new cdk.App();
|
|
115
170
|
const stack = new cdk.Stack(app, 'TestStack');
|
package/src/cdk/mixins.ts
CHANGED
|
@@ -6,13 +6,36 @@ import type { IConstruct } from 'constructs';
|
|
|
6
6
|
import type { IMixin } from 'constructs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Property names used across CloudFormation resources to express deletion
|
|
10
|
+
* protection. L2 constructs and most L1s use `deletionProtection` (e.g. RDS
|
|
11
|
+
* clusters and instances, ELBv2 load balancers), while others spell it
|
|
12
|
+
* `deletionProtectionEnabled` (e.g. the DynamoDB `CfnTable` behind an L2
|
|
13
|
+
* `Table`, Aurora DSQL clusters).
|
|
14
|
+
*/
|
|
15
|
+
const DELETION_PROTECTION_PROPERTIES = ['deletionProtection', 'deletionProtectionEnabled'] as const;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Disables deletion protection on any construct that exposes a deletion
|
|
19
|
+
* protection property (e.g. RDS clusters, RDS instances, DynamoDB tables).
|
|
20
|
+
* Uses duck-typing so it automatically covers current and future resource
|
|
21
|
+
* types, matching both the `deletionProtection` and
|
|
22
|
+
* `deletionProtectionEnabled` spellings.
|
|
23
|
+
*
|
|
24
|
+
* Note that a DynamoDB L2 `Table` only accepts `deletionProtection` as a prop
|
|
25
|
+
* and does not re-expose it, so tables are matched through their underlying
|
|
26
|
+
* L1 `CfnTable.deletionProtectionEnabled`.
|
|
12
27
|
*
|
|
13
28
|
* Intended for sandbox teardown — use in the CDK layer alongside
|
|
14
29
|
* `RemovalPolicies.of(stack).destroy()` to ensure `sandbox:destroy` can
|
|
15
|
-
* delete the entire stack without manual cleanup.
|
|
30
|
+
* delete the entire stack without manual cleanup. DynamoDB refuses
|
|
31
|
+
* `DeleteTable` while deletion protection is enabled, regardless of the
|
|
32
|
+
* CloudFormation `DeletionPolicy`.
|
|
33
|
+
*
|
|
34
|
+
* @deprecated Prefer the stack-wide `defaults` prop on `BlocksStack`/`BlocksBackend`
|
|
35
|
+
* (`defaults: BlocksPresets.sandbox` / `.production`, or `sandboxMode ? … : …`).
|
|
36
|
+
* Amazon-authored Building Blocks now read removal policy + deletion protection
|
|
37
|
+
* from `defaults`, so this mixin is no longer needed; it is retained only for
|
|
38
|
+
* backward compatibility.
|
|
16
39
|
*
|
|
17
40
|
* @example
|
|
18
41
|
* ```ts
|
|
@@ -27,15 +50,17 @@ import type { IMixin } from 'constructs';
|
|
|
27
50
|
*/
|
|
28
51
|
export class SandboxDisableDeletionProtection extends Mixin implements IMixin {
|
|
29
52
|
supports(construct: any): boolean {
|
|
30
|
-
return
|
|
53
|
+
return DELETION_PROTECTION_PROPERTIES.some((property) => property in construct);
|
|
31
54
|
}
|
|
32
55
|
applyTo(node: IConstruct): void {
|
|
33
56
|
// Only flip explicitly-enabled protection. When undefined (the default),
|
|
34
57
|
// deletion protection is already off — setting it to false would emit the
|
|
35
58
|
// property in the CloudFormation template, which breaks Aurora DB instances
|
|
36
59
|
// (RDS rejects DeletionProtection on cluster members).
|
|
37
|
-
|
|
38
|
-
(node as any)
|
|
60
|
+
for (const property of DELETION_PROTECTION_PROPERTIES) {
|
|
61
|
+
if ((node as any)[property] === true) {
|
|
62
|
+
(node as any)[property] = false;
|
|
63
|
+
}
|
|
39
64
|
}
|
|
40
65
|
}
|
|
41
66
|
}
|
package/src/common/index.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import type { StackProps } from 'aws-cdk-lib';
|
|
5
5
|
import type { Construct } from 'constructs';
|
|
6
|
+
import type { BlocksDefaults } from '../cdk/blocks-defaults.js';
|
|
6
7
|
import { CORE_VERSION } from '../version.js';
|
|
7
8
|
import { OFFICIAL_BB_NAMES } from './official-bb-names.generated.js';
|
|
8
9
|
export { OFFICIAL_BB_NAMES } from './official-bb-names.generated.js';
|
|
@@ -325,6 +326,14 @@ export function computeScopeFullId(scope: { id: string; parent?: any }) {
|
|
|
325
326
|
export interface BlocksStackProps extends StackProps {
|
|
326
327
|
backendHandlerPath: string;
|
|
327
328
|
backendCDKPath: string;
|
|
329
|
+
/**
|
|
330
|
+
* Stack-wide infrastructure defaults applied to every Building Block (removal
|
|
331
|
+
* policy, deletion protection, …). Start from `BlocksPresets.sandbox` or
|
|
332
|
+
* `BlocksPresets.production` and override individual fields as needed. Any
|
|
333
|
+
* field a block also exposes as a per-block option is overridden by that
|
|
334
|
+
* option. See `BlocksDefaults` in `@aws-blocks/core/cdk`.
|
|
335
|
+
*/
|
|
336
|
+
defaults: BlocksDefaults;
|
|
328
337
|
}
|
|
329
338
|
|
|
330
339
|
export class BlocksStack {
|
package/src/index.cdk.ts
CHANGED
|
@@ -8,7 +8,11 @@ export { EventSourceMapping } from './lambda-handler.js';
|
|
|
8
8
|
export { BlocksStackProps } from './common/index.js';
|
|
9
9
|
export { registerSdkIdentifiers, getSdkIdentifiers, getAllSdkIdentifiers, _resetSdkRegistry } from './common/sdk-registry.js';
|
|
10
10
|
export { getConfig, getConfigSync, preloadConfig, loadConfigToProcessEnv, _resetConfigCache } from './common/config.js';
|
|
11
|
-
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME, type BlocksBackendProps } from './cdk/index.js';
|
|
11
|
+
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME, blocksNodejsBundling, type BlocksBackendProps } from './cdk/index.js';
|
|
12
|
+
export {
|
|
13
|
+
type BlocksDefaults,
|
|
14
|
+
BlocksPresets,
|
|
15
|
+
} from './cdk/index.js';
|
|
12
16
|
export {
|
|
13
17
|
Hosting,
|
|
14
18
|
type HostingProps,
|
package/src/rpc.test.ts
CHANGED
|
@@ -97,6 +97,28 @@ describe('params decoding', () => {
|
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
+
describe('-32602 Invalid Params validation', () => {
|
|
101
|
+
for (const params of ['abc', 42, true, false, null]) {
|
|
102
|
+
it(`rejects ${JSON.stringify(params)} params`, () => {
|
|
103
|
+
const result = parseRpcRequest(JSON.stringify({
|
|
104
|
+
jsonrpc: '2.0',
|
|
105
|
+
method: 'api.echo',
|
|
106
|
+
params,
|
|
107
|
+
id: 'request-1',
|
|
108
|
+
}));
|
|
109
|
+
|
|
110
|
+
assert.strictEqual(result.ok, false);
|
|
111
|
+
if (!result.ok) {
|
|
112
|
+
const response = JSON.parse(result.response);
|
|
113
|
+
assert.strictEqual(response.error.code, RpcErrorCode.InvalidParams);
|
|
114
|
+
assert.strictEqual(response.error.data.name, 'InvalidParams');
|
|
115
|
+
assert.ok(response.error.message.includes('expected an array or object'));
|
|
116
|
+
assert.strictEqual(response.id, 'request-1');
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
100
122
|
describe('batch requests (top-level JSON array body)', () => {
|
|
101
123
|
it('rejects an array body as Invalid Request with a null id', () => {
|
|
102
124
|
const result = parseRpcRequest(JSON.stringify([
|
package/src/rpc.ts
CHANGED
|
@@ -118,15 +118,31 @@ export function parseRpcRequest(bodyText: string): RpcParseResult {
|
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
const hasParams = Object.hasOwn(parsed, 'params');
|
|
122
|
+
if (hasParams && (parsed.params === null || typeof parsed.params !== 'object')) {
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
response: errorResponse(
|
|
126
|
+
RpcErrorCode.InvalidParams,
|
|
127
|
+
'Invalid params: expected an array or object',
|
|
128
|
+
id,
|
|
129
|
+
{ name: 'InvalidParams' },
|
|
130
|
+
),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let args: unknown[] = [];
|
|
135
|
+
if (hasParams) {
|
|
136
|
+
args = Array.isArray(parsed.params) ? parsed.params : Object.values(parsed.params);
|
|
137
|
+
}
|
|
138
|
+
|
|
121
139
|
return {
|
|
122
140
|
ok: true,
|
|
123
141
|
request: {
|
|
124
142
|
apiNamespace: parsed.method.substring(0, dotIndex),
|
|
125
143
|
method: parsed.method.substring(dotIndex + 1),
|
|
126
144
|
// JSON-RPC 2.0 §4.2: params may be an array (positional) or object (named).
|
|
127
|
-
args
|
|
128
|
-
? parsed.params
|
|
129
|
-
: Object.values(parsed.params ?? {}),
|
|
145
|
+
args,
|
|
130
146
|
id,
|
|
131
147
|
},
|
|
132
148
|
};
|
|
@@ -29,7 +29,9 @@ export function isCI(): boolean {
|
|
|
29
29
|
process.env.JENKINS_URL ||
|
|
30
30
|
process.env.TF_BUILD ||
|
|
31
31
|
process.env.BITBUCKET_BUILD_NUMBER ||
|
|
32
|
-
process.env.BUILDKITE
|
|
32
|
+
process.env.BUILDKITE ||
|
|
33
|
+
process.env.RENDER ||
|
|
34
|
+
process.env.TASKCLUSTER_ROOT_URL
|
|
33
35
|
);
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -133,6 +133,8 @@ describe('telemetry/environment', () => {
|
|
|
133
133
|
delete process.env.TF_BUILD;
|
|
134
134
|
delete process.env.BITBUCKET_BUILD_NUMBER;
|
|
135
135
|
delete process.env.BUILDKITE;
|
|
136
|
+
delete process.env.RENDER;
|
|
137
|
+
delete process.env.TASKCLUSTER_ROOT_URL;
|
|
136
138
|
});
|
|
137
139
|
|
|
138
140
|
it('returns false when no CI env vars set', () => {
|
|
@@ -153,6 +155,16 @@ describe('telemetry/environment', () => {
|
|
|
153
155
|
process.env.CODEBUILD_BUILD_ID = 'build-123';
|
|
154
156
|
assert.strictEqual(isCI(), true);
|
|
155
157
|
});
|
|
158
|
+
|
|
159
|
+
it('returns true when RENDER is set', () => {
|
|
160
|
+
process.env.RENDER = 'true';
|
|
161
|
+
assert.strictEqual(isCI(), true);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('returns true when TASKCLUSTER_ROOT_URL is set', () => {
|
|
165
|
+
process.env.TASKCLUSTER_ROOT_URL = 'https://tc.example.com';
|
|
166
|
+
assert.strictEqual(isCI(), true);
|
|
167
|
+
});
|
|
156
168
|
});
|
|
157
169
|
|
|
158
170
|
it('detectOS returns a valid platform', () => {
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-version.mjs — do not edit manually
|
|
2
|
-
export const CORE_VERSION = '0.
|
|
2
|
+
export const CORE_VERSION = '0.2.0';
|