@aws-blocks/core 0.1.18 → 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 +11 -0
- package/dist/cdk/blocks-backend.d.ts.map +1 -1
- package/dist/cdk/blocks-backend.js +22 -6
- package/dist/cdk/blocks-backend.test.js +66 -0
- 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 +8 -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 +46 -7
- package/dist/cdk/index.d.ts.map +1 -1
- package/dist/cdk/index.js +84 -18
- 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 +76 -0
- package/src/cdk/blocks-backend.ts +35 -6
- package/src/cdk/blocks-defaults.test.ts +25 -0
- package/src/cdk/blocks-defaults.ts +49 -0
- package/src/cdk/blocks-stack.test.ts +8 -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 +94 -19
- 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
package/dist/index.cdk.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ export { EventSourceMapping } from './lambda-handler.js';
|
|
|
5
5
|
export { BlocksStackProps } from './common/index.js';
|
|
6
6
|
export { registerSdkIdentifiers, getSdkIdentifiers, getAllSdkIdentifiers, _resetSdkRegistry } from './common/sdk-registry.js';
|
|
7
7
|
export { getConfig, getConfigSync, preloadConfig, loadConfigToProcessEnv, _resetConfigCache } from './common/config.js';
|
|
8
|
-
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME, type BlocksBackendProps } from './cdk/index.js';
|
|
8
|
+
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME, blocksNodejsBundling, type BlocksBackendProps } from './cdk/index.js';
|
|
9
|
+
export { type BlocksDefaults, BlocksPresets, } from './cdk/index.js';
|
|
9
10
|
export { Hosting, type HostingProps, type BlocksStackApi, type FrameworkType, type ComputeConfig, type HostingDomainConfig, type HostingWafConfig, } from './hosting.js';
|
|
10
11
|
export { RawRoute, RawRouteErrors, type RawRouteOptions, type HttpMethod, } from './raw-route.cdk.js';
|
|
11
12
|
export { registerRoute, matchRoute, getRegisteredRoutes, clearRouteRegistry, lockRouteRegistry, unlockRouteRegistry, type RegisteredRoute, } from './raw-route.js';
|
package/dist/index.cdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cdk.d.ts","sourceRoot":"","sources":["../src/index.cdk.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9H,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxH,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,gCAAgC,EAAE,aAAa,EAAE,cAAc,EAAE,sBAAsB,EAAE,UAAU,EAAE,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.cdk.d.ts","sourceRoot":"","sources":["../src/index.cdk.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9H,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxH,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,gCAAgC,EAAE,aAAa,EAAE,cAAc,EAAE,sBAAsB,EAAE,UAAU,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9N,OAAO,EACL,KAAK,cAAc,EACnB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,OAAO,EACP,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC"}
|
package/dist/index.cdk.js
CHANGED
|
@@ -6,7 +6,8 @@ export { ApiError, isBlocksError, hasAuthError, DEFAULT_API_ERROR_NAME } from '.
|
|
|
6
6
|
export { EventSourceMapping } from './lambda-handler.js';
|
|
7
7
|
export { registerSdkIdentifiers, getSdkIdentifiers, getAllSdkIdentifiers, _resetSdkRegistry } from './common/sdk-registry.js';
|
|
8
8
|
export { getConfig, getConfigSync, preloadConfig, loadConfigToProcessEnv, _resetConfigCache } from './common/config.js';
|
|
9
|
-
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME } from './cdk/index.js';
|
|
9
|
+
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME, blocksNodejsBundling } from './cdk/index.js';
|
|
10
|
+
export { BlocksPresets, } from './cdk/index.js';
|
|
10
11
|
export { Hosting, } from './hosting.js';
|
|
11
12
|
export { RawRoute, RawRouteErrors, } from './raw-route.cdk.js';
|
|
12
13
|
export { registerRoute, matchRoute, getRegisteredRoutes, clearRouteRegistry, lockRouteRegistry, unlockRouteRegistry, } from './raw-route.js';
|
package/dist/rpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAgBA,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,yDAAyD;AACzD,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAMpC,qCAAqC;AACrC,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAMX,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAO9F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAiBxD;AAID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAgBA,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,yDAAyD;AACzD,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAMpC,qCAAqC;AACrC,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAMX,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAO9F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAiBxD;AAID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CA0DhE;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAEnF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAOzF;AAED,yCAAyC;AACzC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAEzF;AAID,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC1B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAMR"}
|
package/dist/rpc.js
CHANGED
|
@@ -79,15 +79,24 @@ export function parseRpcRequest(bodyText) {
|
|
|
79
79
|
response: errorResponse(RpcErrorCode.InvalidRequest, 'Invalid Request: method must be "namespace.method"', id, { name: 'InvalidRequest' }),
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
+
const hasParams = Object.hasOwn(parsed, 'params');
|
|
83
|
+
if (hasParams && (parsed.params === null || typeof parsed.params !== 'object')) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
response: errorResponse(RpcErrorCode.InvalidParams, 'Invalid params: expected an array or object', id, { name: 'InvalidParams' }),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
let args = [];
|
|
90
|
+
if (hasParams) {
|
|
91
|
+
args = Array.isArray(parsed.params) ? parsed.params : Object.values(parsed.params);
|
|
92
|
+
}
|
|
82
93
|
return {
|
|
83
94
|
ok: true,
|
|
84
95
|
request: {
|
|
85
96
|
apiNamespace: parsed.method.substring(0, dotIndex),
|
|
86
97
|
method: parsed.method.substring(dotIndex + 1),
|
|
87
98
|
// JSON-RPC 2.0 §4.2: params may be an array (positional) or object (named).
|
|
88
|
-
args
|
|
89
|
-
? parsed.params
|
|
90
|
-
: Object.values(parsed.params ?? {}),
|
|
99
|
+
args,
|
|
91
100
|
id,
|
|
92
101
|
},
|
|
93
102
|
};
|
package/dist/rpc.test.js
CHANGED
|
@@ -82,6 +82,26 @@ describe('params decoding', () => {
|
|
|
82
82
|
assert.deepStrictEqual(result.request.args, []);
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
|
+
describe('-32602 Invalid Params validation', () => {
|
|
86
|
+
for (const params of ['abc', 42, true, false, null]) {
|
|
87
|
+
it(`rejects ${JSON.stringify(params)} params`, () => {
|
|
88
|
+
const result = parseRpcRequest(JSON.stringify({
|
|
89
|
+
jsonrpc: '2.0',
|
|
90
|
+
method: 'api.echo',
|
|
91
|
+
params,
|
|
92
|
+
id: 'request-1',
|
|
93
|
+
}));
|
|
94
|
+
assert.strictEqual(result.ok, false);
|
|
95
|
+
if (!result.ok) {
|
|
96
|
+
const response = JSON.parse(result.response);
|
|
97
|
+
assert.strictEqual(response.error.code, RpcErrorCode.InvalidParams);
|
|
98
|
+
assert.strictEqual(response.error.data.name, 'InvalidParams');
|
|
99
|
+
assert.ok(response.error.message.includes('expected an array or object'));
|
|
100
|
+
assert.strictEqual(response.id, 'request-1');
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
85
105
|
describe('batch requests (top-level JSON array body)', () => {
|
|
86
106
|
it('rejects an array body as Invalid Request with a null id', () => {
|
|
87
107
|
const result = parseRpcRequest(JSON.stringify([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/telemetry/environment.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,GAAG,QAAQ,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/telemetry/environment.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,GAAG,QAAQ,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAgB9B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAEzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,SAAS,CAiBhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,EAAE,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAwBA"}
|
|
@@ -25,7 +25,9 @@ export function isCI() {
|
|
|
25
25
|
process.env.JENKINS_URL ||
|
|
26
26
|
process.env.TF_BUILD ||
|
|
27
27
|
process.env.BITBUCKET_BUILD_NUMBER ||
|
|
28
|
-
process.env.BUILDKITE
|
|
28
|
+
process.env.BUILDKITE ||
|
|
29
|
+
process.env.RENDER ||
|
|
30
|
+
process.env.TASKCLUSTER_ROOT_URL);
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
33
|
* Detect the package manager from npm_config_user_agent.
|
|
@@ -117,6 +117,8 @@ describe('telemetry/environment', () => {
|
|
|
117
117
|
delete process.env.TF_BUILD;
|
|
118
118
|
delete process.env.BITBUCKET_BUILD_NUMBER;
|
|
119
119
|
delete process.env.BUILDKITE;
|
|
120
|
+
delete process.env.RENDER;
|
|
121
|
+
delete process.env.TASKCLUSTER_ROOT_URL;
|
|
120
122
|
});
|
|
121
123
|
it('returns false when no CI env vars set', () => {
|
|
122
124
|
assert.strictEqual(isCI(), false);
|
|
@@ -133,6 +135,14 @@ describe('telemetry/environment', () => {
|
|
|
133
135
|
process.env.CODEBUILD_BUILD_ID = 'build-123';
|
|
134
136
|
assert.strictEqual(isCI(), true);
|
|
135
137
|
});
|
|
138
|
+
it('returns true when RENDER is set', () => {
|
|
139
|
+
process.env.RENDER = 'true';
|
|
140
|
+
assert.strictEqual(isCI(), true);
|
|
141
|
+
});
|
|
142
|
+
it('returns true when TASKCLUSTER_ROOT_URL is set', () => {
|
|
143
|
+
process.env.TASKCLUSTER_ROOT_URL = 'https://tc.example.com';
|
|
144
|
+
assert.strictEqual(isCI(), true);
|
|
145
|
+
});
|
|
136
146
|
});
|
|
137
147
|
it('detectOS returns a valid platform', () => {
|
|
138
148
|
const os = detectOS();
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CORE_VERSION = "0.
|
|
1
|
+
export declare const CORE_VERSION = "0.2.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,UAAU,CAAC"}
|
package/dist/version.js
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';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-blocks/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/aws-devtools-labs/aws-blocks.git",
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"types": "./dist/index.cdk.js",
|
|
33
33
|
"default": "./dist/index.cdk.js"
|
|
34
34
|
},
|
|
35
|
+
"./cdk/internal": {
|
|
36
|
+
"types": "./dist/cdk/internal.d.ts",
|
|
37
|
+
"default": "./dist/cdk/internal.js"
|
|
38
|
+
},
|
|
35
39
|
"./client": "./dist/client/index.js",
|
|
36
40
|
"./lambda-handler": "./dist/lambda-handler.js",
|
|
37
41
|
"./bb-utils": {
|
|
@@ -67,6 +71,7 @@
|
|
|
67
71
|
"@types/cross-spawn": "^6.0.6",
|
|
68
72
|
"@types/http-proxy": "^1.17.16",
|
|
69
73
|
"@types/node": "^20.0.0",
|
|
74
|
+
"esbuild": "^0.27.0",
|
|
70
75
|
"typescript": "^5.3.0",
|
|
71
76
|
"unctx": "^2.0.0"
|
|
72
77
|
},
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Repro fixture for the "handler bundles to CJS but uses import.meta.url" bug.
|
|
5
|
+
//
|
|
6
|
+
// The handler is bundled to CJS by NodejsFunction. In a CJS bundle `import.meta`
|
|
7
|
+
// is empty, so this top-level `fileURLToPath(import.meta.url)` would become
|
|
8
|
+
// `fileURLToPath(undefined)` and throw at Lambda load. blocksNodejsBundling shims
|
|
9
|
+
// `import.meta.url` to a CommonJS equivalent, so the bundle loads and resolves a
|
|
10
|
+
// real path instead of crashing — see bundling.test.ts.
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
|
|
13
|
+
export const moduleDir = fileURLToPath(import.meta.url);
|
|
14
|
+
|
|
15
|
+
// Reference moduleDir so esbuild can't tree-shake the import.meta.url usage away.
|
|
16
|
+
export const handler = async () => ({ statusCode: 200, body: JSON.stringify({ moduleDir }) });
|
|
@@ -9,6 +9,7 @@ import * as cdk from 'aws-cdk-lib';
|
|
|
9
9
|
import { Template, Match } from 'aws-cdk-lib/assertions';
|
|
10
10
|
import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
|
|
11
11
|
import { BlocksBackend } from './blocks-backend.js';
|
|
12
|
+
import { BlocksPresets } from './blocks-defaults.js';
|
|
12
13
|
import { Scope } from './index.js';
|
|
13
14
|
|
|
14
15
|
// Simulate the CDK condition being active (tests import CDK files directly)
|
|
@@ -22,6 +23,7 @@ const sideEffectBackendPath = join(__dirname, '__fixtures__', 'side-effect-backe
|
|
|
22
23
|
const factoryBackendPath = join(__dirname, '__fixtures__', 'factory-backend.js');
|
|
23
24
|
const fullIdConstructBackendPath = join(__dirname, '__fixtures__', 'fullid-construct-backend.js');
|
|
24
25
|
const EXECUTION_ROLE_MARKER_ACTION = 'blocks-test:MarkerAction';
|
|
26
|
+
const importMetaHandlerPath = join(__dirname, '__fixtures__', 'import-meta-handler.js');
|
|
25
27
|
|
|
26
28
|
describe('ESM cache-busting (multi-stage)', () => {
|
|
27
29
|
test('BlocksBackend.create() with same backendCDKPath but different IDs produces constructs in each', async () => {
|
|
@@ -31,11 +33,13 @@ describe('ESM cache-busting (multi-stage)', () => {
|
|
|
31
33
|
const backend1 = await BlocksBackend.create(stack, 'Stage1', {
|
|
32
34
|
backendHandlerPath: handlerPath,
|
|
33
35
|
backendCDKPath: sideEffectBackendPath,
|
|
36
|
+
defaults: BlocksPresets.production,
|
|
34
37
|
});
|
|
35
38
|
|
|
36
39
|
const backend2 = await BlocksBackend.create(stack, 'Stage2', {
|
|
37
40
|
backendHandlerPath: handlerPath,
|
|
38
41
|
backendCDKPath: sideEffectBackendPath,
|
|
42
|
+
defaults: BlocksPresets.production,
|
|
39
43
|
});
|
|
40
44
|
|
|
41
45
|
const findMarker = (scope: cdk.aws_lambda_nodejs.NodejsFunction | any) =>
|
|
@@ -60,6 +64,7 @@ describe('synth shape (drop into existing stack)', () => {
|
|
|
60
64
|
const backend = await BlocksBackend.create(parent, 'Blocks', {
|
|
61
65
|
backendHandlerPath: handlerPath,
|
|
62
66
|
backendCDKPath: sideEffectBackendPath,
|
|
67
|
+
defaults: BlocksPresets.production,
|
|
63
68
|
});
|
|
64
69
|
|
|
65
70
|
// Public surface mirrors BlocksStack.
|
|
@@ -81,10 +86,12 @@ describe('synth shape (drop into existing stack)', () => {
|
|
|
81
86
|
await BlocksBackend.create(parent, 'BackendA', {
|
|
82
87
|
backendHandlerPath: handlerPath,
|
|
83
88
|
backendCDKPath: sideEffectBackendPath,
|
|
89
|
+
defaults: BlocksPresets.production,
|
|
84
90
|
});
|
|
85
91
|
await BlocksBackend.create(parent, 'BackendB', {
|
|
86
92
|
backendHandlerPath: handlerPath,
|
|
87
93
|
backendCDKPath: sideEffectBackendPath,
|
|
94
|
+
defaults: BlocksPresets.production,
|
|
88
95
|
});
|
|
89
96
|
|
|
90
97
|
const template = Template.fromStack(parent);
|
|
@@ -100,6 +107,7 @@ describe('shared execution role', () => {
|
|
|
100
107
|
const backend = await BlocksBackend.create(parent, 'Blocks', {
|
|
101
108
|
backendHandlerPath: handlerPath,
|
|
102
109
|
backendCDKPath: sideEffectBackendPath,
|
|
110
|
+
defaults: BlocksPresets.production,
|
|
103
111
|
});
|
|
104
112
|
|
|
105
113
|
assert.ok(backend.executionRole, 'BlocksBackend should expose .executionRole');
|
|
@@ -112,6 +120,7 @@ describe('shared execution role', () => {
|
|
|
112
120
|
await BlocksBackend.create(parent, 'Blocks', {
|
|
113
121
|
backendHandlerPath: handlerPath,
|
|
114
122
|
backendCDKPath: sideEffectBackendPath,
|
|
123
|
+
defaults: BlocksPresets.production,
|
|
115
124
|
});
|
|
116
125
|
|
|
117
126
|
const template = Template.fromStack(parent);
|
|
@@ -148,6 +157,7 @@ describe('shared execution role', () => {
|
|
|
148
157
|
const backend = await BlocksBackend.create(parent, 'Blocks', {
|
|
149
158
|
backendHandlerPath: handlerPath,
|
|
150
159
|
backendCDKPath: sideEffectBackendPath,
|
|
160
|
+
defaults: BlocksPresets.production,
|
|
151
161
|
});
|
|
152
162
|
|
|
153
163
|
// Build nested Scopes under the backend (outer → inner), the same shape a
|
|
@@ -178,6 +188,27 @@ describe('shared execution role', () => {
|
|
|
178
188
|
});
|
|
179
189
|
});
|
|
180
190
|
|
|
191
|
+
describe('CJS bundle: import.meta.url in the handler is shimmed (no Lambda-load crash)', () => {
|
|
192
|
+
test('a handler that uses import.meta.url bundles successfully instead of throwing at load', async () => {
|
|
193
|
+
// The handler is bundled to CJS, where `import.meta` is empty. Left unshimmed,
|
|
194
|
+
// `fileURLToPath(import.meta.url)` compiles to `fileURLToPath(undefined)` and
|
|
195
|
+
// throws at Lambda load (esbuild only warns, so the broken bundle would deploy).
|
|
196
|
+
// blocksNodejsBundling shims import.meta.* to CommonJS equivalents, so bundling
|
|
197
|
+
// (which runs synchronously during construction) succeeds. The runtime behaviour
|
|
198
|
+
// of the emitted shim is verified directly in bundling.test.ts.
|
|
199
|
+
const app = new cdk.App();
|
|
200
|
+
const stack = new cdk.Stack(app, 'ImportMetaStack');
|
|
201
|
+
|
|
202
|
+
await assert.doesNotReject(() =>
|
|
203
|
+
BlocksBackend.create(stack, 'blocks', {
|
|
204
|
+
backendHandlerPath: importMetaHandlerPath,
|
|
205
|
+
backendCDKPath: sideEffectBackendPath,
|
|
206
|
+
defaults: BlocksPresets.production,
|
|
207
|
+
}),
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
181
212
|
describe('factory function support', () => {
|
|
182
213
|
test('BlocksBackend.create() calls default export function with the backend instance', async () => {
|
|
183
214
|
const app = new cdk.App();
|
|
@@ -186,6 +217,7 @@ describe('factory function support', () => {
|
|
|
186
217
|
const backend = await BlocksBackend.create(stack, 'FactoryStage', {
|
|
187
218
|
backendHandlerPath: handlerPath,
|
|
188
219
|
backendCDKPath: factoryBackendPath,
|
|
220
|
+
defaults: BlocksPresets.production,
|
|
189
221
|
});
|
|
190
222
|
|
|
191
223
|
const marker = backend.node.tryFindChild('FactoryMarker');
|
|
@@ -201,6 +233,7 @@ describe('fullId is token-free (construct IDs / env-var keys)', () => {
|
|
|
201
233
|
const backend = await BlocksBackend.create(stack, 'blocks', {
|
|
202
234
|
backendHandlerPath: handlerPath,
|
|
203
235
|
backendCDKPath: sideEffectBackendPath,
|
|
236
|
+
defaults: BlocksPresets.production,
|
|
204
237
|
});
|
|
205
238
|
|
|
206
239
|
assert.strictEqual(backend.fullId, 'TopLevelStack-blocks');
|
|
@@ -225,6 +258,7 @@ describe('fullId is token-free (construct IDs / env-var keys)', () => {
|
|
|
225
258
|
const backend = await BlocksBackend.create(nested, 'blocks', {
|
|
226
259
|
backendHandlerPath: handlerPath,
|
|
227
260
|
backendCDKPath: sideEffectBackendPath,
|
|
261
|
+
defaults: BlocksPresets.production,
|
|
228
262
|
});
|
|
229
263
|
|
|
230
264
|
assert.ok(
|
|
@@ -245,6 +279,7 @@ describe('fullId is token-free (construct IDs / env-var keys)', () => {
|
|
|
245
279
|
const backend = await BlocksBackend.create(nested, 'blocks', {
|
|
246
280
|
backendHandlerPath: handlerPath,
|
|
247
281
|
backendCDKPath: fullIdConstructBackendPath,
|
|
282
|
+
defaults: BlocksPresets.production,
|
|
248
283
|
});
|
|
249
284
|
|
|
250
285
|
// The construct ID is `${scope.fullId}Marker` → `ParentStack-blocks-blocks-dbMarker`.
|
|
@@ -272,6 +307,7 @@ describe('fullId is token-free (construct IDs / env-var keys)', () => {
|
|
|
272
307
|
const backend = await BlocksBackend.create(nested, 'blocks', {
|
|
273
308
|
backendHandlerPath: handlerPath,
|
|
274
309
|
backendCDKPath: sideEffectBackendPath,
|
|
310
|
+
defaults: BlocksPresets.production,
|
|
275
311
|
});
|
|
276
312
|
|
|
277
313
|
const template = Template.fromStack(nested);
|
|
@@ -294,3 +330,43 @@ describe('fullId is token-free (construct IDs / env-var keys)', () => {
|
|
|
294
330
|
}
|
|
295
331
|
});
|
|
296
332
|
});
|
|
333
|
+
|
|
334
|
+
describe('infrastructure defaults (backend-anchored)', () => {
|
|
335
|
+
test('each backend exposes its own defaults', async () => {
|
|
336
|
+
const app = new cdk.App();
|
|
337
|
+
const stack = new cdk.Stack(app, 'TwoBackendsStack');
|
|
338
|
+
|
|
339
|
+
const a = await BlocksBackend.create(stack, 'A', {
|
|
340
|
+
backendHandlerPath: handlerPath,
|
|
341
|
+
backendCDKPath: sideEffectBackendPath,
|
|
342
|
+
defaults: BlocksPresets.production,
|
|
343
|
+
});
|
|
344
|
+
const b = await BlocksBackend.create(stack, 'B', {
|
|
345
|
+
backendHandlerPath: handlerPath,
|
|
346
|
+
backendCDKPath: sideEffectBackendPath,
|
|
347
|
+
defaults: BlocksPresets.sandbox,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// Two backends in one stack must NOT clobber each other — defaults are
|
|
351
|
+
// anchored on the backend, not the shared stack.
|
|
352
|
+
assert.strictEqual(a.defaults, BlocksPresets.production);
|
|
353
|
+
assert.strictEqual(b.defaults, BlocksPresets.sandbox);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test('a nested block resolves its owning backend defaults via the tree-walk', async () => {
|
|
357
|
+
const app = new cdk.App();
|
|
358
|
+
const stack = new cdk.Stack(app, 'ResolveDefaultsStack');
|
|
359
|
+
|
|
360
|
+
const backend = await BlocksBackend.create(stack, 'Blocks', {
|
|
361
|
+
backendHandlerPath: handlerPath,
|
|
362
|
+
backendCDKPath: sideEffectBackendPath,
|
|
363
|
+
defaults: BlocksPresets.sandbox,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// A Scope under the backend resolves scope.defaults by walking up to it.
|
|
367
|
+
const outer = new Scope('outer');
|
|
368
|
+
const inner = new Scope('inner', { parent: outer });
|
|
369
|
+
assert.strictEqual(inner.defaults, backend.defaults);
|
|
370
|
+
assert.strictEqual(inner.defaults, BlocksPresets.sandbox);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
@@ -9,8 +9,10 @@ import { CfnGroup } from 'aws-cdk-lib/aws-resourcegroups';
|
|
|
9
9
|
import { Construct } from 'constructs';
|
|
10
10
|
import { pathToFileURL } from 'node:url';
|
|
11
11
|
import { DEFAULT_NODE_RUNTIME } from './node-version.js';
|
|
12
|
+
import { blocksNodejsBundling } from './bundling.js';
|
|
12
13
|
import { addBlocksStackMetadata } from './stack-metadata.js';
|
|
13
14
|
import { finalizeConfigRegistry, registerConfig } from './config-registry.js';
|
|
15
|
+
import type { BlocksDefaults } from './blocks-defaults.js';
|
|
14
16
|
import { BLOCKS_NAMESPACE, BLOCKS_RPC_PREFIX } from '../constants.js';
|
|
15
17
|
import { registerBuiltinRoutes } from '../builtin-routes.js';
|
|
16
18
|
|
|
@@ -45,18 +47,35 @@ export function assertCdkConditionActive(): void {
|
|
|
45
47
|
export interface BlocksBackendProps {
|
|
46
48
|
backendHandlerPath: string;
|
|
47
49
|
backendCDKPath: string;
|
|
50
|
+
/**
|
|
51
|
+
* Stack-wide infrastructure defaults applied to every Building Block (removal
|
|
52
|
+
* policy, deletion protection, …). See {@link BlocksDefaults}. Start from
|
|
53
|
+
* `BlocksPresets.sandbox` or `BlocksPresets.production` and override
|
|
54
|
+
* individual fields as needed. A per-block option always wins over the
|
|
55
|
+
* corresponding stack default.
|
|
56
|
+
*/
|
|
57
|
+
defaults: BlocksDefaults;
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
/** Shared infra setup — creates Lambda + API Gateway on the given scope. */
|
|
51
61
|
export function setupBlocksInfra(scope: Construct, props: BlocksBackendProps, id?: string) {
|
|
62
|
+
// Fail fast with an actionable message at the create() call site if `defaults`
|
|
63
|
+
// is missing (e.g. a plain-JS caller, `as any`, or a dynamically-built props
|
|
64
|
+
// object) — otherwise the first Building Block to read `scope.defaults` throws
|
|
65
|
+
// a cryptic `Cannot read properties of undefined (reading 'removalPolicy')`.
|
|
66
|
+
if (!props.defaults) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
'BlocksStack/BlocksBackend requires a `defaults` field. Pass a posture from ' +
|
|
69
|
+
'`@aws-blocks/core/cdk` — typically `defaults: sandboxMode ? BlocksPresets.sandbox : BlocksPresets.production`.',
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
52
73
|
// ── Shared execution role ──────────────────────────────────────────────
|
|
53
74
|
// A single IAM role that every Building Block grants to. Provisioned here so
|
|
54
75
|
// it exists before the backend module is imported (Building Blocks reach it
|
|
55
76
|
// via `scope.executionRole`). Block grants sit on the role's default (inline)
|
|
56
|
-
// policy
|
|
57
|
-
//
|
|
58
|
-
// AWSLambdaBasicExecutionRole is attached explicitly because the auto-role
|
|
59
|
-
// included it by default — omitting it would silently break CloudWatch Logs.
|
|
77
|
+
// policy. AWSLambdaBasicExecutionRole is attached so the handler retains
|
|
78
|
+
// CloudWatch Logs permissions.
|
|
60
79
|
const executionRole = new iam.Role(scope, 'BlocksRole', {
|
|
61
80
|
// CompositePrincipal (rather than a bare ServicePrincipal) so additional
|
|
62
81
|
// compute types can assume this same shared role as they are introduced
|
|
@@ -87,10 +106,13 @@ export function setupBlocksInfra(scope: Construct, props: BlocksBackendProps, id
|
|
|
87
106
|
*/
|
|
88
107
|
BLOCKS_STACK_NAME: id ?? cdk.Stack.of(scope).stackName,
|
|
89
108
|
},
|
|
90
|
-
|
|
109
|
+
// blocksNodejsBundling shims import.meta.* to CommonJS equivalents so a
|
|
110
|
+
// CJS-bundled `fileURLToPath(import.meta.url)` resolves instead of throwing at
|
|
111
|
+
// Lambda load. See ./bundling.ts.
|
|
112
|
+
bundling: blocksNodejsBundling({
|
|
91
113
|
minify: true,
|
|
92
114
|
esbuildArgs: { '--conditions': 'aws-runtime' },
|
|
93
|
-
},
|
|
115
|
+
}),
|
|
94
116
|
});
|
|
95
117
|
|
|
96
118
|
// In sandbox mode, allow localhost origins so the local dev frontend can
|
|
@@ -199,6 +221,8 @@ export class BlocksBackend extends Construct {
|
|
|
199
221
|
public readonly backendHandlerPath: string;
|
|
200
222
|
/** Shared IAM role assumed by all Blocks compute. Building Blocks grant to this role. */
|
|
201
223
|
public readonly executionRole: iam.IRole;
|
|
224
|
+
/** Infrastructure defaults for Building Blocks created under this backend. */
|
|
225
|
+
public readonly defaults: BlocksDefaults;
|
|
202
226
|
|
|
203
227
|
/**
|
|
204
228
|
* The fullId used by child Scopes to compute their env var names,
|
|
@@ -239,6 +263,11 @@ export class BlocksBackend extends Construct {
|
|
|
239
263
|
// Expose self to Building Blocks at CDK time
|
|
240
264
|
(globalThis as any).CURRENT_BLOCKS_STACK = this;
|
|
241
265
|
|
|
266
|
+
// Store defaults on the backend (not the stack) so several BlocksBackends
|
|
267
|
+
// in one stack each keep their own posture; Building Blocks resolve them by
|
|
268
|
+
// walking up to their owning backend (see Scope.defaults).
|
|
269
|
+
this.defaults = props.defaults;
|
|
270
|
+
|
|
242
271
|
const infra = setupBlocksInfra(this, props, id);
|
|
243
272
|
this.handler = infra.handler;
|
|
244
273
|
this.gateway = infra.gateway;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* BlocksPresets carry the expected posture. Resolution/anchoring (a block
|
|
6
|
+
* reading its owning backend's defaults, and two backends in one stack keeping
|
|
7
|
+
* separate postures) is covered in blocks-backend.test.ts, which has the
|
|
8
|
+
* fixtures to construct real backends.
|
|
9
|
+
*/
|
|
10
|
+
import { test, describe } from 'node:test';
|
|
11
|
+
import assert from 'node:assert';
|
|
12
|
+
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
13
|
+
import { BlocksPresets } from './blocks-defaults.js';
|
|
14
|
+
|
|
15
|
+
describe('BlocksPresets', () => {
|
|
16
|
+
test('sandbox is disposable: DESTROY + deletion protection off', () => {
|
|
17
|
+
assert.strictEqual(BlocksPresets.sandbox.removalPolicy, RemovalPolicy.DESTROY);
|
|
18
|
+
assert.strictEqual(BlocksPresets.sandbox.deletionProtection, false);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('production is durable: RETAIN + deletion protection on', () => {
|
|
22
|
+
assert.strictEqual(BlocksPresets.production.removalPolicy, RemovalPolicy.RETAIN);
|
|
23
|
+
assert.strictEqual(BlocksPresets.production.deletionProtection, true);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Default values for every Amazon-authored Building Block created within a
|
|
8
|
+
* `BlocksStack` or `BlocksBackend`. A per-block option always overrides the
|
|
9
|
+
* corresponding default (`option ?? scope.defaults.field`).
|
|
10
|
+
*
|
|
11
|
+
* Start from {@link BlocksPresets} and override individual fields as needed.
|
|
12
|
+
*/
|
|
13
|
+
export interface BlocksDefaults {
|
|
14
|
+
/**
|
|
15
|
+
* What happens to a stateful resource (table, bucket, user pool) when the
|
|
16
|
+
* stack is deleted, via CDK/CloudFormation: `RETAIN` keeps the resource (and
|
|
17
|
+
* its data) behind; `DESTROY` tears it down. Applies only to CDK/CloudFormation
|
|
18
|
+
* deletions.
|
|
19
|
+
*/
|
|
20
|
+
removalPolicy: RemovalPolicy;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Whether to block deletion of a stateful resource. Unlike `removalPolicy`,
|
|
24
|
+
* this guards against deletion through **any** path — CDK/CloudFormation as
|
|
25
|
+
* well as the CLI, API, and AWS console — until it is turned off.
|
|
26
|
+
*/
|
|
27
|
+
deletionProtection: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Prepared starting points for {@link BlocksDefaults}. Pick one and override
|
|
32
|
+
* individual fields with a spread:
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* defaults: { ...BlocksPresets.production, deletionProtection: false }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export const BlocksPresets = {
|
|
39
|
+
/** Disposable development stacks: tear down cleanly, no delete guard. */
|
|
40
|
+
sandbox: {
|
|
41
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
42
|
+
deletionProtection: false,
|
|
43
|
+
},
|
|
44
|
+
/** Durable, protected posture for permanent deployments. */
|
|
45
|
+
production: {
|
|
46
|
+
removalPolicy: RemovalPolicy.RETAIN,
|
|
47
|
+
deletionProtection: true,
|
|
48
|
+
},
|
|
49
|
+
} satisfies Record<string, BlocksDefaults>;
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
import { dirname, join } from 'node:path';
|
|
8
8
|
import * as cdk from 'aws-cdk-lib';
|
|
9
9
|
import { BlocksBackend } from './blocks-backend.js';
|
|
10
|
-
import { BlocksStack, Scope } from './index.js';
|
|
10
|
+
import { BlocksStack, BlocksPresets, Scope } from './index.js';
|
|
11
11
|
|
|
12
12
|
// Simulate the CDK condition being active (tests import CDK files directly)
|
|
13
13
|
before(() => {
|
|
@@ -26,11 +26,13 @@ describe('ESM cache-busting (multi-stage)', () => {
|
|
|
26
26
|
const stack1 = await BlocksStack.create(app, 'PipelineStage1', {
|
|
27
27
|
backendHandlerPath: handlerPath,
|
|
28
28
|
backendCDKPath: sideEffectBackendPath,
|
|
29
|
+
defaults: BlocksPresets.production,
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
const stack2 = await BlocksStack.create(app, 'PipelineStage2', {
|
|
32
33
|
backendHandlerPath: handlerPath,
|
|
33
34
|
backendCDKPath: sideEffectBackendPath,
|
|
35
|
+
defaults: BlocksPresets.production,
|
|
34
36
|
});
|
|
35
37
|
|
|
36
38
|
const findMarker = (scope: any) => scope.node.tryFindChild('SideEffectMarker');
|
|
@@ -53,6 +55,7 @@ describe('factory function support', () => {
|
|
|
53
55
|
const stack = await BlocksStack.create(app, 'FactoryBlocksStack', {
|
|
54
56
|
backendHandlerPath: handlerPath,
|
|
55
57
|
backendCDKPath: factoryBackendPath,
|
|
58
|
+
defaults: BlocksPresets.production,
|
|
56
59
|
});
|
|
57
60
|
|
|
58
61
|
const marker = stack.node.tryFindChild('FactoryMarker');
|
|
@@ -68,6 +71,7 @@ describe('legacy side-effect mode (no default export)', () => {
|
|
|
68
71
|
const backend = await BlocksBackend.create(stack, 'LegacyStage', {
|
|
69
72
|
backendHandlerPath: handlerPath,
|
|
70
73
|
backendCDKPath: sideEffectBackendPath,
|
|
74
|
+
defaults: BlocksPresets.production,
|
|
71
75
|
});
|
|
72
76
|
|
|
73
77
|
const marker = backend.node.tryFindChild('SideEffectMarker');
|
|
@@ -88,6 +92,7 @@ describe('shared execution role (BlocksStack)', () => {
|
|
|
88
92
|
const stack = await BlocksStack.create(app, 'StackRoleStack', {
|
|
89
93
|
backendHandlerPath: handlerPath,
|
|
90
94
|
backendCDKPath: sideEffectBackendPath,
|
|
95
|
+
defaults: BlocksPresets.production,
|
|
91
96
|
});
|
|
92
97
|
|
|
93
98
|
assert.ok(stack.executionRole, 'BlocksStack should expose a populated .executionRole');
|
|
@@ -100,6 +105,7 @@ describe('executionRole globalThis fallback', () => {
|
|
|
100
105
|
const stack = await BlocksStack.create(app, 'FallbackStack', {
|
|
101
106
|
backendHandlerPath: handlerPath,
|
|
102
107
|
backendCDKPath: sideEffectBackendPath,
|
|
108
|
+
defaults: BlocksPresets.production,
|
|
103
109
|
});
|
|
104
110
|
|
|
105
111
|
// A Scope whose construct-tree ancestry has no BlocksStack/BlocksBackend
|
|
@@ -132,6 +138,7 @@ describe('assertCdkConditionActive', () => {
|
|
|
132
138
|
BlocksStack.create(app, 'MissingConditionStack', {
|
|
133
139
|
backendHandlerPath: handlerPath,
|
|
134
140
|
backendCDKPath: sideEffectBackendPath,
|
|
141
|
+
defaults: BlocksPresets.production,
|
|
135
142
|
}),
|
|
136
143
|
(err: Error) => {
|
|
137
144
|
assert.ok(err.message.includes('Missing --conditions=cdk'), `Expected condition error, got: ${err.message}`);
|