@pulse-compute/provider-fastly 1.0.0-beta.1 → 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 +7 -6
- package/dist/config-schema.json +30 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/package.json +11 -10
- package/src/build/canonical-target.js +35 -2
- 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 +6 -11
- 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 +155 -32
- package/src/build/native-platform-capabilities.js +755 -210
- 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/config-api.js +6 -0
- package/src/config-schema.json +30 -0
- package/src/index.ts +25 -0
- package/src/javascript/jwt-verifier.js +14 -4
- package/src/javascript/logging.js +11 -2
- package/src/javascript/package-effects.js +5 -2
- package/src/javascript/runtime-host.js +7 -3
- package/src/javascript/source-package.js +4 -2
- package/src/javascript/target-support-policy.js +20 -3
- package/src/javascript/target.js +17 -1
- package/src/javascript/test-runtime.js +1 -0
- package/src/provider-contract.js +22 -6
- package/src/runtime/canonical-api-runtime.js +6 -0
- package/src/testing/conditional-kv-host.js +155 -0
- package/src/testing/native-dynamic-backends-host.js +39 -0
- package/src/testing/native-http-effects-host.js +9 -1
- package/src/testing/native-platform-capabilities-host.js +349 -24
- package/src/toolchain/body-forwarding.js +25 -0
- package/src/toolchain/config.js +16 -0
- package/src/toolchain/index.js +48 -5
- package/src/toolchain/logging.js +18 -0
- package/src/toolchain/native-execution.js +78 -0
- package/src/toolchain/s3.js +26 -0
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const dynamicBackends = require('./native-dynamic-backends.js');
|
|
4
|
+
|
|
5
|
+
const { scalarRecordProjectionLines } = require('./schema-scalar-record.js');
|
|
6
|
+
const { hasJsonAdmission, tracksJsonDuplicates, schemaParserDepth, nestedJsonProjectionLines, schemaJsonAdmissionSource, schemaFetchJsonSource } = require('./schema-nested-json.js');
|
|
7
|
+
|
|
3
8
|
const crypto = require('node:crypto');
|
|
9
|
+
const { nativeStringAssembly, nativeStringFields, nativeStringConcat, nativeStringTrim, nativeStringIndex, needsNativeValueFailureGuard } = require('./native-string-values.js');
|
|
4
10
|
const fs = require('node:fs');
|
|
5
11
|
const os = require('node:os');
|
|
6
12
|
const path = require('node:path');
|
|
@@ -72,6 +78,7 @@ const FASTLY_NATIVE_HTTP_EFFECTS_REQUIRED_IMPORTS = Object.freeze([
|
|
|
72
78
|
]);
|
|
73
79
|
|
|
74
80
|
const FASTLY_NATIVE_HTTP_EFFECTS_ALLOWED_IMPORTS = new Set([
|
|
81
|
+
'fastly_http_req:register_dynamic_backend',
|
|
75
82
|
...FASTLY_NATIVE_HTTP_EFFECTS_IMPORTS.map(([moduleName, name]) => `${moduleName}:${name}`)
|
|
76
83
|
]);
|
|
77
84
|
|
|
@@ -150,8 +157,9 @@ function literalOriginFromExpression(expression) {
|
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
function resolveBackendBindings(plan, options = {}) {
|
|
153
|
-
const
|
|
154
|
-
const
|
|
160
|
+
const source = options.bindings || options;
|
|
161
|
+
const byEffect = source.effectBackends || {};
|
|
162
|
+
const byOrigin = source.backends || {};
|
|
155
163
|
const bindings = [];
|
|
156
164
|
for (const [index, effect] of (plan.effects || []).entries()) {
|
|
157
165
|
const urlInput = (effect.inputs || []).find((entry) => entry.name === 'url');
|
|
@@ -161,7 +169,7 @@ function resolveBackendBindings(plan, options = {}) {
|
|
|
161
169
|
const backend = byEffect[effect.id]
|
|
162
170
|
|| (origin && byOrigin[origin])
|
|
163
171
|
|| (effect.resource && effect.resource.value && byOrigin[effect.resource.value]);
|
|
164
|
-
if (typeof backend !== 'string' || backend.trim() === '') {
|
|
172
|
+
if ((typeof backend !== 'string' || backend.trim() === '') && source.dynamicBackends !== true) {
|
|
165
173
|
fail(`Fastly native effect ${effect.id} has no static backend binding.`, 'PULSE_FASTLY_NATIVE_HTTP_BACKEND_MISSING', {
|
|
166
174
|
effectId: effect.id,
|
|
167
175
|
effectIndex: index,
|
|
@@ -169,7 +177,7 @@ function resolveBackendBindings(plan, options = {}) {
|
|
|
169
177
|
hint: `Provide options.effectBackends[${JSON.stringify(effect.id)}] or options.backends[${JSON.stringify(origin || '<origin>')}].`
|
|
170
178
|
});
|
|
171
179
|
}
|
|
172
|
-
bindings.push(Object.freeze({ index, effectId: effect.id, origin: origin || null, backend: backend.trim() }));
|
|
180
|
+
bindings.push(Object.freeze({ index, effectId: effect.id, origin: origin || null, backend: typeof backend === 'string' ? backend.trim() : '', ...(typeof backend !== 'string' || !backend.trim() ? { dynamic: true } : {}) }));
|
|
173
181
|
}
|
|
174
182
|
return Object.freeze(bindings);
|
|
175
183
|
}
|
|
@@ -198,30 +206,43 @@ function generateSchemaRuntime(plan) {
|
|
|
198
206
|
const fields = node.kind === 'object'
|
|
199
207
|
? node.fields.map((field) => Object.freeze({ field, apply: emitNode(schemaIndex, field.value) }))
|
|
200
208
|
: [];
|
|
201
|
-
const body = [`function ${functionName}(valueHandle: i32): i32 {`, ' const input = __pulse_fastly_value(valueHandle)'];
|
|
209
|
+
const body = [`function ${functionName}(valueHandle: i32, checkDuplicates: bool): i32 {`, ' const input = __pulse_fastly_value(valueHandle)'];
|
|
202
210
|
if (node.kind === 'nullable') {
|
|
203
211
|
body.push(' if (input.kind == PULSE_VALUE_NULL) return valueHandle');
|
|
204
|
-
body.push(` return ${child}(valueHandle)`);
|
|
212
|
+
body.push(` return ${child}(valueHandle, checkDuplicates)`);
|
|
205
213
|
} else if (node.kind === 'array') {
|
|
206
214
|
body.push(' if (input.kind != PULSE_VALUE_ARRAY) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 52, -1); return 0 }');
|
|
207
215
|
body.push(' const output = host_value_array()');
|
|
208
216
|
body.push(' for (let index = 0; index < input.values.length; index += 1) {');
|
|
209
|
-
body.push(` const item = ${child}(unchecked(input.values[index]))`);
|
|
217
|
+
body.push(` const item = ${child}(unchecked(input.values[index]), checkDuplicates)`);
|
|
210
218
|
body.push(' if (item <= 0) return 0');
|
|
211
219
|
body.push(' host_value_array_push(output, item)');
|
|
212
220
|
body.push(' }');
|
|
213
221
|
body.push(' return output');
|
|
222
|
+
} else if (node.kind === 'json-value' || node.kind === 'json-object') {
|
|
223
|
+
body.push(...nestedJsonProjectionLines(node));
|
|
224
|
+
} else if (node.kind === 'scalar-record') {
|
|
225
|
+
body.push(...scalarRecordProjectionLines(node));
|
|
214
226
|
} else if (node.kind === 'object') {
|
|
215
227
|
body.push(' if (input.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 50, -1); return 0 }');
|
|
228
|
+
if (node.additionalProperties) body.push(' if (checkDuplicates && input.duplicateJsonKeys) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 57, -1); return 0 }');
|
|
216
229
|
body.push(' const output = host_value_object()');
|
|
217
230
|
fields.forEach(({ field, apply }, fieldIndex) => {
|
|
218
231
|
body.push(` const key_${currentIndex}_${fieldIndex} = __pulse_fastly_string_value(${quote(field.name)})`);
|
|
232
|
+
if (!field.required) body.push(` if (__pulse_fastly_find(input, ${quote(field.name)}) >= 0) {`);
|
|
219
233
|
body.push(` const field_${currentIndex}_${fieldIndex} = host_value_property(valueHandle, key_${currentIndex}_${fieldIndex})`);
|
|
220
234
|
body.push(` if (__pulse_fastly_value(field_${currentIndex}_${fieldIndex}).kind == PULSE_VALUE_UNDEFINED) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 51, -1); return 0 }`);
|
|
221
|
-
body.push(` const projected_${currentIndex}_${fieldIndex} = ${apply}(field_${currentIndex}_${fieldIndex})`);
|
|
235
|
+
body.push(` const projected_${currentIndex}_${fieldIndex} = ${apply}(field_${currentIndex}_${fieldIndex}, checkDuplicates)`);
|
|
222
236
|
body.push(` if (projected_${currentIndex}_${fieldIndex} <= 0) return 0`);
|
|
223
237
|
body.push(` host_value_object_set(output, key_${currentIndex}_${fieldIndex}, projected_${currentIndex}_${fieldIndex})`);
|
|
238
|
+
if (!field.required) body.push(' }');
|
|
224
239
|
});
|
|
240
|
+
if (node.additionalProperties) {
|
|
241
|
+
body.push(' for (let index = 0; index < input.keys.length; index++) {', ' const key = unchecked(input.keys[index])');
|
|
242
|
+
if (node.fields.length) body.push(` if (${node.fields.map(field => `key == ${quote(field.name)}`).join(' || ')}) continue`);
|
|
243
|
+
body.push(' const item = __pulse_fastly_copy_json(unchecked(input.values[index]), checkDuplicates)',
|
|
244
|
+
' if (item <= 0) return 0', ' host_value_object_set(output, __pulse_fastly_string_value(key), item)', ' }');
|
|
245
|
+
}
|
|
225
246
|
body.push(' return output');
|
|
226
247
|
} else if (node.kind === 'string') {
|
|
227
248
|
body.push(' if (input.kind != PULSE_VALUE_STRING) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 52, -1); return 0 }');
|
|
@@ -255,17 +276,21 @@ function generateSchemaRuntime(plan) {
|
|
|
255
276
|
`const __PULSE_SCHEMA_MAX_BYTES: i32 = ${Number(registry.maxBytes || FASTLY_NATIVE_HTTP_EFFECTS_BUFFER_BYTES)}`,
|
|
256
277
|
`const __PULSE_SCHEMA_REQUIRE_JSON: bool = ${registry.contentTypePolicy === 'require-json' ? 'true' : 'false'}`,
|
|
257
278
|
'',
|
|
279
|
+
schemaJsonAdmissionSource(plan),
|
|
280
|
+
schemaFetchJsonSource(),
|
|
258
281
|
...nodeLines,
|
|
259
282
|
'function __pulse_fastly_schema_apply(schemaId: string, valueHandle: i32, encode: bool): i32 {',
|
|
260
283
|
' if (schemaId.length == 0) return valueHandle'
|
|
261
284
|
];
|
|
262
285
|
for (const [schemaIndex, schema] of schemas.entries()) {
|
|
263
286
|
lines.push(`${schemaIndex === 0 ? ' if' : ' else if'} (schemaId == ${quote(schema.id)}) {`);
|
|
264
|
-
lines.push(`
|
|
287
|
+
if (schema.jsonLimits) lines.push(` if (__pulse_fastly_admit_bounded_value(valueHandle, __pulse_schema_json_limits_${schemaIndex}()).failure != 0) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 57, -1); return 0 }`);
|
|
288
|
+
lines.push(` const projected = ${roots[schemaIndex]}(valueHandle, !encode)`);
|
|
265
289
|
lines.push(' if (projected <= 0) return 0');
|
|
266
290
|
lines.push(' const input = __pulse_fastly_json(projected, 0)');
|
|
267
291
|
lines.push(` const normalized = encode ? __pulse_schema_encode_${schemaIndex}(input) : __pulse_schema_decode_${schemaIndex}(input)`);
|
|
268
|
-
lines.push('
|
|
292
|
+
if (schema.jsonLimits) lines.push(' const output = __pulse_fastly_parse_json(normalized)', ' if (output > 0) __pulse_fastly_deep_freeze(output)', ' return output');
|
|
293
|
+
else lines.push(' return __pulse_fastly_parse_json(normalized)');
|
|
269
294
|
lines.push(' }');
|
|
270
295
|
}
|
|
271
296
|
lines.push(' __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 55, -1)');
|
|
@@ -354,17 +379,34 @@ const PULSE_ERROR_TRANSPORT: i32 = 1006
|
|
|
354
379
|
const PULSE_ERROR_STATE: i32 = 1007
|
|
355
380
|
|
|
356
381
|
class __PulseFastlyValue {
|
|
382
|
+
${tracksJsonDuplicates(plan) ? 'duplicateJsonKeys: bool = false' : ''}
|
|
383
|
+
immutable: bool = false
|
|
357
384
|
kind: i32 = PULSE_VALUE_UNDEFINED
|
|
358
385
|
boolean: i32 = 0
|
|
359
386
|
number: f64 = 0.0
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
387
|
+
${nativeStringFields}
|
|
388
|
+
// Scalar handles do not need collection backing stores.
|
|
389
|
+
private keysStorage: Array<string> | null = null
|
|
390
|
+
get keys(): Array<string> {
|
|
391
|
+
if (this.keysStorage === null) this.keysStorage = new Array<string>()
|
|
392
|
+
return this.keysStorage!
|
|
393
|
+
}
|
|
394
|
+
// Scalar handles do not need collection backing stores.
|
|
395
|
+
private valuesStorage: Array<i32> | null = null
|
|
396
|
+
get values(): Array<i32> {
|
|
397
|
+
if (this.valuesStorage === null) this.valuesStorage = new Array<i32>()
|
|
398
|
+
return this.valuesStorage!
|
|
399
|
+
}
|
|
363
400
|
responseHandle: i32 = 0
|
|
364
401
|
bodyHandle: i32 = 0
|
|
365
402
|
bodyLoaded: i32 = 0
|
|
366
403
|
status: i32 = 200
|
|
367
|
-
|
|
404
|
+
// Scalar handles do not need collection backing stores.
|
|
405
|
+
private headersStorage: Array<__PulseFastlyHeader> | null = null
|
|
406
|
+
get headers(): Array<__PulseFastlyHeader> {
|
|
407
|
+
if (this.headersStorage === null) this.headersStorage = new Array<__PulseFastlyHeader>()
|
|
408
|
+
return this.headersStorage!
|
|
409
|
+
}
|
|
368
410
|
}
|
|
369
411
|
class __PulseFastlyHeader {
|
|
370
412
|
constructor(public name: string, public value: string) {}
|
|
@@ -377,7 +419,7 @@ class __PulseJsonParser {
|
|
|
377
419
|
skip(): void { while (this.index < this.source.length) { const c = this.source.charCodeAt(this.index); if (c != 32 && c != 9 && c != 10 && c != 13) return; this.index += 1 } }
|
|
378
420
|
parse(): i32 { this.skip(); const value = this.value(0); this.skip(); if (this.index != this.source.length) this.failed = true; return this.failed ? 0 : value }
|
|
379
421
|
value(depth: i32): i32 {
|
|
380
|
-
this.skip(); if (this.index >= this.source.length || depth >
|
|
422
|
+
this.skip(); if (this.index >= this.source.length || depth > ${schemaParserDepth(plan)}) { this.failed = true; return 0 }
|
|
381
423
|
const c = this.source.charCodeAt(this.index)
|
|
382
424
|
if (c == 34) return __pulse_fastly_string_value(this.string())
|
|
383
425
|
if (c == 123) return this.object(depth + 1)
|
|
@@ -469,6 +511,7 @@ class __PulseJsonParser {
|
|
|
469
511
|
this.skip(); if (this.index >= this.source.length || this.source.charCodeAt(this.index) != 34) { this.failed = true; break }
|
|
470
512
|
const key = this.string(); this.skip()
|
|
471
513
|
if (this.index >= this.source.length || this.source.charCodeAt(this.index) != 58) { this.failed = true; break }
|
|
514
|
+
${tracksJsonDuplicates(plan) ? 'if (__pulse_fastly_find(__pulse_fastly_value(output), key) >= 0) __pulse_fastly_value(output).duplicateJsonKeys = true' : ''}
|
|
472
515
|
this.index += 1; host_value_object_set(output, __pulse_fastly_string_value(key), this.value(depth)); this.skip()
|
|
473
516
|
if (this.index >= this.source.length) { this.failed = true; break }
|
|
474
517
|
const c = this.source.charCodeAt(this.index); this.index += 1
|
|
@@ -480,6 +523,10 @@ class __PulseJsonParser {
|
|
|
480
523
|
}
|
|
481
524
|
|
|
482
525
|
const __pulse_fastly_values = new Array<__PulseFastlyValue>()
|
|
526
|
+
// Shared schema admission uses storage-independent lookups. This retained
|
|
527
|
+
// HTTP emitter keeps its existing dense table and lifetime policy.
|
|
528
|
+
function __pulse_fastly_has_value(handle: i32): bool { return handle > 0 && handle <= __pulse_fastly_values.length }
|
|
529
|
+
function __pulse_fastly_value_count(): i32 { return __pulse_fastly_values.length }
|
|
483
530
|
const __pulse_fastly_pending = new StaticArray<i32>(PULSE_FASTLY_EFFECT_COUNT)
|
|
484
531
|
const __pulse_fastly_pending_active = new StaticArray<i32>(PULSE_FASTLY_EFFECT_COUNT)
|
|
485
532
|
const __pulse_fastly_payloads = new StaticArray<i32>(PULSE_FASTLY_EFFECT_COUNT)
|
|
@@ -507,9 +554,37 @@ function __pulse_fastly_number_string(value: f64): string { if (value >= -900719
|
|
|
507
554
|
function __pulse_fastly_string(handle: i32): string { const value = __pulse_fastly_value(handle); if (value.kind == PULSE_VALUE_STRING) return value.text; if (value.kind == PULSE_VALUE_NUMBER) return __pulse_fastly_number_string(value.number); if (value.kind == PULSE_VALUE_BOOLEAN) return value.boolean != 0 ? "true" : "false"; if (value.kind == PULSE_VALUE_NULL) return "null"; if (value.kind == PULSE_VALUE_UNDEFINED) return "undefined"; return __pulse_fastly_json(handle, 0) }
|
|
508
555
|
function __pulse_fastly_number(handle: i32): f64 { const value = __pulse_fastly_value(handle); if (value.kind == PULSE_VALUE_NUMBER) return value.number; if (value.kind == PULSE_VALUE_BOOLEAN) return value.boolean != 0 ? 1.0 : 0.0; if (value.kind == PULSE_VALUE_STRING) return F64.parseFloat(value.text); return 0.0 }
|
|
509
556
|
function __pulse_fastly_hex(value: i32): string { return String.fromCharCode(value < 10 ? 48 + value : 87 + value) }
|
|
510
|
-
function
|
|
557
|
+
function __pulse_fastly_is_unpaired(value: string, i: i32): bool {
|
|
558
|
+
const c = value.charCodeAt(i);
|
|
559
|
+
if (c >= 0xd800 && c <= 0xdbff) return i + 1 >= value.length || value.charCodeAt(i + 1) < 0xdc00 || value.charCodeAt(i + 1) > 0xdfff;
|
|
560
|
+
if (c >= 0xdc00 && c <= 0xdfff) return i == 0 || value.charCodeAt(i - 1) < 0xd800 || value.charCodeAt(i - 1) > 0xdbff;
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
function __pulse_fastly_quote(value: string): string {
|
|
564
|
+
// Count once and write UTF-16 units once. Repeated concatenation can allocate
|
|
565
|
+
// gigabytes for a valid bounded string when every byte needs JSON escaping.
|
|
566
|
+
let size = 2;
|
|
567
|
+
for (let i = 0; i < value.length; i++) {
|
|
568
|
+
const c = value.charCodeAt(i);
|
|
569
|
+
size += c == 34 || c == 92 || c == 8 || c == 9 || c == 10 || c == 12 || c == 13 ? 2 : (c < 32 || __pulse_fastly_is_unpaired(value, i)) ? 6 : 1;
|
|
570
|
+
}
|
|
571
|
+
const out = new Uint16Array(size); let cursor = 0; out[cursor++] = 34;
|
|
572
|
+
for (let i = 0; i < value.length; i++) {
|
|
573
|
+
const c = value.charCodeAt(i);
|
|
574
|
+
if (c == 34 || c == 92) { out[cursor++] = 92; out[cursor++] = u16(c); }
|
|
575
|
+
else if (c == 8 || c == 9 || c == 10 || c == 12 || c == 13) {
|
|
576
|
+
out[cursor++] = 92; out[cursor++] = c == 8 ? 98 : c == 9 ? 116 : c == 10 ? 110 : c == 12 ? 102 : 114;
|
|
577
|
+
} else if (c < 32 || __pulse_fastly_is_unpaired(value, i)) {
|
|
578
|
+
out[cursor++] = 92; out[cursor++] = 117;
|
|
579
|
+
out[cursor++] = u16('0123456789abcdef'.charCodeAt((c >> 12) & 15)); out[cursor++] = u16('0123456789abcdef'.charCodeAt((c >> 8) & 15));
|
|
580
|
+
out[cursor++] = u16('0123456789abcdef'.charCodeAt((c >> 4) & 15)); out[cursor++] = u16('0123456789abcdef'.charCodeAt(c & 15));
|
|
581
|
+
} else out[cursor++] = u16(c);
|
|
582
|
+
}
|
|
583
|
+
out[cursor] = 34;
|
|
584
|
+
return String.UTF16.decodeUnsafe(out.dataStart, out.byteLength);
|
|
585
|
+
}
|
|
511
586
|
function __pulse_fastly_json(handle: i32, depth: i32): string {
|
|
512
|
-
if (depth >
|
|
587
|
+
if (depth > ${schemaParserDepth(plan)}) { __pulse_fastly_fail(PULSE_ERROR_JSON, 2, -1); return "null" }
|
|
513
588
|
const value = __pulse_fastly_value(handle)
|
|
514
589
|
if (value.kind == PULSE_VALUE_UNDEFINED || value.kind == PULSE_VALUE_NULL) return "null"
|
|
515
590
|
if (value.kind == PULSE_VALUE_BOOLEAN) return value.boolean != 0 ? "true" : "false"
|
|
@@ -519,6 +594,11 @@ function __pulse_fastly_json(handle: i32, depth: i32): string {
|
|
|
519
594
|
if (value.kind == PULSE_VALUE_OBJECT) { let out = "{"; for (let i = 0; i < value.keys.length; i += 1) { if (i > 0) out += ","; out += __pulse_fastly_quote(unchecked(value.keys[i])) + ":" + __pulse_fastly_json(unchecked(value.values[i]), depth + 1) } return out + "}" }
|
|
520
595
|
return "null"
|
|
521
596
|
}
|
|
597
|
+
${nativeStringAssembly}
|
|
598
|
+
${nativeStringConcat}
|
|
599
|
+
${nativeStringTrim}
|
|
600
|
+
${nativeStringIndex}
|
|
601
|
+
function __pulse_fastly_deep_freeze(handle: i32): void { const value = __pulse_fastly_value(handle); if (value.immutable) return; value.immutable = true; if (value.kind == PULSE_VALUE_ARRAY || value.kind == PULSE_VALUE_OBJECT) for (let index = 0; index < value.values.length; index += 1) __pulse_fastly_deep_freeze(unchecked(value.values[index])) }
|
|
522
602
|
function __pulse_fastly_parse_json(text: string): i32 { const parser = new __PulseJsonParser(text); const value = parser.parse(); if (parser.failed || value <= 0) { __pulse_fastly_fail(PULSE_ERROR_JSON, 3, -1); return 0 } return value }
|
|
523
603
|
function __pulse_fastly_path(uri: string): string { let start = 0; const scheme = uri.indexOf("://"); if (scheme >= 0) { const slash = uri.indexOf("/", scheme + 3); start = slash >= 0 ? slash : uri.length } let end = uri.length; const query = uri.indexOf("?", start); if (query >= 0 && query < end) end = query; const fragment = uri.indexOf("#", start); if (fragment >= 0 && fragment < end) end = fragment; return start >= end ? "/" : uri.substring(start, end) }
|
|
524
604
|
function __pulse_fastly_read_req_string(kind: i32): string { const buffer = new Uint8Array(PULSE_FASTLY_BUFFER_BYTES); const written = __pulse_fastly_out_i32(); const status = kind == 0 ? fastly_http_req_method_get(__pulse_fastly_request_handle, buffer.dataStart, PULSE_FASTLY_BUFFER_BYTES, changetype<usize>(written)) : fastly_http_req_uri_get(__pulse_fastly_request_handle, buffer.dataStart, PULSE_FASTLY_BUFFER_BYTES, changetype<usize>(written)); if (status != FASTLY_STATUS_OK) { __pulse_fastly_fail(PULSE_ERROR_HOSTCALL, 10 + kind, -1); return "" } return __pulse_fastly_decode(buffer, __pulse_fastly_out_value(written)) }
|
|
@@ -530,21 +610,28 @@ function __pulse_fastly_fetch_body(value: __PulseFastlyValue): string { if (valu
|
|
|
530
610
|
function host_value_undefined(): i32 { const item = new __PulseFastlyValue(); item.kind = PULSE_VALUE_UNDEFINED; return __pulse_fastly_put(item) }
|
|
531
611
|
function host_value_null(): i32 { const item = new __PulseFastlyValue(); item.kind = PULSE_VALUE_NULL; return __pulse_fastly_put(item) }
|
|
532
612
|
function host_value_boolean(value: i32): i32 { const item = new __PulseFastlyValue(); item.kind = PULSE_VALUE_BOOLEAN; item.boolean = value != 0 ? 1 : 0; return __pulse_fastly_put(item) }
|
|
613
|
+
${plan.binaryResources || plan.numericWorkspaces?.length ? require('./native-binary-resources.js').source() : ''}
|
|
533
614
|
function host_value_number(value: f64): i32 { const item = new __PulseFastlyValue(); item.kind = PULSE_VALUE_NUMBER; item.number = value; return __pulse_fastly_put(item) }
|
|
534
615
|
function host_value_string(pointer: i32, length: i32): i32 { return __pulse_fastly_string_value(changetype<string>(pointer)) }
|
|
616
|
+
function host_effect_collection_count(handle: i32, max: i32, stateIndex: i32): i32 {
|
|
617
|
+
const input = __pulse_fastly_value(handle)
|
|
618
|
+
if (__pulse_fastly_last_error != 0 || input.kind != PULSE_VALUE_ARRAY || max < 1 || max > 32) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 173, -1); return -1 }
|
|
619
|
+
if (input.values.length > max) { __pulse_fastly_fail(PULSE_ERROR_STATE, 172, -1); return -1 }
|
|
620
|
+
return input.values.length
|
|
621
|
+
}
|
|
535
622
|
function host_value_array(): i32 { const item = new __PulseFastlyValue(); item.kind = PULSE_VALUE_ARRAY; return __pulse_fastly_put(item) }
|
|
536
|
-
function host_value_array_push(target: i32, value: i32): void { const item = __pulse_fastly_value(target); if (item.kind != PULSE_VALUE_ARRAY) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 30, -1); return } item.values.push(value) }
|
|
623
|
+
function host_value_array_push(target: i32, value: i32): void { const item = __pulse_fastly_value(target); if (item.kind != PULSE_VALUE_ARRAY || item.immutable) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 30, -1); return } item.values.push(value) }
|
|
537
624
|
function host_value_array_spread(target: i32, source: i32): void { const from = __pulse_fastly_value(source); if (from.kind != PULSE_VALUE_ARRAY) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 31, -1); return } for (let i = 0; i < from.values.length; i += 1) host_value_array_push(target, unchecked(from.values[i])) }
|
|
538
625
|
function host_value_object(): i32 { const item = new __PulseFastlyValue(); item.kind = PULSE_VALUE_OBJECT; return __pulse_fastly_put(item) }
|
|
539
|
-
function host_value_object_set(target: i32, keyHandle: i32, value: i32): void { const item = __pulse_fastly_value(target); if (item.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 32, -1); return } const key = __pulse_fastly_string(keyHandle); const index = __pulse_fastly_find(item, key); if (index >= 0) unchecked(item.values[index] = value); else { item.keys.push(key); item.values.push(value) } }
|
|
626
|
+
function host_value_object_set(target: i32, keyHandle: i32, value: i32): void { const item = __pulse_fastly_value(target); if (item.kind != PULSE_VALUE_OBJECT || item.immutable) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 32, -1); return } const key = __pulse_fastly_string(keyHandle); const index = __pulse_fastly_find(item, key); if (index >= 0) unchecked(item.values[index] = value); else { item.keys.push(key); item.values.push(value) } }
|
|
540
627
|
function host_value_object_spread(target: i32, source: i32): void { const from = __pulse_fastly_value(source); if (from.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 33, -1); return } for (let i = 0; i < from.keys.length; i += 1) host_value_object_set(target, __pulse_fastly_string_value(unchecked(from.keys[i])), unchecked(from.values[i])) }
|
|
541
|
-
function host_value_property(target: i32, keyHandle: i32): i32 { const item = __pulse_fastly_value(target); const key = __pulse_fastly_string(keyHandle); if (item.kind == PULSE_VALUE_OBJECT) { const index = __pulse_fastly_find(item, key); return index >= 0 ? unchecked(item.values[index]) : host_value_undefined() } if (item.kind == PULSE_VALUE_FETCH && key == "status") { const out = __pulse_fastly_out_i32(); const status = fastly_http_resp_status_get(item.responseHandle, changetype<usize>(out)); if (status != FASTLY_STATUS_OK) { __pulse_fastly_fail(PULSE_ERROR_HOSTCALL, 34, -1); return 0 } return host_value_number(__pulse_fastly_out_value(out)) } if ((item.kind == PULSE_VALUE_STRING || item.kind == PULSE_VALUE_ARRAY) && key == "length") return host_value_number(item.kind == PULSE_VALUE_STRING ? item.
|
|
628
|
+
function host_value_property(target: i32, keyHandle: i32): i32 { const item = __pulse_fastly_value(target); const key = __pulse_fastly_string(keyHandle); if (item.kind == PULSE_VALUE_OBJECT) { const index = __pulse_fastly_find(item, key); return index >= 0 ? unchecked(item.values[index]) : host_value_undefined() } if (item.kind == PULSE_VALUE_FETCH && key == "status") { const out = __pulse_fastly_out_i32(); const status = fastly_http_resp_status_get(item.responseHandle, changetype<usize>(out)); if (status != FASTLY_STATUS_OK) { __pulse_fastly_fail(PULSE_ERROR_HOSTCALL, 34, -1); return 0 } return host_value_number(__pulse_fastly_out_value(out)) } if ((item.kind == PULSE_VALUE_STRING || item.kind == PULSE_VALUE_ARRAY) && key == "length") return host_value_number(item.kind == PULSE_VALUE_STRING ? item.textLength : item.values.length); return host_value_undefined() }
|
|
542
629
|
function host_value_property_set(target: i32, key: i32, value: i32): i32 { host_value_object_set(target, key, value); return value }
|
|
543
|
-
function host_value_element(target: i32, keyHandle: i32): i32 { const item = __pulse_fastly_value(target); if (item.kind == PULSE_VALUE_ARRAY) { const index = i32(__pulse_fastly_number(keyHandle)); return index >= 0 && index < item.values.length ? unchecked(item.values[index]) : host_value_undefined() } return host_value_property(target, keyHandle) }
|
|
544
|
-
function host_value_element_set(target: i32, keyHandle: i32, value: i32): i32 { const item = __pulse_fastly_value(target); if (item.kind == PULSE_VALUE_ARRAY) { const index = i32(__pulse_fastly_number(keyHandle)); if (index < 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 35, -1); return 0 } while (item.values.length <= index) item.values.push(host_value_undefined()); unchecked(item.values[index] = value); return value } return host_value_property_set(target, keyHandle, value) }
|
|
545
|
-
function host_value_truthy(handle: i32): i32 { const value = __pulse_fastly_value(handle); if (value.kind == PULSE_VALUE_UNDEFINED || value.kind == PULSE_VALUE_NULL) return 0; if (value.kind == PULSE_VALUE_BOOLEAN) return value.boolean; if (value.kind == PULSE_VALUE_NUMBER) return value.number != 0.0 && !isNaN(value.number) ? 1 : 0; if (value.kind == PULSE_VALUE_STRING) return value.
|
|
630
|
+
function host_value_element(target: i32, keyHandle: i32): i32 { const item = __pulse_fastly_value(target); if (item.kind == PULSE_VALUE_STRING) return __pulse_fastly_string_index(item, keyHandle); if (item.kind == PULSE_VALUE_ARRAY) { const index = i32(__pulse_fastly_number(keyHandle)); return index >= 0 && index < item.values.length ? unchecked(item.values[index]) : host_value_undefined() } return host_value_property(target, keyHandle) }
|
|
631
|
+
function host_value_element_set(target: i32, keyHandle: i32, value: i32): i32 { const item = __pulse_fastly_value(target); if (item.immutable) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 35, -1); return 0 } if (item.kind == PULSE_VALUE_ARRAY) { const index = i32(__pulse_fastly_number(keyHandle)); if (index < 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 35, -1); return 0 } while (item.values.length <= index) item.values.push(host_value_undefined()); unchecked(item.values[index] = value); return value } return host_value_property_set(target, keyHandle, value) }
|
|
632
|
+
function host_value_truthy(handle: i32): i32 { const value = __pulse_fastly_value(handle); if (value.kind == PULSE_VALUE_UNDEFINED || value.kind == PULSE_VALUE_NULL) return 0; if (value.kind == PULSE_VALUE_BOOLEAN) return value.boolean; if (value.kind == PULSE_VALUE_NUMBER) return value.number != 0.0 && !isNaN(value.number) ? 1 : 0; if (value.kind == PULSE_VALUE_STRING) return value.textLength > 0 ? 1 : 0; return 1 }
|
|
546
633
|
function host_value_nullish(handle: i32): i32 { const kind = __pulse_fastly_value(handle).kind; return kind == PULSE_VALUE_UNDEFINED || kind == PULSE_VALUE_NULL ? 1 : 0 }
|
|
547
|
-
function host_value_binary(operator: i32, leftHandle: i32, rightHandle: i32): i32 { const left = __pulse_fastly_value(leftHandle); const right = __pulse_fastly_value(rightHandle); if (operator == 0 || operator == 2) { let equal = false; if (left.kind == right.kind) { if (left.kind == PULSE_VALUE_UNDEFINED || left.kind == PULSE_VALUE_NULL) equal = true; else if (left.kind == PULSE_VALUE_BOOLEAN) equal = left.boolean == right.boolean; else if (left.kind == PULSE_VALUE_NUMBER) equal = left.number == right.number; else if (left.kind == PULSE_VALUE_STRING) equal = left.text == right.text; else equal = leftHandle == rightHandle } return host_value_boolean(equal ? 1 : 0) } if (operator == 1 || operator == 3) { const result = host_value_binary(operator == 1 ? 0 : 2, leftHandle, rightHandle); return host_value_boolean(host_value_truthy(result) == 0 ? 1 : 0) } if (operator == 8) { if (left.kind == PULSE_VALUE_STRING || right.kind == PULSE_VALUE_STRING) return
|
|
634
|
+
function host_value_binary(operator: i32, leftHandle: i32, rightHandle: i32): i32 { const left = __pulse_fastly_value(leftHandle); const right = __pulse_fastly_value(rightHandle); if (operator == 0 || operator == 2) { let equal = false; if (left.kind == right.kind) { if (left.kind == PULSE_VALUE_UNDEFINED || left.kind == PULSE_VALUE_NULL) equal = true; else if (left.kind == PULSE_VALUE_BOOLEAN) equal = left.boolean == right.boolean; else if (left.kind == PULSE_VALUE_NUMBER) equal = left.number == right.number; else if (left.kind == PULSE_VALUE_STRING) equal = left.text == right.text; else equal = leftHandle == rightHandle } return host_value_boolean(equal ? 1 : 0) } if (operator == 1 || operator == 3) { const result = host_value_binary(operator == 1 ? 0 : 2, leftHandle, rightHandle); return host_value_boolean(host_value_truthy(result) == 0 ? 1 : 0) } if (operator == 8) { if (left.kind == PULSE_VALUE_STRING || right.kind == PULSE_VALUE_STRING) return __pulse_fastly_concat(leftHandle, rightHandle); return host_value_number(__pulse_fastly_number(leftHandle) + __pulse_fastly_number(rightHandle)) } if (left.kind == PULSE_VALUE_STRING && right.kind == PULSE_VALUE_STRING) { if (operator == 4) return host_value_boolean(left.text < right.text ? 1 : 0); if (operator == 5) return host_value_boolean(left.text <= right.text ? 1 : 0); if (operator == 6) return host_value_boolean(left.text > right.text ? 1 : 0); if (operator == 7) return host_value_boolean(left.text >= right.text ? 1 : 0); } if (operator == 4) return host_value_boolean(__pulse_fastly_number(leftHandle) < __pulse_fastly_number(rightHandle) ? 1 : 0); if (operator == 5) return host_value_boolean(__pulse_fastly_number(leftHandle) <= __pulse_fastly_number(rightHandle) ? 1 : 0); if (operator == 6) return host_value_boolean(__pulse_fastly_number(leftHandle) > __pulse_fastly_number(rightHandle) ? 1 : 0); if (operator == 7) return host_value_boolean(__pulse_fastly_number(leftHandle) >= __pulse_fastly_number(rightHandle) ? 1 : 0); if (operator == 9) return host_value_number(__pulse_fastly_number(leftHandle) - __pulse_fastly_number(rightHandle)); if (operator == 10) return host_value_number(__pulse_fastly_number(leftHandle) * __pulse_fastly_number(rightHandle)); if (operator == 11) return host_value_number(__pulse_fastly_number(leftHandle) / __pulse_fastly_number(rightHandle)); if (operator == 12) return host_value_number(__pulse_fastly_number(leftHandle) % __pulse_fastly_number(rightHandle)); if (operator == 14) return host_value_truthy(leftHandle) != 0 ? rightHandle : leftHandle; if (operator == 15) return host_value_truthy(leftHandle) != 0 ? leftHandle : rightHandle; if (operator == 16) return host_value_nullish(leftHandle) == 0 ? leftHandle : rightHandle; __pulse_fastly_fail(PULSE_ERROR_UNSUPPORTED, 36, -1); return 0 }
|
|
548
635
|
function host_value_unary(operator: i32, handle: i32): i32 { if (operator == 0) return host_value_boolean(host_value_truthy(handle) == 0 ? 1 : 0); if (operator == 1) return host_value_number(__pulse_fastly_number(handle)); if (operator == 2) return host_value_number(-__pulse_fastly_number(handle)); if (operator == 5) return host_value_undefined(); __pulse_fastly_fail(PULSE_ERROR_UNSUPPORTED, 37, -1); return 0 }
|
|
549
636
|
|
|
550
637
|
function host_request_method(): i32 { return __pulse_fastly_string_value(__pulse_fastly_request_method) }
|
|
@@ -558,10 +645,32 @@ function host_request_path(): i32 { return __pulse_fastly_string_value(__pulse_f
|
|
|
558
645
|
function host_request_headers(): i32 { return host_value_object() }
|
|
559
646
|
function host_request_header(name: i32): i32 { const value = __pulse_fastly_request_header_text(__pulse_fastly_string(name)); return value.length == 0 ? host_value_undefined() : __pulse_fastly_string_value(value) }
|
|
560
647
|
function host_request_text(): i32 { if (__pulse_fastly_request_body_loaded == 0) { __pulse_fastly_request_body = __pulse_fastly_read_body(__pulse_fastly_request_body_handle, -1); __pulse_fastly_request_body_loaded = 1 } return __pulse_fastly_string_value(__pulse_fastly_request_body) }
|
|
561
|
-
function host_request_json(schema: i32): i32 { const parsed = __pulse_fastly_parse_json(__pulse_fastly_string(host_request_text())); if (parsed <= 0) return 0; const schemaValue = __pulse_fastly_value(schema); return schemaValue.kind == PULSE_VALUE_STRING ? __pulse_fastly_schema_apply(schemaValue.text, parsed, false) : parsed }
|
|
648
|
+
function host_request_json(schema: i32): i32 { const parsed = ${hasJsonAdmission(plan) ? '__pulse_fastly_schema_parse_json(__pulse_fastly_string(host_request_text()), schema)' : '__pulse_fastly_parse_json(__pulse_fastly_string(host_request_text()))'}; if (parsed <= 0) return 0; const schemaValue = __pulse_fastly_value(schema); return schemaValue.kind == PULSE_VALUE_STRING ? __pulse_fastly_schema_apply(schemaValue.text, parsed, false) : parsed }
|
|
562
649
|
function __pulse_fastly_headers_from_options(options: __PulseFastlyValue, output: __PulseFastlyValue): void { const index = __pulse_fastly_find(options, "headers"); if (index < 0) return; const headers = __pulse_fastly_value(unchecked(options.values[index])); if (headers.kind == PULSE_VALUE_OBJECT) { for (let i = 0; i < headers.keys.length; i += 1) { const name = unchecked(headers.keys[i]); const value = __pulse_fastly_value(unchecked(headers.values[i])); if (value.kind == PULSE_VALUE_ARRAY) { for (let j = 0; j < value.values.length; j += 1) output.headers.push(new __PulseFastlyHeader(name, __pulse_fastly_string(unchecked(value.values[j])))) } else output.headers.push(new __PulseFastlyHeader(name, __pulse_fastly_string(unchecked(headers.values[i])))) } return } if (headers.kind == PULSE_VALUE_ARRAY) { for (let i = 0; i < headers.values.length; i += 1) { const pair = __pulse_fastly_value(unchecked(headers.values[i])); if (pair.kind != PULSE_VALUE_ARRAY || pair.values.length < 2) continue; output.headers.push(new __PulseFastlyHeader(__pulse_fastly_string(unchecked(pair.values[0])), __pulse_fastly_string(unchecked(pair.values[1])))) } } }
|
|
563
650
|
function __pulse_fastly_response(value: i32, optionsHandle: i32, json: bool): i32 { const output = new __PulseFastlyValue(); output.kind = PULSE_VALUE_RESPONSE; output.status = 200; const options = __pulse_fastly_value(optionsHandle); let bodyValue = value; if (options.kind == PULSE_VALUE_OBJECT) { const statusIndex = __pulse_fastly_find(options, "status"); if (statusIndex >= 0) output.status = i32(__pulse_fastly_number(unchecked(options.values[statusIndex]))); const schemaIndex = __pulse_fastly_find(options, "schema"); if (json && schemaIndex >= 0) { bodyValue = __pulse_fastly_schema_apply(__pulse_fastly_string(unchecked(options.values[schemaIndex])), value, true); if (bodyValue <= 0) return 0 } __pulse_fastly_headers_from_options(options, output) } output.text = json ? __pulse_fastly_json(bodyValue, 0) : __pulse_fastly_string(value); let hasContentType = false; for (let i = 0; i < output.headers.length; i += 1) if (unchecked(output.headers[i]).name.toLowerCase() == "content-type") hasContentType = true; if (!hasContentType) output.headers.push(new __PulseFastlyHeader("content-type", json ? "application/json; charset=utf-8" : "text/plain; charset=utf-8")); return __pulse_fastly_put(output) }
|
|
564
651
|
function host_response_json(value: i32, options: i32): i32 { return __pulse_fastly_response(value, options, true) }
|
|
652
|
+
function host_schema_decode(text: i32, schema: i32): i32 {
|
|
653
|
+
const id = __pulse_fastly_value(schema)
|
|
654
|
+
if (id.kind != PULSE_VALUE_STRING || id.text.length == 0) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 55, -1); return 0 }
|
|
655
|
+
const input = __pulse_fastly_value(text)
|
|
656
|
+
if (input.kind != PULSE_VALUE_STRING) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 52, -1); return 0 }
|
|
657
|
+
if (String.UTF8.byteLength(input.text) > __PULSE_SCHEMA_MAX_BYTES) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 21, -1); return 0 }
|
|
658
|
+
const parsed = ${hasJsonAdmission(plan) ? '__pulse_fastly_schema_parse_json(input.text, schema)' : '__pulse_fastly_parse_json(input.text)'}
|
|
659
|
+
if (parsed <= 0) return 0
|
|
660
|
+
const decoded = __pulse_fastly_schema_apply(id.text, parsed, false)
|
|
661
|
+
if (decoded <= 0) return 0
|
|
662
|
+
__pulse_fastly_deep_freeze(decoded)
|
|
663
|
+
return decoded
|
|
664
|
+
}
|
|
665
|
+
function host_schema_encode(value: i32, schema: i32): i32 {
|
|
666
|
+
const id = __pulse_fastly_value(schema)
|
|
667
|
+
if (id.kind != PULSE_VALUE_STRING || id.text.length == 0) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 55, -1); return 0 }
|
|
668
|
+
const projected = __pulse_fastly_schema_apply(id.text, value, true)
|
|
669
|
+
if (projected <= 0) return 0
|
|
670
|
+
const text = __pulse_fastly_json(projected, 0)
|
|
671
|
+
if (String.UTF8.byteLength(text) > __PULSE_SCHEMA_MAX_BYTES) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 21, -1); return 0 }
|
|
672
|
+
return __pulse_fastly_string_value(text)
|
|
673
|
+
}
|
|
565
674
|
function host_response_text(value: i32, options: i32): i32 { return __pulse_fastly_response(value, options, false) }
|
|
566
675
|
function host_response_custom(specHandle: i32): i32 { const spec = __pulse_fastly_value(specHandle); if (spec.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 40, -1); return 0 } const output = new __PulseFastlyValue(); output.kind = PULSE_VALUE_RESPONSE; output.status = 200; const statusIndex = __pulse_fastly_find(spec, "status"); if (statusIndex >= 0) output.status = i32(__pulse_fastly_number(unchecked(spec.values[statusIndex]))); const bodyIndex = __pulse_fastly_find(spec, "body"); if (bodyIndex >= 0) output.text = __pulse_fastly_string(unchecked(spec.values[bodyIndex])); __pulse_fastly_headers_from_options(spec, output); return __pulse_fastly_put(output) }
|
|
567
676
|
function __pulse_fastly_grip_frame_channels(options: __PulseFastlyValue, output: __PulseFastlyValue): bool { const channelsIndex = __pulse_fastly_find(options, "channels"); const channelIndex = __pulse_fastly_find(options, "channel"); let count = 0; if (channelsIndex >= 0) { const channels = __pulse_fastly_value(unchecked(options.values[channelsIndex])); if (channels.kind != PULSE_VALUE_ARRAY) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 133, -1); return false } for (let i = 0; i < channels.values.length; i += 1) { const channel = __pulse_fastly_string(unchecked(channels.values[i])).trim(); if (channel.length == 0 || channel.indexOf(",") >= 0 || channel.indexOf("\r") >= 0 || channel.indexOf("\n") >= 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 134, -1); return false } output.headers.push(new __PulseFastlyHeader("Grip-Channel", channel)); count += 1 } } else if (channelIndex >= 0) { const channel = __pulse_fastly_string(unchecked(options.values[channelIndex])).trim(); if (channel.length == 0 || channel.indexOf(",") >= 0 || channel.indexOf("\r") >= 0 || channel.indexOf("\n") >= 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 134, -1); return false } output.headers.push(new __PulseFastlyHeader("Grip-Channel", channel)); count = 1 } if (count == 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 135, -1); return false } return true }
|
|
@@ -571,9 +680,18 @@ function host_grip_subscribe(responseHandle: i32, optionsHandle: i32): i32 { con
|
|
|
571
680
|
function host_grip_handoff(optionsHandle: i32): i32 { const options = __pulse_fastly_value(optionsHandle); if (options.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 139, -1); return 0 } const output = new __PulseFastlyValue(); output.kind = PULSE_VALUE_RESPONSE; output.status = 200; const statusIndex = __pulse_fastly_find(options, "status"); if (statusIndex >= 0) output.status = i32(__pulse_fastly_number(unchecked(options.values[statusIndex]))); const bodyIndex = __pulse_fastly_find(options, "body"); if (bodyIndex >= 0) output.text = __pulse_fastly_string(unchecked(options.values[bodyIndex])); __pulse_fastly_headers_from_options(options, output); let hasContentType = false; for (let i = 0; i < output.headers.length; i += 1) if (unchecked(output.headers[i]).name.toLowerCase() == "content-type") hasContentType = true; if (!hasContentType) output.headers.push(new __PulseFastlyHeader("Content-Type", "application/websocket-events")); return __pulse_fastly_grip_frame(options, output) ? __pulse_fastly_put(output) : 0 }
|
|
572
681
|
function host_kv_namespace(name: i32): i32 { __pulse_fastly_fail(PULSE_ERROR_UNSUPPORTED, 41, -1); return 0 }
|
|
573
682
|
function host_fetch_text(responseHandle: i32): i32 { const response = __pulse_fastly_value(responseHandle); if (response.kind != PULSE_VALUE_FETCH) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 42, -1); return 0 } return __pulse_fastly_string_value(__pulse_fastly_fetch_body(response)) }
|
|
574
|
-
function host_fetch_json(responseHandle: i32, schemaHandle: i32): i32 { const response = __pulse_fastly_value(responseHandle); if (response.kind != PULSE_VALUE_FETCH) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 43, -1); return 0 } if (__PULSE_SCHEMA_REQUIRE_JSON) { const contentType = __pulse_fastly_fetch_header_text(response.responseHandle, "content-type"); if (contentType.length == 0 || contentType.toLowerCase().indexOf("json") < 0) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 44, -1); return 0 } } const parsed = __pulse_fastly_parse_json(__pulse_fastly_fetch_body(response)); if (parsed <= 0) return 0; const schema = __pulse_fastly_value(schemaHandle); return schema.kind == PULSE_VALUE_STRING ? __pulse_fastly_schema_apply(schema.text, parsed, false) : parsed }
|
|
683
|
+
function host_fetch_json(responseHandle: i32, schemaHandle: i32): i32 { const response = __pulse_fastly_value(responseHandle); if (response.kind != PULSE_VALUE_FETCH) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 43, -1); return 0 } if (__PULSE_SCHEMA_REQUIRE_JSON) { const contentType = __pulse_fastly_fetch_header_text(response.responseHandle, "content-type"); if (contentType.length == 0 || contentType.toLowerCase().indexOf("json") < 0) { __pulse_fastly_fail(PULSE_ERROR_SCHEMA, 44, -1); return 0 } } const parsed = ${hasJsonAdmission(plan) ? '__pulse_fastly_schema_parse_json(__pulse_fastly_fetch_body(response), schemaHandle)' : '__pulse_fastly_parse_json(__pulse_fastly_fetch_body(response))'}; if (parsed <= 0) return 0; const schema = __pulse_fastly_value(schemaHandle); return schema.kind == PULSE_VALUE_STRING ? __pulse_fastly_schema_apply(schema.text, parsed, false) : parsed }
|
|
575
684
|
function host_fetch_header(responseHandle: i32, nameHandle: i32): i32 { const response = __pulse_fastly_value(responseHandle); if (response.kind != PULSE_VALUE_FETCH) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 45, -1); return 0 } const value = __pulse_fastly_fetch_header_text(response.responseHandle, __pulse_fastly_string(nameHandle)); return value.length == 0 ? host_value_undefined() : __pulse_fastly_string_value(value) }
|
|
576
|
-
function host_effect_begin(effectIndex: i32, payload: i32): void { if (effectIndex < 0 || effectIndex >= PULSE_FASTLY_EFFECT_COUNT || unchecked(__pulse_fastly_pending_active[effectIndex]) != 0) { __pulse_fastly_fail(PULSE_ERROR_STATE, 46, effectIndex); return } const payloadValue = __pulse_fastly_value(payload); if (payloadValue.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 47, effectIndex); return } const urlIndex = __pulse_fastly_find(payloadValue, "url"); if (urlIndex < 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 48, effectIndex); return } const url = __pulse_fastly_string(unchecked(payloadValue.values[urlIndex])); const initIndex = __pulse_fastly_find(payloadValue, "init"); const init = initIndex >= 0 ? __pulse_fastly_value(unchecked(payloadValue.values[initIndex])) : new __PulseFastlyValue(); let method = "GET"; let body = ""; let headers = new __PulseFastlyValue(); headers.kind = PULSE_VALUE_OBJECT; if (init.kind == PULSE_VALUE_OBJECT) { const methodIndex = __pulse_fastly_find(init, "method"); if (methodIndex >= 0) method = __pulse_fastly_string(unchecked(init.values[methodIndex])).toUpperCase(); const headersIndex = __pulse_fastly_find(init, "headers"); if (headersIndex >= 0) headers = __pulse_fastly_value(unchecked(init.values[headersIndex])); const bodyIndex = __pulse_fastly_find(init, "body"); if (bodyIndex >= 0) { const bodyValue = unchecked(init.values[bodyIndex]); const bodyObject = __pulse_fastly_value(bodyValue); body = bodyObject.kind == PULSE_VALUE_STRING ? bodyObject.text : __pulse_fastly_json(bodyValue, 0) }
|
|
685
|
+
function host_effect_begin(effectIndex: i32, payload: i32): void { ${needsNativeValueFailureGuard(plan) ? 'if (__pulse_fastly_last_error != PULSE_ERROR_NONE) return; ' : ''}if (effectIndex < 0 || effectIndex >= PULSE_FASTLY_EFFECT_COUNT || unchecked(__pulse_fastly_pending_active[effectIndex]) != 0) { __pulse_fastly_fail(PULSE_ERROR_STATE, 46, effectIndex); return } const payloadValue = __pulse_fastly_value(payload); if (payloadValue.kind != PULSE_VALUE_OBJECT) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 47, effectIndex); return } const urlIndex = __pulse_fastly_find(payloadValue, "url"); if (urlIndex < 0) { __pulse_fastly_fail(PULSE_ERROR_VALUE, 48, effectIndex); return } const url = __pulse_fastly_string(unchecked(payloadValue.values[urlIndex])); const initIndex = __pulse_fastly_find(payloadValue, "init"); const init = initIndex >= 0 ? __pulse_fastly_value(unchecked(payloadValue.values[initIndex])) : new __PulseFastlyValue(); let method = "GET"; let body = ""; let headers = new __PulseFastlyValue(); headers.kind = PULSE_VALUE_OBJECT; if (init.kind == PULSE_VALUE_OBJECT) { const methodIndex = __pulse_fastly_find(init, "method"); if (methodIndex >= 0) method = __pulse_fastly_string(unchecked(init.values[methodIndex])).toUpperCase(); const headersIndex = __pulse_fastly_find(init, "headers"); if (headersIndex >= 0) headers = __pulse_fastly_value(unchecked(init.values[headersIndex])); const bodyIndex = __pulse_fastly_find(init, "body"); if (bodyIndex >= 0) { const bodyValue = unchecked(init.values[bodyIndex]); const bodyObject = __pulse_fastly_value(bodyValue); body = bodyObject.kind == PULSE_VALUE_STRING ? bodyObject.text : __pulse_fastly_json(bodyValue, 0) }
|
|
686
|
+
else {
|
|
687
|
+
const jsonIndex = __pulse_fastly_find(init, "json")
|
|
688
|
+
if (jsonIndex >= 0) {
|
|
689
|
+
body = __pulse_fastly_fetch_json_body(init, unchecked(init.values[jsonIndex]))
|
|
690
|
+
if (__pulse_fastly_last_error != 0) return
|
|
691
|
+
headers = __pulse_fastly_fetch_json_headers(headers)
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
577
695
|
const requestOut = __pulse_fastly_out_i32(); let status = fastly_http_req_new(changetype<usize>(requestOut)); if (status != FASTLY_STATUS_OK) { __pulse_fastly_fail(PULSE_ERROR_HOSTCALL, 70, effectIndex); return } const requestHandle = __pulse_fastly_out_value(requestOut)
|
|
578
696
|
const bodyOut = __pulse_fastly_out_i32(); status = fastly_http_body_new(changetype<usize>(bodyOut)); if (status != FASTLY_STATUS_OK) { __pulse_fastly_fail(PULSE_ERROR_HOSTCALL, 71, effectIndex); return } const bodyHandle = __pulse_fastly_out_value(bodyOut)
|
|
579
697
|
const methodBytes = __pulse_fastly_utf8(method); status = fastly_http_req_method_set(requestHandle, changetype<usize>(methodBytes), methodBytes.byteLength); if (status != FASTLY_STATUS_OK) { __pulse_fastly_fail(PULSE_ERROR_HOSTCALL, 72, effectIndex); return }
|
|
@@ -633,15 +751,16 @@ function generateFastlyNativeHttpEffectsAssemblyScript(plan, options = {}) {
|
|
|
633
751
|
const bindings = resolveBackendBindings(plan, options);
|
|
634
752
|
const portable = generateCanonicalNativeAssemblyScript(plan, options);
|
|
635
753
|
const portableSource = stripPulseHostImports(portable.source);
|
|
636
|
-
|
|
754
|
+
let source = [
|
|
637
755
|
'/* Generated by Pulse Pass97 Fastly native HTTP effects compiler. */',
|
|
638
|
-
'export function __pulse_fastly_abort(message: string | null, fileName: string | null, line: u32, column: u32): void { unreachable() }',
|
|
756
|
+
'export function __pulse_fastly_abort(message: string | null, fileName: string | null = null, line: u32 = 0, column: u32 = 0): void { unreachable() }',
|
|
639
757
|
'',
|
|
640
758
|
fastlyRuntimeSource(plan, bindings),
|
|
641
759
|
portableSource,
|
|
642
760
|
driverSource(plan),
|
|
643
761
|
''
|
|
644
762
|
].join('\n');
|
|
763
|
+
source = dynamicBackends.instrument(source, bindings, false, (options.bindings || options).backends);
|
|
645
764
|
const manifest = Object.freeze({
|
|
646
765
|
version: FASTLY_NATIVE_HTTP_EFFECTS_VERSION,
|
|
647
766
|
generatorVersion: FASTLY_NATIVE_HTTP_EFFECTS_GENERATOR_VERSION,
|
|
@@ -656,7 +775,10 @@ function generateFastlyNativeHttpEffectsAssemblyScript(plan, options = {}) {
|
|
|
656
775
|
continuationCount: (plan.continuations || []).length,
|
|
657
776
|
groupedContinuationCount: (plan.continuations || []).filter((entry) => (entry.effectIds || []).length > 1).length,
|
|
658
777
|
backends: bindings,
|
|
659
|
-
|
|
778
|
+
...(dynamicBackends.active(bindings) ? { dynamicBackends: dynamicBackends.describe((options.bindings || options).backends) } : {}),
|
|
779
|
+
allowedImports: dynamicBackends.active(bindings)
|
|
780
|
+
? Object.freeze([...FASTLY_NATIVE_HTTP_EFFECTS_IMPORTS, Object.freeze(['fastly_http_req', 'register_dynamic_backend'])])
|
|
781
|
+
: FASTLY_NATIVE_HTTP_EFFECTS_IMPORTS,
|
|
660
782
|
requiredExports: Object.freeze([
|
|
661
783
|
'_start',
|
|
662
784
|
'pulse_fastly_last_error',
|
|
@@ -778,6 +900,7 @@ function compileFastlyNativeHttpEffectsPlan(plan, options = {}) {
|
|
|
778
900
|
'--path', jsonAs.dependencyRoot
|
|
779
901
|
);
|
|
780
902
|
}
|
|
903
|
+
require('@pulse-compute/wasm-build-support/native-optimization').appendJsonCacheArenaArgs(args, options.elideJsonCacheArena, schemaCodecsActive);
|
|
781
904
|
const startedAt = Date.now();
|
|
782
905
|
const result = spawnSync(asc.executable, args, {
|
|
783
906
|
cwd: stagingDir,
|
|
@@ -785,7 +908,7 @@ function compileFastlyNativeHttpEffectsPlan(plan, options = {}) {
|
|
|
785
908
|
maxBuffer: 64 * 1024 * 1024,
|
|
786
909
|
timeout: Number(options.timeoutMs || 180000),
|
|
787
910
|
env: schemaCodecsActive
|
|
788
|
-
? { ...process.env, JSON_STRICT: 'true', JSON_USE_FAST_PATH: '0' }
|
|
911
|
+
? { ...process.env, JSON_STRICT: 'true', JSON_USE_FAST_PATH: '0', JSON_MODE: 'NAIVE' }
|
|
789
912
|
: process.env
|
|
790
913
|
});
|
|
791
914
|
const durationMs = Date.now() - startedAt;
|
|
@@ -808,7 +931,7 @@ function compileFastlyNativeHttpEffectsPlan(plan, options = {}) {
|
|
|
808
931
|
compilerVersion: FASTLY_NATIVE_HTTP_EFFECTS_COMPILER_VERSION,
|
|
809
932
|
assemblyScript: Object.freeze({ package: 'assemblyscript', version: require(path.join(asc.packageRoot, 'package.json')).version }),
|
|
810
933
|
jsonAs: jsonAs
|
|
811
|
-
? Object.freeze({ package: 'json-as', version: jsonAs.version, transform: true, strict: true })
|
|
934
|
+
? Object.freeze({ package: 'json-as', version: jsonAs.version, transform: true, strict: true, mode: 'NAIVE', fastPath: false, elideDisabledCacheArena: options.elideJsonCacheArena === true })
|
|
812
935
|
: undefined,
|
|
813
936
|
wasm: Object.freeze({ bytes: inspection.bytes, sha256: inspection.sha256, magic: inspection.magic }),
|
|
814
937
|
wat: Object.freeze({ bytes: Buffer.byteLength(wat), sha256: sha256(wat) }),
|