@pulse-compute/provider-fastly 0.0.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +52 -1
  2. package/dist/config-schema.json +73 -0
  3. package/dist/index.d.ts +61 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +59 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +87 -5
  8. package/src/build/canonical-target.js +436 -0
  9. package/src/build/entities-native.js +564 -0
  10. package/src/build/fixed-memory-runtime.as.ts +148 -0
  11. package/src/build/native-http-effects.js +871 -0
  12. package/src/build/native-http-shell.js +703 -0
  13. package/src/build/native-platform-capabilities.js +2109 -0
  14. package/src/compiler/assets-package-out-parity-proof.js +338 -0
  15. package/src/compiler/assets-provider-proof.js +499 -0
  16. package/src/compiler/config-provider-resolution.js +573 -0
  17. package/src/compiler/fastly-adapter.js +564 -0
  18. package/src/compiler/fastly-command-entry.js +390 -0
  19. package/src/compiler/fastly-config-secret-serve.js +323 -0
  20. package/src/compiler/fastly-hostcall-binding.js +598 -0
  21. package/src/compiler/fastly-readiness.js +477 -0
  22. package/src/compiler/index.js +40 -0
  23. package/src/compiler/lifecycle-parity-contract.js +70 -0
  24. package/src/compiler/lifecycle-parity-proof.js +260 -0
  25. package/src/compiler/route-handler-effect-proof.js +255 -0
  26. package/src/compiler/runtime-provider-kv.js +237 -0
  27. package/src/compiler/runtime-provider-shape.js +109 -0
  28. package/src/config-api.js +63 -0
  29. package/src/config-schema.d.ts +13 -0
  30. package/src/config-schema.js +27 -0
  31. package/src/config-schema.json +73 -0
  32. package/src/index.js +3 -0
  33. package/src/index.ts +118 -0
  34. package/src/javascript/assets-adapter.js +122 -0
  35. package/src/javascript/bindings-adapter.js +237 -0
  36. package/src/javascript/errors.js +26 -0
  37. package/src/javascript/fetch-adapter.js +93 -0
  38. package/src/javascript/grip-broadcast.js +261 -0
  39. package/src/javascript/jwt-verifier.js +137 -0
  40. package/src/javascript/lifecycle.js +55 -0
  41. package/src/javascript/local-loader.js +138 -0
  42. package/src/javascript/logging.js +26 -0
  43. package/src/javascript/package-effects.js +68 -0
  44. package/src/javascript/runtime-host.js +108 -0
  45. package/src/javascript/sha256.js +128 -0
  46. package/src/javascript/source-package.js +776 -0
  47. package/src/javascript/support.js +142 -0
  48. package/src/javascript/target-support-policy.js +260 -0
  49. package/src/javascript/target.js +73 -0
  50. package/src/javascript/test-runtime.js +407 -0
  51. package/src/provider-contract.js +72 -0
  52. package/src/runtime/assets-provider.js +464 -0
  53. package/src/runtime/canonical-api-runtime.js +597 -0
  54. package/src/runtime/index.js +28 -0
  55. package/src/runtime/provider-primitives-contract.js +272 -0
  56. package/src/runtime/provider-primitives.js +82 -0
  57. package/src/runtime/route-handler-effects.js +507 -0
  58. package/src/testing/fastly-cli.js +538 -0
  59. package/src/testing/native-http-effects-host.js +390 -0
  60. package/src/testing/native-http-shell-host.js +190 -0
  61. package/src/testing/native-platform-capabilities-host.js +599 -0
  62. package/src/toolchain/config.js +128 -0
  63. package/src/toolchain/index.js +343 -0
@@ -0,0 +1,128 @@
1
+ 'use strict';
2
+
3
+ function providerConfigError(code, message, detail) {
4
+ const error = new TypeError(message);
5
+ error.code = code;
6
+ error.detail = Object.freeze({ ...detail });
7
+ return error;
8
+ }
9
+
10
+ function normalizeStringMap(input, code) {
11
+ if (input === undefined) return Object.freeze({});
12
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
13
+ throw providerConfigError(code, 'Provider binding maps must be objects.', {
14
+ valueType: Array.isArray(input) ? 'array' : typeof input
15
+ });
16
+ }
17
+ return Object.freeze(Object.fromEntries(
18
+ Object.entries(input).map(([key, value]) => [String(key), String(value)])
19
+ ));
20
+ }
21
+
22
+ function normalizeFastlyProviderConfig(value) {
23
+ const input = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
24
+ const bindings = input.bindings && typeof input.bindings === 'object' && !Array.isArray(input.bindings)
25
+ ? input.bindings
26
+ : {};
27
+ const local = input.local && typeof input.local === 'object' && !Array.isArray(input.local)
28
+ ? input.local
29
+ : {};
30
+ const gripInput = bindings.grip && typeof bindings.grip === 'object' && !Array.isArray(bindings.grip)
31
+ ? bindings.grip
32
+ : {};
33
+ return Object.freeze({
34
+ kind: 'fastly',
35
+ version: input.version ? String(input.version) : undefined,
36
+ bindings: Object.freeze({
37
+ configStore: String(bindings.configStore || 'pulse_config'),
38
+ secretStore: String(bindings.secretStore || 'pulse_secrets'),
39
+ kv: normalizeStringMap(bindings.kv, 'PULSE_FASTLY_KV_BINDINGS_INVALID'),
40
+ backends: normalizeStringMap(bindings.backends, 'PULSE_FASTLY_BACKEND_BINDINGS_INVALID'),
41
+ grip: Object.freeze({
42
+ fanoutBackend: gripInput.fanoutBackend === undefined ? undefined : String(gripInput.fanoutBackend),
43
+ publishEndpoint: gripInput.publishEndpoint === undefined ? undefined : String(gripInput.publishEndpoint),
44
+ publishUrl: gripInput.publishUrl === undefined ? undefined : String(gripInput.publishUrl),
45
+ publishBackend: gripInput.publishBackend === undefined ? undefined : String(gripInput.publishBackend),
46
+ authentication: gripInput.authentication === undefined ? undefined : Object.freeze({
47
+ scheme: String(gripInput.authentication && gripInput.authentication.scheme || 'bearer').toLowerCase(),
48
+ secretRef: String(gripInput.authentication && gripInput.authentication.secretRef || '')
49
+ }),
50
+ directHold: gripInput.directHold !== false
51
+ }),
52
+ dynamicBackends: bindings.dynamicBackends === true
53
+ }),
54
+ build: Object.freeze({
55
+ name: String(input.build && input.build.name || 'pulse-app'),
56
+ description: String(input.build && input.build.description || 'Pulse application'),
57
+ authors: Object.freeze(Array.isArray(input.build && input.build.authors) ? input.build.authors.map(String) : [])
58
+ }),
59
+ local: Object.freeze({ networkFetch: local.networkFetch === true }),
60
+ providerSpecificUserland: false
61
+ });
62
+ }
63
+
64
+ function fastlyProjectConfigDocument(config) {
65
+ return Object.freeze({
66
+ kind: 'fastly',
67
+ bindings: config.bindings,
68
+ build: config.build,
69
+ local: config.local,
70
+ providerSpecificUserland: false
71
+ });
72
+ }
73
+
74
+ function fastlyInitTemplate(name) {
75
+ return Object.freeze({
76
+ profileFragment: ` fastly: {
77
+ bindings: {
78
+ configStore: 'pulse_config',
79
+ secretStore: 'pulse_secrets',
80
+ kv: { sessions: 'sessions' },
81
+ dynamicBackends: false,
82
+ },
83
+ build: { name: '${name}' },
84
+ },
85
+ `,
86
+ dependencies: Object.freeze({
87
+ '@pulse-compute/provider-fastly': require('../../package.json').version
88
+ })
89
+ });
90
+ }
91
+
92
+ const FASTLY_PROJECT_CONFIG_REFERENCE = Object.freeze({
93
+ sections: Object.freeze([
94
+ Object.freeze({
95
+ id: 'fastly',
96
+ title: 'Fastly provider options',
97
+ description: 'Options passed to fastly(...) from @pulse-compute/provider-fastly.'
98
+ })
99
+ ]),
100
+ fields: Object.freeze([
101
+ Object.freeze({ section: 'fastly', path: 'fastly.configStore', type: 'string', default: '`pulse_config`', scope: 'Fastly config capability', description: 'Fastly Config Store resource name.' }),
102
+ Object.freeze({ section: 'fastly', path: 'fastly.secretStore', type: 'string', default: '`pulse_secrets`', scope: 'Fastly secret capability', description: 'Fastly Secret Store resource name.', security: 'The name is build metadata; secret values are never embedded by this option.' }),
103
+ Object.freeze({ section: 'fastly', path: 'fastly.kv', type: 'Readonly<Record<string, string>>', default: '`{}`', scope: 'Fastly KV capability', description: 'Maps logical ctx.kv names to Fastly KV Store resource names.', diagnostics: Object.freeze(['PULSE_FASTLY_KV_BINDINGS_INVALID']) }),
104
+ Object.freeze({ section: 'fastly', path: 'fastly.backends', type: 'Readonly<Record<string, string>>', default: '`{}`', scope: 'Fastly fetch capability', description: 'Maps static absolute origin URLs to named Fastly backends.', security: 'Prefer explicit backends over dynamic origin authority.', diagnostics: Object.freeze(['PULSE_FASTLY_BACKEND_BINDINGS_INVALID', 'PULSE_FASTLY_BACKEND_REQUIRED']) }),
105
+ Object.freeze({ section: 'fastly', path: 'fastly.dynamicBackends', type: 'boolean', default: '`false`', scope: 'Fastly fetch capability', description: 'Allows undeclared outbound origins to use dynamic backends.', security: 'Opt in deliberately because it broadens outbound authority.', diagnostics: Object.freeze(['PULSE_FASTLY_BACKEND_REQUIRED']) }),
106
+ Object.freeze({ section: 'fastly', path: 'fastly.grip', type: 'object', default: 'omitted', scope: 'Fastly GRIP capability', description: 'Provider-owned bindings used by package-owned GRIP compatibility and canonical broadcast effects.' }),
107
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.fanoutBackend', type: 'string', default: 'omitted', scope: 'GRIP hold', description: 'Named Fastly Fanout backend.', diagnostics: Object.freeze(['PULSE_FASTLY_GRIP_FANOUT_BACKEND_REQUIRED']) }),
108
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.publishEndpoint', type: 'string', default: 'omitted', scope: 'GRIP broadcast', description: 'Provider-owned absolute publish/control endpoint; distinct from public gateway and ingress URLs.', diagnostics: Object.freeze(['PULSE_FASTLY_GRIP_PUBLISH_BINDING_REQUIRED']) }),
109
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.publishUrl', type: 'string', default: 'omitted', scope: 'GRIP publish', description: 'Absolute publish endpoint URL.', diagnostics: Object.freeze(['PULSE_FASTLY_GRIP_PUBLISH_BINDING_REQUIRED']) }),
110
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.publishBackend', type: 'string', default: 'omitted', scope: 'GRIP broadcast/publish', description: 'Named backend for the provider publish endpoint.', diagnostics: Object.freeze(['PULSE_FASTLY_GRIP_PUBLISH_BINDING_REQUIRED']) }),
111
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.authentication', type: 'object', default: 'omitted', scope: 'GRIP broadcast authentication', description: 'Authentication metadata containing references only; no credential value is accepted here.', security: 'Store the value in Fastly Secret Store and configure only secretRef.' }),
112
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.authentication.scheme', type: "'bearer'", default: '`bearer`', scope: 'GRIP broadcast authentication', description: 'Provider authentication scheme.', diagnostics: Object.freeze(['PULSE_FASTLY_NATIVE_GRIP_AUTH_SCHEME_UNSUPPORTED']) }),
113
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.authentication.secretRef', type: 'string', default: 'omitted', scope: 'GRIP broadcast authentication', description: 'Named Fastly Secret Store key used for the bearer token.', security: 'The secret value is resolved only at request execution and is redacted from traces.', diagnostics: Object.freeze(['PULSE_FASTLY_NATIVE_GRIP_SECRET_REFERENCE_MISSING']) }),
114
+ Object.freeze({ section: 'fastly', path: 'fastly.grip.directHold', type: 'boolean', default: '`true`', scope: 'GRIP hold', description: 'Enables the direct host-owned hold response realization.' }),
115
+ Object.freeze({ section: 'fastly', path: 'fastly.name', type: 'string', default: '`pulse-app`', scope: 'Fastly package metadata', description: 'Generated Fastly package name.' }),
116
+ Object.freeze({ section: 'fastly', path: 'fastly.description', type: 'string', default: '`Pulse application`', scope: 'Fastly package metadata', description: 'Generated Fastly package description.' }),
117
+ Object.freeze({ section: 'fastly', path: 'fastly.authors', type: 'readonly string[]', default: '`[]`', scope: 'Fastly package metadata', description: 'Generated Fastly package authors.' }),
118
+ Object.freeze({ section: 'fastly', path: 'fastly.local', type: 'object', default: '`{}`', scope: 'local Fastly conformance', description: 'Local-only behavior; it does not alter the deployed target.' }),
119
+ Object.freeze({ section: 'fastly', path: 'fastly.local.networkFetch', type: 'boolean', default: '`false`', scope: 'local Fastly fetch realization', description: 'Allows unmatched local Fastly fetches to use the network.', precedence: '`dev.networkFetch` overrides this value when explicitly set.', security: 'Keep disabled for deterministic tests and offline development.' })
120
+ ])
121
+ });
122
+
123
+ module.exports = Object.freeze({
124
+ normalizeFastlyProviderConfig,
125
+ fastlyProjectConfigDocument,
126
+ fastlyInitTemplate,
127
+ FASTLY_PROJECT_CONFIG_REFERENCE
128
+ });
@@ -0,0 +1,343 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const {
5
+ PROVIDER_DRIVER_VERSION,
6
+ PROVIDER_TARGET_RESULT_VERSION,
7
+ PROVIDER_PACKAGING_AUDIT_VERSION,
8
+ defineProviderToolchain,
9
+ defineProviderDriver,
10
+ normalizeProviderTargetResult,
11
+ normalizeProviderJavascriptPackageResult
12
+ } = require('@pulse-compute/wasm-contracts/provider/toolchain');
13
+ const { defineFinalWasmPolicy, FINAL_WASM_POLICY_VERSION } = require('@pulse-compute/wasm-contracts/provider/final-wasm-policy');
14
+ const { defineCryptoTargetCapabilities } = require('@pulse-compute/wasm-contracts/crypto/contracts');
15
+ const nativeRuntime = require('@pulse-compute/wasm-contracts/handler/canonical-native-runtime');
16
+ const fastlyRuntime = require('../runtime/canonical-api-runtime.js');
17
+ const { writeFastlyCanonicalTarget, inspectFastlyCanonicalTarget } = require('../build/canonical-target.js');
18
+ const { FASTLY_NATIVE_PLATFORM_CAPABILITIES_IMPORTS } = require('../build/native-platform-capabilities.js');
19
+ const { FASTLY_PROVIDER_DESCRIPTOR, createFastlyLoweringPlan } = require('../provider-contract.js');
20
+ const { FASTLY_JAVASCRIPT_TARGET_DESCRIPTOR } = require('../javascript/target.js');
21
+ const { FASTLY_JAVASCRIPT_TARGET_SUPPORT_DECLARATION } = require('../javascript/support.js');
22
+ const {
23
+ classifyFastlyJavascriptCapability,
24
+ classifyFastlyJavascriptProviderRequirement,
25
+ fastlyJavascriptProjectRestrictions
26
+ } = require('../javascript/target-support-policy.js');
27
+ const fastlyJavascriptTestRuntime = require('../javascript/test-runtime.js');
28
+ const fastlyJavascriptLocalLoader = require('../javascript/local-loader.js');
29
+ const { writeFastlyJavascriptSourcePackage } = require('../javascript/source-package.js');
30
+ const {
31
+ normalizeFastlyProviderConfig,
32
+ fastlyProjectConfigDocument,
33
+ fastlyInitTemplate,
34
+ FASTLY_PROJECT_CONFIG_REFERENCE
35
+ } = require('./config.js');
36
+ const packageManifest = require('../../package.json');
37
+
38
+ const reportingTargetCapability = Object.freeze({
39
+ supported: true,
40
+ default: 'info',
41
+ levels: Object.freeze(['off', 'error', 'warn', 'info', 'debug'])
42
+ });
43
+
44
+ const fastlyFinalWasmPolicy = defineFinalWasmPolicy({
45
+ version: FINAL_WASM_POLICY_VERSION,
46
+ descriptorOwner: packageManifest.name,
47
+ toolchainVersion: 'pulse.provider-toolchain.v1',
48
+ descriptorIdentity: 'fastly-compute-native',
49
+ permittedImports: FASTLY_NATIVE_PLATFORM_CAPABILITIES_IMPORTS
50
+ .map(([module, name]) => ({ module, name, kind: 'function' })),
51
+ requiredExports: nativeRuntime.CANONICAL_NATIVE_EXPORTS.map(([name, second]) => ({
52
+ name,
53
+ kind: second === 'memory' ? 'memory' : 'function'
54
+ }))
55
+ });
56
+
57
+ function adjustPackages(packages, restrictions) {
58
+ return packages.map((entry) => {
59
+ if (!entry.required) return entry;
60
+ const packageRestriction = entry.contractId === 'pulse.assets'
61
+ ? restrictions.assets
62
+ : (entry.contractId === 'pulse.grip' ? restrictions.grip : null);
63
+ if (!packageRestriction) return entry;
64
+ return Object.freeze({
65
+ ...entry,
66
+ status: 'blocked',
67
+ reasonId: packageRestriction.reasonId,
68
+ owner: packageRestriction.owner
69
+ });
70
+ });
71
+ }
72
+
73
+ function createDriver() {
74
+ return defineProviderDriver({
75
+ version: PROVIDER_DRIVER_VERSION,
76
+ id: 'fastly',
77
+ descriptor: FASTLY_PROVIDER_DESCRIPTOR,
78
+ executable: true,
79
+ localExecution: true,
80
+ deployable: true,
81
+ deploymentValidated: false,
82
+ sourcePackage: true,
83
+ compiledWasm: true,
84
+ defaultBuildMode: 'native-provider',
85
+ sourceOnlySupported: false,
86
+ targetSupport: Object.freeze({ javascript: FASTLY_JAVASCRIPT_TARGET_SUPPORT_DECLARATION }),
87
+ normalizeConfig: normalizeFastlyProviderConfig,
88
+ defaultLocalNetworkFetch: false,
89
+ projectConfigDocument: fastlyProjectConfigDocument,
90
+ configReference: FASTLY_PROJECT_CONFIG_REFERENCE,
91
+ initTemplate: fastlyInitTemplate,
92
+ javascript: Object.freeze({
93
+ kind: 'provider-bundled',
94
+ localEmulation: true,
95
+ buildTimeLoader: true,
96
+ localExecutionMode: fastlyJavascriptTestRuntime.FASTLY_JAVASCRIPT_LOCAL_EXECUTION_MODE,
97
+ realityRunner: 'fastly compute serve',
98
+ targetSupportPolicy: Object.freeze({
99
+ providerId: 'fastly',
100
+ declaration: FASTLY_JAVASCRIPT_TARGET_SUPPORT_DECLARATION,
101
+ context: fastlyJavascriptProjectRestrictions,
102
+ classifyCapability: classifyFastlyJavascriptCapability,
103
+ classifyProviderRequirement(id, _compilerCapabilities, restrictions) {
104
+ return classifyFastlyJavascriptProviderRequirement(id, restrictions);
105
+ },
106
+ packageOptions: Object.freeze({
107
+ suppliedCoreOwner: 'runtime',
108
+ packageResolutionReasonId: 'fastly-esbuild-package-resolution-planned',
109
+ packageResolutionOwner: 'provider-fastly',
110
+ packageRuntimeOwner: 'provider-fastly'
111
+ }),
112
+ adjustPackages,
113
+ commandOptions: Object.freeze({ projectScopedBuild: true })
114
+ }),
115
+ loadApplication(plan, options) {
116
+ return fastlyJavascriptLocalLoader.loadFastlyJavascriptLocalApplication(plan, {
117
+ projectRoot: options.projectRoot,
118
+ schemaBundle: options.schemaBundle
119
+ });
120
+ },
121
+ writeSourcePackage(invocation) {
122
+ return normalizeProviderJavascriptPackageResult(writeFastlyJavascriptSourcePackage({
123
+ plan: invocation.applicationPlan,
124
+ projectRoot: invocation.project.root,
125
+ outDir: invocation.project.outDir,
126
+ schemaBundle: invocation.javascript.schemaBundle,
127
+ providerConfig: invocation.providerConfig,
128
+ reporting: invocation.javascript.reporting,
129
+ strict: invocation.javascript.strict,
130
+ maxStructuredBodyBytes: invocation.javascript.maxStructuredBodyBytes,
131
+ targetSupport: invocation.javascript.targetSupport
132
+ }), { provider: 'fastly' });
133
+ },
134
+ describeSourcePackage(sourcePackage, context) {
135
+ return Object.freeze({
136
+ deploymentCandidate: true,
137
+ downstreamJavascriptRuntimeWasm: true,
138
+ application: Object.freeze({
139
+ entry: path.relative(context.outDir, sourcePackage.paths.entry).replace(/\\/g, '/'),
140
+ modules: context.plan.graph.modules.filter((entry) => entry.runtime).length,
141
+ bundledApplication: path.relative(context.outDir, sourcePackage.paths.bundledApplication).replace(/\\/g, '/'),
142
+ deployment: path.basename(sourcePackage.paths.deployment),
143
+ deploymentCandidate: path.basename(sourcePackage.paths.deploymentCandidate),
144
+ fastlyToml: path.basename(sourcePackage.paths.fastlyToml),
145
+ buildConfig: path.basename(sourcePackage.paths.buildConfig),
146
+ bundledInputs: sourcePackage.manifest.summary.bundledInputs
147
+ }),
148
+ files: Object.freeze({
149
+ bundledApplication: sourcePackage.paths.bundledApplication,
150
+ deployment: sourcePackage.paths.deployment,
151
+ deploymentCandidate: sourcePackage.paths.deploymentCandidate,
152
+ fastlyToml: sourcePackage.paths.fastlyToml,
153
+ buildConfig: sourcePackage.paths.buildConfig
154
+ })
155
+ });
156
+ },
157
+ executeTestCase(application, testCase, options) {
158
+ return fastlyJavascriptTestRuntime.executeFastlyJavascriptTestCase(application, testCase, options);
159
+ },
160
+ createLocalEnvironment: fastlyJavascriptTestRuntime.createFastlyJavascriptLocalEnvironment,
161
+ createTestRequest: fastlyJavascriptTestRuntime.createFastlyJavascriptTestRequest,
162
+ executeLocalRequest: fastlyJavascriptTestRuntime.executeFastlyJavascriptLocalRequest
163
+ }),
164
+ targets: Object.freeze({
165
+ native: Object.freeze({
166
+ version: 'pulse.provider-target-descriptor.v1',
167
+ target: 'native',
168
+ targetId: 'fastly-compute-native',
169
+ runtimeClass: 'native',
170
+ status: 'supported',
171
+ capabilities: Object.freeze([
172
+ 'jwt.verify',
173
+ 'jwt.verify.hs256',
174
+ 'jwt.verify.es256',
175
+ 'secret.get',
176
+ 'time.wall-clock'
177
+ ]),
178
+ keyTypes: Object.freeze(['secret', 'jwk', 'jwks']),
179
+ realizations: Object.freeze([
180
+ Object.freeze({
181
+ kind: 'crypto-composed',
182
+ realization: 'guest-source:pulse-hmac-as',
183
+ implementation: 'pulse-hmac-as.v1',
184
+ algorithms: Object.freeze(['HS256']),
185
+ keyTypes: Object.freeze(['secret']),
186
+ implemented: true,
187
+ status: 'implemented-e2',
188
+ semanticOwner: '@pulse-compute/crypto',
189
+ guestUnitRequired: false,
190
+ portable: true,
191
+ automaticFallback: false
192
+ }),
193
+ Object.freeze({
194
+ kind: 'crypto-composed',
195
+ realization: 'guest-linked:pulse-es256-rustcrypto-p256',
196
+ implementation: 'rustcrypto.p256-0.13.2.ecdsa-0.16.9.sha2-0.10.9.v1',
197
+ algorithms: Object.freeze(['ES256']),
198
+ keyTypes: Object.freeze(['jwk', 'jwks']),
199
+ implemented: true,
200
+ status: 'implemented-g4',
201
+ semanticOwner: '@pulse-compute/crypto',
202
+ guestUnitRequired: true,
203
+ portable: true,
204
+ automaticFallback: false
205
+ })
206
+ ]),
207
+ jwt: Object.freeze({
208
+ status: 'implemented-e2',
209
+ realization: 'guest-source:pulse-hmac-as',
210
+ implementation: 'pulse-hmac-as.v1',
211
+ packageSource: 'pulse-jwt-as',
212
+ providerAuthorities: Object.freeze([
213
+ 'request',
214
+ 'secret',
215
+ 'wall-clock',
216
+ 'schema',
217
+ 'error-transport'
218
+ ]),
219
+ automaticFallback: false
220
+ }),
221
+ automaticFallback: false,
222
+ crypto: defineCryptoTargetCapabilities({
223
+ target: 'native',
224
+ algorithms: [{
225
+ algorithm: 'HS256',
226
+ realization: 'guest-source:pulse-hmac-as',
227
+ implemented: true,
228
+ status: 'implemented-c3'
229
+ }, {
230
+ algorithm: 'ES256',
231
+ realization: 'guest-linked:pulse-es256-rustcrypto-p256',
232
+ implemented: true,
233
+ status: 'implemented-g4'
234
+ }]
235
+ }),
236
+ finalWasmPolicy: fastlyFinalWasmPolicy,
237
+ reporting: reportingTargetCapability,
238
+ commands: Object.freeze({ compile: true, inspect: true, doctor: true, build: true, test: true, dev: true })
239
+ }),
240
+ javascript: FASTLY_JAVASCRIPT_TARGET_DESCRIPTOR
241
+ }),
242
+ execute: fastlyRuntime.executeCanonicalProgram,
243
+ createLoweringPlan(metadata, providerConfig = {}) {
244
+ return createFastlyLoweringPlan(metadata, providerConfig.bindings || {});
245
+ },
246
+ inspectRealization(invocation) {
247
+ const realization = inspectFastlyCanonicalTarget({
248
+ plan: invocation.applicationPlan,
249
+ providerPlan: invocation.providerPlan,
250
+ providerConfig: invocation.providerConfig,
251
+ projectRoot: invocation.project.root,
252
+ profile: invocation.project.profile,
253
+ targetDescriptor: invocation.selectedTarget,
254
+ synchronizedPackages: invocation.synchronizedPackages,
255
+ realizationArtifacts: invocation.nativeArtifact.realizationArtifacts,
256
+ guestUnits: invocation.nativeArtifact.guestUnits,
257
+ nativeOptimization: invocation.optimization,
258
+ compileTimeoutMs: invocation.timeoutMs
259
+ });
260
+ const { native, ...publicRealization } = realization;
261
+ return normalizeProviderTargetResult({
262
+ version: PROVIDER_TARGET_RESULT_VERSION,
263
+ action: 'inspect-native',
264
+ provider: 'fastly',
265
+ target: 'native',
266
+ status: 'inspected',
267
+ automaticFallback: false,
268
+ files: Object.freeze({}),
269
+ build: null,
270
+ realization: publicRealization,
271
+ packaging: null
272
+ });
273
+ },
274
+ writeTarget(invocation) {
275
+ const inspected = inspectFastlyCanonicalTarget({
276
+ plan: invocation.applicationPlan,
277
+ providerPlan: invocation.providerPlan,
278
+ providerConfig: invocation.providerConfig,
279
+ projectRoot: invocation.project.root,
280
+ profile: invocation.project.profile,
281
+ targetDescriptor: invocation.selectedTarget,
282
+ synchronizedPackages: invocation.synchronizedPackages,
283
+ realizationArtifacts: invocation.nativeArtifact.realizationArtifacts,
284
+ guestUnits: invocation.nativeArtifact.guestUnits,
285
+ nativeOptimization: invocation.optimization,
286
+ compileTimeoutMs: invocation.timeoutMs
287
+ });
288
+ const providerBuild = writeFastlyCanonicalTarget({
289
+ outDir: invocation.project.outDir,
290
+ plan: invocation.applicationPlan,
291
+ providerPlan: invocation.providerPlan,
292
+ native: inspected.native,
293
+ providerConfig: invocation.providerConfig,
294
+ bindings: invocation.providerConfig.bindings,
295
+ projectRoot: invocation.project.root,
296
+ profile: invocation.project.profile,
297
+ targetDescriptor: invocation.selectedTarget,
298
+ synchronizedPackages: invocation.synchronizedPackages
299
+ });
300
+ const { native, ...publicRealization } = inspected;
301
+ const audit = native.guestLink && native.guestLink.audit;
302
+ return normalizeProviderTargetResult({
303
+ version: PROVIDER_TARGET_RESULT_VERSION,
304
+ action: 'write-native',
305
+ provider: 'fastly',
306
+ target: 'native',
307
+ status: 'built',
308
+ automaticFallback: false,
309
+ files: Object.freeze({
310
+ provider: providerBuild.providerFile,
311
+ providerEntry: providerBuild.entryFile,
312
+ providerBuild: providerBuild.buildFile,
313
+ providerWasm: providerBuild.wasmFile,
314
+ providerWat: providerBuild.watFile,
315
+ providerNativePlan: providerBuild.nativePlanFile,
316
+ providerNativeManifest: providerBuild.nativeManifestFile,
317
+ fastlyToml: providerBuild.fastlyTomlFile,
318
+ providerPackage: providerBuild.packageFile,
319
+ providerSourceEntry: providerBuild.sourceEntryFile
320
+ }),
321
+ build: providerBuild.build,
322
+ realization: publicRealization,
323
+ packaging: audit ? Object.freeze({
324
+ version: PROVIDER_PACKAGING_AUDIT_VERSION,
325
+ artifactSha256: providerBuild.build.wasm.sha256,
326
+ auditedSha256: audit.artifact.sha256,
327
+ authorized: native.guestLink.providerPackaging.authorized === true
328
+ }) : null
329
+ });
330
+ },
331
+ executionOptions(providerConfig = {}, values = {}) {
332
+ return { ...values, bindings: providerConfig.bindings };
333
+ }
334
+ });
335
+ }
336
+
337
+ module.exports = defineProviderToolchain({
338
+ version: 'pulse.provider-toolchain.v1',
339
+ id: 'fastly',
340
+ packageName: packageManifest.name,
341
+ packageVersion: packageManifest.version,
342
+ createDriver
343
+ });