@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.
- package/README.md +52 -1
- package/dist/config-schema.json +73 -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 +87 -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/native-http-effects.js +871 -0
- package/src/build/native-http-shell.js +703 -0
- package/src/build/native-platform-capabilities.js +2109 -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 +73 -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 +260 -0
- package/src/javascript/target.js +73 -0
- package/src/javascript/test-runtime.js +407 -0
- package/src/provider-contract.js +72 -0
- package/src/runtime/assets-provider.js +464 -0
- package/src/runtime/canonical-api-runtime.js +597 -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/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 +599 -0
- package/src/toolchain/config.js +128 -0
- 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
|
+
});
|