@aws-blocks/core 0.1.18 → 0.3.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 +46 -9
- package/dist/cdk/blocks-backend.d.ts.map +1 -1
- package/dist/cdk/blocks-backend.js +66 -67
- package/dist/cdk/blocks-backend.test.js +114 -56
- package/dist/cdk/blocks-defaults.d.ts +70 -0
- package/dist/cdk/blocks-defaults.d.ts.map +1 -0
- package/dist/cdk/blocks-defaults.js +27 -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 +24 -0
- package/dist/cdk/blocks-stack.test.js +74 -31
- 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/compute/default-compute-factory.d.ts +33 -0
- package/dist/cdk/compute/default-compute-factory.d.ts.map +1 -0
- package/dist/cdk/compute/default-compute-factory.js +3 -0
- package/dist/cdk/index.d.ts +92 -12
- package/dist/cdk/index.d.ts.map +1 -1
- package/dist/cdk/index.js +141 -25
- package/dist/cdk/internal.d.ts +25 -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/hosting-secrets.d.ts +48 -0
- package/dist/hosting-secrets.d.ts.map +1 -0
- package/dist/hosting-secrets.js +57 -0
- package/dist/hosting-secrets.test.d.ts +2 -0
- package/dist/hosting-secrets.test.d.ts.map +1 -0
- package/dist/hosting-secrets.test.js +81 -0
- package/dist/hosting.d.ts +88 -6
- package/dist/hosting.d.ts.map +1 -1
- package/dist/hosting.js +83 -24
- package/dist/hosting.test.js +158 -10
- package/dist/index.cdk.d.ts +13 -11
- package/dist/index.cdk.d.ts.map +1 -1
- package/dist/index.cdk.js +13 -8
- package/dist/index.d.ts +8 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/lambda-handler.test.js +66 -0
- package/dist/pipeline/index.d.ts +24 -2
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +41 -1
- package/dist/pipeline.test.d.ts +2 -0
- package/dist/pipeline.test.d.ts.map +1 -0
- package/dist/pipeline.test.js +47 -0
- package/dist/rpc.d.ts +21 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +46 -3
- package/dist/rpc.test.js +58 -1
- package/dist/scripts/config.d.ts +15 -0
- package/dist/scripts/config.d.ts.map +1 -0
- package/dist/scripts/config.js +29 -0
- package/dist/scripts/deploy.d.ts.map +1 -1
- package/dist/scripts/deploy.js +4 -0
- package/dist/scripts/dev-server.d.ts +8 -0
- package/dist/scripts/dev-server.d.ts.map +1 -1
- package/dist/scripts/dev-server.js +31 -0
- package/dist/scripts/generate-client.d.ts.map +1 -1
- package/dist/scripts/generate-client.js +9 -4
- package/dist/scripts/generate-client.test.js +19 -4
- package/dist/scripts/index.d.ts +13 -10
- package/dist/scripts/index.d.ts.map +1 -1
- package/dist/scripts/index.js +11 -8
- package/dist/scripts/preflight-credentials.d.ts +30 -0
- package/dist/scripts/preflight-credentials.d.ts.map +1 -0
- package/dist/scripts/preflight-credentials.js +108 -0
- package/dist/scripts/preflight-credentials.test.d.ts +2 -0
- package/dist/scripts/preflight-credentials.test.d.ts.map +1 -0
- package/dist/scripts/preflight-credentials.test.js +77 -0
- package/dist/scripts/sandbox-args.test.d.ts +2 -0
- package/dist/scripts/sandbox-args.test.d.ts.map +1 -0
- package/dist/scripts/sandbox-args.test.js +77 -0
- package/dist/scripts/sandbox.d.ts +52 -0
- package/dist/scripts/sandbox.d.ts.map +1 -1
- package/dist/scripts/sandbox.js +92 -15
- package/dist/scripts/secret.d.ts +15 -0
- package/dist/scripts/secret.d.ts.map +1 -0
- package/dist/scripts/secret.js +29 -0
- package/dist/scripts/secret.test.d.ts +2 -0
- package/dist/scripts/secret.test.d.ts.map +1 -0
- package/dist/scripts/secret.test.js +28 -0
- package/dist/scripts/telemetry.test.js +2 -0
- package/dist/scripts/typegen.d.ts +15 -0
- package/dist/scripts/typegen.d.ts.map +1 -0
- package/dist/scripts/typegen.js +16 -0
- package/dist/secret-naming.d.ts +58 -0
- package/dist/secret-naming.d.ts.map +1 -0
- package/dist/secret-naming.js +67 -0
- package/dist/secret-naming.test.d.ts +2 -0
- package/dist/secret-naming.test.d.ts.map +1 -0
- package/dist/secret-naming.test.js +40 -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 +7 -1
- package/src/cdk/__fixtures__/import-meta-handler.ts +16 -0
- package/src/cdk/blocks-backend.test.ts +308 -237
- package/src/cdk/blocks-backend.ts +98 -77
- package/src/cdk/blocks-defaults.test.ts +27 -0
- package/src/cdk/blocks-defaults.ts +75 -0
- package/src/cdk/blocks-stack.test.ts +160 -110
- 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/compute/default-compute-factory.ts +37 -0
- package/src/cdk/index.ts +178 -27
- package/src/cdk/internal.ts +30 -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/hosting-secrets.test.ts +106 -0
- package/src/hosting-secrets.ts +106 -0
- package/src/hosting.test.ts +244 -63
- package/src/hosting.ts +180 -68
- package/src/index.cdk.ts +79 -36
- package/src/index.ts +35 -16
- package/src/lambda-handler.test.ts +74 -0
- package/src/pipeline/index.ts +64 -11
- package/src/pipeline.test.ts +55 -0
- package/src/rpc.test.ts +66 -1
- package/src/rpc.ts +60 -3
- package/src/scripts/config.ts +35 -0
- package/src/scripts/deploy.ts +5 -0
- package/src/scripts/dev-server.ts +40 -0
- package/src/scripts/generate-client.test.ts +43 -8
- package/src/scripts/generate-client.ts +70 -65
- package/src/scripts/index.ts +20 -17
- package/src/scripts/preflight-credentials.test.ts +110 -0
- package/src/scripts/preflight-credentials.ts +131 -0
- package/src/scripts/sandbox-args.test.ts +92 -0
- package/src/scripts/sandbox.ts +102 -15
- package/src/scripts/secret.test.ts +35 -0
- package/src/scripts/secret.ts +35 -0
- package/src/scripts/telemetry.test.ts +2 -0
- package/src/scripts/typegen.ts +18 -0
- package/src/secret-naming.test.ts +59 -0
- package/src/secret-naming.ts +99 -0
- package/src/telemetry/environment.ts +3 -1
- package/src/telemetry/telemetry.test.ts +12 -0
- package/src/version.ts +1 -1
package/dist/hosting.test.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
4
3
|
import assert from 'node:assert';
|
|
5
4
|
import * as fs from 'node:fs';
|
|
6
|
-
import * as path from 'node:path';
|
|
7
5
|
import * as os from 'node:os';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import { afterEach, beforeEach, describe, it } from 'node:test';
|
|
8
|
+
import { config, secret } from '@aws-blocks/hosting';
|
|
9
|
+
import { _setSynthExistsChecker } from '@aws-blocks/hosting/constructs';
|
|
8
10
|
import * as cdk from 'aws-cdk-lib';
|
|
9
11
|
import { App, Duration, Stack } from 'aws-cdk-lib';
|
|
10
|
-
import {
|
|
12
|
+
import { Match, Template } from 'aws-cdk-lib/assertions';
|
|
11
13
|
import { BLOCKS_RPC_PREFIX } from './constants.js';
|
|
12
14
|
import { Hosting } from './hosting.js';
|
|
13
15
|
import { clearRouteRegistry, registerRoute } from './raw-route.js';
|
|
@@ -84,6 +86,31 @@ describe('Hosting', () => {
|
|
|
84
86
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
85
87
|
clearRouteRegistry();
|
|
86
88
|
});
|
|
89
|
+
// ── Deploy-time existence check (key change 4) ───────────────
|
|
90
|
+
describe('environment marker existence check (Hosting.create)', () => {
|
|
91
|
+
it('rejects at deploy when a declared environment secret has no value', async () => {
|
|
92
|
+
createSpaBuildOutput(tmpDir);
|
|
93
|
+
const app = new App();
|
|
94
|
+
const stack = new Stack(app, 'MissingEnvSecretStack');
|
|
95
|
+
// Stub the synth existence probe to report "not set" — rejects before any
|
|
96
|
+
// CDK construction, so this needs no assets and no AWS.
|
|
97
|
+
_setSynthExistsChecker(async () => {
|
|
98
|
+
const e = new Error('missing');
|
|
99
|
+
e.name = 'ResourceNotFoundException';
|
|
100
|
+
throw e;
|
|
101
|
+
});
|
|
102
|
+
try {
|
|
103
|
+
await assert.rejects(Hosting.create(stack, 'Hosting', {
|
|
104
|
+
root: tmpDir,
|
|
105
|
+
api: MOCK_API,
|
|
106
|
+
environment: { MISSING_SECRET: secret('MISSING_SECRET') },
|
|
107
|
+
}), /MISSING_SECRET.*not set/s);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
_setSynthExistsChecker(null);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
87
114
|
// ── SPA tests ────────────────────────────────────────────────
|
|
88
115
|
describe('SPA mode', () => {
|
|
89
116
|
it('creates S3 bucket and CloudFront distribution', () => {
|
|
@@ -1092,8 +1119,7 @@ describe('Hosting', () => {
|
|
|
1092
1119
|
...(basePath !== undefined ? { basePath } : {}),
|
|
1093
1120
|
});
|
|
1094
1121
|
const tpl = Template.fromStack(stack).toJSON();
|
|
1095
|
-
const kvKeys = Object.entries(tpl.Resources).find(([id, r]) => r.Type === 'AWS::CloudFormation::CustomResource' &&
|
|
1096
|
-
/RouteStoreKeys/.test(id));
|
|
1122
|
+
const kvKeys = Object.entries(tpl.Resources).find(([id, r]) => r.Type === 'AWS::CloudFormation::CustomResource' && /RouteStoreKeys/.test(id));
|
|
1097
1123
|
assert.ok(kvKeys, 'expected a RouteStoreKeys custom resource');
|
|
1098
1124
|
const entries = JSON.parse(kvKeys[1].Properties.Entries);
|
|
1099
1125
|
const meta = JSON.parse(entries.meta);
|
|
@@ -1134,6 +1160,131 @@ describe('Hosting', () => {
|
|
|
1134
1160
|
`found DependsOn=${JSON.stringify(dependsOn)}`);
|
|
1135
1161
|
});
|
|
1136
1162
|
});
|
|
1163
|
+
// ── value() integration ─────────────────────────────────────────
|
|
1164
|
+
//
|
|
1165
|
+
// Runtime values: the store LOCATOR (never the value) is injected as a Lambda
|
|
1166
|
+
// env var, and the role is granted read + kms:Decrypt. The store is derived from
|
|
1167
|
+
// the marker's type — secret → Secrets Manager, config → SSM Parameter Store.
|
|
1168
|
+
// Domain markers resolve at synth time via Hosting.create().
|
|
1169
|
+
describe('secret() / config() integration', () => {
|
|
1170
|
+
it('secret() → Secrets Manager: injects the locator (not the value) + grants read+decrypt', () => {
|
|
1171
|
+
createNextjsBuildOutput(tmpDir);
|
|
1172
|
+
const app = new App();
|
|
1173
|
+
const stack = new Stack(app, 'SecretEnvStack');
|
|
1174
|
+
new Hosting(stack, 'Hosting', {
|
|
1175
|
+
root: tmpDir,
|
|
1176
|
+
customAdapter: createNextjsFixtureAdapter(tmpDir),
|
|
1177
|
+
api: MOCK_API,
|
|
1178
|
+
environment: { STRIPE_KEY: secret('STRIPE_KEY') },
|
|
1179
|
+
});
|
|
1180
|
+
const template = Template.fromStack(stack);
|
|
1181
|
+
// secret → Secrets Manager: slash-free locator under the Blocks /blocks/secrets namespace.
|
|
1182
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
1183
|
+
Environment: {
|
|
1184
|
+
Variables: Match.objectLike({ HOSTING_SECRET_PARAM_STRIPE_KEY: 'blocks/secrets/STRIPE_KEY' }),
|
|
1185
|
+
},
|
|
1186
|
+
});
|
|
1187
|
+
// The plaintext value must NOT appear anywhere in the template.
|
|
1188
|
+
const json = JSON.stringify(template.toJSON());
|
|
1189
|
+
assert.ok(!json.includes('STRIPE_KEY_VALUE'), 'no value should be in the template');
|
|
1190
|
+
// The role has secretsmanager:GetSecretValue scoped to the secret + kms:Decrypt.
|
|
1191
|
+
template.hasResourceProperties('AWS::IAM::Policy', {
|
|
1192
|
+
PolicyDocument: {
|
|
1193
|
+
Statement: Match.arrayWith([
|
|
1194
|
+
Match.objectLike({ Action: 'secretsmanager:GetSecretValue' }),
|
|
1195
|
+
Match.objectLike({
|
|
1196
|
+
Action: 'kms:Decrypt',
|
|
1197
|
+
Condition: { StringEquals: Match.objectLike({ 'kms:ViaService': Match.anyValue() }) },
|
|
1198
|
+
}),
|
|
1199
|
+
]),
|
|
1200
|
+
},
|
|
1201
|
+
});
|
|
1202
|
+
});
|
|
1203
|
+
it('threads secretStore { prefix, stage, cacheTtlSeconds } from core HostingProps to the wiring (B3)', () => {
|
|
1204
|
+
createNextjsBuildOutput(tmpDir);
|
|
1205
|
+
const app = new App();
|
|
1206
|
+
const stack = new Stack(app, 'SecretStoreOverrideStack');
|
|
1207
|
+
new Hosting(stack, 'Hosting', {
|
|
1208
|
+
root: tmpDir,
|
|
1209
|
+
customAdapter: createNextjsFixtureAdapter(tmpDir),
|
|
1210
|
+
api: MOCK_API,
|
|
1211
|
+
environment: { STRIPE_KEY: secret('STRIPE_KEY') },
|
|
1212
|
+
// Custom prefix + stage + warm-cache TTL must all reach the leaf wiring.
|
|
1213
|
+
secretStore: { prefix: '/myapp/secrets', stage: 'prod', cacheTtlSeconds: 30 },
|
|
1214
|
+
});
|
|
1215
|
+
const template = Template.fromStack(stack);
|
|
1216
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
1217
|
+
Environment: {
|
|
1218
|
+
Variables: Match.objectLike({
|
|
1219
|
+
// custom prefix + stage (Secrets Manager → slash-free)
|
|
1220
|
+
HOSTING_SECRET_PARAM_STRIPE_KEY: 'myapp/secrets/prod/STRIPE_KEY',
|
|
1221
|
+
// shared fallback (no stage)
|
|
1222
|
+
HOSTING_SECRET_PARAM_STRIPE_KEY_FALLBACK: 'myapp/secrets/STRIPE_KEY',
|
|
1223
|
+
// warm-cache TTL for rotation without a cold start
|
|
1224
|
+
HOSTING_SECRET_CACHE_TTL: '30',
|
|
1225
|
+
}),
|
|
1226
|
+
},
|
|
1227
|
+
});
|
|
1228
|
+
});
|
|
1229
|
+
it('config() → SSM: HOSTING_CONFIG_PARAM_* (leading-slash) + ssm:GetParameter', () => {
|
|
1230
|
+
createNextjsBuildOutput(tmpDir);
|
|
1231
|
+
const app = new App();
|
|
1232
|
+
const stack = new Stack(app, 'ConfigEnvStack');
|
|
1233
|
+
new Hosting(stack, 'Hosting', {
|
|
1234
|
+
root: tmpDir,
|
|
1235
|
+
customAdapter: createNextjsFixtureAdapter(tmpDir),
|
|
1236
|
+
api: MOCK_API,
|
|
1237
|
+
environment: { FEATURE_FLAGS: config('FEATURE_FLAGS') },
|
|
1238
|
+
});
|
|
1239
|
+
const template = Template.fromStack(stack);
|
|
1240
|
+
template.hasResourceProperties('AWS::Lambda::Function', {
|
|
1241
|
+
Environment: {
|
|
1242
|
+
Variables: Match.objectLike({ HOSTING_CONFIG_PARAM_FEATURE_FLAGS: '/blocks/config/FEATURE_FLAGS' }),
|
|
1243
|
+
},
|
|
1244
|
+
});
|
|
1245
|
+
template.hasResourceProperties('AWS::IAM::Policy', {
|
|
1246
|
+
PolicyDocument: { Statement: Match.arrayWith([Match.objectLike({ Action: 'ssm:GetParameter' })]) },
|
|
1247
|
+
});
|
|
1248
|
+
});
|
|
1249
|
+
it('does not inject a plaintext env var for a runtime value', () => {
|
|
1250
|
+
createNextjsBuildOutput(tmpDir);
|
|
1251
|
+
const app = new App();
|
|
1252
|
+
const stack = new Stack(app, 'SecretNoPlaintextStack');
|
|
1253
|
+
new Hosting(stack, 'Hosting', {
|
|
1254
|
+
root: tmpDir,
|
|
1255
|
+
customAdapter: createNextjsFixtureAdapter(tmpDir),
|
|
1256
|
+
api: MOCK_API,
|
|
1257
|
+
environment: { FLAG: 'on', STRIPE_KEY: secret('STRIPE_KEY') },
|
|
1258
|
+
});
|
|
1259
|
+
const template = Template.fromStack(stack);
|
|
1260
|
+
const fns = template.findResources('AWS::Lambda::Function');
|
|
1261
|
+
for (const fn of Object.values(fns)) {
|
|
1262
|
+
const vars = (fn.Properties?.Environment?.Variables ?? {});
|
|
1263
|
+
assert.strictEqual(vars.STRIPE_KEY, undefined, 'value key must not be a plaintext env var');
|
|
1264
|
+
}
|
|
1265
|
+
});
|
|
1266
|
+
it('rejects a runtime value whose key mismatches the env var name', () => {
|
|
1267
|
+
createNextjsBuildOutput(tmpDir);
|
|
1268
|
+
const app = new App();
|
|
1269
|
+
const stack = new Stack(app, 'SecretMismatchStack');
|
|
1270
|
+
assert.throws(() => new Hosting(stack, 'Hosting', {
|
|
1271
|
+
root: tmpDir,
|
|
1272
|
+
customAdapter: createNextjsFixtureAdapter(tmpDir),
|
|
1273
|
+
api: MOCK_API,
|
|
1274
|
+
environment: { STRIPE_KEY: secret('OTHER') },
|
|
1275
|
+
}), /must match the environment variable name/);
|
|
1276
|
+
});
|
|
1277
|
+
it('throws if a domain marker is used with the sync constructor', () => {
|
|
1278
|
+
createSpaBuildOutput(tmpDir);
|
|
1279
|
+
const app = new App();
|
|
1280
|
+
const stack = new Stack(app, 'SecretDomainSyncStack');
|
|
1281
|
+
assert.throws(() => new Hosting(stack, 'Hosting', {
|
|
1282
|
+
root: tmpDir,
|
|
1283
|
+
api: MOCK_API,
|
|
1284
|
+
domain: { domainName: config('DOMAIN_PROD') },
|
|
1285
|
+
}), /requires async resolution/);
|
|
1286
|
+
});
|
|
1287
|
+
});
|
|
1137
1288
|
describe('config.json stale-placeholder guard (#173)', () => {
|
|
1138
1289
|
// Helper: pull every BucketDeployment custom resource's Properties.
|
|
1139
1290
|
const bucketDeployments = (stack) => {
|
|
@@ -1169,8 +1320,7 @@ describe('Hosting', () => {
|
|
|
1169
1320
|
directive.includes('s-maxage=31536000') &&
|
|
1170
1321
|
!excludes(p).includes('.blocks-sandbox/config.json'));
|
|
1171
1322
|
});
|
|
1172
|
-
assert.strictEqual(leaks.length, 0, 'no mutable-tier deployment may apply s-maxage=31536000 to ' +
|
|
1173
|
-
'.blocks-sandbox/config.json');
|
|
1323
|
+
assert.strictEqual(leaks.length, 0, 'no mutable-tier deployment may apply s-maxage=31536000 to ' + '.blocks-sandbox/config.json');
|
|
1174
1324
|
});
|
|
1175
1325
|
it('registers the placeholder as a no-cache path even for a static-only site (no api)', () => {
|
|
1176
1326
|
// The placeholder is always written (step 5), so its no-cache
|
|
@@ -1201,9 +1351,7 @@ describe('Hosting', () => {
|
|
|
1201
1351
|
// Assert via Template + Match so a CDK property rename fails loudly here
|
|
1202
1352
|
// rather than silently skipping a structural-heuristic lookup.
|
|
1203
1353
|
Template.fromStack(stack).hasResourceProperties('Custom::CDKBucketDeployment', Match.objectLike({
|
|
1204
|
-
DistributionPaths: Match.arrayWith([
|
|
1205
|
-
Match.stringLikeRegexp('^/builds/.+/\\.blocks-sandbox/\\*$'),
|
|
1206
|
-
]),
|
|
1354
|
+
DistributionPaths: Match.arrayWith([Match.stringLikeRegexp('^/builds/.+/\\.blocks-sandbox/\\*$')]),
|
|
1207
1355
|
}));
|
|
1208
1356
|
});
|
|
1209
1357
|
});
|
package/dist/index.cdk.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
1
|
+
export { type ConfigValue, config, DEFAULT_CONFIG_PARAMETER_PREFIX, DEFAULT_SECRET_PARAMETER_PREFIX, isConfig, isManagedValue, isSecret, type ManagedValue, type SecretValue, secret, type ValueKind, } from '@aws-blocks/hosting';
|
|
2
|
+
export { type ApiHandler, ApiNamespace, type BlocksContext } from './api.js';
|
|
3
|
+
export { BlocksBackend, type BlocksBackendProps, type BlocksDefaults, BlocksPresets, BlocksStack, blocksNodejsBundling, type CoreBlocksBackendProps, type CoreBlocksStackProps, DEFAULT_NODE_RUNTIME, finalizeConfigRegistry, registerConfig, SandboxDisableDeletionProtection, Scope, SHARED_HANDLER_TIMEOUT_SECONDS, synthGuard, } from './cdk/index.js';
|
|
4
|
+
export { _resetConfigCache, getConfig, getConfigSync, loadConfigToProcessEnv, preloadConfig } from './common/config.js';
|
|
5
5
|
export { BlocksStackProps } from './common/index.js';
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
6
|
+
export { _resetSdkRegistry, getAllSdkIdentifiers, getSdkIdentifiers, registerSdkIdentifiers, } from './common/sdk-registry.js';
|
|
7
|
+
export { BLOCKS_AUTH_PREFIX, BLOCKS_RPC_PREFIX } from './constants.js';
|
|
8
|
+
export { ApiError, DEFAULT_API_ERROR_NAME, hasAuthError, isBlocksError } from './errors.js';
|
|
9
|
+
export { type BlocksStackApi, type ComputeConfig, type FrameworkType, Hosting, type HostingDomainConfig, type HostingProps, type HostingWafConfig, } from './hosting.js';
|
|
10
|
+
export { EventSourceMapping } from './lambda-handler.js';
|
|
11
|
+
export { __PIPELINE_STAGE_SCOPE__, type BranchConfig, DeployStage, type DeployStageProps, Pipeline, type PipelineProps, type PipelineSourceConfig, type PipelineStageConfig, type PipelineSynthConfig, } from './pipeline/index.js';
|
|
12
|
+
export { type HttpMethod, RawRoute, RawRouteErrors, type RawRouteOptions, } from './raw-route.cdk.js';
|
|
13
|
+
export { clearRouteRegistry, getRegisteredRoutes, lockRouteRegistry, matchRoute, type RegisteredRoute, registerRoute, unlockRouteRegistry, } from './raw-route.js';
|
|
14
|
+
export { BLOCKS_CONFIG_PARAMETER_PREFIX, BLOCKS_SECRET_PARAMETER_PREFIX, blocksConfigParameterName, blocksSecretParameterName, } from './secret-naming.js';
|
|
13
15
|
//# sourceMappingURL=index.cdk.d.ts.map
|
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":"
|
|
1
|
+
{"version":3,"file":"index.cdk.d.ts","sourceRoot":"","sources":["../src/index.cdk.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,WAAW,EAChB,MAAM,EACN,+BAA+B,EAC/B,+BAA+B,EAC/B,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,MAAM,EACN,KAAK,SAAS,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,UAAU,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EACN,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,cAAc,EACd,gCAAgC,EAChC,KAAK,EACL,8BAA8B,EAC9B,UAAU,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACN,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,OAAO,EACP,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,gBAAgB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACN,wBAAwB,EACxB,KAAK,YAAY,EACjB,WAAW,EACX,KAAK,gBAAgB,EACrB,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,UAAU,EACf,QAAQ,EACR,cAAc,EACd,KAAK,eAAe,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,KAAK,eAAe,EACpB,aAAa,EACb,mBAAmB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,8BAA8B,EAC9B,8BAA8B,EAC9B,yBAAyB,EACzB,yBAAyB,GACzB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.cdk.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// Declare functions for infra (secret/config). The runtime getters
|
|
4
|
+
// (getSecret/getConfig) are imported from '@aws-blocks/hosting' — core's own
|
|
5
|
+
// getConfig (backend config loader, above) owns that name here.
|
|
6
|
+
export { config, DEFAULT_CONFIG_PARAMETER_PREFIX, DEFAULT_SECRET_PARAMETER_PREFIX, isConfig, isManagedValue, isSecret, secret, } from '@aws-blocks/hosting';
|
|
3
7
|
export { ApiNamespace } from './api.js';
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export { BlocksStack, Scope, SandboxDisableDeletionProtection, BlocksBackend, registerConfig, finalizeConfigRegistry, synthGuard, DEFAULT_NODE_RUNTIME } from './cdk/index.js';
|
|
8
|
+
export { BlocksBackend, BlocksPresets, BlocksStack, blocksNodejsBundling, DEFAULT_NODE_RUNTIME, finalizeConfigRegistry, registerConfig, SandboxDisableDeletionProtection, Scope, SHARED_HANDLER_TIMEOUT_SECONDS, synthGuard, } from './cdk/index.js';
|
|
9
|
+
export { _resetConfigCache, getConfig, getConfigSync, loadConfigToProcessEnv, preloadConfig } from './common/config.js';
|
|
10
|
+
export { _resetSdkRegistry, getAllSdkIdentifiers, getSdkIdentifiers, registerSdkIdentifiers, } from './common/sdk-registry.js';
|
|
11
|
+
export { BLOCKS_AUTH_PREFIX, BLOCKS_RPC_PREFIX } from './constants.js';
|
|
12
|
+
export { ApiError, DEFAULT_API_ERROR_NAME, hasAuthError, isBlocksError } from './errors.js';
|
|
10
13
|
export { Hosting, } from './hosting.js';
|
|
14
|
+
export { EventSourceMapping } from './lambda-handler.js';
|
|
15
|
+
export { __PIPELINE_STAGE_SCOPE__, DeployStage, Pipeline, } from './pipeline/index.js';
|
|
11
16
|
export { RawRoute, RawRouteErrors, } from './raw-route.cdk.js';
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
17
|
+
export { clearRouteRegistry, getRegisteredRoutes, lockRouteRegistry, matchRoute, registerRoute, unlockRouteRegistry, } from './raw-route.js';
|
|
18
|
+
export { BLOCKS_CONFIG_PARAMETER_PREFIX, BLOCKS_SECRET_PARAMETER_PREFIX, blocksConfigParameterName, blocksSecretParameterName, } from './secret-naming.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export { Scope, type ScopeOptions, type ScopeParent
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
1
|
+
export { type ConfigValue, config, isConfig, isManagedValue, isSecret, type ManagedValue, type SecretValue, secret, type ValueKind, } from '@aws-blocks/hosting';
|
|
2
|
+
export { type ApiHandler, ApiNamespace, type BlocksContext } from './api.js';
|
|
3
|
+
export { _resetConfigCache, getConfig, getConfigSync, loadConfigToProcessEnv, preloadConfig } from './common/config.js';
|
|
4
|
+
export { type BuildingBlockMeta, Scope, type ScopeOptions, type ScopeParent } from './common/index.js';
|
|
5
|
+
export { _resetSdkRegistry, getAllSdkIdentifiers, getSdkIdentifiers, registerSdkIdentifiers, } from './common/sdk-registry.js';
|
|
6
|
+
export { BLOCKS_AUTH_PREFIX, BLOCKS_RPC_PREFIX } from './constants.js';
|
|
7
|
+
export { ApiError, DEFAULT_API_ERROR_NAME, hasAuthError, isBlocksError } from './errors.js';
|
|
8
|
+
export { clearRouteRegistry, getRegisteredRoutes, type HttpMethod, lockRouteRegistry, matchRoute, RawRouteErrors, type RawRouteOptions, type RegisteredRoute, registerRoute, unlockRouteRegistry, } from './raw-route.js';
|
|
8
9
|
export { RawRoute } from './raw-route.mock.js';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACN,KAAK,WAAW,EAChB,MAAM,EACN,QAAQ,EACR,cAAc,EACd,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,MAAM,EACN,KAAK,SAAS,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,UAAU,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxH,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvG,OAAO,EACN,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,UAAU,EACf,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,aAAa,EACb,mBAAmB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// secret()/config() declare markers (CDK-free subpath). The runtime getters
|
|
4
|
+
// getSecret()/getConfig() are imported from '@aws-blocks/hosting' directly —
|
|
5
|
+
// core already exports a backend `getConfig` (config loader) under this name.
|
|
6
|
+
export { config, isConfig, isManagedValue, isSecret, secret, } from '@aws-blocks/hosting';
|
|
3
7
|
export { ApiNamespace } from './api.js';
|
|
4
|
-
export {
|
|
5
|
-
export { ApiError, isBlocksError, hasAuthError, DEFAULT_API_ERROR_NAME } from './errors.js';
|
|
8
|
+
export { _resetConfigCache, getConfig, getConfigSync, loadConfigToProcessEnv, preloadConfig } from './common/config.js';
|
|
6
9
|
export { Scope } from './common/index.js';
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
+
export { _resetSdkRegistry, getAllSdkIdentifiers, getSdkIdentifiers, registerSdkIdentifiers, } from './common/sdk-registry.js';
|
|
11
|
+
export { BLOCKS_AUTH_PREFIX, BLOCKS_RPC_PREFIX } from './constants.js';
|
|
12
|
+
export { ApiError, DEFAULT_API_ERROR_NAME, hasAuthError, isBlocksError } from './errors.js';
|
|
13
|
+
export { clearRouteRegistry, getRegisteredRoutes, lockRouteRegistry, matchRoute, RawRouteErrors, registerRoute, unlockRouteRegistry, } from './raw-route.js';
|
|
10
14
|
export { RawRoute } from './raw-route.mock.js';
|
|
@@ -890,3 +890,69 @@ describe('createLambdaHandler — sandbox forwarded-host reaches the route', ()
|
|
|
890
890
|
assert.strictEqual(capturedHost, 'abc123.execute-api.us-east-1.amazonaws.com');
|
|
891
891
|
});
|
|
892
892
|
});
|
|
893
|
+
// ── SQS partial batch failure tests ─────────────────────────────────────────
|
|
894
|
+
/**
|
|
895
|
+
* These pin the runtime half of the bb-async-job BatchSize fix: with a batch
|
|
896
|
+
* larger than 1, failing records must be reported individually via
|
|
897
|
+
* `batchItemFailures` so SQS retries only those messages. If this response
|
|
898
|
+
* shape regresses, every successful sibling message in a partially-failing
|
|
899
|
+
* batch would be redelivered (or, worse, the failures silently dropped).
|
|
900
|
+
*/
|
|
901
|
+
function makeSqsBatchEvent(count) {
|
|
902
|
+
return {
|
|
903
|
+
Records: Array.from({ length: count }, (_, i) => ({
|
|
904
|
+
eventSource: 'aws:sqs',
|
|
905
|
+
eventSourceARN: 'arn:aws:sqs:us-east-1:123456789012:my-queue',
|
|
906
|
+
messageId: `msg-${i}`,
|
|
907
|
+
body: JSON.stringify({ n: i }),
|
|
908
|
+
})),
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
describe('handleEventSourceRecords — SQS partial batch responses', () => {
|
|
912
|
+
it('reports only the failed records of a mixed-success 10-record batch', async () => {
|
|
913
|
+
const processed = [];
|
|
914
|
+
const handlers = new Map();
|
|
915
|
+
handlers.set('aws:sqs:my-queue', async (record) => {
|
|
916
|
+
const { n } = JSON.parse(record.body);
|
|
917
|
+
if (n % 3 === 0)
|
|
918
|
+
throw new Error(`boom on ${n}`);
|
|
919
|
+
processed.push(n);
|
|
920
|
+
});
|
|
921
|
+
globalThis.__BLOCKS_LAMBDA_EVENT_HANDLERS__ = handlers;
|
|
922
|
+
try {
|
|
923
|
+
const handler = createLambdaHandler(async () => ({}));
|
|
924
|
+
const result = await handler(makeSqsBatchEvent(10));
|
|
925
|
+
assert.deepStrictEqual(result.batchItemFailures.map((f) => f.itemIdentifier).sort(), ['msg-0', 'msg-3', 'msg-6', 'msg-9']);
|
|
926
|
+
assert.deepStrictEqual(processed.sort((a, b) => a - b), [1, 2, 4, 5, 7, 8]);
|
|
927
|
+
}
|
|
928
|
+
finally {
|
|
929
|
+
delete globalThis.__BLOCKS_LAMBDA_EVENT_HANDLERS__;
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
it('returns no batchItemFailures when every record in the batch succeeds', async () => {
|
|
933
|
+
const handlers = new Map();
|
|
934
|
+
handlers.set('aws:sqs:my-queue', async () => { });
|
|
935
|
+
globalThis.__BLOCKS_LAMBDA_EVENT_HANDLERS__ = handlers;
|
|
936
|
+
try {
|
|
937
|
+
const handler = createLambdaHandler(async () => ({}));
|
|
938
|
+
const result = await handler(makeSqsBatchEvent(10));
|
|
939
|
+
assert.deepStrictEqual(result, {});
|
|
940
|
+
}
|
|
941
|
+
finally {
|
|
942
|
+
delete globalThis.__BLOCKS_LAMBDA_EVENT_HANDLERS__;
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
it('reports all records when the whole batch fails (no silent drop)', async () => {
|
|
946
|
+
const handlers = new Map();
|
|
947
|
+
handlers.set('aws:sqs:my-queue', async () => { throw new Error('always'); });
|
|
948
|
+
globalThis.__BLOCKS_LAMBDA_EVENT_HANDLERS__ = handlers;
|
|
949
|
+
try {
|
|
950
|
+
const handler = createLambdaHandler(async () => ({}));
|
|
951
|
+
const result = await handler(makeSqsBatchEvent(10));
|
|
952
|
+
assert.strictEqual(result.batchItemFailures.length, 10);
|
|
953
|
+
}
|
|
954
|
+
finally {
|
|
955
|
+
delete globalThis.__BLOCKS_LAMBDA_EVENT_HANDLERS__;
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
});
|
package/dist/pipeline/index.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { __PIPELINE_STAGE_SCOPE__, DeployStage, Pipeline as LeafPipeline } from '@aws-blocks/pipeline';
|
|
2
|
+
import type { BranchConfig, DeployStageProps, PipelineProps, PipelineSourceConfig, PipelineStageConfig, PipelineSynthConfig } from '@aws-blocks/pipeline';
|
|
3
|
+
import type { Construct } from 'constructs';
|
|
4
|
+
export { __PIPELINE_STAGE_SCOPE__, DeployStage };
|
|
5
|
+
export type { BranchConfig, DeployStageProps, PipelineProps, PipelineSourceConfig, PipelineStageConfig, PipelineSynthConfig, };
|
|
6
|
+
/**
|
|
7
|
+
* Blocks `Pipeline` — the framework-neutral `@aws-blocks/pipeline` construct with
|
|
8
|
+
* the Blocks value namespace pinned. It defaults `secretStore` / `configStore` to
|
|
9
|
+
* `/blocks/secrets` and `/blocks/config` (the prefixes the Blocks `secret` /
|
|
10
|
+
* `config` CLIs write), mirroring how the Blocks `Hosting` block pins the same
|
|
11
|
+
* namespace — so a value set with `npm run secret`/`config` is the value the
|
|
12
|
+
* pipeline reads. Pass `secretStore` / `configStore` to override.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link https://github.com/aws-devtools-labs/aws-blocks/blob/main/packages/pipeline/README.md}
|
|
15
|
+
*/
|
|
16
|
+
export declare class Pipeline<TConfig = Record<string, unknown>> extends LeafPipeline<TConfig> {
|
|
17
|
+
constructor(scope: Construct, id: string, props: PipelineProps<TConfig>);
|
|
18
|
+
/**
|
|
19
|
+
* Async constructor — required when `source.connectionArn` is a `config()`
|
|
20
|
+
* marker (resolved at synth time). Pins the Blocks namespace, then delegates to
|
|
21
|
+
* the leaf {@link LeafPipeline.create}.
|
|
22
|
+
*/
|
|
23
|
+
static create<TConfig = Record<string, unknown>>(scope: Construct, id: string, props: PipelineProps<TConfig>): Promise<LeafPipeline<TConfig>>;
|
|
24
|
+
}
|
|
3
25
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,CAAC;AACjD,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACnB,CAAC;AAkBF;;;;;;;;;GASG;AACH,qBAAa,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAY,CAAC,OAAO,CAAC;gBACzE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC;IAIvE;;;;OAIG;WACU,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,KAAK,EAAE,SAAS,EAChB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;CAGjC"}
|
package/dist/pipeline/index.js
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
3
|
+
import { __PIPELINE_STAGE_SCOPE__, DeployStage, Pipeline as LeafPipeline } from '@aws-blocks/pipeline';
|
|
4
|
+
import { blocksStoreConfig } from '../secret-naming.js';
|
|
5
|
+
export { __PIPELINE_STAGE_SCOPE__, DeployStage };
|
|
6
|
+
/**
|
|
7
|
+
* Merge the Blocks `/blocks/*` namespace as the DEFAULT store config, so a
|
|
8
|
+
* Blocks pipeline resolves `connectionArn` / `buildSecrets` from the same place
|
|
9
|
+
* the Blocks CLI (`npm run secret` / `npm run config`) writes. Per-kind and
|
|
10
|
+
* shallow: any field the caller sets (a custom `prefix`, a `stage`, a
|
|
11
|
+
* `cacheTtlSeconds`) wins over the Blocks default.
|
|
12
|
+
*/
|
|
13
|
+
function withBlocksDefaults(props) {
|
|
14
|
+
const blocks = blocksStoreConfig();
|
|
15
|
+
return {
|
|
16
|
+
...props,
|
|
17
|
+
secretStore: { ...blocks.secretStore, ...props.secretStore },
|
|
18
|
+
configStore: { ...blocks.configStore, ...props.configStore },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Blocks `Pipeline` — the framework-neutral `@aws-blocks/pipeline` construct with
|
|
23
|
+
* the Blocks value namespace pinned. It defaults `secretStore` / `configStore` to
|
|
24
|
+
* `/blocks/secrets` and `/blocks/config` (the prefixes the Blocks `secret` /
|
|
25
|
+
* `config` CLIs write), mirroring how the Blocks `Hosting` block pins the same
|
|
26
|
+
* namespace — so a value set with `npm run secret`/`config` is the value the
|
|
27
|
+
* pipeline reads. Pass `secretStore` / `configStore` to override.
|
|
28
|
+
*
|
|
29
|
+
* @see {@link https://github.com/aws-devtools-labs/aws-blocks/blob/main/packages/pipeline/README.md}
|
|
30
|
+
*/
|
|
31
|
+
export class Pipeline extends LeafPipeline {
|
|
32
|
+
constructor(scope, id, props) {
|
|
33
|
+
super(scope, id, withBlocksDefaults(props));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Async constructor — required when `source.connectionArn` is a `config()`
|
|
37
|
+
* marker (resolved at synth time). Pins the Blocks namespace, then delegates to
|
|
38
|
+
* the leaf {@link LeafPipeline.create}.
|
|
39
|
+
*/
|
|
40
|
+
static async create(scope, id, props) {
|
|
41
|
+
return LeafPipeline.create(scope, id, withBlocksDefaults(props));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.test.d.ts","sourceRoot":"","sources":["../src/pipeline.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
import { afterEach, describe, it } from 'node:test';
|
|
5
|
+
import { _setSynthSecretFetcher } from '@aws-blocks/hosting/constructs';
|
|
6
|
+
import { config } from '@aws-blocks/hosting';
|
|
7
|
+
import { App, Stack } from 'aws-cdk-lib';
|
|
8
|
+
import { Pipeline } from './pipeline/index.js';
|
|
9
|
+
const MOCK_CONNECTION_ARN = 'arn:aws:codeconnections:us-east-1:123456789012:connection/test-connection-id';
|
|
10
|
+
function minimalStageFactory(scope, stageConfig) {
|
|
11
|
+
new Stack(scope, 'AppStack', { env: stageConfig.env });
|
|
12
|
+
}
|
|
13
|
+
// B2: the core Pipeline wrapper must resolve values from the SAME namespace the
|
|
14
|
+
// Blocks CLI writes (`/blocks/*`), not the leaf-neutral `/hosting/*` — otherwise
|
|
15
|
+
// `npm run config -- set CONNECTION_ARN` writes one name and the deploy reads
|
|
16
|
+
// another. The leaf default is `/hosting/config`; the wrapper must pin `/blocks/config`.
|
|
17
|
+
void describe('core Pipeline pins the Blocks namespace', () => {
|
|
18
|
+
afterEach(() => _setSynthSecretFetcher(null));
|
|
19
|
+
void it('resolves a config() connectionArn under /blocks/config by default', async () => {
|
|
20
|
+
const seen = [];
|
|
21
|
+
_setSynthSecretFetcher(async (locator) => {
|
|
22
|
+
seen.push(locator);
|
|
23
|
+
return MOCK_CONNECTION_ARN;
|
|
24
|
+
});
|
|
25
|
+
await Pipeline.create(new App(), 'BlocksPipeline', {
|
|
26
|
+
source: { repo: 'my-org/my-app', connectionArn: config('CONNECTION_ARN') },
|
|
27
|
+
branches: [{ branch: 'main', stages: [{ name: 'prod' }] }],
|
|
28
|
+
stageFactory: minimalStageFactory,
|
|
29
|
+
});
|
|
30
|
+
// The Blocks CLI writes /blocks/config/CONNECTION_ARN; the wrapper must read it there.
|
|
31
|
+
assert.deepStrictEqual(seen, ['/blocks/config/CONNECTION_ARN']);
|
|
32
|
+
});
|
|
33
|
+
void it('lets the caller override the pinned prefix', async () => {
|
|
34
|
+
const seen = [];
|
|
35
|
+
_setSynthSecretFetcher(async (locator) => {
|
|
36
|
+
seen.push(locator);
|
|
37
|
+
return MOCK_CONNECTION_ARN;
|
|
38
|
+
});
|
|
39
|
+
await Pipeline.create(new App(), 'OverridePipeline', {
|
|
40
|
+
source: { repo: 'my-org/my-app', connectionArn: config('CONNECTION_ARN') },
|
|
41
|
+
branches: [{ branch: 'main', stages: [{ name: 'prod' }] }],
|
|
42
|
+
stageFactory: minimalStageFactory,
|
|
43
|
+
configStore: { prefix: '/myapp/config' },
|
|
44
|
+
});
|
|
45
|
+
assert.deepStrictEqual(seen, ['/myapp/config/CONNECTION_ARN']);
|
|
46
|
+
});
|
|
47
|
+
});
|
package/dist/rpc.d.ts
CHANGED
|
@@ -14,6 +14,27 @@ export type RpcParseResult = {
|
|
|
14
14
|
ok: false;
|
|
15
15
|
response: string;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Maximum accepted request-body size, in bytes (10 MiB).
|
|
19
|
+
*
|
|
20
|
+
* Matches the payload limit API Gateway enforces in production (~10 MB for a
|
|
21
|
+
* REST API). In prod an oversized body is rejected by API Gateway at the edge —
|
|
22
|
+
* before the Lambda is invoked — so this guard's rejection path effectively
|
|
23
|
+
* runs on the dev/mock server, where there is no edge to stop it: an oversized
|
|
24
|
+
* body would otherwise buffer and wedge the local database (e.g. PGlite). By
|
|
25
|
+
* enforcing the *same* limit locally, the dev server rejects the same oversized
|
|
26
|
+
* body prod would 413 at the edge, instead of failing only in one environment.
|
|
27
|
+
* Enforced in `parseRpcRequest`, the single choke point both the Lambda handler
|
|
28
|
+
* and the dev server route through.
|
|
29
|
+
*
|
|
30
|
+
* Note: this value is the Lambda + API Gateway limit. It lives here (in the
|
|
31
|
+
* compute-agnostic parser) because Lambda is the only compute path today. When
|
|
32
|
+
* a non-API-Gateway compute (e.g. container/ALB) is introduced, this should
|
|
33
|
+
* become compute-aware — sourced from / overridden by the compute layer (via
|
|
34
|
+
* the Compute `setEnv` config hook) rather than a fixed constant in `core` —
|
|
35
|
+
* since an ALB has a different payload limit. Tracked with the multi-compute work.
|
|
36
|
+
*/
|
|
37
|
+
export declare const MAX_RPC_BODY_BYTES: number;
|
|
17
38
|
/** Reserved JSON-RPC error codes. */
|
|
18
39
|
export declare const RpcErrorCode: {
|
|
19
40
|
readonly ParseError: -32700;
|
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;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AAEnD,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,CA6EhE;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"}
|