@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.
Files changed (70) hide show
  1. package/dist/cdk/__fixtures__/import-meta-handler.d.ts +6 -0
  2. package/dist/cdk/__fixtures__/import-meta-handler.d.ts.map +1 -0
  3. package/dist/cdk/__fixtures__/import-meta-handler.js +13 -0
  4. package/dist/cdk/blocks-backend.d.ts +11 -0
  5. package/dist/cdk/blocks-backend.d.ts.map +1 -1
  6. package/dist/cdk/blocks-backend.js +22 -6
  7. package/dist/cdk/blocks-backend.test.js +66 -0
  8. package/dist/cdk/blocks-defaults.d.ts +44 -0
  9. package/dist/cdk/blocks-defaults.d.ts.map +1 -0
  10. package/dist/cdk/blocks-defaults.js +23 -0
  11. package/dist/cdk/blocks-defaults.test.d.ts +2 -0
  12. package/dist/cdk/blocks-defaults.test.d.ts.map +1 -0
  13. package/dist/cdk/blocks-defaults.test.js +22 -0
  14. package/dist/cdk/blocks-stack.test.js +8 -1
  15. package/dist/cdk/bundling.d.ts +42 -0
  16. package/dist/cdk/bundling.d.ts.map +1 -0
  17. package/dist/cdk/bundling.js +72 -0
  18. package/dist/cdk/bundling.test.d.ts +2 -0
  19. package/dist/cdk/bundling.test.d.ts.map +1 -0
  20. package/dist/cdk/bundling.test.js +80 -0
  21. package/dist/cdk/compute/compute.d.ts +33 -0
  22. package/dist/cdk/compute/compute.d.ts.map +1 -0
  23. package/dist/cdk/compute/compute.js +28 -0
  24. package/dist/cdk/index.d.ts +46 -7
  25. package/dist/cdk/index.d.ts.map +1 -1
  26. package/dist/cdk/index.js +84 -18
  27. package/dist/cdk/internal.d.ts +24 -0
  28. package/dist/cdk/internal.d.ts.map +1 -0
  29. package/dist/cdk/internal.js +27 -0
  30. package/dist/cdk/mixins.d.ts +18 -4
  31. package/dist/cdk/mixins.d.ts.map +1 -1
  32. package/dist/cdk/mixins.js +31 -7
  33. package/dist/cdk/mixins.test.js +45 -0
  34. package/dist/common/index.d.ts +9 -0
  35. package/dist/common/index.d.ts.map +1 -1
  36. package/dist/index.cdk.d.ts +2 -1
  37. package/dist/index.cdk.d.ts.map +1 -1
  38. package/dist/index.cdk.js +2 -1
  39. package/dist/rpc.d.ts.map +1 -1
  40. package/dist/rpc.js +12 -3
  41. package/dist/rpc.test.js +20 -0
  42. package/dist/scripts/telemetry.test.js +2 -0
  43. package/dist/telemetry/environment.d.ts.map +1 -1
  44. package/dist/telemetry/environment.js +3 -1
  45. package/dist/telemetry/telemetry.test.js +10 -0
  46. package/dist/version.d.ts +1 -1
  47. package/dist/version.d.ts.map +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +6 -1
  50. package/src/cdk/__fixtures__/import-meta-handler.ts +16 -0
  51. package/src/cdk/blocks-backend.test.ts +76 -0
  52. package/src/cdk/blocks-backend.ts +35 -6
  53. package/src/cdk/blocks-defaults.test.ts +25 -0
  54. package/src/cdk/blocks-defaults.ts +49 -0
  55. package/src/cdk/blocks-stack.test.ts +8 -1
  56. package/src/cdk/bundling.test.ts +90 -0
  57. package/src/cdk/bundling.ts +76 -0
  58. package/src/cdk/compute/compute.ts +37 -0
  59. package/src/cdk/index.ts +94 -19
  60. package/src/cdk/internal.ts +29 -0
  61. package/src/cdk/mixins.test.ts +56 -1
  62. package/src/cdk/mixins.ts +32 -7
  63. package/src/common/index.ts +9 -0
  64. package/src/index.cdk.ts +5 -1
  65. package/src/rpc.test.ts +22 -0
  66. package/src/rpc.ts +19 -3
  67. package/src/scripts/telemetry.test.ts +2 -0
  68. package/src/telemetry/environment.ts +3 -1
  69. package/src/telemetry/telemetry.test.ts +12 -0
  70. package/src/version.ts +1 -1
@@ -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';
@@ -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;AACxM,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"}
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,CA0ChE;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"}
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: Array.isArray(parsed.params)
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([
@@ -23,6 +23,8 @@ const NO_CI_ENV = {
23
23
  TF_BUILD: '',
24
24
  BITBUCKET_BUILD_NUMBER: '',
25
25
  BUILDKITE: '',
26
+ RENDER: '',
27
+ TASKCLUSTER_ROOT_URL: '',
26
28
  AWS_BLOCKS_DISABLE_TELEMETRY: '',
27
29
  };
28
30
  function createTmpDir() {
@@ -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,CAc9B;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"}
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.18";
1
+ export declare const CORE_VERSION = "0.2.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,WAAW,CAAC"}
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.1.18';
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.1.18",
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, exactly as they did on the auto-generated NodejsFunction role.
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
- bundling: {
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}`);