@clef-sh/runtime 0.1.6-beta.32
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/decrypt.d.ts +25 -0
- package/dist/decrypt.d.ts.map +1 -0
- package/dist/decrypt.js +82 -0
- package/dist/decrypt.js.map +1 -0
- package/dist/disk-cache.d.ts +22 -0
- package/dist/disk-cache.d.ts.map +1 -0
- package/dist/disk-cache.js +113 -0
- package/dist/disk-cache.js.map +1 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +165 -0
- package/dist/index.js.map +1 -0
- package/dist/kms/aws.d.ts +15 -0
- package/dist/kms/aws.d.ts.map +1 -0
- package/dist/kms/aws.js +92 -0
- package/dist/kms/aws.js.map +1 -0
- package/dist/kms/azure.d.ts +16 -0
- package/dist/kms/azure.d.ts.map +1 -0
- package/dist/kms/azure.js +85 -0
- package/dist/kms/azure.js.map +1 -0
- package/dist/kms/gcp.d.ts +17 -0
- package/dist/kms/gcp.d.ts.map +1 -0
- package/dist/kms/gcp.js +87 -0
- package/dist/kms/gcp.js.map +1 -0
- package/dist/kms/index.d.ts +12 -0
- package/dist/kms/index.d.ts.map +1 -0
- package/dist/kms/index.js +29 -0
- package/dist/kms/index.js.map +1 -0
- package/dist/kms/types.d.ts +10 -0
- package/dist/kms/types.d.ts.map +1 -0
- package/dist/kms/types.js +3 -0
- package/dist/kms/types.js.map +1 -0
- package/dist/poller.d.ts +80 -0
- package/dist/poller.d.ts.map +1 -0
- package/dist/poller.js +329 -0
- package/dist/poller.js.map +1 -0
- package/dist/secrets-cache.d.ts +23 -0
- package/dist/secrets-cache.d.ts.map +1 -0
- package/dist/secrets-cache.js +51 -0
- package/dist/secrets-cache.js.map +1 -0
- package/dist/sources/file.d.ts +9 -0
- package/dist/sources/file.d.ts.map +1 -0
- package/dist/sources/file.js +53 -0
- package/dist/sources/file.js.map +1 -0
- package/dist/sources/http.d.ts +9 -0
- package/dist/sources/http.d.ts.map +1 -0
- package/dist/sources/http.js +24 -0
- package/dist/sources/http.js.map +1 -0
- package/dist/sources/index.d.ts +5 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +10 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/types.d.ts +15 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +3 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/sources/vcs.d.ts +13 -0
- package/dist/sources/vcs.d.ts.map +1 -0
- package/dist/sources/vcs.js +25 -0
- package/dist/sources/vcs.js.map +1 -0
- package/dist/telemetry.d.ts +129 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +192 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/vcs/bitbucket.d.ts +11 -0
- package/dist/vcs/bitbucket.d.ts.map +1 -0
- package/dist/vcs/bitbucket.js +43 -0
- package/dist/vcs/bitbucket.js.map +1 -0
- package/dist/vcs/github.d.ts +11 -0
- package/dist/vcs/github.d.ts.map +1 -0
- package/dist/vcs/github.js +35 -0
- package/dist/vcs/github.js.map +1 -0
- package/dist/vcs/gitlab.d.ts +11 -0
- package/dist/vcs/gitlab.d.ts.map +1 -0
- package/dist/vcs/gitlab.js +36 -0
- package/dist/vcs/gitlab.js.map +1 -0
- package/dist/vcs/index.d.ts +8 -0
- package/dist/vcs/index.d.ts.map +1 -0
- package/dist/vcs/index.js +27 -0
- package/dist/vcs/index.js.map +1 -0
- package/dist/vcs/types.d.ts +29 -0
- package/dist/vcs/types.d.ts.map +1 -0
- package/dist/vcs/types.js +3 -0
- package/dist/vcs/types.js.map +1 -0
- package/package.json +41 -0
package/dist/poller.js
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ArtifactPoller = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
const decrypt_1 = require("./decrypt");
|
|
39
|
+
const kms_1 = require("./kms");
|
|
40
|
+
/**
|
|
41
|
+
* Periodically fetches a published artifact, decrypts it, and swaps the
|
|
42
|
+
* secrets cache when a new revision is detected.
|
|
43
|
+
*/
|
|
44
|
+
/** Minimum poll interval in milliseconds (floor for all scheduling). */
|
|
45
|
+
const MIN_POLL_MS = 5_000;
|
|
46
|
+
class ArtifactPoller {
|
|
47
|
+
timer = null;
|
|
48
|
+
lastContentHash = null;
|
|
49
|
+
lastRevision = null;
|
|
50
|
+
lastExpiresAt = null;
|
|
51
|
+
decryptor = new decrypt_1.AgeDecryptor();
|
|
52
|
+
options;
|
|
53
|
+
telemetryOverride;
|
|
54
|
+
constructor(options) {
|
|
55
|
+
this.options = options;
|
|
56
|
+
}
|
|
57
|
+
/** Set or replace the telemetry emitter (e.g. after resolving token from secrets). */
|
|
58
|
+
setTelemetry(emitter) {
|
|
59
|
+
this.telemetryOverride = emitter;
|
|
60
|
+
}
|
|
61
|
+
get telemetry() {
|
|
62
|
+
return this.telemetryOverride ?? this.options.telemetry;
|
|
63
|
+
}
|
|
64
|
+
/** Fetch, validate, decrypt, and cache the artifact. */
|
|
65
|
+
async fetchAndDecrypt() {
|
|
66
|
+
let raw;
|
|
67
|
+
let contentHash;
|
|
68
|
+
try {
|
|
69
|
+
const result = await this.options.source.fetch();
|
|
70
|
+
raw = result.raw;
|
|
71
|
+
contentHash = result.contentHash;
|
|
72
|
+
// Content-hash short-circuit: skip parse+decrypt if unchanged
|
|
73
|
+
if (contentHash && contentHash === this.lastContentHash)
|
|
74
|
+
return;
|
|
75
|
+
// Write to disk cache on successful fetch
|
|
76
|
+
this.options.diskCache?.write(raw, contentHash);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
this.telemetry?.fetchFailed({
|
|
80
|
+
error: err instanceof Error ? err.message : String(err),
|
|
81
|
+
diskCacheAvailable: !!this.options.diskCache?.read(),
|
|
82
|
+
});
|
|
83
|
+
const ttl = this.options.cacheTtl;
|
|
84
|
+
// Attempt disk cache fallback
|
|
85
|
+
if (this.options.diskCache) {
|
|
86
|
+
const cached = this.options.diskCache.read();
|
|
87
|
+
if (cached) {
|
|
88
|
+
// Check if disk cache has also expired
|
|
89
|
+
if (ttl !== undefined) {
|
|
90
|
+
const fetchedAt = this.options.diskCache.getFetchedAt();
|
|
91
|
+
if (fetchedAt && (Date.now() - new Date(fetchedAt).getTime()) / 1000 > ttl) {
|
|
92
|
+
this.options.cache.wipe();
|
|
93
|
+
this.options.diskCache.purge();
|
|
94
|
+
this.telemetry?.cacheExpired({
|
|
95
|
+
cacheTtlSeconds: ttl,
|
|
96
|
+
diskCachePurged: true,
|
|
97
|
+
});
|
|
98
|
+
throw new Error("Secrets cache expired: no successful refresh within TTL");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
raw = cached;
|
|
102
|
+
contentHash = this.options.diskCache.getCachedSha();
|
|
103
|
+
// If the cached hash matches, still skip
|
|
104
|
+
if (contentHash && contentHash === this.lastContentHash)
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// No disk cache content — check in-memory TTL
|
|
109
|
+
if (ttl !== undefined && this.options.cache.isExpired(ttl)) {
|
|
110
|
+
this.options.cache.wipe();
|
|
111
|
+
this.telemetry?.cacheExpired({
|
|
112
|
+
cacheTtlSeconds: ttl,
|
|
113
|
+
diskCachePurged: false,
|
|
114
|
+
});
|
|
115
|
+
throw new Error("Secrets cache expired: no successful refresh within TTL");
|
|
116
|
+
}
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// No disk cache configured — check in-memory TTL
|
|
122
|
+
if (ttl !== undefined && this.options.cache.isExpired(ttl)) {
|
|
123
|
+
this.options.cache.wipe();
|
|
124
|
+
this.telemetry?.cacheExpired({
|
|
125
|
+
cacheTtlSeconds: ttl,
|
|
126
|
+
diskCachePurged: false,
|
|
127
|
+
});
|
|
128
|
+
throw new Error("Secrets cache expired: no successful refresh within TTL");
|
|
129
|
+
}
|
|
130
|
+
throw err;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Check for revocation before full validation — a revoked artifact
|
|
134
|
+
// won't have ciphertext/revision fields.
|
|
135
|
+
const parsed = JSON.parse(raw);
|
|
136
|
+
if (parsed.revokedAt) {
|
|
137
|
+
this.options.cache.wipe();
|
|
138
|
+
this.options.diskCache?.purge();
|
|
139
|
+
this.lastRevision = null;
|
|
140
|
+
this.lastContentHash = null;
|
|
141
|
+
this.telemetry?.artifactRevoked({
|
|
142
|
+
revokedAt: String(parsed.revokedAt),
|
|
143
|
+
});
|
|
144
|
+
throw new Error(`Artifact revoked: ${parsed.identity}/${parsed.environment} at ${parsed.revokedAt}`);
|
|
145
|
+
}
|
|
146
|
+
// Validate, decrypt, and cache — emit artifact.invalid on any failure
|
|
147
|
+
await this.validateDecryptAndCache(raw, contentHash);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validate the artifact, decrypt it, and swap the cache.
|
|
151
|
+
* Emits `artifact.invalid` on any validation or decryption failure,
|
|
152
|
+
* and `artifact.expired` / `artifact.refreshed` on their respective paths.
|
|
153
|
+
*/
|
|
154
|
+
async validateDecryptAndCache(raw, contentHash) {
|
|
155
|
+
let artifact;
|
|
156
|
+
try {
|
|
157
|
+
artifact = this.parseAndValidate(raw);
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
this.telemetry?.artifactInvalid({
|
|
161
|
+
reason: classifyValidationError(err),
|
|
162
|
+
error: err instanceof Error ? err.message : String(err),
|
|
163
|
+
});
|
|
164
|
+
throw err;
|
|
165
|
+
}
|
|
166
|
+
// Check artifact-level expiry
|
|
167
|
+
if (artifact.expiresAt && Date.now() > new Date(artifact.expiresAt).getTime()) {
|
|
168
|
+
this.options.cache.wipe();
|
|
169
|
+
this.options.diskCache?.purge();
|
|
170
|
+
this.telemetry?.artifactExpired({ expiresAt: artifact.expiresAt });
|
|
171
|
+
throw new Error(`Artifact expired at ${artifact.expiresAt}`);
|
|
172
|
+
}
|
|
173
|
+
// Skip if revision unchanged
|
|
174
|
+
if (artifact.revision === this.lastRevision)
|
|
175
|
+
return;
|
|
176
|
+
// Verify integrity
|
|
177
|
+
const hash = crypto.createHash("sha256").update(artifact.ciphertext).digest("hex");
|
|
178
|
+
if (hash !== artifact.ciphertextHash) {
|
|
179
|
+
const err = new Error(`Artifact integrity check failed: expected hash ${artifact.ciphertextHash}, got ${hash}`);
|
|
180
|
+
this.telemetry?.artifactInvalid({
|
|
181
|
+
reason: "integrity",
|
|
182
|
+
error: err.message,
|
|
183
|
+
});
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
// Resolve the age private key
|
|
187
|
+
let agePrivateKey;
|
|
188
|
+
if (artifact.envelope) {
|
|
189
|
+
// KMS envelope: unwrap the ephemeral private key via KMS
|
|
190
|
+
try {
|
|
191
|
+
const kms = (0, kms_1.createKmsProvider)(artifact.envelope.provider);
|
|
192
|
+
const wrappedKey = Buffer.from(artifact.envelope.wrappedKey, "base64");
|
|
193
|
+
const unwrapped = await kms.unwrap(artifact.envelope.keyId, wrappedKey, artifact.envelope.algorithm);
|
|
194
|
+
// Note: unwrapped Buffer is zeroed below, but the resulting JS string is
|
|
195
|
+
// immutable and cannot be cleared (inherent V8/Node.js limitation). Accepted risk.
|
|
196
|
+
agePrivateKey = unwrapped.toString("utf-8");
|
|
197
|
+
unwrapped.fill(0);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
this.telemetry?.artifactInvalid({
|
|
201
|
+
reason: "kms_unwrap",
|
|
202
|
+
error: err instanceof Error ? err.message : String(err),
|
|
203
|
+
});
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// Age-only: use the static private key (config error, not artifact.invalid)
|
|
209
|
+
if (!this.options.privateKey) {
|
|
210
|
+
throw new Error("Artifact requires an age private key. Set CLEF_AGENT_AGE_KEY or use KMS envelope encryption.");
|
|
211
|
+
}
|
|
212
|
+
agePrivateKey = this.options.privateKey;
|
|
213
|
+
}
|
|
214
|
+
// Decrypt
|
|
215
|
+
try {
|
|
216
|
+
const plaintext = await this.decryptor.decrypt(artifact.ciphertext, agePrivateKey);
|
|
217
|
+
const values = JSON.parse(plaintext);
|
|
218
|
+
// Atomic swap
|
|
219
|
+
this.options.cache.swap(values, artifact.keys, artifact.revision);
|
|
220
|
+
this.lastRevision = artifact.revision;
|
|
221
|
+
this.lastContentHash = contentHash ?? null;
|
|
222
|
+
this.lastExpiresAt = artifact.expiresAt ?? null;
|
|
223
|
+
this.options.onRefresh?.(artifact.revision);
|
|
224
|
+
this.telemetry?.artifactRefreshed({
|
|
225
|
+
revision: artifact.revision,
|
|
226
|
+
keyCount: artifact.keys.length,
|
|
227
|
+
kmsEnvelope: !!artifact.envelope,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
// Don't double-emit for errors already classified above
|
|
232
|
+
if (err instanceof Error && !err.message.includes("integrity check failed")) {
|
|
233
|
+
this.telemetry?.artifactInvalid({
|
|
234
|
+
reason: err instanceof SyntaxError ? "payload_parse" : "decrypt",
|
|
235
|
+
error: err.message,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
throw err;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/** Start the polling loop. Performs an initial fetch immediately. */
|
|
242
|
+
async start() {
|
|
243
|
+
// Initial fetch — fail fast if source is unreachable
|
|
244
|
+
await this.fetchAndDecrypt();
|
|
245
|
+
this.scheduleNext();
|
|
246
|
+
}
|
|
247
|
+
/** Start only the polling schedule (no initial fetch). */
|
|
248
|
+
startPolling() {
|
|
249
|
+
if (this.timer)
|
|
250
|
+
return;
|
|
251
|
+
this.scheduleNext();
|
|
252
|
+
}
|
|
253
|
+
/** Stop the polling loop. */
|
|
254
|
+
stop() {
|
|
255
|
+
if (this.timer) {
|
|
256
|
+
clearTimeout(this.timer);
|
|
257
|
+
this.timer = null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/** Whether the poller is currently running. */
|
|
261
|
+
isRunning() {
|
|
262
|
+
return this.timer !== null;
|
|
263
|
+
}
|
|
264
|
+
/** Compute the next poll delay and schedule a fetch. */
|
|
265
|
+
scheduleNext() {
|
|
266
|
+
const delayMs = this.computeNextPollMs();
|
|
267
|
+
this.timer = setTimeout(async () => {
|
|
268
|
+
this.timer = null;
|
|
269
|
+
try {
|
|
270
|
+
await this.fetchAndDecrypt();
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
this.options.onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
274
|
+
}
|
|
275
|
+
this.scheduleNext();
|
|
276
|
+
}, delayMs);
|
|
277
|
+
}
|
|
278
|
+
/** Compute ms until next poll: 80% of expiresAt remaining, or cacheTtl / 10 fallback. */
|
|
279
|
+
computeNextPollMs() {
|
|
280
|
+
// If the artifact has an expiresAt, refresh at 80% of remaining time
|
|
281
|
+
if (this.lastExpiresAt) {
|
|
282
|
+
const msRemaining = new Date(this.lastExpiresAt).getTime() - Date.now();
|
|
283
|
+
if (msRemaining > 0) {
|
|
284
|
+
return Math.max(msRemaining * 0.8, MIN_POLL_MS);
|
|
285
|
+
}
|
|
286
|
+
// Already expired — poll immediately (with floor)
|
|
287
|
+
return MIN_POLL_MS;
|
|
288
|
+
}
|
|
289
|
+
// Fallback: derive from cacheTtl (default 30s if no TTL configured)
|
|
290
|
+
const ttl = this.options.cacheTtl;
|
|
291
|
+
if (ttl !== undefined) {
|
|
292
|
+
return Math.max((ttl / 10) * 1000, MIN_POLL_MS);
|
|
293
|
+
}
|
|
294
|
+
return 30_000;
|
|
295
|
+
}
|
|
296
|
+
parseAndValidate(raw) {
|
|
297
|
+
const artifact = JSON.parse(raw);
|
|
298
|
+
if (artifact.version !== 1) {
|
|
299
|
+
throw new Error(`Unsupported artifact version: ${artifact.version}`);
|
|
300
|
+
}
|
|
301
|
+
if (!artifact.ciphertext || !artifact.revision || !artifact.ciphertextHash) {
|
|
302
|
+
throw new Error("Invalid artifact: missing required fields.");
|
|
303
|
+
}
|
|
304
|
+
if (artifact.envelope) {
|
|
305
|
+
if (!artifact.envelope.provider ||
|
|
306
|
+
!artifact.envelope.keyId ||
|
|
307
|
+
!artifact.envelope.wrappedKey ||
|
|
308
|
+
!artifact.envelope.algorithm) {
|
|
309
|
+
throw new Error("Invalid artifact: incomplete envelope fields.");
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return artifact;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.ArtifactPoller = ArtifactPoller;
|
|
316
|
+
/** Classify a validation error from parseAndValidate into a machine-readable reason. */
|
|
317
|
+
function classifyValidationError(err) {
|
|
318
|
+
if (err instanceof SyntaxError)
|
|
319
|
+
return "json_parse";
|
|
320
|
+
const msg = err instanceof Error ? err.message : "";
|
|
321
|
+
if (msg.includes("Unsupported artifact version"))
|
|
322
|
+
return "unsupported_version";
|
|
323
|
+
if (msg.includes("missing required fields"))
|
|
324
|
+
return "missing_fields";
|
|
325
|
+
if (msg.includes("incomplete envelope"))
|
|
326
|
+
return "incomplete_envelope";
|
|
327
|
+
return "unknown";
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=poller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poller.js","sourceRoot":"","sources":["../src/poller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** In-memory secrets cache with single-reference swap. */
|
|
2
|
+
export declare class SecretsCache {
|
|
3
|
+
private snapshot;
|
|
4
|
+
/** Replace the cached secrets in a single reference assignment. */
|
|
5
|
+
swap(values: Record<string, string>, keys: string[], revision: string): void;
|
|
6
|
+
/** Whether the cache has exceeded the given TTL (seconds). */
|
|
7
|
+
isExpired(ttlSeconds: number): boolean;
|
|
8
|
+
/** Clear the cached snapshot. */
|
|
9
|
+
wipe(): void;
|
|
10
|
+
/** Epoch ms when the cache was last swapped, or null if never loaded. */
|
|
11
|
+
getSwappedAt(): number | null;
|
|
12
|
+
/** Get a single secret value by key. Returns undefined if not cached or key missing. */
|
|
13
|
+
get(key: string): string | undefined;
|
|
14
|
+
/** Get all cached secret values. Returns null if not yet loaded. */
|
|
15
|
+
getAll(): Record<string, string> | null;
|
|
16
|
+
/** Get the list of available secret key names. */
|
|
17
|
+
getKeys(): string[];
|
|
18
|
+
/** Get the current artifact revision, or null if not loaded. */
|
|
19
|
+
getRevision(): string | null;
|
|
20
|
+
/** Whether the cache has been loaded at least once. */
|
|
21
|
+
isReady(): boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=secrets-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-cache.d.ts","sourceRoot":"","sources":["../src/secrets-cache.ts"],"names":[],"mappings":"AAOA,0DAA0D;AAC1D,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAA8B;IAE9C,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI5E,8DAA8D;IAC9D,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAKtC,iCAAiC;IACjC,IAAI,IAAI,IAAI;IAIZ,yEAAyE;IACzE,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,wFAAwF;IACxF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpC,oEAAoE;IACpE,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAMvC,kDAAkD;IAClD,OAAO,IAAI,MAAM,EAAE;IAKnB,gEAAgE;IAChE,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,uDAAuD;IACvD,OAAO,IAAI,OAAO;CAGnB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SecretsCache = void 0;
|
|
4
|
+
/** In-memory secrets cache with single-reference swap. */
|
|
5
|
+
class SecretsCache {
|
|
6
|
+
snapshot = null;
|
|
7
|
+
/** Replace the cached secrets in a single reference assignment. */
|
|
8
|
+
swap(values, keys, revision) {
|
|
9
|
+
this.snapshot = { values: { ...values }, keys: [...keys], revision, swappedAt: Date.now() };
|
|
10
|
+
}
|
|
11
|
+
/** Whether the cache has exceeded the given TTL (seconds). */
|
|
12
|
+
isExpired(ttlSeconds) {
|
|
13
|
+
if (!this.snapshot)
|
|
14
|
+
return false;
|
|
15
|
+
return (Date.now() - this.snapshot.swappedAt) / 1000 > ttlSeconds;
|
|
16
|
+
}
|
|
17
|
+
/** Clear the cached snapshot. */
|
|
18
|
+
wipe() {
|
|
19
|
+
this.snapshot = null;
|
|
20
|
+
}
|
|
21
|
+
/** Epoch ms when the cache was last swapped, or null if never loaded. */
|
|
22
|
+
getSwappedAt() {
|
|
23
|
+
return this.snapshot?.swappedAt ?? null;
|
|
24
|
+
}
|
|
25
|
+
/** Get a single secret value by key. Returns undefined if not cached or key missing. */
|
|
26
|
+
get(key) {
|
|
27
|
+
return this.snapshot?.values[key];
|
|
28
|
+
}
|
|
29
|
+
/** Get all cached secret values. Returns null if not yet loaded. */
|
|
30
|
+
getAll() {
|
|
31
|
+
const s = this.snapshot;
|
|
32
|
+
if (!s)
|
|
33
|
+
return null;
|
|
34
|
+
return { ...s.values };
|
|
35
|
+
}
|
|
36
|
+
/** Get the list of available secret key names. */
|
|
37
|
+
getKeys() {
|
|
38
|
+
const s = this.snapshot;
|
|
39
|
+
return s ? [...s.keys] : [];
|
|
40
|
+
}
|
|
41
|
+
/** Get the current artifact revision, or null if not loaded. */
|
|
42
|
+
getRevision() {
|
|
43
|
+
return this.snapshot?.revision ?? null;
|
|
44
|
+
}
|
|
45
|
+
/** Whether the cache has been loaded at least once. */
|
|
46
|
+
isReady() {
|
|
47
|
+
return this.snapshot !== null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.SecretsCache = SecretsCache;
|
|
51
|
+
//# sourceMappingURL=secrets-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-cache.js","sourceRoot":"","sources":["../src/secrets-cache.ts"],"names":[],"mappings":";;;AAOA,0DAA0D;AAC1D,MAAa,YAAY;IACf,QAAQ,GAAyB,IAAI,CAAC;IAE9C,mEAAmE;IACnE,IAAI,CAAC,MAA8B,EAAE,IAAc,EAAE,QAAgB;QACnE,IAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC9F,CAAC;IAED,8DAA8D;IAC9D,SAAS,CAAC,UAAkB;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC;IACpE,CAAC;IAED,iCAAiC;IACjC,IAAI;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,yEAAyE;IACzE,YAAY;QACV,OAAO,IAAI,CAAC,QAAQ,EAAE,SAAS,IAAI,IAAI,CAAC;IAC1C,CAAC;IAED,wFAAwF;IACxF,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,oEAAoE;IACpE,MAAM;QACJ,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxB,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;IACzB,CAAC;IAED,kDAAkD;IAClD,OAAO;QACL,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9B,CAAC;IAED,gEAAgE;IAChE,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,EAAE,QAAQ,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,uDAAuD;IACvD,OAAO;QACL,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC;IAChC,CAAC;CACF;AAnDD,oCAmDC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ArtifactSource, ArtifactFetchResult } from "./types";
|
|
2
|
+
/** Reads an artifact from a local file. */
|
|
3
|
+
export declare class FileArtifactSource implements ArtifactSource {
|
|
4
|
+
private readonly path;
|
|
5
|
+
constructor(filePath: string);
|
|
6
|
+
fetch(): Promise<ArtifactFetchResult>;
|
|
7
|
+
describe(): string;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/sources/file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9D,2CAA2C;AAC3C,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,QAAQ,EAAE,MAAM;IAItB,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAK3C,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FileArtifactSource = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
/** Reads an artifact from a local file. */
|
|
39
|
+
class FileArtifactSource {
|
|
40
|
+
path;
|
|
41
|
+
constructor(filePath) {
|
|
42
|
+
this.path = filePath;
|
|
43
|
+
}
|
|
44
|
+
async fetch() {
|
|
45
|
+
const raw = fs.readFileSync(this.path, "utf-8");
|
|
46
|
+
return { raw };
|
|
47
|
+
}
|
|
48
|
+
describe() {
|
|
49
|
+
return `file ${this.path}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.FileArtifactSource = FileArtifactSource;
|
|
53
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/sources/file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAGzB,2CAA2C;AAC3C,MAAa,kBAAkB;IACZ,IAAI,CAAS;IAE9B,YAAY,QAAgB;QAC1B,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC;IAED,QAAQ;QACN,OAAO,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;CACF;AAfD,gDAeC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ArtifactSource, ArtifactFetchResult } from "./types";
|
|
2
|
+
/** Fetches an artifact from an HTTP(S) URL. */
|
|
3
|
+
export declare class HttpArtifactSource implements ArtifactSource {
|
|
4
|
+
private readonly url;
|
|
5
|
+
constructor(url: string);
|
|
6
|
+
fetch(): Promise<ArtifactFetchResult>;
|
|
7
|
+
describe(): string;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/sources/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9D,+CAA+C;AAC/C,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;gBAEjB,GAAG,EAAE,MAAM;IAIjB,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAU3C,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpArtifactSource = void 0;
|
|
4
|
+
/** Fetches an artifact from an HTTP(S) URL. */
|
|
5
|
+
class HttpArtifactSource {
|
|
6
|
+
url;
|
|
7
|
+
constructor(url) {
|
|
8
|
+
this.url = url;
|
|
9
|
+
}
|
|
10
|
+
async fetch() {
|
|
11
|
+
const res = await fetch(this.url);
|
|
12
|
+
if (!res.ok) {
|
|
13
|
+
throw new Error(`Failed to fetch artifact from ${this.url}: ${res.status}`);
|
|
14
|
+
}
|
|
15
|
+
const raw = await res.text();
|
|
16
|
+
const etag = res.headers.get("etag") ?? undefined;
|
|
17
|
+
return { raw, contentHash: etag };
|
|
18
|
+
}
|
|
19
|
+
describe() {
|
|
20
|
+
return `HTTP ${this.url}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.HttpArtifactSource = HttpArtifactSource;
|
|
24
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/sources/http.ts"],"names":[],"mappings":";;;AAEA,+CAA+C;AAC/C,MAAa,kBAAkB;IACZ,GAAG,CAAS;IAE7B,YAAY,GAAW;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;QAClD,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,QAAQ;QACN,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;IAC5B,CAAC;CACF;AApBD,gDAoBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VcsArtifactSource = exports.FileArtifactSource = exports.HttpArtifactSource = void 0;
|
|
4
|
+
var http_1 = require("./http");
|
|
5
|
+
Object.defineProperty(exports, "HttpArtifactSource", { enumerable: true, get: function () { return http_1.HttpArtifactSource; } });
|
|
6
|
+
var file_1 = require("./file");
|
|
7
|
+
Object.defineProperty(exports, "FileArtifactSource", { enumerable: true, get: function () { return file_1.FileArtifactSource; } });
|
|
8
|
+
var vcs_1 = require("./vcs");
|
|
9
|
+
Object.defineProperty(exports, "VcsArtifactSource", { enumerable: true, get: function () { return vcs_1.VcsArtifactSource; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":";;;AACA,+BAA4C;AAAnC,0GAAA,kBAAkB,OAAA;AAC3B,+BAA4C;AAAnC,0GAAA,kBAAkB,OAAA;AAC3B,6BAA0C;AAAjC,wGAAA,iBAAiB,OAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Result of fetching an artifact from a source. */
|
|
2
|
+
export interface ArtifactFetchResult {
|
|
3
|
+
/** Raw artifact JSON string. */
|
|
4
|
+
raw: string;
|
|
5
|
+
/** VCS SHA / HTTP ETag for change detection. */
|
|
6
|
+
contentHash?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Strategy interface for fetching packed artifacts. */
|
|
9
|
+
export interface ArtifactSource {
|
|
10
|
+
/** Fetch the artifact. */
|
|
11
|
+
fetch(): Promise<ArtifactFetchResult>;
|
|
12
|
+
/** Human-readable description for logging. */
|
|
13
|
+
describe(): string;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtC,8CAA8C;IAC9C,QAAQ,IAAI,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { VcsProvider } from "../vcs/types";
|
|
2
|
+
import { ArtifactSource, ArtifactFetchResult } from "./types";
|
|
3
|
+
/** Fetches a packed artifact from a VCS provider. */
|
|
4
|
+
export declare class VcsArtifactSource implements ArtifactSource {
|
|
5
|
+
private readonly provider;
|
|
6
|
+
private readonly path;
|
|
7
|
+
private readonly identity;
|
|
8
|
+
private readonly environment;
|
|
9
|
+
constructor(provider: VcsProvider, identity: string, environment: string);
|
|
10
|
+
fetch(): Promise<ArtifactFetchResult>;
|
|
11
|
+
describe(): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=vcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vcs.d.ts","sourceRoot":"","sources":["../../src/sources/vcs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9D,qDAAqD;AACrD,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAOlE,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAK3C,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VcsArtifactSource = void 0;
|
|
4
|
+
/** Fetches a packed artifact from a VCS provider. */
|
|
5
|
+
class VcsArtifactSource {
|
|
6
|
+
provider;
|
|
7
|
+
path;
|
|
8
|
+
identity;
|
|
9
|
+
environment;
|
|
10
|
+
constructor(provider, identity, environment) {
|
|
11
|
+
this.provider = provider;
|
|
12
|
+
this.identity = identity;
|
|
13
|
+
this.environment = environment;
|
|
14
|
+
this.path = `.clef/packed/${identity}/${environment}.age.json`;
|
|
15
|
+
}
|
|
16
|
+
async fetch() {
|
|
17
|
+
const result = await this.provider.fetchFile(this.path);
|
|
18
|
+
return { raw: result.content, contentHash: result.sha };
|
|
19
|
+
}
|
|
20
|
+
describe() {
|
|
21
|
+
return `VCS .clef/packed/${this.identity}/${this.environment}.age.json`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.VcsArtifactSource = VcsArtifactSource;
|
|
25
|
+
//# sourceMappingURL=vcs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vcs.js","sourceRoot":"","sources":["../../src/sources/vcs.ts"],"names":[],"mappings":";;;AAGA,qDAAqD;AACrD,MAAa,iBAAiB;IACX,QAAQ,CAAc;IACtB,IAAI,CAAS;IACb,QAAQ,CAAS;IACjB,WAAW,CAAS;IAErC,YAAY,QAAqB,EAAE,QAAgB,EAAE,WAAmB;QACtE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,gBAAgB,QAAQ,IAAI,WAAW,WAAW,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;IAC1D,CAAC;IAED,QAAQ;QACN,OAAO,oBAAoB,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,WAAW,CAAC;IAC1E,CAAC;CACF;AArBD,8CAqBC"}
|