@pulse-compute/provider-fastly 0.0.0 → 1.0.0-beta.10
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 +103 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -5
- package/src/build/canonical-target.js +469 -0
- package/src/build/digest-native.js +25 -0
- package/src/build/effect-invocations.js +49 -0
- package/src/build/embedded-assets.as.ts +32 -0
- package/src/build/entities-native.js +559 -0
- package/src/build/fixed-memory-runtime.as.ts +148 -0
- package/src/build/kv-native.as.ts +331 -0
- package/src/build/kv-native.js +27 -0
- package/src/build/native-application-errors.js +159 -0
- package/src/build/native-binary-resources.js +30 -0
- package/src/build/native-body-forwarding.as.ts +341 -0
- package/src/build/native-body-forwarding.js +69 -0
- package/src/build/native-dynamic-backends.as.ts +115 -0
- package/src/build/native-dynamic-backends.js +52 -0
- package/src/build/native-fetch-deadlines.as.ts +164 -0
- package/src/build/native-fetch-deadlines.js +27 -0
- package/src/build/native-fetch-errors.js +38 -0
- package/src/build/native-handle-ownership.js +127 -0
- package/src/build/native-header-lookup.js +50 -0
- package/src/build/native-http-effects.js +994 -0
- package/src/build/native-http-shell.js +703 -0
- package/src/build/native-platform-capabilities.js +2654 -0
- package/src/build/native-request-body.js +44 -0
- package/src/build/native-request-headers.js +93 -0
- package/src/build/native-send-error-detail.as.ts +12 -0
- package/src/build/native-stdio.js +45 -0
- package/src/build/native-string-values.js +143 -0
- package/src/build/native-transport-details.as.ts +84 -0
- package/src/build/native-value-budget.js +90 -0
- package/src/build/package-native-application.js +114 -0
- package/src/build/request-budget.as.ts +50 -0
- package/src/build/request-budget.js +47 -0
- package/src/build/s3-body.as.ts +97 -0
- package/src/build/s3-native.as.ts +228 -0
- package/src/build/s3-native.js +30 -0
- package/src/build/schema-admission.js +83 -0
- package/src/build/schema-nested-json.js +93 -0
- package/src/build/schema-scalar-record.js +41 -0
- package/src/build/time-native.js +49 -0
- package/src/build/wasm-budget.js +28 -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 +69 -0
- package/src/config-schema.d.ts +13 -0
- package/src/config-schema.js +27 -0
- package/src/config-schema.json +103 -0
- package/src/index.js +3 -0
- package/src/index.ts +143 -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 +147 -0
- package/src/javascript/lifecycle.js +55 -0
- package/src/javascript/local-loader.js +138 -0
- package/src/javascript/logging.js +35 -0
- package/src/javascript/package-effects.js +71 -0
- package/src/javascript/runtime-host.js +112 -0
- package/src/javascript/sha256.js +128 -0
- package/src/javascript/source-package.js +778 -0
- package/src/javascript/support.js +142 -0
- package/src/javascript/target-support-policy.js +277 -0
- package/src/javascript/target.js +89 -0
- package/src/javascript/test-runtime.js +408 -0
- package/src/provider-contract.js +88 -0
- package/src/runtime/assets-provider.js +464 -0
- package/src/runtime/canonical-api-runtime.js +603 -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 +155 -0
- package/src/testing/fastly-cli.js +538 -0
- package/src/testing/native-dynamic-backends-host.js +39 -0
- package/src/testing/native-http-effects-host.js +398 -0
- package/src/testing/native-http-shell-host.js +190 -0
- package/src/testing/native-platform-capabilities-host.js +924 -0
- package/src/toolchain/body-forwarding.js +25 -0
- package/src/toolchain/config.js +144 -0
- package/src/toolchain/index.js +386 -0
- package/src/toolchain/logging.js +18 -0
- package/src/toolchain/native-execution.js +78 -0
- package/src/toolchain/s3.js +26 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { schemaHasScalarRecord } = require('@pulse-compute/wasm-contracts/schema-json/registry');
|
|
4
|
+
|
|
5
|
+
function hasScalarRecords(plan) {
|
|
6
|
+
return (plan.schemas?.registry?.schemas || []).some(schema => schemaHasScalarRecord(schema.root));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Both Fastly Native realizations validate handles before json-as sees them.
|
|
10
|
+
function scalarRecordProjectionLines(node) {
|
|
11
|
+
const limits = node.limits;
|
|
12
|
+
return [
|
|
13
|
+
' if (input.kind != PULSE_VALUE_OBJECT || (checkDuplicates && input.duplicateJsonKeys)) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 56, -1); return 0 }',
|
|
14
|
+
` if (input.keys.length > ${limits.maxKeys}) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 56, -1); return 0 }`,
|
|
15
|
+
' const keys = input.keys.slice().sort()',
|
|
16
|
+
' const output = host_value_object()',
|
|
17
|
+
' let bytes = 2',
|
|
18
|
+
' for (let i = 0; i < keys.length; i++) {',
|
|
19
|
+
' const key = keys[i]',
|
|
20
|
+
` if (key.length > ${limits.maxKeyLength}) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 56, -1); return 0 }`,
|
|
21
|
+
' const keyHandle = __pulse_fastly_string_value(key)',
|
|
22
|
+
' const itemHandle = host_value_property(valueHandle, keyHandle)',
|
|
23
|
+
' const item = __pulse_fastly_value(itemHandle)',
|
|
24
|
+
' let size = 0',
|
|
25
|
+
' if (item.kind == PULSE_VALUE_STRING) {',
|
|
26
|
+
` if (item.text.length > ${limits.maxStringLength}) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 56, -1); return 0 }`,
|
|
27
|
+
' size = __pulse_scalar_record_string_bytes(item.text)',
|
|
28
|
+
' } else if (item.kind == PULSE_VALUE_NUMBER && isFinite(item.number)) {',
|
|
29
|
+
` size = ${limits.numberBytes}`,
|
|
30
|
+
' } else if (item.kind == PULSE_VALUE_BOOLEAN) size = item.boolean != 0 ? 4 : 5',
|
|
31
|
+
' else if (item.kind == PULSE_VALUE_NULL) size = 4',
|
|
32
|
+
' else { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 56, -1); return 0 }',
|
|
33
|
+
' bytes += (i == 0 ? 0 : 1) + __pulse_scalar_record_string_bytes(key) + 1 + size',
|
|
34
|
+
` if (bytes > ${limits.maxBytes}) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 56, -1); return 0 }`,
|
|
35
|
+
' host_value_object_set(output, keyHandle, itemHandle)',
|
|
36
|
+
' }',
|
|
37
|
+
' return output'
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = { hasScalarRecords, scalarRecordProjectionLines };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Provider-owned realtime sampling. The portable guest still suspends through
|
|
4
|
+
// effect_begin; no clock import is exposed to application-authored code.
|
|
5
|
+
function timeNativeSource(plan) {
|
|
6
|
+
if (!(plan.effects || []).some(effect => effect.kind === 'time.now')) return '';
|
|
7
|
+
return `
|
|
8
|
+
function __pulse_time_pad(value: i32, width: i32): string {
|
|
9
|
+
let text = value.toString()
|
|
10
|
+
while (text.length < width) text = "0" + text
|
|
11
|
+
return text
|
|
12
|
+
}
|
|
13
|
+
function __pulse_time_iso(ms: u64): string {
|
|
14
|
+
// Gregorian civil date from whole days since the Unix epoch.
|
|
15
|
+
const z = <i32>(ms / 86400000) + 719468
|
|
16
|
+
const era = z / 146097
|
|
17
|
+
const doe = z - era * 146097
|
|
18
|
+
const yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365
|
|
19
|
+
let year = yoe + era * 400
|
|
20
|
+
const doy = doe - (365 * yoe + yoe / 4 - yoe / 100)
|
|
21
|
+
const mp = (5 * doy + 2) / 153
|
|
22
|
+
const day = doy - (153 * mp + 2) / 5 + 1
|
|
23
|
+
const month = mp + (mp < 10 ? 3 : -9)
|
|
24
|
+
if (month <= 2) year += 1
|
|
25
|
+
const rest = <i32>(ms % 86400000)
|
|
26
|
+
return __pulse_time_pad(year, 4) + "-" + __pulse_time_pad(month, 2) + "-" + __pulse_time_pad(day, 2)
|
|
27
|
+
+ "T" + __pulse_time_pad(rest / 3600000, 2) + ":" + __pulse_time_pad((rest / 60000) % 60, 2)
|
|
28
|
+
+ ":" + __pulse_time_pad((rest / 1000) % 60, 2) + "." + __pulse_time_pad(rest % 1000, 3) + "Z"
|
|
29
|
+
}
|
|
30
|
+
function __pulse_fastly_time_begin(effectIndex: i32, payload: __PulseFastlyValue): void {
|
|
31
|
+
const out = new StaticArray<u64>(1)
|
|
32
|
+
const status = wasi_snapshot_preview1_clock_time_get(0, 1000000, changetype<usize>(out))
|
|
33
|
+
const result = host_value_object()
|
|
34
|
+
if (status != 0) {
|
|
35
|
+
host_value_object_set(result, __pulse_fastly_string_value("status"), __pulse_fastly_string_value("failed"))
|
|
36
|
+
host_value_object_set(result, __pulse_fastly_string_value("reason"), __pulse_fastly_string_value("unavailable"))
|
|
37
|
+
} else {
|
|
38
|
+
// Divide integer nanoseconds before conversion to f64 to retain millisecond precision.
|
|
39
|
+
const ms = unchecked(out[0]) / 1000000
|
|
40
|
+
host_value_object_set(result, __pulse_fastly_string_value("status"), __pulse_fastly_string_value("ok"))
|
|
41
|
+
host_value_object_set(result, __pulse_fastly_string_value("unixEpochMs"), host_value_number(<f64>ms))
|
|
42
|
+
host_value_object_set(result, __pulse_fastly_string_value("iso8601"), __pulse_fastly_string_value(__pulse_time_iso(ms)))
|
|
43
|
+
}
|
|
44
|
+
__pulse_fastly_ready_effect(effectIndex, result)
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = Object.freeze({ timeNativeSource });
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { fastlyConfigDefault } = require('../config-schema.js');
|
|
4
|
+
const DEFAULT_FASTLY_MAX_WASM_BYTES = fastlyConfigDefault('fastly.build.maxWasmBytes');
|
|
5
|
+
|
|
6
|
+
function normalizeFastlyMaxWasmBytes(value) {
|
|
7
|
+
if (value === undefined) return DEFAULT_FASTLY_MAX_WASM_BYTES;
|
|
8
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
9
|
+
const error = new TypeError('fastly.build.maxWasmBytes must be a positive safe integer byte count.');
|
|
10
|
+
error.code = 'PULSE_FASTLY_MAX_WASM_BYTES_INVALID';
|
|
11
|
+
throw error;
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function assertFastlyWasmBudget(bytes, value) {
|
|
17
|
+
const maxBytes = normalizeFastlyMaxWasmBytes(value);
|
|
18
|
+
if (bytes > maxBytes) {
|
|
19
|
+
const error = new Error('Generated Fastly Native module exceeds the configured Pulse compilation budget.');
|
|
20
|
+
error.name = 'FastlyNativePlatformCapabilitiesError';
|
|
21
|
+
error.code = 'PULSE_FASTLY_NATIVE_PLATFORM_CAPABILITIES_WASM_TOO_LARGE';
|
|
22
|
+
error.detail = Object.freeze({ bytes, maxBytes });
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
return maxBytes;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = Object.freeze({ DEFAULT_FASTLY_MAX_WASM_BYTES, normalizeFastlyMaxWasmBytes, assertFastlyWasmBudget });
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function loadAssetsContracts() {
|
|
4
|
+
try {
|
|
5
|
+
return require('@pulse-compute/wasm-contracts/assets/contracts');
|
|
6
|
+
} catch (error) {
|
|
7
|
+
if (error && error.code === 'MODULE_NOT_FOUND' && String(error.message).includes('@pulse-compute/wasm-contracts')) {
|
|
8
|
+
return require('../../../../wasm/packages/contracts/src/assets/contracts.js');
|
|
9
|
+
}
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function loadDiagnostics() {
|
|
15
|
+
try {
|
|
16
|
+
return require('@pulse-compute/wasm-contracts/diagnostics');
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error && error.code === 'MODULE_NOT_FOUND' && String(error.message).includes('@pulse-compute/wasm-contracts')) {
|
|
19
|
+
return require('../../../../wasm/packages/contracts/src/diagnostics.js');
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const assetsContracts = loadAssetsContracts();
|
|
26
|
+
const { PACKAGE_VERSION, normalizeArtifact, normalizeDiagnostic } = loadDiagnostics();
|
|
27
|
+
const { buildFastlyAssetsProviderProof } = require('./assets-provider-proof.js');
|
|
28
|
+
const { buildFastlyAssetsProviderConfig } = require('../runtime/assets-provider.js');
|
|
29
|
+
|
|
30
|
+
const phaseName = 'fastly-assets-package-out-parity-proof';
|
|
31
|
+
|
|
32
|
+
function clone(value) {
|
|
33
|
+
if (Array.isArray(value)) return value.map(clone);
|
|
34
|
+
if (value && typeof value === 'object') return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, clone(entry)]));
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function normalize(input) {
|
|
39
|
+
return input && input.artifact && typeof input.artifact === 'object' ? input.artifact : input;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function makeDiagnostic(code, message, severity = 'error', details) {
|
|
43
|
+
return normalizeDiagnostic({
|
|
44
|
+
phase: phaseName,
|
|
45
|
+
severity,
|
|
46
|
+
code,
|
|
47
|
+
message,
|
|
48
|
+
hint: details && details.hint,
|
|
49
|
+
details,
|
|
50
|
+
loc: { file: '<fastly-assets-package-out-parity-proof>' }
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function check(name, passed, details, failures, diagnostics) {
|
|
55
|
+
const entry = { name, status: passed ? 'ok' : 'error', details: details || {} };
|
|
56
|
+
if (!passed) {
|
|
57
|
+
failures.push(entry);
|
|
58
|
+
diagnostics.push(makeDiagnostic(
|
|
59
|
+
assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_PACKAGE_OUT_PARITY_SMOKE_FAILED,
|
|
60
|
+
`Fastly assets package-out parity check failed: ${name}.`,
|
|
61
|
+
'error',
|
|
62
|
+
{ check: name, details: entry.details }
|
|
63
|
+
));
|
|
64
|
+
}
|
|
65
|
+
return entry;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function checkByName(proof, needle) {
|
|
69
|
+
const checks = proof && proof.smoke && Array.isArray(proof.smoke.checks) ? proof.smoke.checks : [];
|
|
70
|
+
return checks.some((entry) => entry && String(entry.name || '').includes(needle) && entry.status === 'ok');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function summaryFlag(proof, name) {
|
|
74
|
+
return Boolean(proof && proof.summary && proof.summary[name] === true);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function packageOutDiscovered(packageOutProof) {
|
|
78
|
+
return Boolean(packageOutProof && (
|
|
79
|
+
packageOutProof.discoveredFromNodeModules === true ||
|
|
80
|
+
(packageOutProof.discovery && packageOutProof.discovery.discoveredFromNodeModules === true) ||
|
|
81
|
+
(packageOutProof.summary && packageOutProof.summary.discoveredFromNodeModules === true)
|
|
82
|
+
));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function builderLoadedFromPackageOut(packageOutProof) {
|
|
86
|
+
const compilerBuilder = packageOutProof && packageOutProof.discovery && packageOutProof.discovery.compilerBuilder;
|
|
87
|
+
return Boolean(compilerBuilder &&
|
|
88
|
+
compilerBuilder.builderOwner === '@pulse-compute/assets' &&
|
|
89
|
+
String(compilerBuilder.entry || '').includes('node_modules/@pulse-compute/assets/pulsewasm.compiler.cjs'));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function packageOwnedLowerer(plan) {
|
|
93
|
+
const policy = plan && plan.policy || {};
|
|
94
|
+
return Boolean(plan &&
|
|
95
|
+
plan.npmPackage === '@pulse-compute/assets' &&
|
|
96
|
+
plan.lowerableSubpath === '@pulse-compute/assets' &&
|
|
97
|
+
policy.builderOwner === '@pulse-compute/assets' &&
|
|
98
|
+
policy.compilerOwnsPackageMapping === false);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function providerProofOrBuild(options, plan, diagnostics) {
|
|
102
|
+
const provided = normalize(options.fastlyAssetsProviderProof || options.providerProof);
|
|
103
|
+
if (provided) return { artifact: provided, diagnostics: [] };
|
|
104
|
+
if (!plan) return undefined;
|
|
105
|
+
const proof = buildFastlyAssetsProviderProof({
|
|
106
|
+
cwd: options.cwd,
|
|
107
|
+
generatedBy: options.generatedBy || PACKAGE_VERSION,
|
|
108
|
+
assetsLoweringPlan: plan,
|
|
109
|
+
resolvedConfig: options.resolvedConfig,
|
|
110
|
+
fastlyHostcallBinding: options.fastlyHostcallBinding,
|
|
111
|
+
fastlyAdapter: options.fastlyAdapter,
|
|
112
|
+
requestResultHeaders: options.requestResultHeaders,
|
|
113
|
+
streamingPassthrough: options.streamingPassthrough,
|
|
114
|
+
wasmHostAbi: options.wasmHostAbi
|
|
115
|
+
});
|
|
116
|
+
diagnostics.push(...(proof.diagnostics || []));
|
|
117
|
+
return proof;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function buildFastlyAssetsPackageOutParityProof(options = {}) {
|
|
121
|
+
const cwd = options.cwd || process.cwd();
|
|
122
|
+
const generatedBy = options.generatedBy || PACKAGE_VERSION;
|
|
123
|
+
const plan = normalize(options.assetsLoweringPlan || options.plan);
|
|
124
|
+
const sidecarPlan = normalize(options.assetsCompiledWasmSidecarPlan || options.sidecarPlan);
|
|
125
|
+
const packageOutProof = normalize(options.assetsPackageOutDiscoveryProof || options.packageOutDiscoveryProof || options.packageOutProof);
|
|
126
|
+
const nodeCompiledProof = normalize(options.nodeCompiledWasmAssetsLifecycleProof || options.nodeProof);
|
|
127
|
+
const diagnostics = [];
|
|
128
|
+
const failures = [];
|
|
129
|
+
const checks = [];
|
|
130
|
+
|
|
131
|
+
if (!plan) {
|
|
132
|
+
diagnostics.push(makeDiagnostic(
|
|
133
|
+
assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_PACKAGE_OUT_PARITY_PLAN_REQUIRED,
|
|
134
|
+
'Fastly assets package-out parity proof requires assets-lowering-plan.json.',
|
|
135
|
+
'error',
|
|
136
|
+
{ sourceArtifact: assetsContracts.ASSETS_LOWERING_PLAN_VERSION }
|
|
137
|
+
));
|
|
138
|
+
}
|
|
139
|
+
if (!sidecarPlan) {
|
|
140
|
+
diagnostics.push(makeDiagnostic(
|
|
141
|
+
assetsContracts.ASSETS_DIAGNOSTIC_CODES.SIDECAR_FILE_MISSING,
|
|
142
|
+
'Fastly assets package-out parity proof requires assets-compiled-wasm-sidecar-plan.json so compiled-Wasm readiness can be classified honestly.',
|
|
143
|
+
'error',
|
|
144
|
+
{ sourceArtifact: assetsContracts.ASSETS_COMPILED_WASM_SIDECAR_PLAN_ARTIFACT }
|
|
145
|
+
));
|
|
146
|
+
}
|
|
147
|
+
const sidecarPackageOut = sidecarPlan && sidecarPlan.packageOut ? sidecarPlan.packageOut : undefined;
|
|
148
|
+
if (!packageOutProof && !(sidecarPackageOut && sidecarPackageOut.discoveredFromNodeModules === true && sidecarPackageOut.builderLoadedFromNodeModules === true)) {
|
|
149
|
+
diagnostics.push(makeDiagnostic(
|
|
150
|
+
assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_PACKAGE_OUT_PARITY_PLAN_REQUIRED,
|
|
151
|
+
'Fastly assets package-out parity proof requires assets-package-out-discovery-proof.json or sidecar package-out evidence to prove packaged @pulse-compute/assets discovery.',
|
|
152
|
+
'error',
|
|
153
|
+
{ sourceArtifact: assetsContracts.ASSETS_PACKAGE_OUT_DISCOVERY_PROOF_ARTIFACT }
|
|
154
|
+
));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const fastlyProviderProof = providerProofOrBuild(options, plan, diagnostics);
|
|
158
|
+
const providerProofArtifact = fastlyProviderProof && normalize(fastlyProviderProof);
|
|
159
|
+
const providerConfig = options.providerConfig || (providerProofArtifact && providerProofArtifact.providerConfig) || buildFastlyAssetsProviderConfig({ plan, resolvedConfig: options.resolvedConfig });
|
|
160
|
+
|
|
161
|
+
const packageOwnedLoweringConsumed = packageOwnedLowerer(plan);
|
|
162
|
+
const discoveredFromPackagedAssets = packageOutDiscovered(packageOutProof) || Boolean(sidecarPackageOut && sidecarPackageOut.discoveredFromNodeModules === true);
|
|
163
|
+
const packageBuilderLoaded = builderLoadedFromPackageOut(packageOutProof) || Boolean(sidecarPackageOut && sidecarPackageOut.builderLoadedFromNodeModules === true);
|
|
164
|
+
const symbolicStoreConfigValidated = Boolean(providerConfig && providerConfig.provider === 'fastly' && providerConfig.symbolicRefsOnly === true && Array.isArray(providerConfig.stores) && providerConfig.stores.length > 0 && providerConfig.stores.every((store) => String(store.endpointRef || '').startsWith('$config:') && String(store.bucketRef || '').startsWith('$config:') && String(store.keyRef || '').startsWith('$secret:')));
|
|
165
|
+
const getMappingValidated = summaryFlag(providerProofArtifact, 'getTextValidated');
|
|
166
|
+
const headMappingValidated = summaryFlag(providerProofArtifact, 'headValidated');
|
|
167
|
+
const headersValidated = checkByName(providerProofArtifact, 'headers/status pass through') || Boolean(providerProofArtifact && providerProofArtifact.payloadModes && providerProofArtifact.payloadModes.headerPassThrough && providerProofArtifact.payloadModes.headerPassThrough.status === 'implemented-now');
|
|
168
|
+
const cacheControlValidated = checkByName(providerProofArtifact, 'cache-control policy is preserved');
|
|
169
|
+
const notFoundPolicyValidated = summaryFlag(providerProofArtifact, 'notFoundValidated');
|
|
170
|
+
const binaryBodyReserved = summaryFlag(providerProofArtifact, 'binaryReservedValidated') || Boolean(providerProofArtifact && providerProofArtifact.payloadModes && providerProofArtifact.payloadModes.binaryBodyBufferResponse && providerProofArtifact.payloadModes.binaryBodyBufferResponse.status === 'reserved-with-diagnostic');
|
|
171
|
+
const streamProviderProofImplemented = Boolean(providerProofArtifact && providerProofArtifact.payloadModes && providerProofArtifact.payloadModes.streamPassThroughResponse && providerProofArtifact.payloadModes.streamPassThroughResponse.status === 'implemented-fastly-proof');
|
|
172
|
+
const terminalSidecarPlanned = Boolean(sidecarPlan && sidecarPlan.summary && sidecarPlan.summary.terminalAssetResponseEffectPlanned === true);
|
|
173
|
+
const sidecarPackaged = Boolean((sidecarPlan && sidecarPlan.summary && sidecarPlan.summary.packageOutSidecarValidated === true) || (sidecarPackageOut && sidecarPackageOut.discoveredFromNodeModules === true && sidecarPackageOut.sidecarFile));
|
|
174
|
+
const nodeCompiledReferenceImplemented = Boolean(nodeCompiledProof && nodeCompiledProof.compiledWasmLowering === true && nodeCompiledProof.compiledWasmRuntimeBehaviorImplemented === true);
|
|
175
|
+
|
|
176
|
+
checks.push(check('package_owned_lowering_consumed', packageOwnedLoweringConsumed, { package: plan && plan.npmPackage, lowerableSubpath: plan && plan.lowerableSubpath, policy: plan && plan.policy }, failures, diagnostics));
|
|
177
|
+
checks.push(check('packaged_assets_discovered_from_node_modules', discoveredFromPackagedAssets && packageBuilderLoaded, { discoveredFromNodeModules: discoveredFromPackagedAssets, packageBuilderLoaded, compilerBuilder: packageOutProof && packageOutProof.discovery && packageOutProof.discovery.compilerBuilder }, failures, diagnostics));
|
|
178
|
+
checks.push(check('symbolic_fastly_store_config_validated', symbolicStoreConfigValidated, { providerConfig }, failures, diagnostics));
|
|
179
|
+
checks.push(check('get_mapping_validated', getMappingValidated, { summary: providerProofArtifact && providerProofArtifact.summary }, failures, diagnostics));
|
|
180
|
+
checks.push(check('head_mapping_validated', headMappingValidated, { summary: providerProofArtifact && providerProofArtifact.summary }, failures, diagnostics));
|
|
181
|
+
checks.push(check('headers_validated', headersValidated, { headerPassThrough: providerProofArtifact && providerProofArtifact.payloadModes && providerProofArtifact.payloadModes.headerPassThrough }, failures, diagnostics));
|
|
182
|
+
checks.push(check('cache_control_validated', cacheControlValidated, { checks: providerProofArtifact && providerProofArtifact.smoke && providerProofArtifact.smoke.checks }, failures, diagnostics));
|
|
183
|
+
checks.push(check('not_found_policy_validated', notFoundPolicyValidated, { summary: providerProofArtifact && providerProofArtifact.summary }, failures, diagnostics));
|
|
184
|
+
checks.push(check('sidecar_readiness_classified', terminalSidecarPlanned && sidecarPackaged, { terminalAssetResponseEffectPlanned: terminalSidecarPlanned, packageOutSidecarValidated: sidecarPackaged, summary: sidecarPlan && sidecarPlan.summary }, failures, diagnostics));
|
|
185
|
+
checks.push(check('binary_body_reserved', binaryBodyReserved, { binaryBodyBufferResponse: providerProofArtifact && providerProofArtifact.payloadModes && providerProofArtifact.payloadModes.binaryBodyBufferResponse }, failures, diagnostics));
|
|
186
|
+
checks.push(check('no_external_fastly_service_required', Boolean(providerProofArtifact && providerProofArtifact.scope && providerProofArtifact.scope.configSecretRefs === 'symbolic-only') && providerProofArtifact.proofMode === 'direct-fastly-provider-smoke-connected-to-lowering-plan', { proofMode: providerProofArtifact && providerProofArtifact.proofMode, scope: providerProofArtifact && providerProofArtifact.scope }, failures, diagnostics));
|
|
187
|
+
|
|
188
|
+
diagnostics.push(makeDiagnostic(
|
|
189
|
+
assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY,
|
|
190
|
+
'Fastly compiled-Wasm assets terminal response execution is explicitly plan-only until a provider-owned compiled-Wasm Fastly bridge is wired.',
|
|
191
|
+
'warning',
|
|
192
|
+
{ compiledWasmAssetsReadiness: 'plan-only', nodeReferenceCompiledLifecycleImplemented: nodeCompiledReferenceImplemented }
|
|
193
|
+
));
|
|
194
|
+
|
|
195
|
+
const errorDiagnostics = diagnostics.filter((entry) => (entry.severity || 'error') === 'error');
|
|
196
|
+
const artifact = normalizeArtifact({
|
|
197
|
+
version: assetsContracts.ASSETS_FASTLY_PACKAGE_OUT_PARITY_PROOF_VERSION,
|
|
198
|
+
generatedBy,
|
|
199
|
+
phase: '50',
|
|
200
|
+
artifact: assetsContracts.ASSETS_FASTLY_PACKAGE_OUT_PARITY_PROOF_ARTIFACT,
|
|
201
|
+
contractId: assetsContracts.ASSETS_CONTRACT_ID,
|
|
202
|
+
status: errorDiagnostics.length === 0 ? 'ok' : 'error',
|
|
203
|
+
provider: 'fastly',
|
|
204
|
+
providerPackage: '@pulse-compute/provider-fastly',
|
|
205
|
+
package: '@pulse-compute/assets',
|
|
206
|
+
lowerableSubpath: plan && plan.lowerableSubpath || '@pulse-compute/assets',
|
|
207
|
+
sourceAssetsLoweringPlanVersion: plan && plan.version,
|
|
208
|
+
sourceAssetsCompiledWasmSidecarPlanVersion: sidecarPlan && sidecarPlan.version,
|
|
209
|
+
sourcePackageOutDiscoveryProofVersion: packageOutProof && packageOutProof.version,
|
|
210
|
+
sourceFastlyAssetsProviderProofVersion: providerProofArtifact && providerProofArtifact.version,
|
|
211
|
+
sourceNodeCompiledWasmAssetsLifecycleProofVersion: nodeCompiledProof && nodeCompiledProof.version,
|
|
212
|
+
packageOwnedLoweringConsumed,
|
|
213
|
+
discoveredFromPackagedAssets,
|
|
214
|
+
symbolicStoreConfigValidated,
|
|
215
|
+
getMappingValidated,
|
|
216
|
+
headMappingValidated,
|
|
217
|
+
headersValidated,
|
|
218
|
+
cacheControlValidated,
|
|
219
|
+
notFoundPolicyValidated,
|
|
220
|
+
compiledWasmAssetsReadiness: 'plan-only',
|
|
221
|
+
compiledWasmPlanOnlyDiagnostic: assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY,
|
|
222
|
+
binaryBodyReserved,
|
|
223
|
+
streamBodyReadiness: streamProviderProofImplemented ? 'provider-proof-implemented-compiled-wasm-plan-only' : 'plan-only',
|
|
224
|
+
noExternalFastlyServiceRequired: true,
|
|
225
|
+
actualNetworkFetch: false,
|
|
226
|
+
policy: {
|
|
227
|
+
compilerOrchestratesOnly: true,
|
|
228
|
+
packageOwnsLoweringSurface: true,
|
|
229
|
+
packageOwnedLowererConsumed: packageOwnedLoweringConsumed,
|
|
230
|
+
providerOwnsFastlyBehavior: true,
|
|
231
|
+
noExternalFastlyServiceRequired: true,
|
|
232
|
+
packageOutFixtureRequired: true,
|
|
233
|
+
monorepoAssetsSourcePathRequired: false,
|
|
234
|
+
compiledWasmAssetsReadiness: 'plan-only',
|
|
235
|
+
directProviderProofFallback: false,
|
|
236
|
+
symbolicStoreConfigOnly: true,
|
|
237
|
+
objectStoreMutationApis: false,
|
|
238
|
+
uploads: false,
|
|
239
|
+
invalidation: false,
|
|
240
|
+
binaryBody: false,
|
|
241
|
+
streamProviderProofImplemented,
|
|
242
|
+
streamCompiledWasmReadiness: 'plan-only'
|
|
243
|
+
},
|
|
244
|
+
packageOut: {
|
|
245
|
+
packagePacked: Boolean(packageOutProof && packageOutProof.checks && packageOutProof.checks.packagePacked),
|
|
246
|
+
discoveredFromNodeModules: discoveredFromPackagedAssets,
|
|
247
|
+
compilerBuilderLoadedFromNodeModules: packageBuilderLoaded,
|
|
248
|
+
packageTarballIncludesManifest: Boolean(packageOutProof && packageOutProof.checks && packageOutProof.checks.packageTarballIncludesManifest),
|
|
249
|
+
packageTarballIncludesCompilerBuilder: Boolean(packageOutProof && packageOutProof.checks && packageOutProof.checks.packageTarballIncludesCompilerBuilder),
|
|
250
|
+
packageTarballIncludesPulseWasmFacade: Boolean(packageOutProof && packageOutProof.checks && packageOutProof.checks.packageTarballIncludesPulseWasmFacade),
|
|
251
|
+
packageTarballIncludesSidecar: Boolean(packageOutProof && packageOutProof.checks && packageOutProof.checks.packageTarballIncludesSidecar),
|
|
252
|
+
monorepoSourcePathRequired: false,
|
|
253
|
+
npmRegistryRequired: false
|
|
254
|
+
},
|
|
255
|
+
fastly: {
|
|
256
|
+
providerConfig: clone(providerConfig),
|
|
257
|
+
providerProof: providerProofArtifact ? {
|
|
258
|
+
version: providerProofArtifact.version,
|
|
259
|
+
status: providerProofArtifact.status,
|
|
260
|
+
proofMode: providerProofArtifact.proofMode,
|
|
261
|
+
summary: clone(providerProofArtifact.summary),
|
|
262
|
+
payloadModes: clone(providerProofArtifact.payloadModes)
|
|
263
|
+
} : undefined,
|
|
264
|
+
symbolicStoreConfig: {
|
|
265
|
+
validated: symbolicStoreConfigValidated,
|
|
266
|
+
configStore: providerConfig && providerConfig.configStore,
|
|
267
|
+
secretStore: providerConfig && providerConfig.secretStore,
|
|
268
|
+
stores: providerConfig && providerConfig.stores
|
|
269
|
+
},
|
|
270
|
+
mapping: {
|
|
271
|
+
get: getMappingValidated,
|
|
272
|
+
head: headMappingValidated,
|
|
273
|
+
headers: headersValidated,
|
|
274
|
+
cacheControl: cacheControlValidated,
|
|
275
|
+
notFound: notFoundPolicyValidated
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
compiledWasm: {
|
|
279
|
+
sidecarDeclared: Boolean(sidecarPlan && sidecarPlan.summary && sidecarPlan.summary.sidecarDeclared),
|
|
280
|
+
sidecarFileExists: Boolean(sidecarPlan && sidecarPlan.summary && sidecarPlan.summary.sidecarFileExists),
|
|
281
|
+
sidecarSymbolsValidated: Boolean(sidecarPlan && sidecarPlan.summary && sidecarPlan.summary.sidecarSymbolsValidated),
|
|
282
|
+
terminalAssetResponseEffectPlanned: terminalSidecarPlanned,
|
|
283
|
+
nodeReferenceImplemented: nodeCompiledReferenceImplemented,
|
|
284
|
+
fastlyReadiness: 'plan-only',
|
|
285
|
+
diagnostic: assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY,
|
|
286
|
+
asyncAwait: false,
|
|
287
|
+
promises: false,
|
|
288
|
+
asyncify: false
|
|
289
|
+
},
|
|
290
|
+
unsupported: {
|
|
291
|
+
binaryBodyReserved,
|
|
292
|
+
streamBodyReadiness: streamProviderProofImplemented ? 'provider-proof-implemented-compiled-wasm-plan-only' : 'plan-only',
|
|
293
|
+
uploads: false,
|
|
294
|
+
mutationApis: false,
|
|
295
|
+
invalidation: false,
|
|
296
|
+
externalFastlyService: false
|
|
297
|
+
},
|
|
298
|
+
smoke: {
|
|
299
|
+
checks,
|
|
300
|
+
failedChecks: failures
|
|
301
|
+
},
|
|
302
|
+
diagnostics,
|
|
303
|
+
summary: {
|
|
304
|
+
packageOwnedLoweringConsumed,
|
|
305
|
+
discoveredFromPackagedAssets,
|
|
306
|
+
symbolicStoreConfigValidated,
|
|
307
|
+
getMappingValidated,
|
|
308
|
+
headMappingValidated,
|
|
309
|
+
headersValidated,
|
|
310
|
+
cacheControlValidated,
|
|
311
|
+
notFoundPolicyValidated,
|
|
312
|
+
compiledWasmAssetsReadiness: 'plan-only',
|
|
313
|
+
compiledWasmPlanOnlyDiagnostic: assetsContracts.ASSETS_DIAGNOSTIC_CODES.FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY,
|
|
314
|
+
binaryBodyReserved,
|
|
315
|
+
streamBodyReadiness: streamProviderProofImplemented ? 'provider-proof-implemented-compiled-wasm-plan-only' : 'plan-only',
|
|
316
|
+
noExternalFastlyServiceRequired: true,
|
|
317
|
+
actualNetworkFetch: false,
|
|
318
|
+
checks: checks.length,
|
|
319
|
+
failedChecks: failures.length,
|
|
320
|
+
diagnostics: diagnostics.length,
|
|
321
|
+
warnings: diagnostics.filter((entry) => (entry.severity || 'error') === 'warning').length,
|
|
322
|
+
errors: errorDiagnostics.length
|
|
323
|
+
}
|
|
324
|
+
}, cwd);
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
artifact,
|
|
328
|
+
diagnostics,
|
|
329
|
+
providerProof: fastlyProviderProof,
|
|
330
|
+
failures,
|
|
331
|
+
hasErrors: errorDiagnostics.length > 0
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
module.exports = {
|
|
336
|
+
phaseName,
|
|
337
|
+
buildFastlyAssetsPackageOutParityProof
|
|
338
|
+
};
|