@pulse-compute/provider-fastly 0.0.0 → 1.0.0-beta.2
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/README.md +53 -1
- package/dist/config-schema.json +77 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -5
- package/src/build/canonical-target.js +436 -0
- package/src/build/entities-native.js +564 -0
- package/src/build/fixed-memory-runtime.as.ts +148 -0
- package/src/build/kv-native.as.ts +229 -0
- package/src/build/kv-native.js +20 -0
- package/src/build/native-http-effects.js +871 -0
- package/src/build/native-http-shell.js +703 -0
- package/src/build/native-platform-capabilities.js +2196 -0
- package/src/build/s3-native.as.ts +215 -0
- package/src/build/s3-native.js +30 -0
- package/src/compiler/assets-package-out-parity-proof.js +338 -0
- package/src/compiler/assets-provider-proof.js +499 -0
- package/src/compiler/config-provider-resolution.js +573 -0
- package/src/compiler/fastly-adapter.js +564 -0
- package/src/compiler/fastly-command-entry.js +390 -0
- package/src/compiler/fastly-config-secret-serve.js +323 -0
- package/src/compiler/fastly-hostcall-binding.js +598 -0
- package/src/compiler/fastly-readiness.js +477 -0
- package/src/compiler/index.js +40 -0
- package/src/compiler/lifecycle-parity-contract.js +70 -0
- package/src/compiler/lifecycle-parity-proof.js +260 -0
- package/src/compiler/route-handler-effect-proof.js +255 -0
- package/src/compiler/runtime-provider-kv.js +237 -0
- package/src/compiler/runtime-provider-shape.js +109 -0
- package/src/config-api.js +63 -0
- package/src/config-schema.d.ts +13 -0
- package/src/config-schema.js +27 -0
- package/src/config-schema.json +77 -0
- package/src/index.js +3 -0
- package/src/index.ts +118 -0
- package/src/javascript/assets-adapter.js +122 -0
- package/src/javascript/bindings-adapter.js +237 -0
- package/src/javascript/errors.js +26 -0
- package/src/javascript/fetch-adapter.js +93 -0
- package/src/javascript/grip-broadcast.js +261 -0
- package/src/javascript/jwt-verifier.js +137 -0
- package/src/javascript/lifecycle.js +55 -0
- package/src/javascript/local-loader.js +138 -0
- package/src/javascript/logging.js +26 -0
- package/src/javascript/package-effects.js +68 -0
- package/src/javascript/runtime-host.js +108 -0
- package/src/javascript/sha256.js +128 -0
- package/src/javascript/source-package.js +776 -0
- package/src/javascript/support.js +142 -0
- package/src/javascript/target-support-policy.js +264 -0
- package/src/javascript/target.js +73 -0
- package/src/javascript/test-runtime.js +407 -0
- package/src/provider-contract.js +79 -0
- package/src/runtime/assets-provider.js +464 -0
- package/src/runtime/canonical-api-runtime.js +601 -0
- package/src/runtime/index.js +28 -0
- package/src/runtime/provider-primitives-contract.js +272 -0
- package/src/runtime/provider-primitives.js +82 -0
- package/src/runtime/route-handler-effects.js +507 -0
- package/src/testing/conditional-kv-host.js +109 -0
- package/src/testing/fastly-cli.js +538 -0
- package/src/testing/native-http-effects-host.js +390 -0
- package/src/testing/native-http-shell-host.js +190 -0
- package/src/testing/native-platform-capabilities-host.js +676 -0
- package/src/toolchain/config.js +131 -0
- package/src/toolchain/index.js +345 -0
- package/src/toolchain/s3.js +26 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const runtimeApi = require('@pulse-compute/wasm-contracts/handler/runtime-api');
|
|
4
|
+
|
|
5
|
+
const FASTLY_PROVIDER_CONTRACT_VERSION = 'pulse.fastly-provider-contract.v2';
|
|
6
|
+
const primitiveNames = Object.freeze([
|
|
7
|
+
'ProviderRequest',
|
|
8
|
+
'ProviderResponse',
|
|
9
|
+
'ProviderFetch',
|
|
10
|
+
'ProviderConfig',
|
|
11
|
+
'ProviderSecret',
|
|
12
|
+
'ProviderKV',
|
|
13
|
+
'ProviderLog'
|
|
14
|
+
]);
|
|
15
|
+
const ctxSurface = Object.freeze({
|
|
16
|
+
request: Object.freeze(['ctx.req.method', 'ctx.req.url', 'ctx.req.path', 'ctx.req.headers', 'ctx.req.text()', 'ctx.req.json()']),
|
|
17
|
+
response: Object.freeze(['ctx.json()', 'ctx.text()', 'ctx.response()', 'return ctx.fetch(url)']),
|
|
18
|
+
fetch: Object.freeze(['ctx.fetch(url, options)']),
|
|
19
|
+
config: 'ctx.config.get(name)',
|
|
20
|
+
secret: 'ctx.secret.get(name)',
|
|
21
|
+
kv: Object.freeze(['ctx.kv(store).get(key)', 'ctx.kv(store).put(key, value)']),
|
|
22
|
+
log: Object.freeze(['ctx.log.info(message, fields)', 'ctx.log.warn(message, fields)', 'ctx.log.error(message, fields)'])
|
|
23
|
+
});
|
|
24
|
+
const defaults = Object.freeze({
|
|
25
|
+
provider: 'fastly',
|
|
26
|
+
configStore: 'pulse_config',
|
|
27
|
+
secretStore: 'pulse_secrets',
|
|
28
|
+
kvStore: 'pulse_kv',
|
|
29
|
+
allowedMethods: Object.freeze(['GET', 'HEAD', 'POST']),
|
|
30
|
+
defaultTimeoutMs: runtimeApi.limits.fetchTimeoutMs,
|
|
31
|
+
structuredBodyMaxBytes: runtimeApi.limits.structuredBodyBytes,
|
|
32
|
+
opaquePassThrough: true,
|
|
33
|
+
secretRedaction: '[secret:redacted]'
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
function deepFreeze(value) {
|
|
37
|
+
if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
|
|
38
|
+
for (const child of Object.values(value)) deepFreeze(child);
|
|
39
|
+
return Object.freeze(value);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function immutableClone(value) {
|
|
43
|
+
return runtimeApi.body.immutableClone(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function normalizeHeaders(headers) {
|
|
47
|
+
return runtimeApi.body.normalizeHeaders(headers).map(([name, value]) => [String(name).toLowerCase(), String(value)]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function normalizeName(value, fallback = 'VALUE') {
|
|
51
|
+
return String(value || fallback).trim().replace(/[^A-Za-z0-9:_-]+/g, '_') || fallback;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function redactSecretValue(name) {
|
|
55
|
+
return `[secret:${normalizeName(name, 'SECRET')}:redacted]`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function redactSecrets(value, secretNames = []) {
|
|
59
|
+
const names = Array.from(new Set(secretNames.map((name) => normalizeName(name, 'SECRET'))));
|
|
60
|
+
if (Array.isArray(value)) return value.map((entry) => redactSecrets(entry, names));
|
|
61
|
+
if (value && typeof value === 'object') {
|
|
62
|
+
const out = {};
|
|
63
|
+
for (const [key, child] of Object.entries(value)) {
|
|
64
|
+
const lower = String(key).toLowerCase();
|
|
65
|
+
if (lower.includes('secret') || lower.includes('token') || names.some((name) => lower.includes(name.toLowerCase()))) out[key] = redactSecretValue(names[0] || key);
|
|
66
|
+
else out[key] = redactSecrets(child, names);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
const text = String(value ?? '');
|
|
71
|
+
for (const name of names) if (text.includes(name) || /token|secret/i.test(text)) return redactSecretValue(name);
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function createCapabilityManifest(input = {}) {
|
|
76
|
+
const configStore = normalizeName(input.configStore || defaults.configStore, defaults.configStore);
|
|
77
|
+
const secretStore = normalizeName(input.secretStore || defaults.secretStore, defaults.secretStore);
|
|
78
|
+
const kvStore = normalizeName(input.kvStore || defaults.kvStore, defaults.kvStore);
|
|
79
|
+
return deepFreeze({
|
|
80
|
+
kind: 'provider-capability-manifest',
|
|
81
|
+
provider: 'fastly',
|
|
82
|
+
contractVersion: FASTLY_PROVIDER_CONTRACT_VERSION,
|
|
83
|
+
primitives: primitiveNames,
|
|
84
|
+
ctxSurface,
|
|
85
|
+
bindings: { configStore, secretStore, kvStore },
|
|
86
|
+
config: { surface: ctxSurface.config, exactNameOnly: true, enumerable: false, provider: 'fastly.configStore', store: configStore },
|
|
87
|
+
secret: { surface: ctxSurface.secret, exactNameOnly: true, enumerable: false, provider: 'fastly.secretStore', store: secretStore, traceRedacted: true },
|
|
88
|
+
kv: { surface: ctxSurface.kv, provider: 'fastly.kvStore', store: kvStore, operations: ['get', 'put'], deleteReserved: true },
|
|
89
|
+
fetch: { surface: ctxSurface.fetch, methods: defaults.allowedMethods, timeoutMs: defaults.defaultTimeoutMs, opaquePassThrough: true },
|
|
90
|
+
request: { surface: ctxSurface.request, exposesProviderObject: false },
|
|
91
|
+
response: { surface: ctxSurface.response, exposesProviderObject: false, opaquePassThrough: true },
|
|
92
|
+
log: { surface: ctxSurface.log, secretRedaction: true },
|
|
93
|
+
providerSpecificUserland: false,
|
|
94
|
+
providerSdkWrapper: false,
|
|
95
|
+
capabilityDiscoveryFromUserland: false
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function createRequestAdapter(input = {}) {
|
|
100
|
+
return deepFreeze({
|
|
101
|
+
kind: 'ProviderRequest',
|
|
102
|
+
provider: 'fastly',
|
|
103
|
+
method: String(input.method || 'GET').toUpperCase(),
|
|
104
|
+
url: String(input.url || 'https://edge.example.test/'),
|
|
105
|
+
path: String(input.path || '/'),
|
|
106
|
+
query: immutableClone(input.query || {}),
|
|
107
|
+
headers: normalizeHeaders(input.headers || []),
|
|
108
|
+
bodyClass: input.bodyClass || 'structured',
|
|
109
|
+
exposesProviderObject: false,
|
|
110
|
+
providerSpecificUserland: false,
|
|
111
|
+
authority: 'ctx-only'
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function createResponseAdapter(input = {}) {
|
|
116
|
+
const status = Number(input.status || 200);
|
|
117
|
+
const headers = normalizeHeaders(input.headers || [['content-type', input.contentType || 'application/json; charset=utf-8']]);
|
|
118
|
+
const bodyClass = input.bodyClass || 'structured';
|
|
119
|
+
return deepFreeze({
|
|
120
|
+
kind: 'ProviderResponse',
|
|
121
|
+
provider: 'fastly',
|
|
122
|
+
status,
|
|
123
|
+
headers,
|
|
124
|
+
bodyClass,
|
|
125
|
+
bodyKind: input.bodyKind || (bodyClass === 'opaque' ? 'stream' : 'json'),
|
|
126
|
+
preserveStatus: true,
|
|
127
|
+
preserveHeaders: true,
|
|
128
|
+
preserveBodyHandle: bodyClass === 'opaque',
|
|
129
|
+
exposesProviderObject: false,
|
|
130
|
+
providerSpecificUserland: false,
|
|
131
|
+
traceBodyContents: bodyClass !== 'opaque',
|
|
132
|
+
bodyCopiedIntoWasm: bodyClass === 'opaque' ? false : Boolean(input.bodyCopiedIntoWasm)
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function createFetchAdapter(input = {}) {
|
|
137
|
+
const method = String(input.method || 'GET').toUpperCase();
|
|
138
|
+
if (!defaults.allowedMethods.includes(method)) return deepFreeze({ ok: false, error: runtimeApi.errors.hostEffect, method });
|
|
139
|
+
const headers = normalizeHeaders(input.headers || [['accept', 'application/json']]);
|
|
140
|
+
const timeoutMs = Number(input.timeoutMs || defaults.defaultTimeoutMs);
|
|
141
|
+
return deepFreeze({
|
|
142
|
+
kind: 'ProviderFetch',
|
|
143
|
+
provider: 'fastly',
|
|
144
|
+
effect: {
|
|
145
|
+
ok: true,
|
|
146
|
+
kind: 'fetch-request-effect',
|
|
147
|
+
effectKind: 'backend-fetch',
|
|
148
|
+
method,
|
|
149
|
+
url: String(input.url || 'https://api.example.test/'),
|
|
150
|
+
headers,
|
|
151
|
+
timeoutMs,
|
|
152
|
+
bodyClass: Object.prototype.hasOwnProperty.call(input, 'body') ? 'structured' : 'none',
|
|
153
|
+
body: Object.prototype.hasOwnProperty.call(input, 'body') ? String(input.body ?? '') : undefined,
|
|
154
|
+
providerSpecificUserland: false
|
|
155
|
+
},
|
|
156
|
+
dispatch: 'backend-fetch',
|
|
157
|
+
providerSpecificUserland: false,
|
|
158
|
+
supportsStructuredBodies: true,
|
|
159
|
+
supportsOpaquePassThrough: true,
|
|
160
|
+
timeoutMs,
|
|
161
|
+
methods: defaults.allowedMethods
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function createConfigAdapter(values = {}) {
|
|
166
|
+
const store = Object.fromEntries(Object.entries(values).map(([key, value]) => [normalizeName(key), String(value)]));
|
|
167
|
+
return Object.freeze({
|
|
168
|
+
kind: 'ProviderConfig',
|
|
169
|
+
provider: 'fastly',
|
|
170
|
+
store: defaults.configStore,
|
|
171
|
+
exactNameOnly: true,
|
|
172
|
+
enumerable: false,
|
|
173
|
+
providerSpecificUserland: false,
|
|
174
|
+
get(name) {
|
|
175
|
+
const key = normalizeName(name);
|
|
176
|
+
return Object.prototype.hasOwnProperty.call(store, key) ? store[key] : undefined;
|
|
177
|
+
},
|
|
178
|
+
list() { return deepFreeze({ ok: false, error: 'CapabilityDiscoveryError', enumerable: false }); },
|
|
179
|
+
snapshot() { return deepFreeze({ keys: Object.keys(store).sort(), valuesVisibleInTrace: false, exactNameOnly: true }); }
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function createSecretAdapter(values = {}) {
|
|
184
|
+
const store = Object.fromEntries(Object.entries(values).map(([key, value]) => [normalizeName(key), String(value)]));
|
|
185
|
+
return Object.freeze({
|
|
186
|
+
kind: 'ProviderSecret',
|
|
187
|
+
provider: 'fastly',
|
|
188
|
+
store: defaults.secretStore,
|
|
189
|
+
exactNameOnly: true,
|
|
190
|
+
enumerable: false,
|
|
191
|
+
traceRedacted: true,
|
|
192
|
+
providerSpecificUserland: false,
|
|
193
|
+
get(name) {
|
|
194
|
+
const key = normalizeName(name);
|
|
195
|
+
if (!Object.prototype.hasOwnProperty.call(store, key)) return undefined;
|
|
196
|
+
return deepFreeze({ kind: 'secret-value', name: key, value: store[key], redacted: redactSecretValue(key), traceRedacted: true, enumerable: false });
|
|
197
|
+
},
|
|
198
|
+
list() { return deepFreeze({ ok: false, error: 'CapabilityDiscoveryError', enumerable: false, traceRedacted: true }); }
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function createKvAdapter(stores = {}) {
|
|
203
|
+
const normalizedStores = {};
|
|
204
|
+
for (const [storeName, entries] of Object.entries(stores)) normalizedStores[normalizeName(storeName, 'default')] = { ...(entries || {}) };
|
|
205
|
+
function ensureStore(storeName) {
|
|
206
|
+
const name = normalizeName(storeName, 'default');
|
|
207
|
+
if (!normalizedStores[name]) normalizedStores[name] = {};
|
|
208
|
+
return { name, entries: normalizedStores[name] };
|
|
209
|
+
}
|
|
210
|
+
return Object.freeze({
|
|
211
|
+
kind: 'ProviderKV',
|
|
212
|
+
provider: 'fastly',
|
|
213
|
+
exactStoreBinding: true,
|
|
214
|
+
operations: Object.freeze(['get', 'put']),
|
|
215
|
+
deleteReserved: true,
|
|
216
|
+
providerSpecificUserland: false,
|
|
217
|
+
get(storeName, key) {
|
|
218
|
+
const store = ensureStore(storeName);
|
|
219
|
+
const normalizedKey = String(key || '');
|
|
220
|
+
const hit = Object.prototype.hasOwnProperty.call(store.entries, normalizedKey);
|
|
221
|
+
return deepFreeze({ ok: true, operation: 'get', store: store.name, key: normalizedKey, hit, value: hit ? immutableClone(store.entries[normalizedKey]) : undefined });
|
|
222
|
+
},
|
|
223
|
+
put(storeName, key, value) {
|
|
224
|
+
const store = ensureStore(storeName);
|
|
225
|
+
const normalizedKey = String(key || '');
|
|
226
|
+
store.entries[normalizedKey] = immutableClone(value);
|
|
227
|
+
return deepFreeze({ ok: true, operation: 'put', store: store.name, key: normalizedKey, valueStored: true, generation: `${store.name}:${normalizedKey}:1` });
|
|
228
|
+
},
|
|
229
|
+
delete() { return deepFreeze({ ok: false, operation: 'delete', error: 'CapabilityReservedError', reserved: true }); }
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function createLogAdapter(options = {}) {
|
|
234
|
+
const secretNames = Array.isArray(options.secretNames) ? options.secretNames : [];
|
|
235
|
+
const adapter = {
|
|
236
|
+
kind: 'ProviderLog',
|
|
237
|
+
provider: 'fastly',
|
|
238
|
+
traceRedacted: true,
|
|
239
|
+
providerSpecificUserland: false,
|
|
240
|
+
event(level, message, fields = {}) {
|
|
241
|
+
const safeLevel = ['debug', 'info', 'warn', 'error'].includes(String(level)) ? String(level) : 'info';
|
|
242
|
+
return deepFreeze({ level: safeLevel, message: String(message || ''), fields: redactSecrets(fields, secretNames), secretRedactionApplied: true });
|
|
243
|
+
},
|
|
244
|
+
info(message, fields) { return adapter.event('info', message, fields); },
|
|
245
|
+
warn(message, fields) { return adapter.event('warn', message, fields); },
|
|
246
|
+
error(message, fields) { return adapter.event('error', message, fields); }
|
|
247
|
+
};
|
|
248
|
+
return Object.freeze(adapter);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
module.exports = Object.freeze({
|
|
252
|
+
version: FASTLY_PROVIDER_CONTRACT_VERSION,
|
|
253
|
+
primitiveNames,
|
|
254
|
+
ctxSurface,
|
|
255
|
+
ctxSurfaces: ctxSurface,
|
|
256
|
+
defaults,
|
|
257
|
+
capabilityDefaults: defaults,
|
|
258
|
+
deepFreeze,
|
|
259
|
+
immutableClone,
|
|
260
|
+
normalizeHeaders,
|
|
261
|
+
normalizeName,
|
|
262
|
+
redactSecretValue,
|
|
263
|
+
redactSecrets,
|
|
264
|
+
createCapabilityManifest,
|
|
265
|
+
createRequestAdapter,
|
|
266
|
+
createResponseAdapter,
|
|
267
|
+
createFetchAdapter,
|
|
268
|
+
createConfigAdapter,
|
|
269
|
+
createSecretAdapter,
|
|
270
|
+
createKvAdapter,
|
|
271
|
+
createLogAdapter
|
|
272
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const contract = require('./provider-primitives-contract.js');
|
|
4
|
+
|
|
5
|
+
function clone(value) {
|
|
6
|
+
if (Array.isArray(value)) return value.map(clone);
|
|
7
|
+
if (value && typeof value === 'object') return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, clone(child)]));
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function createFastlyProviderPrimitiveSurface(options = {}) {
|
|
12
|
+
const manifest = contract.createCapabilityManifest(options);
|
|
13
|
+
const configAdapter = contract.createConfigAdapter(options.configValues || options.configProvider || {});
|
|
14
|
+
const secretAdapter = contract.createSecretAdapter(options.secretValues || options.secretProvider || {});
|
|
15
|
+
const kvAdapter = contract.createKvAdapter(options.kvStores || options.kvValues || {});
|
|
16
|
+
const logAdapter = contract.createLogAdapter({ secretNames: Object.keys(options.secretValues || options.secretProvider || {}) });
|
|
17
|
+
const logs = [];
|
|
18
|
+
|
|
19
|
+
return Object.freeze({
|
|
20
|
+
kind: 'FastlyProviderPrimitiveSurface',
|
|
21
|
+
provider: 'fastly',
|
|
22
|
+
manifest,
|
|
23
|
+
providerSpecificUserland: false,
|
|
24
|
+
providerSdkWrapper: false,
|
|
25
|
+
request(input) {
|
|
26
|
+
return contract.createRequestAdapter(input);
|
|
27
|
+
},
|
|
28
|
+
response(input) {
|
|
29
|
+
return contract.createResponseAdapter(input);
|
|
30
|
+
},
|
|
31
|
+
fetch(input) {
|
|
32
|
+
return contract.createFetchAdapter(input);
|
|
33
|
+
},
|
|
34
|
+
config: Object.freeze({
|
|
35
|
+
get(name) {
|
|
36
|
+
const value = configAdapter.get(name);
|
|
37
|
+
return contract.deepFreeze({ kind: 'ProviderConfigRead', provider: 'fastly', name: contract.normalizeName(name), value, hit: value !== undefined, exactNameOnly: true, enumerable: false, providerSpecificUserland: false });
|
|
38
|
+
},
|
|
39
|
+
list() { return configAdapter.list(); },
|
|
40
|
+
adapter: configAdapter
|
|
41
|
+
}),
|
|
42
|
+
secret: Object.freeze({
|
|
43
|
+
get(name) {
|
|
44
|
+
const secret = secretAdapter.get(name);
|
|
45
|
+
return contract.deepFreeze({ kind: 'ProviderSecretRead', provider: 'fastly', name: contract.normalizeName(name), hit: Boolean(secret), valueRef: secret ? secret.redacted : undefined, traceValue: secret ? secret.redacted : undefined, traceRedacted: true, enumerable: false, providerSpecificUserland: false });
|
|
46
|
+
},
|
|
47
|
+
list() { return secretAdapter.list(); },
|
|
48
|
+
adapter: secretAdapter
|
|
49
|
+
}),
|
|
50
|
+
kv: Object.freeze({
|
|
51
|
+
get(store, key) { return kvAdapter.get(store || manifest.bindings.kvStore, key); },
|
|
52
|
+
put(store, key, value) { return kvAdapter.put(store || manifest.bindings.kvStore, key, value); },
|
|
53
|
+
delete(store, key) { return kvAdapter.delete(store, key); },
|
|
54
|
+
adapter: kvAdapter
|
|
55
|
+
}),
|
|
56
|
+
log: Object.freeze({
|
|
57
|
+
event(level, message, fields) {
|
|
58
|
+
const event = logAdapter.event(level, message, fields);
|
|
59
|
+
logs.push(event);
|
|
60
|
+
return event;
|
|
61
|
+
},
|
|
62
|
+
info(message, fields) { return this.event('info', message, fields); },
|
|
63
|
+
warn(message, fields) { return this.event('warn', message, fields); },
|
|
64
|
+
error(message, fields) { return this.event('error', message, fields); },
|
|
65
|
+
entries() { return logs.map(clone); },
|
|
66
|
+
adapter: logAdapter
|
|
67
|
+
}),
|
|
68
|
+
diagnostics() {
|
|
69
|
+
return contract.deepFreeze({ provider: 'fastly', primitiveCount: contract.primitiveNames.length, logs: logs.length, secretsRedacted: true, providerSpecificUserland: false, providerSdkWrapper: false });
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function buildFastlyProviderPrimitiveManifest(options = {}) {
|
|
75
|
+
return contract.createCapabilityManifest(options);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
contract,
|
|
80
|
+
createFastlyProviderPrimitiveSurface,
|
|
81
|
+
buildFastlyProviderPrimitiveManifest
|
|
82
|
+
};
|