miniflare 0.0.0-e1d2fd668 → 0.0.0-e2b3306e1

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.
@@ -8633,9 +8633,62 @@ var PerformanceTimer = class {
8633
8633
  }
8634
8634
  };
8635
8635
 
8636
+ // ../workers-shared/utils/responses.ts
8637
+ var OkResponse = class extends Response {
8638
+ constructor(body, init) {
8639
+ super(body, {
8640
+ ...init,
8641
+ status: 200
8642
+ });
8643
+ }
8644
+ }, NotFoundResponse = class extends Response {
8645
+ constructor(...[body, init]) {
8646
+ super(body, {
8647
+ ...init,
8648
+ status: 404,
8649
+ statusText: "Not Found"
8650
+ });
8651
+ }
8652
+ }, MethodNotAllowedResponse = class extends Response {
8653
+ constructor(...[body, init]) {
8654
+ super(body, {
8655
+ ...init,
8656
+ status: 405,
8657
+ statusText: "Method Not Allowed"
8658
+ });
8659
+ }
8660
+ }, InternalServerErrorResponse = class extends Response {
8661
+ constructor(err, init) {
8662
+ super(null, {
8663
+ ...init,
8664
+ status: 500
8665
+ });
8666
+ }
8667
+ }, NotModifiedResponse = class extends Response {
8668
+ constructor(...[_body, init]) {
8669
+ super(null, {
8670
+ ...init,
8671
+ status: 304,
8672
+ statusText: "Not Modified"
8673
+ });
8674
+ }
8675
+ }, TemporaryRedirectResponse = class extends Response {
8676
+ constructor(location, init) {
8677
+ super(null, {
8678
+ ...init,
8679
+ status: 307,
8680
+ statusText: "Temporary Redirect",
8681
+ headers: {
8682
+ ...init?.headers,
8683
+ Location: location
8684
+ }
8685
+ });
8686
+ }
8687
+ };
8688
+
8636
8689
  // ../workers-shared/utils/sentry.ts
8637
8690
  var import_toucan_js = __toESM(require_index_cjs());
8638
- function setupSentry(request, context, dsn, clientId, clientSecret) {
8691
+ function setupSentry(request, context, dsn, clientId, clientSecret, coloMetadata, accountId, scriptId) {
8639
8692
  if (!(dsn && clientId && clientSecret))
8640
8693
  return;
8641
8694
  let sentry = new import_toucan_js.Toucan({
@@ -8662,10 +8715,37 @@ function setupSentry(request, context, dsn, clientId, clientSecret) {
8662
8715
  "CF-Access-Client-Secret": clientSecret
8663
8716
  }
8664
8717
  }
8665
- }), colo = request.cf?.colo ?? "UNKNOWN";
8666
- sentry.setTag("colo", colo);
8667
- let userAgent = request.headers.get("user-agent") ?? "UA UNKNOWN";
8668
- return sentry.setUser({ userAgent, colo }), sentry;
8718
+ });
8719
+ return coloMetadata && (sentry.setTag("colo", coloMetadata.coloId), sentry.setTag("metal", coloMetadata.metalId)), accountId && scriptId && (sentry.setTag("accountId", accountId), sentry.setTag("scriptId", scriptId)), sentry.setUser({ id: accountId?.toString() }), sentry;
8720
+ }
8721
+
8722
+ // ../workers-shared/utils/tracing.ts
8723
+ function mockJaegerBindingSpan() {
8724
+ return {
8725
+ addLogs: () => {
8726
+ },
8727
+ setTags: () => {
8728
+ },
8729
+ end: () => {
8730
+ },
8731
+ isRecording: !0
8732
+ };
8733
+ }
8734
+ function mockJaegerBinding() {
8735
+ return {
8736
+ enterSpan: (_, span, ...args) => span(mockJaegerBindingSpan(), ...args),
8737
+ getSpanContext: () => ({
8738
+ traceId: "test-trace",
8739
+ spanId: "test-span",
8740
+ parentSpanId: "test-parent-span",
8741
+ traceFlags: 0
8742
+ }),
8743
+ runWithSpanContext: (_, callback, ...args) => callback(...args),
8744
+ traceId: "test-trace",
8745
+ spanId: "test-span",
8746
+ parentSpanId: "test-parent-span",
8747
+ cfTraceIdHeader: "test-trace:test-span:0"
8748
+ };
8669
8749
  }
8670
8750
 
8671
8751
  // ../workers-shared/asset-worker/src/analytics.ts
@@ -8681,12 +8761,11 @@ var Analytics = class {
8681
8761
  getData(key) {
8682
8762
  return this.data[key];
8683
8763
  }
8684
- write(hostname) {
8764
+ write() {
8685
8765
  this.readyAnalytics && this.readyAnalytics.logEvent({
8686
8766
  version: 1,
8687
- accountId: 0,
8688
- // TODO: need to plumb through
8689
- indexId: hostname,
8767
+ accountId: this.data.accountId,
8768
+ indexId: this.data.scriptId?.toString(),
8690
8769
  doubles: [
8691
8770
  this.data.requestTime ?? -1,
8692
8771
  // double1
@@ -8731,7 +8810,10 @@ var AssetsManifest = class {
8731
8810
  return entry ? contentHashToKey(entry) : null;
8732
8811
  }
8733
8812
  }, hashPath = async (path) => {
8734
- let data = new TextEncoder().encode(path), hashBuffer = await crypto.subtle.digest("SHA-256", data.buffer);
8813
+ let data = new TextEncoder().encode(path), hashBuffer = await crypto.subtle.digest(
8814
+ "SHA-256",
8815
+ data.buffer
8816
+ );
8735
8817
  return new Uint8Array(hashBuffer, 0, 16);
8736
8818
  }, binarySearch = (arr, searchValue) => {
8737
8819
  if (arr.byteLength === 0)
@@ -8774,62 +8856,14 @@ var AssetsManifest = class {
8774
8856
  )].map((b) => b.toString(16).padStart(2, "0")).join("");
8775
8857
 
8776
8858
  // ../workers-shared/asset-worker/src/configuration.ts
8777
- var applyConfigurationDefaults = (configuration) => ({
8778
- html_handling: configuration?.html_handling ?? "auto-trailing-slash",
8779
- not_found_handling: configuration?.not_found_handling ?? "none"
8780
- });
8781
-
8782
- // ../workers-shared/asset-worker/src/responses.ts
8783
- var OkResponse = class extends Response {
8784
- constructor(body, init) {
8785
- super(body, {
8786
- ...init,
8787
- status: 200
8788
- });
8789
- }
8790
- }, NotFoundResponse = class extends Response {
8791
- constructor(...[body, init]) {
8792
- super(body, {
8793
- ...init,
8794
- status: 404,
8795
- statusText: "Not Found"
8796
- });
8797
- }
8798
- }, MethodNotAllowedResponse = class extends Response {
8799
- constructor(...[body, init]) {
8800
- super(body, {
8801
- ...init,
8802
- status: 405,
8803
- statusText: "Method Not Allowed"
8804
- });
8805
- }
8806
- }, InternalServerErrorResponse = class extends Response {
8807
- constructor(err, init) {
8808
- super(null, {
8809
- ...init,
8810
- status: 500
8811
- });
8812
- }
8813
- }, NotModifiedResponse = class extends Response {
8814
- constructor(...[_body, init]) {
8815
- super(null, {
8816
- ...init,
8817
- status: 304,
8818
- statusText: "Not Modified"
8819
- });
8820
- }
8821
- }, TemporaryRedirectResponse = class extends Response {
8822
- constructor(location, init) {
8823
- super(null, {
8824
- ...init,
8825
- status: 307,
8826
- statusText: "Temporary Redirect",
8827
- headers: {
8828
- ...init?.headers,
8829
- Location: location
8830
- }
8831
- });
8832
- }
8859
+ var applyConfigurationDefaults = (configuration) => {
8860
+ let runWorkerFirst;
8861
+ return configuration?.run_worker_first !== void 0 ? runWorkerFirst = configuration?.run_worker_first : configuration?.serve_directly !== void 0 ? runWorkerFirst = !configuration.serve_directly : runWorkerFirst = !1, {
8862
+ html_handling: configuration?.html_handling ?? "auto-trailing-slash",
8863
+ not_found_handling: configuration?.not_found_handling ?? "none",
8864
+ run_worker_first: runWorkerFirst,
8865
+ serve_directly: !runWorkerFirst
8866
+ };
8833
8867
  };
8834
8868
 
8835
8869
  // ../workers-shared/asset-worker/src/constants.ts
@@ -8848,28 +8882,56 @@ function isCacheable(request) {
8848
8882
  }
8849
8883
 
8850
8884
  // ../workers-shared/asset-worker/src/handler.ts
8851
- var handleRequest = async (request, configuration, exists, getByETag) => {
8852
- let { pathname, search } = new URL(request.url), decodedPathname = decodePath(pathname), intent = await getIntent(decodedPathname, configuration, exists);
8885
+ var handleRequest = async (request, env, configuration, exists, getByETag) => {
8886
+ let { pathname, search } = new URL(request.url), decodedPathname = decodePath(pathname);
8887
+ decodedPathname = decodedPathname.replace(/\/+/g, "/");
8888
+ let intent = await getIntent(decodedPathname, configuration, exists);
8853
8889
  if (!intent)
8854
- return new NotFoundResponse();
8890
+ return env.JAEGER.enterSpan("no_intent", (span) => (span.setTags({
8891
+ decodedPathname,
8892
+ configuration: JSON.stringify(configuration),
8893
+ status: 404
8894
+ }), new NotFoundResponse()));
8855
8895
  let method = request.method.toUpperCase();
8856
8896
  if (!["GET", "HEAD"].includes(method))
8857
- return new MethodNotAllowedResponse();
8897
+ return env.JAEGER.enterSpan("method_not_allowed", (span) => (span.setTags({
8898
+ method,
8899
+ status: 405
8900
+ }), new MethodNotAllowedResponse()));
8858
8901
  let decodedDestination = intent.redirect ?? decodedPathname, encodedDestination = encodePath(decodedDestination);
8859
- if (encodedDestination !== pathname || intent.redirect)
8860
- return new TemporaryRedirectResponse(encodedDestination + search);
8902
+ if (encodedDestination !== pathname && intent.asset || intent.redirect)
8903
+ return env.JAEGER.enterSpan("redirect", (span) => (span.setTags({
8904
+ originalPath: pathname,
8905
+ location: encodedDestination !== pathname ? encodedDestination : intent.redirect ?? "<unknown>",
8906
+ status: 307
8907
+ }), new TemporaryRedirectResponse(encodedDestination + search)));
8861
8908
  if (!intent.asset)
8862
- return new InternalServerErrorResponse(new Error("Unknown action"));
8863
- let asset = await getByETag(intent.asset.eTag), headers = getHeaders(intent.asset.eTag, asset.contentType, request), strongETag = `"${intent.asset.eTag}"`, weakETag = `W/${strongETag}`, ifNoneMatch = request.headers.get("If-None-Match") || "";
8864
- if ([weakETag, strongETag].includes(ifNoneMatch))
8865
- return new NotModifiedResponse(null, { headers });
8866
- let body = method === "HEAD" ? null : asset.readableStream;
8867
- switch (intent.asset.status) {
8868
- case 404:
8869
- return new NotFoundResponse(body, { headers });
8870
- case 200:
8871
- return new OkResponse(body, { headers });
8872
- }
8909
+ return env.JAEGER.enterSpan("unknown_action", (span) => (span.setTags({
8910
+ pathname,
8911
+ status: 500
8912
+ }), new InternalServerErrorResponse(new Error("Unknown action"))));
8913
+ let asset = await env.JAEGER.enterSpan("getByETag", async (span) => (span.setTags({
8914
+ pathname,
8915
+ eTag: intent.asset.eTag,
8916
+ status: intent.asset.status
8917
+ }), await getByETag(intent.asset.eTag))), headers = getHeaders(intent.asset.eTag, asset.contentType, request), strongETag = `"${intent.asset.eTag}"`, weakETag = `W/${strongETag}`, ifNoneMatch = request.headers.get("If-None-Match") || "";
8918
+ return [weakETag, strongETag].includes(ifNoneMatch) ? env.JAEGER.enterSpan("matched_etag", (span) => (span.setTags({
8919
+ matchedEtag: ifNoneMatch,
8920
+ status: 304
8921
+ }), new NotModifiedResponse(null, { headers }))) : env.JAEGER.enterSpan("response", (span) => {
8922
+ span.setTags({
8923
+ etag: intent.asset.eTag,
8924
+ status: intent.asset.status,
8925
+ head: method === "HEAD"
8926
+ });
8927
+ let body = method === "HEAD" ? null : asset.readableStream;
8928
+ switch (intent.asset.status) {
8929
+ case 404:
8930
+ return new NotFoundResponse(body, { headers });
8931
+ case 200:
8932
+ return new OkResponse(body, { headers });
8933
+ }
8934
+ });
8873
8935
  }, getIntent = async (pathname, configuration, exists, skipRedirects = !1) => {
8874
8936
  switch (configuration.html_handling) {
8875
8937
  case "auto-trailing-slash":
@@ -9238,18 +9300,46 @@ var handleRequest = async (request, configuration, exists, getByETag) => {
9238
9300
  };
9239
9301
  }
9240
9302
  return null;
9241
- }, decodePath = (pathname) => pathname.split("/").map((x) => decodeURIComponent(x)).join("/"), encodePath = (pathname) => pathname.split("/").map((x) => encodeURIComponent(x)).join("/");
9303
+ }, decodePath = (pathname) => pathname.split("/").map((x) => {
9304
+ try {
9305
+ return decodeURIComponent(x);
9306
+ } catch {
9307
+ return x;
9308
+ }
9309
+ }).join("/"), encodePath = (pathname) => pathname.split("/").map((x) => {
9310
+ try {
9311
+ return encodeURIComponent(x);
9312
+ } catch {
9313
+ return x;
9314
+ }
9315
+ }).join("/");
9242
9316
 
9243
9317
  // ../workers-shared/asset-worker/src/utils/kv.ts
9244
- async function getAssetWithMetadataFromKV(assetsKVNamespace, assetKey, retries = 1) {
9318
+ async function getAssetWithMetadataFromKV(assetsKVNamespace, assetKey, sentry, retries = 1) {
9245
9319
  let attempts = 0;
9246
9320
  for (; attempts <= retries; )
9247
9321
  try {
9248
- return await assetsKVNamespace.getWithMetadata(assetKey, {
9249
- type: "stream",
9250
- cacheTtl: 31536e3
9251
- // 1 year
9252
- });
9322
+ let asset = await assetsKVNamespace.getWithMetadata(
9323
+ assetKey,
9324
+ {
9325
+ type: "stream",
9326
+ cacheTtl: 31536e3
9327
+ // 1 year
9328
+ }
9329
+ );
9330
+ if (asset.value === null) {
9331
+ let retriedAsset = await assetsKVNamespace.getWithMetadata(assetKey, {
9332
+ type: "stream",
9333
+ cacheTtl: 60
9334
+ // Minimum value allowed
9335
+ });
9336
+ return retriedAsset.value !== null && sentry && sentry.captureException(
9337
+ new Error(
9338
+ `Initial request for asset ${assetKey} failed, but subsequent request succeeded.`
9339
+ )
9340
+ ), retriedAsset;
9341
+ }
9342
+ return asset;
9253
9343
  } catch {
9254
9344
  if (attempts >= retries)
9255
9345
  throw new Error(
@@ -9266,55 +9356,72 @@ var src_default = class extends WorkerEntrypoint {
9266
9356
  async fetch(request) {
9267
9357
  let sentry, analytics = new Analytics(this.env.ANALYTICS), performance = new PerformanceTimer(this.env.UNSAFE_PERFORMANCE), startTimeMs = performance.now();
9268
9358
  try {
9269
- sentry = setupSentry(
9359
+ this.env.JAEGER || (this.env.JAEGER = mockJaegerBinding()), sentry = setupSentry(
9270
9360
  request,
9271
9361
  this.ctx,
9272
9362
  this.env.SENTRY_DSN,
9273
9363
  this.env.SENTRY_ACCESS_CLIENT_ID,
9274
- this.env.SENTRY_ACCESS_CLIENT_SECRET
9364
+ this.env.SENTRY_ACCESS_CLIENT_SECRET,
9365
+ this.env.COLO_METADATA,
9366
+ this.env.CONFIG?.account_id,
9367
+ this.env.CONFIG?.script_id
9275
9368
  );
9276
- let config = applyConfigurationDefaults(this.env.CONFIG), userAgent = request.headers.get("user-agent") ?? "UA UNKNOWN";
9277
- if (sentry) {
9278
- let colo = this.env.COLO_METADATA.coloId;
9279
- sentry.setTag("colo", this.env.COLO_METADATA.coloId), sentry.setTag("metal", this.env.COLO_METADATA.metalId), sentry.setUser({ userAgent, colo });
9280
- }
9281
- if (this.env.COLO_METADATA && this.env.VERSION_METADATA) {
9282
- let url = new URL(request.url);
9283
- analytics.setData({
9284
- coloId: this.env.COLO_METADATA.coloId,
9285
- metalId: this.env.COLO_METADATA.metalId,
9286
- coloTier: this.env.COLO_METADATA.coloTier,
9287
- coloRegion: this.env.COLO_METADATA.coloRegion,
9288
- version: this.env.VERSION_METADATA.id,
9289
- hostname: url.hostname,
9290
- htmlHandling: config.html_handling,
9291
- notFoundHandling: config.not_found_handling,
9292
- userAgent
9293
- });
9294
- }
9295
- return handleRequest(
9369
+ let config = applyConfigurationDefaults(this.env.CONFIG), userAgent = request.headers.get("user-agent") ?? "UA UNKNOWN", url = new URL(request.url);
9370
+ return this.env.COLO_METADATA && this.env.VERSION_METADATA && this.env.CONFIG && analytics.setData({
9371
+ accountId: this.env.CONFIG.account_id,
9372
+ scriptId: this.env.CONFIG.script_id,
9373
+ coloId: this.env.COLO_METADATA.coloId,
9374
+ metalId: this.env.COLO_METADATA.metalId,
9375
+ coloTier: this.env.COLO_METADATA.coloTier,
9376
+ coloRegion: this.env.COLO_METADATA.coloRegion,
9377
+ version: this.env.VERSION_METADATA.id,
9378
+ hostname: url.hostname,
9379
+ htmlHandling: config.html_handling,
9380
+ notFoundHandling: config.not_found_handling,
9381
+ userAgent
9382
+ }), await this.env.JAEGER.enterSpan("handleRequest", async (span) => (span.setTags({
9383
+ hostname: url.hostname,
9384
+ eyeballPath: url.pathname,
9385
+ env: this.env.ENVIRONMENT,
9386
+ version: this.env.VERSION_METADATA?.id
9387
+ }), handleRequest(
9296
9388
  request,
9389
+ this.env,
9297
9390
  config,
9298
9391
  this.unstable_exists.bind(this),
9299
9392
  this.unstable_getByETag.bind(this)
9300
- );
9393
+ )));
9301
9394
  } catch (err) {
9395
+ let errorResponse = this.handleError(sentry, analytics, err);
9396
+ return this.submitMetrics(analytics, performance, startTimeMs), errorResponse;
9397
+ }
9398
+ }
9399
+ handleError(sentry, analytics, err) {
9400
+ try {
9302
9401
  let response = new InternalServerErrorResponse(err);
9303
9402
  return sentry && sentry.captureException(err), err instanceof Error && analytics.setData({ error: err.message }), response;
9304
- } finally {
9403
+ } catch (e) {
9404
+ return console.error("Error handling error", e), new InternalServerErrorResponse(e);
9405
+ }
9406
+ }
9407
+ submitMetrics(analytics, performance, startTimeMs) {
9408
+ try {
9305
9409
  analytics.setData({ requestTime: performance.now() - startTimeMs }), analytics.write();
9410
+ } catch (e) {
9411
+ console.error("Error submitting metrics", e);
9306
9412
  }
9307
9413
  }
9414
+ // TODO: Trace unstable methods
9308
9415
  async unstable_canFetch(request) {
9309
- let url = new URL(request.url), method = request.method.toUpperCase(), decodedPathname = decodePath(url.pathname), intent = await getIntent(
9416
+ let url = new URL(request.url), decodedPathname = decodePath(url.pathname);
9417
+ return await getIntent(
9310
9418
  decodedPathname,
9311
9419
  {
9312
9420
  ...applyConfigurationDefaults(this.env.CONFIG),
9313
9421
  not_found_handling: "none"
9314
9422
  },
9315
9423
  this.unstable_exists.bind(this)
9316
- );
9317
- return intent && ["GET", "HEAD"].includes(method) ? new MethodNotAllowedResponse() : intent !== null;
9424
+ ) !== null;
9318
9425
  }
9319
9426
  async unstable_getByETag(eTag) {
9320
9427
  let asset = await getAssetWithMetadataFromKV(