@pipeline-builder/pipeline-events 4.0.9 → 4.0.11
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/lib/auth.d.ts +14 -0
- package/lib/auth.js +99 -0
- package/lib/health.d.ts +13 -0
- package/lib/health.js +191 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.js +678 -930
- package/lib/parse.d.ts +40 -0
- package/lib/parse.js +150 -0
- package/lib/scm.d.ts +21 -0
- package/lib/scm.js +286 -0
- package/lib/tags.d.ts +18 -0
- package/lib/tags.js +125 -0
- package/lib/testing/exports.json +8 -0
- package/lib/util.d.ts +21 -0
- package/lib/util.js +43 -0
- package/package.json +16 -6
package/lib/tags.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { BoundedMap, CACHE_MAX_ENTRIES, log } from './util.js';
|
|
4
|
+
let codepipelineMod;
|
|
5
|
+
async function loadCodePipeline() {
|
|
6
|
+
if (!codepipelineMod)
|
|
7
|
+
codepipelineMod = (await import('@aws-sdk/client-codepipeline'));
|
|
8
|
+
return codepipelineMod;
|
|
9
|
+
}
|
|
10
|
+
// Tag resolution: pb.pipeline-id + pb.deploys.
|
|
11
|
+
// Pipelines are tagged at CDK synth with:
|
|
12
|
+
// pb.pipeline-id = <platform pipelineId>
|
|
13
|
+
// pb.deploys = <stage>:<env> pairs joined by '+', e.g.
|
|
14
|
+
// "Deploy-stg:staging+Deploy-prod:production"
|
|
15
|
+
// We resolve those tags from the live CodePipeline (region-aware). The ARN/account
|
|
16
|
+
// never leave AWS, so there's no masking. Cached per ARN (warm-container) to avoid
|
|
17
|
+
// hammering the ListTags API.
|
|
18
|
+
//
|
|
19
|
+
// Requires the Lambda execution role to allow `codepipeline:ListTagsForResource`.
|
|
20
|
+
// AccessDenied is a config error (alert loudly); a missing pb.pipeline-id tag is
|
|
21
|
+
// treated as "not yet registered" (skip).
|
|
22
|
+
const PIPELINE_ID_TAG = 'pb.pipeline-id';
|
|
23
|
+
const DEPLOYS_TAG = 'pb.deploys';
|
|
24
|
+
// Canonical per-pipeline org tag (applied at synth by pipeline-core). It is the
|
|
25
|
+
// RESOLVED org for every event of this pipeline — used to key the per-org GitHub
|
|
26
|
+
// token and to attribute ingest-health. orgId is a platform id, never an AWS
|
|
27
|
+
// account id, so it is safe to read/forward.
|
|
28
|
+
const ORG_ID_TAG = 'OrgId';
|
|
29
|
+
const clientsByRegion = new Map();
|
|
30
|
+
// `ts` lets BOTH outcomes expire: a negative (resolved-but-untagged) so a
|
|
31
|
+
// pipeline tagged AFTER its first event becomes resolvable, and a positive so a
|
|
32
|
+
// re-synth that changes `pb.deploys` (a stage renamed, an environment added) or
|
|
33
|
+
// `OrgId` is picked up without recycling the warm container — a lifetime cache
|
|
34
|
+
// would keep attributing deploys to stages that no longer exist.
|
|
35
|
+
const resolvedByArn = new BoundedMap(CACHE_MAX_ENTRIES);
|
|
36
|
+
const NEG_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
37
|
+
const POS_CACHE_TTL_MS = 15 * 60 * 1000;
|
|
38
|
+
/** Cap on commit/ref/environment fields — the ingest contract allows max 255. */
|
|
39
|
+
export const MAX_ATTR = 255;
|
|
40
|
+
/**
|
|
41
|
+
* Parse the `pb.deploys` tag value into a stage→environment map. The value is
|
|
42
|
+
* `<stage>:<env>` pairs joined by `+` (CodePipeline-tag-safe; no JSON). A stage
|
|
43
|
+
* present here is a deploy; its mapped environment is what the forwarder stamps on
|
|
44
|
+
* that stage's STAGE/ACTION events (DORA deploy attribution). Malformed pairs are
|
|
45
|
+
* skipped defensively.
|
|
46
|
+
*/
|
|
47
|
+
function parseDeploys(value) {
|
|
48
|
+
const map = new Map();
|
|
49
|
+
if (!value)
|
|
50
|
+
return map;
|
|
51
|
+
for (const pair of value.split('+')) {
|
|
52
|
+
const idx = pair.indexOf(':');
|
|
53
|
+
if (idx <= 0)
|
|
54
|
+
continue;
|
|
55
|
+
const stage = pair.slice(0, idx).trim();
|
|
56
|
+
const env = pair.slice(idx + 1).trim();
|
|
57
|
+
if (stage && env)
|
|
58
|
+
map.set(stage, env.slice(0, MAX_ATTR));
|
|
59
|
+
}
|
|
60
|
+
return map;
|
|
61
|
+
}
|
|
62
|
+
async function pipelineClient(region) {
|
|
63
|
+
let client = clientsByRegion.get(region);
|
|
64
|
+
if (!client) {
|
|
65
|
+
const { CodePipelineClient } = await loadCodePipeline();
|
|
66
|
+
client = new CodePipelineClient({ region });
|
|
67
|
+
clientsByRegion.set(region, client);
|
|
68
|
+
}
|
|
69
|
+
return client;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Resolve a CodePipeline's tags → the platform pipelineId (pb.pipeline-id) plus the
|
|
73
|
+
* deploy-stage→environment map (pb.deploys). `pipelineId` is null when the pipeline
|
|
74
|
+
* has no pb.pipeline-id tag (unregistered). Throws on AccessDenied so a missing IAM
|
|
75
|
+
* grant surfaces loudly instead of silently dropping every event.
|
|
76
|
+
*/
|
|
77
|
+
export async function resolvePipeline(arn, region) {
|
|
78
|
+
const cached = resolvedByArn.get(arn);
|
|
79
|
+
// Serve a hit until its TTL (short for a negative, longer for a positive),
|
|
80
|
+
// then re-resolve so tag changes land.
|
|
81
|
+
if (cached && Date.now() - cached.ts < (cached.pipelineId !== null ? POS_CACHE_TTL_MS : NEG_CACHE_TTL_MS)) {
|
|
82
|
+
return { pipelineId: cached.pipelineId, orgId: cached.orgId, deploys: cached.deploys };
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const client = await pipelineClient(region);
|
|
86
|
+
const { ListTagsForResourceCommand } = await loadCodePipeline();
|
|
87
|
+
const out = await client.send(new ListTagsForResourceCommand({ resourceArn: arn }));
|
|
88
|
+
const pipelineId = out.tags?.find(t => t.key === PIPELINE_ID_TAG)?.value ?? null;
|
|
89
|
+
const orgId = out.tags?.find(t => t.key === ORG_ID_TAG)?.value ?? null;
|
|
90
|
+
const deploys = parseDeploys(out.tags?.find(t => t.key === DEPLOYS_TAG)?.value);
|
|
91
|
+
if (!pipelineId)
|
|
92
|
+
log.warn('Pipeline missing pb.pipeline-id tag — skipping (register it?)', { arn });
|
|
93
|
+
resolvedByArn.set(arn, { pipelineId, orgId, deploys, ts: Date.now() });
|
|
94
|
+
return { pipelineId, orgId, deploys };
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
const name = err?.name;
|
|
98
|
+
if (name === 'AccessDeniedException') {
|
|
99
|
+
// Don't cache — this is a fixable misconfig, not a property of the pipeline.
|
|
100
|
+
log.error('AccessDenied calling codepipeline:ListTagsForResource — grant it to the Lambda role', { arn, error: name });
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
// Transient/infra errors (throttling, timeouts, 5xx) MUST propagate so the SQS
|
|
104
|
+
// batch is retried rather than silently dropping the event — an event dropped
|
|
105
|
+
// BEFORE it reaches the ingest is lost permanently (the ingest's partial-unique
|
|
106
|
+
// index only dedupes events that were actually POSTed). Only swallow when the
|
|
107
|
+
// failure is a definitive answer that this ARN has no usable tag.
|
|
108
|
+
const e = err;
|
|
109
|
+
const status = e.$metadata?.httpStatusCode;
|
|
110
|
+
const retryable = e.$retryable != null
|
|
111
|
+
|| (typeof status === 'number' && status >= 500)
|
|
112
|
+
|| /throttl|timeout|toomanyrequests|serviceunavailable|econnreset|networkingerror/i.test(name ?? '');
|
|
113
|
+
if (retryable) {
|
|
114
|
+
log.error('Transient error resolving pb.pipeline-id tag — will retry the batch', { arn, error: name ?? String(err) });
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
log.error('Failed to resolve pb.pipeline-id tag', { arn, error: name ?? String(err) });
|
|
118
|
+
return { pipelineId: null, orgId: null, deploys: new Map() };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** @internal Test-only: forget resolved pipelines. */
|
|
122
|
+
export function _resetTagsForTests() {
|
|
123
|
+
resolvedByArn.clear();
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFncy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90YWdzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFZL0QsSUFBSSxlQUErQyxDQUFDO0FBQ3BELEtBQUssVUFBVSxnQkFBZ0I7SUFDN0IsSUFBSSxDQUFDLGVBQWU7UUFBRSxlQUFlLEdBQUcsQ0FBQyxNQUFNLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFrQyxDQUFDO0lBQ3hILE9BQU8sZUFBZSxDQUFDO0FBQ3pCLENBQUM7QUFFRCwrQ0FBK0M7QUFDL0MsMENBQTBDO0FBQzFDLDJDQUEyQztBQUMzQyw2REFBNkQ7QUFDN0QsaUVBQWlFO0FBQ2pFLG1GQUFtRjtBQUNuRixtRkFBbUY7QUFDbkYsOEJBQThCO0FBQzlCLEVBQUU7QUFDRixrRkFBa0Y7QUFDbEYsaUZBQWlGO0FBQ2pGLDBDQUEwQztBQUUxQyxNQUFNLGVBQWUsR0FBRyxnQkFBZ0IsQ0FBQztBQUN6QyxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUM7QUFDakMsZ0ZBQWdGO0FBQ2hGLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsNkNBQTZDO0FBQzdDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQztBQUMzQixNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0MsQ0FBQztBQUdsRSwwRUFBMEU7QUFDMUUsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRiwrRUFBK0U7QUFDL0UsaUVBQWlFO0FBQ2pFLE1BQU0sYUFBYSxHQUFHLElBQUksVUFBVSxDQUF3RyxpQkFBaUIsQ0FBQyxDQUFDO0FBQy9KLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDdkMsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElB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LENBQUMsT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLE1BQU0sSUFBSSxHQUFHLENBQUM7ZUFDN0MsZ0ZBQWdGLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ2QsR0FBRyxDQUFDLEtBQUssQ0FBQyxxRUFBcUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdEgsTUFBTSxHQUFHLENBQUM7UUFDWixDQUFDO1FBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxzQ0FBc0MsRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkYsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQy9ELENBQUM7QUFDSCxDQUFDO0FBRUQsc0RBQXNEO0FBQ3RELE1BQU0sVUFBVSxrQkFBa0I7SUFDaEMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgQm91bmRlZE1hcCwgQ0FDSEVfTUFYX0VOVFJJRVMsIGxvZyB9IGZyb20gJy4vdXRpbC5qcyc7XG5cbi8vIEFXUyBMYW1iZGEncyBOb2RlIHJ1bnRpbWUgcHJvdmlkZXMgQGF3cy1zZGsgdjMsIHNvIHRoZSBDb2RlUGlwZWxpbmUgY2xpZW50IGlzXG4vLyBsb2FkZWQgbGF6aWx5IHZpYSBkeW5hbWljIGltcG9ydCgpIOKAlCBhIHN0YXRpYyB3b3Jrc3BhY2UgZGVwZW5kZW5jeSB3b3VsZFxuLy8gcGVydHVyYiB0aGUgc2hhcmVkIEBhd3Mtc2RrIHZlcnNpb24gdHJlZS4gTWluaW1hbCBsb2NhbCB0eXBlcyBrZWVwIHRoZSBjYWxsXG4vLyBzaXRlcyB0eXBlLWNoZWNrZWQuXG5pbnRlcmZhY2UgTGlzdFRhZ3NPdXRwdXQgeyB0YWdzPzogQXJyYXk8eyBrZXk/OiBzdHJpbmc7IHZhbHVlPzogc3RyaW5nIH0+IH1cbmludGVyZmFjZSBDb2RlUGlwZWxpbmVDbGllbnRMaWtlIHsgc2VuZChjb21tYW5kOiB1bmtub3duKTogUHJvbWlzZTxMaXN0VGFnc091dHB1dD4gfVxuaW50ZXJmYWNlIENvZGVQaXBlbGluZU1vZHVsZSB7XG4gIENvZGVQaXBlbGluZUNsaWVudDogbmV3IChjb25maWc6IHsgcmVnaW9uOiBzdHJpbmcgfSkgPT4gQ29kZVBpcGVsaW5lQ2xpZW50TGlrZTtcbiAgTGlzdFRhZ3NGb3JSZXNvdXJjZUNvbW1hbmQ6IG5ldyAoaW5wdXQ6IHsgcmVzb3VyY2VBcm46IHN0cmluZyB9KSA9PiB1bmtub3duO1xufVxubGV0IGNvZGVwaXBlbGluZU1vZDogQ29kZVBpcGVsaW5lTW9kdWxlIHwgdW5kZWZpbmVkO1xuYXN5bmMgZnVuY3Rpb24gbG9hZENvZGVQaXBlbGluZSgpOiBQcm9taXNlPENvZGVQaXBlbGluZU1vZHVsZT4ge1xuICBpZiAoIWNvZGVwaXBlbGluZU1vZCkgY29kZXBpcGVsaW5lTW9kID0gKGF3YWl0IGltcG9ydCgnQGF3cy1zZGsvY2xpZW50LWNvZGVwaXBlbGluZScpKSBhcyB1bmtub3duIGFzIENvZGVQaXBlbGluZU1vZHVsZTtcbiAgcmV0dXJuIGNvZGVwaXBlbGluZU1vZDtcbn1cblxuLy8gVGFnIHJlc29sdXRpb246IHBiLnBpcGVsaW5lLWlkICsgcGIuZGVwbG95cy5cbi8vIFBpcGVsaW5lcyBhcmUgdGFnZ2VkIGF0IENESyBzeW50aCB3aXRoOlxuLy8gICBwYi5waXBlbGluZS1pZCA9IDxwbGF0Zm9ybSBwaXBlbGluZUlkPlxuLy8gICBwYi5kZXBsb3lzICAgICA9IDxzdGFnZT46PGVudj4gcGFpcnMgam9pbmVkIGJ5ICcrJywgZS5nLlxuLy8gICAgICAgICAgICAgICAgICAgIFwiRGVwbG95LXN0ZzpzdGFnaW5nK0RlcGxveS1wcm9kOnByb2R1Y3Rpb25cIlxuLy8gV2UgcmVzb2x2ZSB0aG9zZSB0YWdzIGZyb20gdGhlIGxpdmUgQ29kZVBpcGVsaW5lIChyZWdpb24tYXdhcmUpLiBUaGUgQVJOL2FjY291bnRcbi8vIG5ldmVyIGxlYXZlIEFXUywgc28gdGhlcmUncyBubyBtYXNraW5nLiBDYWNoZWQgcGVyIEFSTiAod2FybS1jb250YWluZXIpIHRvIGF2b2lkXG4vLyBoYW1tZXJpbmcgdGhlIExpc3RUYWdzIEFQSS5cbi8vXG4vLyBSZXF1aXJlcyB0aGUgTGFtYmRhIGV4ZWN1dGlvbiByb2xlIHRvIGFsbG93IGBjb2RlcGlwZWxpbmU6TGlzdFRhZ3NGb3JSZXNvdXJjZWAuXG4vLyBBY2Nlc3NEZW5pZWQgaXMgYSBjb25maWcgZXJyb3IgKGFsZXJ0IGxvdWRseSk7IGEgbWlzc2luZyBwYi5waXBlbGluZS1pZCB0YWcgaXNcbi8vIHRyZWF0ZWQgYXMgXCJub3QgeWV0IHJlZ2lzdGVyZWRcIiAoc2tpcCkuXG5cbmNvbnN0IFBJUEVMSU5FX0lEX1RBRyA9ICdwYi5waXBlbGluZS1pZCc7XG5jb25zdCBERVBMT1lTX1RBRyA9ICdwYi5kZXBsb3lzJztcbi8vIENhbm9uaWNhbCBwZXItcGlwZWxpbmUgb3JnIHRhZyAoYXBwbGllZCBhdCBzeW50aCBieSBwaXBlbGluZS1jb3JlKS4gSXQgaXMgdGhlXG4vLyBSRVNPTFZFRCBvcmcgZm9yIGV2ZXJ5IGV2ZW50IG9mIHRoaXMgcGlwZWxpbmUg4oCUIHVzZWQgdG8ga2V5IHRoZSBwZXItb3JnIEdpdEh1YlxuLy8gdG9rZW4gYW5kIHRvIGF0dHJpYnV0ZSBpbmdlc3QtaGVhbHRoLiBvcmdJZCBpcyBhIHBsYXRmb3JtIGlkLCBuZXZlciBhbiBBV1Ncbi8vIGFjY291bnQgaWQsIHNvIGl0IGlzIHNhZmUgdG8gcmVhZC9mb3J3YXJkLlxuY29uc3QgT1JHX0lEX1RBRyA9ICdPcmdJZCc7XG5jb25zdCBjbGllbnRzQnlSZWdpb24gPSBuZXcgTWFwPHN0cmluZywgQ29kZVBpcGVsaW5lQ2xpZW50TGlrZT4oKTtcblxuXG4vLyBgdHNgIGxldHMgQk9USCBvdXRjb21lcyBleHBpcmU6IGEgbmVnYXRpdmUgKHJlc29sdmVkLWJ1dC11bnRhZ2dlZCkgc28gYVxuLy8gcGlwZWxpbmUgdGFnZ2VkIEFGVEVSIGl0cyBmaXJzdCBldmVudCBiZWNvbWVzIHJlc29sdmFibGUsIGFuZCBhIHBvc2l0aXZlIHNvIGFcbi8vIHJlLXN5bnRoIHRoYXQgY2hhbmdlcyBgcGIuZGVwbG95c2AgKGEgc3RhZ2UgcmVuYW1lZCwgYW4gZW52aXJvbm1lbnQgYWRkZWQpIG9yXG4vLyBgT3JnSWRgIGlzIHBpY2tlZCB1cCB3aXRob3V0IHJlY3ljbGluZyB0aGUgd2FybSBjb250YWluZXIg4oCUIGEgbGlmZXRpbWUgY2FjaGVcbi8vIHdvdWxkIGtlZXAgYXR0cmlidXRpbmcgZGVwbG95cyB0byBzdGFnZXMgdGhhdCBubyBsb25nZXIgZXhpc3QuXG5jb25zdCByZXNvbHZlZEJ5QXJuID0gbmV3IEJvdW5kZWRNYXA8c3RyaW5nLCB7IHBpcGVsaW5lSWQ6IHN0cmluZyB8IG51bGw7IG9yZ0lkOiBzdHJpbmcgfCBudWxsOyBkZXBsb3lzOiBNYXA8c3RyaW5nLCBzdHJpbmc+OyB0czogbnVtYmVyIH0+KENBQ0hFX01BWF9FTlRSSUVTKTtcbmNvbnN0IE5FR19DQUNIRV9UVExfTVMgPSA1ICogNjAgKiAxMDAwO1xuY29uc3QgUE9TX0NBQ0hFX1RUTF9NUyA9IDE1ICogNjAgKiAxMDAwO1xuXG4vKiogUmVzb2x2ZWQgcGlwZWxpbmUgbWV0YWRhdGEgcmVhZCBmcm9tIHRoZSBDb2RlUGlwZWxpbmUgcmVzb3VyY2UgdGFncy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRQaXBlbGluZSB7XG4gIC8qKiBQbGF0Zm9ybSBwaXBlbGluZUlkIChwYi5waXBlbGluZS1pZCB0YWcpOyBudWxsIHdoZW4gdW50YWdnZWQvdW5yZWdpc3RlcmVkLiAqL1xuICBwaXBlbGluZUlkOiBzdHJpbmcgfCBudWxsO1xuICAvKiogUGxhdGZvcm0gb3JnSWQgKE9yZ0lkIHRhZyk7IG51bGwgd2hlbiB0aGUgcGlwZWxpbmUgY2FycmllcyBubyBvcmcgdGFnLiAqL1xuICBvcmdJZDogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIE1hcCBvZiBkZXBsb3ktc3RhZ2UgbmFtZSDihpIgZW52aXJvbm1lbnQgKHBhcnNlZCBmcm9tIHBiLmRlcGxveXMpLiBFbXB0eSB3aGVuIG5vbmUuICovXG4gIGRlcGxveXM6IE1hcDxzdHJpbmcsIHN0cmluZz47XG59XG5cbi8qKiBDYXAgb24gY29tbWl0L3JlZi9lbnZpcm9ubWVudCBmaWVsZHMg4oCUIHRoZSBpbmdlc3QgY29udHJhY3QgYWxsb3dzIG1heCAyNTUuICovXG5leHBvcnQgY29uc3QgTUFYX0FUVFIgPSAyNTU7XG5cbi8qKlxuICogUGFyc2UgdGhlIGBwYi5kZXBsb3lzYCB0YWcgdmFsdWUgaW50byBhIHN0YWdl4oaSZW52aXJvbm1lbnQgbWFwLiBUaGUgdmFsdWUgaXNcbiAqIGA8c3RhZ2U+OjxlbnY+YCBwYWlycyBqb2luZWQgYnkgYCtgIChDb2RlUGlwZWxpbmUtdGFnLXNhZmU7IG5vIEpTT04pLiBBIHN0YWdlXG4gKiBwcmVzZW50IGhlcmUgaXMgYSBkZXBsb3k7IGl0cyBtYXBwZWQgZW52aXJvbm1lbnQgaXMgd2hhdCB0aGUgZm9yd2FyZGVyIHN0YW1wcyBvblxuICogdGhhdCBzdGFnZSdzIFNUQUdFL0FDVElPTiBldmVudHMgKERPUkEgZGVwbG95IGF0dHJpYnV0aW9uKS4gTWFsZm9ybWVkIHBhaXJzIGFyZVxuICogc2tpcHBlZCBkZWZlbnNpdmVseS5cbiAqL1xuZnVuY3Rpb24gcGFyc2VEZXBsb3lzKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgbWFwID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgaWYgKCF2YWx1ZSkgcmV0dXJuIG1hcDtcbiAgZm9yIChjb25zdCBwYWlyIG9mIHZhbHVlLnNwbGl0KCcrJykpIHtcbiAgICBjb25zdCBpZHggPSBwYWlyLmluZGV4T2YoJzonKTtcbiAgICBpZiAoaWR4IDw9IDApIGNvbnRpbnVlO1xuICAgIGNvbnN0IHN0YWdlID0gcGFpci5zbGljZSgwLCBpZHgpLnRyaW0oKTtcbiAgICBjb25zdCBlbnYgPSBwYWlyLnNsaWNlKGlkeCArIDEpLnRyaW0oKTtcbiAgICBpZiAoc3RhZ2UgJiYgZW52KSBtYXAuc2V0KHN0YWdlLCBlbnYuc2xpY2UoMCwgTUFYX0FUVFIpKTtcbiAgfVxuICByZXR1cm4gbWFwO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwaXBlbGluZUNsaWVudChyZWdpb246IHN0cmluZyk6IFByb21pc2U8Q29kZVBpcGVsaW5lQ2xpZW50TGlrZT4ge1xuICBsZXQgY2xpZW50ID0gY2xpZW50c0J5UmVnaW9uLmdldChyZWdpb24pO1xuICBpZiAoIWNsaWVudCkge1xuICAgIGNvbnN0IHsgQ29kZVBpcGVsaW5lQ2xpZW50IH0gPSBhd2FpdCBsb2FkQ29kZVBpcGVsaW5lKCk7XG4gICAgY2xpZW50ID0gbmV3IENvZGVQaXBlbGluZUNsaWVudCh7IHJlZ2lvbiB9KTtcbiAgICBjbGllbnRzQnlSZWdpb24uc2V0KHJlZ2lvbiwgY2xpZW50KTtcbiAgfVxuICByZXR1cm4gY2xpZW50O1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBDb2RlUGlwZWxpbmUncyB0YWdzIOKGkiB0aGUgcGxhdGZvcm0gcGlwZWxpbmVJZCAocGIucGlwZWxpbmUtaWQpIHBsdXMgdGhlXG4gKiBkZXBsb3ktc3RhZ2XihpJlbnZpcm9ubWVudCBtYXAgKHBiLmRlcGxveXMpLiBgcGlwZWxpbmVJZGAgaXMgbnVsbCB3aGVuIHRoZSBwaXBlbGluZVxuICogaGFzIG5vIHBiLnBpcGVsaW5lLWlkIHRhZyAodW5yZWdpc3RlcmVkKS4gVGhyb3dzIG9uIEFjY2Vzc0RlbmllZCBzbyBhIG1pc3NpbmcgSUFNXG4gKiBncmFudCBzdXJmYWNlcyBsb3VkbHkgaW5zdGVhZCBvZiBzaWxlbnRseSBkcm9wcGluZyBldmVyeSBldmVudC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVQaXBlbGluZShhcm46IHN0cmluZywgcmVnaW9uOiBzdHJpbmcpOiBQcm9taXNlPFJlc29sdmVkUGlwZWxpbmU+IHtcbiAgY29uc3QgY2FjaGVkID0gcmVzb2x2ZWRCeUFybi5nZXQoYXJuKTtcbiAgLy8gU2VydmUgYSBoaXQgdW50aWwgaXRzIFRUTCAoc2hvcnQgZm9yIGEgbmVnYXRpdmUsIGxvbmdlciBmb3IgYSBwb3NpdGl2ZSksXG4gIC8vIHRoZW4gcmUtcmVzb2x2ZSBzbyB0YWcgY2hhbmdlcyBsYW5kLlxuICBpZiAoY2FjaGVkICYmIERhdGUubm93KCkgLSBjYWNoZWQudHMgPCAoY2FjaGVkLnBpcGVsaW5lSWQgIT09IG51bGwgPyBQT1NfQ0FDSEVfVFRMX01TIDogTkVHX0NBQ0hFX1RUTF9NUykpIHtcbiAgICByZXR1cm4geyBwaXBlbGluZUlkOiBjYWNoZWQucGlwZWxpbmVJZCwgb3JnSWQ6IGNhY2hlZC5vcmdJZCwgZGVwbG95czogY2FjaGVkLmRlcGxveXMgfTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHBpcGVsaW5lQ2xpZW50KHJlZ2lvbik7XG4gICAgY29uc3QgeyBMaXN0VGFnc0ZvclJlc291cmNlQ29tbWFuZCB9ID0gYXdhaXQgbG9hZENvZGVQaXBlbGluZSgpO1xuICAgIGNvbnN0IG91dCA9IGF3YWl0IGNsaWVudC5zZW5kKG5ldyBMaXN0VGFnc0ZvclJlc291cmNlQ29tbWFuZCh7IHJlc291cmNlQXJuOiBhcm4gfSkpO1xuICAgIGNvbnN0IHBpcGVsaW5lSWQgPSBvdXQudGFncz8uZmluZCh0ID0+IHQua2V5ID09PSBQSVBFTElORV9JRF9UQUcpPy52YWx1ZSA/PyBudWxsO1xuICAgIGNvbnN0IG9yZ0lkID0gb3V0LnRhZ3M/LmZpbmQodCA9PiB0LmtleSA9PT0gT1JHX0lEX1RBRyk/LnZhbHVlID8/IG51bGw7XG4gICAgY29uc3QgZGVwbG95cyA9IHBhcnNlRGVwbG95cyhvdXQudGFncz8uZmluZCh0ID0+IHQua2V5ID09PSBERVBMT1lTX1RBRyk/LnZhbHVlKTtcbiAgICBpZiAoIXBpcGVsaW5lSWQpIGxvZy53YXJuKCdQaXBlbGluZSBtaXNzaW5nIHBiLnBpcGVsaW5lLWlkIHRhZyDigJQgc2tpcHBpbmcgKHJlZ2lzdGVyIGl0PyknLCB7IGFybiB9KTtcbiAgICByZXNvbHZlZEJ5QXJuLnNldChhcm4sIHsgcGlwZWxpbmVJZCwgb3JnSWQsIGRlcGxveXMsIHRzOiBEYXRlLm5vdygpIH0pO1xuICAgIHJldHVybiB7IHBpcGVsaW5lSWQsIG9yZ0lkLCBkZXBsb3lzIH07XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnN0IG5hbWUgPSAoZXJyIGFzIHsgbmFtZT86IHN0cmluZyB9KT8ubmFtZTtcbiAgICBpZiAobmFtZSA9PT0gJ0FjY2Vzc0RlbmllZEV4Y2VwdGlvbicpIHtcbiAgICAgIC8vIERvbid0IGNhY2hlIOKAlCB0aGlzIGlzIGEgZml4YWJsZSBtaXNjb25maWcsIG5vdCBhIHByb3BlcnR5IG9mIHRoZSBwaXBlbGluZS5cbiAgICAgIGxvZy5lcnJvcignQWNjZXNzRGVuaWVkIGNhbGxpbmcgY29kZXBpcGVsaW5lOkxpc3RUYWdzRm9yUmVzb3VyY2Ug4oCUIGdyYW50IGl0IHRvIHRoZSBMYW1iZGEgcm9sZScsIHsgYXJuLCBlcnJvcjogbmFtZSB9KTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgLy8gVHJhbnNpZW50L2luZnJhIGVycm9ycyAodGhyb3R0bGluZywgdGltZW91dHMsIDV4eCkgTVVTVCBwcm9wYWdhdGUgc28gdGhlIFNRU1xuICAgIC8vIGJhdGNoIGlzIHJldHJpZWQgcmF0aGVyIHRoYW4gc2lsZW50bHkgZHJvcHBpbmcgdGhlIGV2ZW50IOKAlCBhbiBldmVudCBkcm9wcGVkXG4gICAgLy8gQkVGT1JFIGl0IHJlYWNoZXMgdGhlIGluZ2VzdCBpcyBsb3N0IHBlcm1hbmVudGx5ICh0aGUgaW5nZXN0J3MgcGFydGlhbC11bmlxdWVcbiAgICAvLyBpbmRleCBvbmx5IGRlZHVwZXMgZXZlbnRzIHRoYXQgd2VyZSBhY3R1YWxseSBQT1NUZWQpLiBPbmx5IHN3YWxsb3cgd2hlbiB0aGVcbiAgICAvLyBmYWlsdXJlIGlzIGEgZGVmaW5pdGl2ZSBhbnN3ZXIgdGhhdCB0aGlzIEFSTiBoYXMgbm8gdXNhYmxlIHRhZy5cbiAgICBjb25zdCBlID0gZXJyIGFzIHsgbmFtZT86IHN0cmluZzsgJHJldHJ5YWJsZT86IHVua25vd247ICRtZXRhZGF0YT86IHsgaHR0cFN0YXR1c0NvZGU/OiBudW1iZXIgfSB9O1xuICAgIGNvbnN0IHN0YXR1cyA9IGUuJG1ldGFkYXRhPy5odHRwU3RhdHVzQ29kZTtcbiAgICBjb25zdCByZXRyeWFibGUgPSBlLiRyZXRyeWFibGUgIT0gbnVsbFxuICAgICAgfHwgKHR5cGVvZiBzdGF0dXMgPT09ICdudW1iZXInICYmIHN0YXR1cyA+PSA1MDApXG4gICAgICB8fCAvdGhyb3R0bHx0aW1lb3V0fHRvb21hbnlyZXF1ZXN0c3xzZXJ2aWNldW5hdmFpbGFibGV8ZWNvbm5yZXNldHxuZXR3b3JraW5nZXJyb3IvaS50ZXN0KG5hbWUgPz8gJycpO1xuICAgIGlmIChyZXRyeWFibGUpIHtcbiAgICAgIGxvZy5lcnJvcignVHJhbnNpZW50IGVycm9yIHJlc29sdmluZyBwYi5waXBlbGluZS1pZCB0YWcg4oCUIHdpbGwgcmV0cnkgdGhlIGJhdGNoJywgeyBhcm4sIGVycm9yOiBuYW1lID8/IFN0cmluZyhlcnIpIH0pO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICBsb2cuZXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIHBiLnBpcGVsaW5lLWlkIHRhZycsIHsgYXJuLCBlcnJvcjogbmFtZSA/PyBTdHJpbmcoZXJyKSB9KTtcbiAgICByZXR1cm4geyBwaXBlbGluZUlkOiBudWxsLCBvcmdJZDogbnVsbCwgZGVwbG95czogbmV3IE1hcCgpIH07XG4gIH1cbn1cblxuLyoqIEBpbnRlcm5hbCBUZXN0LW9ubHk6IGZvcmdldCByZXNvbHZlZCBwaXBlbGluZXMuICovXG5leHBvcnQgZnVuY3Rpb24gX3Jlc2V0VGFnc0ZvclRlc3RzKCk6IHZvaWQge1xuICByZXNvbHZlZEJ5QXJuLmNsZWFyKCk7XG59XG4iXX0=
|
package/lib/util.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Shared plumbing for the event-ingestion Lambda modules. */
|
|
2
|
+
export declare const log: {
|
|
3
|
+
info: (msg: string, data?: unknown) => void;
|
|
4
|
+
warn: (msg: string, data?: unknown) => void;
|
|
5
|
+
error: (msg: string, data?: unknown) => void;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A Map that holds at most `max` entries, evicting the least recently SET one.
|
|
9
|
+
* Every per-key cache in this module is keyed by something unbounded (pipeline
|
|
10
|
+
* ARN, pipeline × commit, org), and a fleet forwarder's warm container can live
|
|
11
|
+
* for hours across thousands of pipelines — an unbounded Map is a slow leak that
|
|
12
|
+
* ends in an OOM-killed Lambda and a redelivered batch.
|
|
13
|
+
*/
|
|
14
|
+
export declare class BoundedMap<K, V> extends Map<K, V> {
|
|
15
|
+
private readonly max;
|
|
16
|
+
constructor(max: number);
|
|
17
|
+
set(key: K, value: V): this;
|
|
18
|
+
}
|
|
19
|
+
/** Upper bound for every per-key cache below. */
|
|
20
|
+
export declare const CACHE_MAX_ENTRIES = 5000;
|
|
21
|
+
export declare function loadSdk<T>(pkg: string): Promise<T>;
|
package/lib/util.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/** Shared plumbing for the event-ingestion Lambda modules. */
|
|
4
|
+
export const log = {
|
|
5
|
+
info: (msg, data) => console.log(JSON.stringify({ level: 'INFO', message: msg, data, ts: new Date().toISOString() })),
|
|
6
|
+
warn: (msg, data) => console.log(JSON.stringify({ level: 'WARN', message: msg, data, ts: new Date().toISOString() })),
|
|
7
|
+
error: (msg, data) => console.error(JSON.stringify({ level: 'ERROR', message: msg, data, ts: new Date().toISOString() })),
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A Map that holds at most `max` entries, evicting the least recently SET one.
|
|
11
|
+
* Every per-key cache in this module is keyed by something unbounded (pipeline
|
|
12
|
+
* ARN, pipeline × commit, org), and a fleet forwarder's warm container can live
|
|
13
|
+
* for hours across thousands of pipelines — an unbounded Map is a slow leak that
|
|
14
|
+
* ends in an OOM-killed Lambda and a redelivered batch.
|
|
15
|
+
*/
|
|
16
|
+
export class BoundedMap extends Map {
|
|
17
|
+
max;
|
|
18
|
+
constructor(max) {
|
|
19
|
+
super();
|
|
20
|
+
this.max = max;
|
|
21
|
+
}
|
|
22
|
+
set(key, value) {
|
|
23
|
+
if (super.has(key)) {
|
|
24
|
+
super.delete(key); // refresh recency
|
|
25
|
+
}
|
|
26
|
+
else if (this.size >= this.max) {
|
|
27
|
+
const oldest = this.keys().next().value;
|
|
28
|
+
if (oldest !== undefined)
|
|
29
|
+
super.delete(oldest);
|
|
30
|
+
}
|
|
31
|
+
return super.set(key, value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Upper bound for every per-key cache below. */
|
|
35
|
+
export const CACHE_MAX_ENTRIES = 5000;
|
|
36
|
+
// Variable-specifier loader for SDK clients that are NOT devDependencies of this
|
|
37
|
+
// package (`@aws-sdk/client-codecommit`, `@aws-sdk/client-sqs` — present only in
|
|
38
|
+
// the Lambda runtime / jest mocks). A `string` specifier keeps `tsc` from
|
|
39
|
+
// resolving them at build time, and the bundle leaves `@aws-sdk/*` external.
|
|
40
|
+
export async function loadSdk(pkg) {
|
|
41
|
+
return (await import(pkg));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsOERBQThEO0FBRTlELE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRztJQUNqQixJQUFJLEVBQUUsQ0FBQyxHQUFXLEVBQUUsSUFBYyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN2SSxJQUFJLEVBQUUsQ0FBQyxHQUFXLEVBQUUsSUFBYyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN2SSxLQUFLLEVBQUUsQ0FBQyxHQUFXLEVBQUUsSUFBYyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztDQUM1SSxDQUFDO0FBRUY7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFVBQWlCLFNBQVEsR0FBUztJQUNoQixHQUFHO0lBQWhDLFlBQTZCLEdBQVc7UUFBSSxLQUFLLEVBQUUsQ0FBQzttQkFBdkIsR0FBRztJQUFxQixDQUFDO0lBQzdDLEdBQUcsQ0FBQyxHQUFNLEVBQUUsS0FBUTtRQUMzQixJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNuQixLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsa0JBQWtCO1FBQ3ZDLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDeEMsSUFBSSxNQUFNLEtBQUssU0FBUztnQkFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQy9CLENBQUM7Q0FDRjtBQUVELGlEQUFpRDtBQUNqRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUM7QUFFdEMsaUZBQWlGO0FBQ2pGLGlGQUFpRjtBQUNqRiwwRUFBMEU7QUFDMUUsNkVBQTZFO0FBQzdFLE1BQU0sQ0FBQyxLQUFLLFVBQVUsT0FBTyxDQUFJLEdBQVc7SUFDMUMsT0FBTyxDQUFDLE1BQU0sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFNLENBQUM7QUFDbEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKiogU2hhcmVkIHBsdW1iaW5nIGZvciB0aGUgZXZlbnQtaW5nZXN0aW9uIExhbWJkYSBtb2R1bGVzLiAqL1xuXG5leHBvcnQgY29uc3QgbG9nID0ge1xuICBpbmZvOiAobXNnOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKSA9PiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh7IGxldmVsOiAnSU5GTycsIG1lc3NhZ2U6IG1zZywgZGF0YSwgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSB9KSksXG4gIHdhcm46IChtc2c6IHN0cmluZywgZGF0YT86IHVua25vd24pID0+IGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHsgbGV2ZWw6ICdXQVJOJywgbWVzc2FnZTogbXNnLCBkYXRhLCB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0pKSxcbiAgZXJyb3I6IChtc2c6IHN0cmluZywgZGF0YT86IHVua25vd24pID0+IGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkoeyBsZXZlbDogJ0VSUk9SJywgbWVzc2FnZTogbXNnLCBkYXRhLCB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0pKSxcbn07XG5cbi8qKlxuICogQSBNYXAgdGhhdCBob2xkcyBhdCBtb3N0IGBtYXhgIGVudHJpZXMsIGV2aWN0aW5nIHRoZSBsZWFzdCByZWNlbnRseSBTRVQgb25lLlxuICogRXZlcnkgcGVyLWtleSBjYWNoZSBpbiB0aGlzIG1vZHVsZSBpcyBrZXllZCBieSBzb21ldGhpbmcgdW5ib3VuZGVkIChwaXBlbGluZVxuICogQVJOLCBwaXBlbGluZSDDlyBjb21taXQsIG9yZyksIGFuZCBhIGZsZWV0IGZvcndhcmRlcidzIHdhcm0gY29udGFpbmVyIGNhbiBsaXZlXG4gKiBmb3IgaG91cnMgYWNyb3NzIHRob3VzYW5kcyBvZiBwaXBlbGluZXMg4oCUIGFuIHVuYm91bmRlZCBNYXAgaXMgYSBzbG93IGxlYWsgdGhhdFxuICogZW5kcyBpbiBhbiBPT00ta2lsbGVkIExhbWJkYSBhbmQgYSByZWRlbGl2ZXJlZCBiYXRjaC5cbiAqL1xuZXhwb3J0IGNsYXNzIEJvdW5kZWRNYXA8SywgVj4gZXh0ZW5kcyBNYXA8SywgVj4ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG1heDogbnVtYmVyKSB7IHN1cGVyKCk7IH1cbiAgb3ZlcnJpZGUgc2V0KGtleTogSywgdmFsdWU6IFYpOiB0aGlzIHtcbiAgICBpZiAoc3VwZXIuaGFzKGtleSkpIHtcbiAgICAgIHN1cGVyLmRlbGV0ZShrZXkpOyAvLyByZWZyZXNoIHJlY2VuY3lcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2l6ZSA+PSB0aGlzLm1heCkge1xuICAgICAgY29uc3Qgb2xkZXN0ID0gdGhpcy5rZXlzKCkubmV4dCgpLnZhbHVlO1xuICAgICAgaWYgKG9sZGVzdCAhPT0gdW5kZWZpbmVkKSBzdXBlci5kZWxldGUob2xkZXN0KTtcbiAgICB9XG4gICAgcmV0dXJuIHN1cGVyLnNldChrZXksIHZhbHVlKTtcbiAgfVxufVxuXG4vKiogVXBwZXIgYm91bmQgZm9yIGV2ZXJ5IHBlci1rZXkgY2FjaGUgYmVsb3cuICovXG5leHBvcnQgY29uc3QgQ0FDSEVfTUFYX0VOVFJJRVMgPSA1MDAwO1xuXG4vLyBWYXJpYWJsZS1zcGVjaWZpZXIgbG9hZGVyIGZvciBTREsgY2xpZW50cyB0aGF0IGFyZSBOT1QgZGV2RGVwZW5kZW5jaWVzIG9mIHRoaXNcbi8vIHBhY2thZ2UgKGBAYXdzLXNkay9jbGllbnQtY29kZWNvbW1pdGAsIGBAYXdzLXNkay9jbGllbnQtc3FzYCDigJQgcHJlc2VudCBvbmx5IGluXG4vLyB0aGUgTGFtYmRhIHJ1bnRpbWUgLyBqZXN0IG1vY2tzKS4gQSBgc3RyaW5nYCBzcGVjaWZpZXIga2VlcHMgYHRzY2AgZnJvbVxuLy8gcmVzb2x2aW5nIHRoZW0gYXQgYnVpbGQgdGltZSwgYW5kIHRoZSBidW5kbGUgbGVhdmVzIGBAYXdzLXNkay8qYCBleHRlcm5hbC5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkU2RrPFQ+KHBrZzogc3RyaW5nKTogUHJvbWlzZTxUPiB7XG4gIHJldHVybiAoYXdhaXQgaW1wb3J0KHBrZykpIGFzIFQ7XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -11,17 +11,19 @@
|
|
|
11
11
|
"@jest/globals": "30.4.1",
|
|
12
12
|
"@stylistic/eslint-plugin": "^2",
|
|
13
13
|
"@types/aws-lambda": "8.10.162",
|
|
14
|
-
"@types/node": "
|
|
14
|
+
"@types/node": "^24",
|
|
15
15
|
"@typescript-eslint/eslint-plugin": "^8",
|
|
16
16
|
"@typescript-eslint/parser": "^8",
|
|
17
17
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
18
|
+
"esbuild": "0.28.0",
|
|
18
19
|
"eslint": "^9",
|
|
19
20
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
20
21
|
"eslint-plugin-import": "^2.32.0",
|
|
21
22
|
"jest": "30.4.2",
|
|
22
23
|
"jest-junit": "^17",
|
|
23
24
|
"ts-jest": "29.4.12",
|
|
24
|
-
"typescript": "npm:@typescript/typescript6@^6.0.2"
|
|
25
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
26
|
+
"@pipeline-builder/pipeline-core": "4.1.16"
|
|
25
27
|
},
|
|
26
28
|
"keywords": [
|
|
27
29
|
"ci-cd",
|
|
@@ -77,7 +79,7 @@
|
|
|
77
79
|
"access": "public",
|
|
78
80
|
"registry": "https://registry.npmjs.org/"
|
|
79
81
|
},
|
|
80
|
-
"version": "4.0.
|
|
82
|
+
"version": "4.0.11",
|
|
81
83
|
"bugs": {
|
|
82
84
|
"url": "https://github.com/mwashburn160/pipeline-builder/issues"
|
|
83
85
|
},
|
|
@@ -143,12 +145,17 @@
|
|
|
143
145
|
"setupFilesAfterEnv": [
|
|
144
146
|
"<rootDir>/../../jest-env-guard.js"
|
|
145
147
|
],
|
|
148
|
+
"collectCoverageFrom": [
|
|
149
|
+
"src/**/*.ts",
|
|
150
|
+
"!src/**/*.d.ts",
|
|
151
|
+
"!src/testing/**"
|
|
152
|
+
],
|
|
146
153
|
"coverageThreshold": {
|
|
147
154
|
"global": {
|
|
148
|
-
"statements":
|
|
149
|
-
"branches":
|
|
155
|
+
"statements": 95,
|
|
156
|
+
"branches": 78,
|
|
150
157
|
"functions": 95,
|
|
151
|
-
"lines":
|
|
158
|
+
"lines": 95
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
161
|
},
|
|
@@ -160,11 +167,14 @@
|
|
|
160
167
|
"compile": "pnpm dlx projen compile",
|
|
161
168
|
"default": "pnpm dlx projen default",
|
|
162
169
|
"eslint": "pnpm dlx projen eslint",
|
|
170
|
+
"lint:fix": "pnpm dlx projen lint:fix",
|
|
163
171
|
"package": "pnpm dlx projen package",
|
|
164
172
|
"post-compile": "pnpm dlx projen post-compile",
|
|
165
173
|
"pre-compile": "pnpm dlx projen pre-compile",
|
|
166
174
|
"test": "pnpm dlx projen test",
|
|
175
|
+
"test:update": "pnpm dlx projen test:update",
|
|
167
176
|
"test:watch": "pnpm dlx projen test:watch",
|
|
177
|
+
"typecheck:tests": "pnpm dlx projen typecheck:tests",
|
|
168
178
|
"watch": "pnpm dlx projen watch",
|
|
169
179
|
"projen": "pnpm dlx projen"
|
|
170
180
|
}
|