one 2.7.2 → 2.7.4

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.
@@ -53,5 +53,16 @@
53
53
  android:configChanges="keyboardHidden|orientation|screenSize"
54
54
  android:exported="false"
55
55
  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
56
+ <!-- a scheduled notification's tap records its response here before
57
+ the app opens; react native drops a tap that reaches an app activity
58
+ recreated after process death. never exported: only the notification's
59
+ pending intent launches it. -->
60
+ <activity
61
+ android:name="dev.onejs.onenative.OneNativeNotificationTapActivity"
62
+ android:excludeFromRecents="true"
63
+ android:exported="false"
64
+ android:noHistory="true"
65
+ android:taskAffinity=""
66
+ android:theme="@android:style/Theme.Translucent.NoTitleBar" />
56
67
  </application>
57
68
  </manifest>
@@ -504,9 +504,14 @@ class HybridOneLocation :
504
504
  )
505
505
  return@post
506
506
  }
507
- recentPosition(manager)?.let {
508
- promise.resolve(it)
509
- return@post
507
+ // a live watch keeps the last fix current; without one it can be
508
+ // a fix the device has since moved from, so ask for a fresh one
509
+ // (the ios contract).
510
+ if (monitoring) {
511
+ recentPosition(manager)?.let {
512
+ promise.resolve(it)
513
+ return@post
514
+ }
510
515
  }
511
516
  if (!serviceEnabled(manager)) {
512
517
  promise.reject(
@@ -24,6 +24,7 @@ import com.facebook.react.modules.core.PermissionListener
24
24
  import com.margelo.nitro.NitroModules
25
25
  import com.margelo.nitro.core.AnyMap
26
26
  import com.margelo.nitro.core.Promise
27
+ import dev.onejs.onenative.OneNativeNotificationTapActivity
27
28
  import dev.onejs.onenative.OneNativeNotificationsReceiver
28
29
  import dev.onejs.onenative.OneNativePush
29
30
  import org.json.JSONArray
@@ -601,21 +602,7 @@ class HybridOneNotifications :
601
602
  if (intent == null || !intent.getBooleanExtra(EXTRA_TAP, false)) return
602
603
  // consumed at once: onNewIntent and onHostResume both report a tap.
603
604
  intent.removeExtra(EXTRA_TAP)
604
- val response =
605
- TapResponse(
606
- intent.getStringExtra(EXTRA_IDENTIFIER) ?: return,
607
- intent.getStringExtra(EXTRA_TITLE),
608
- intent.getStringExtra(EXTRA_SUBTITLE),
609
- intent.getStringExtra(EXTRA_BODY),
610
- intent.getStringExtra(EXTRA_DATA) ?: "{}",
611
- intent.getBooleanExtra(EXTRA_SOUND, false),
612
- if (intent.hasExtra(EXTRA_BADGE)) intent.getIntExtra(EXTRA_BADGE, 0) else null,
613
- intent.getStringExtra(EXTRA_TRIGGER) ?: IMMEDIATE_TRIGGER_JSON,
614
- System.currentTimeMillis(),
615
- intent.getStringExtra(EXTRA_ACTION) ?: DEFAULT_ACTION_IDENTIFIER,
616
- intent.getStringExtra(EXTRA_USER_TEXT),
617
- intent.getStringExtra(EXTRA_CATEGORY)
618
- )
605
+ val response = tapResponse(intent, intent.getStringExtra(EXTRA_USER_TEXT)) ?: return
619
606
  lastResponse = response
620
607
  currentListeners()?.onResponse?.invoke(responsePayload(response))
621
608
  }
@@ -626,21 +613,11 @@ class HybridOneNotifications :
626
613
  fun handleAction(context: Context, intent: Intent) {
627
614
  val results = androidx.core.app.RemoteInput.getResultsFromIntent(intent)
628
615
  val response =
629
- TapResponse(
630
- intent.getStringExtra(EXTRA_IDENTIFIER) ?: return,
631
- intent.getStringExtra(EXTRA_TITLE),
632
- intent.getStringExtra(EXTRA_SUBTITLE),
633
- intent.getStringExtra(EXTRA_BODY),
634
- intent.getStringExtra(EXTRA_DATA) ?: "{}",
635
- intent.getBooleanExtra(EXTRA_SOUND, false),
636
- if (intent.hasExtra(EXTRA_BADGE)) intent.getIntExtra(EXTRA_BADGE, 0) else null,
637
- intent.getStringExtra(EXTRA_TRIGGER) ?: IMMEDIATE_TRIGGER_JSON,
638
- System.currentTimeMillis(),
639
- intent.getStringExtra(EXTRA_ACTION) ?: DEFAULT_ACTION_IDENTIFIER,
616
+ tapResponse(
617
+ intent,
640
618
  results?.getCharSequence(EXTRA_USER_TEXT)?.toString()
641
- ?: intent.getStringExtra(EXTRA_USER_TEXT),
642
- intent.getStringExtra(EXTRA_CATEGORY)
643
- )
619
+ ?: intent.getStringExtra(EXTRA_USER_TEXT)
620
+ ) ?: return
644
621
  lastResponse = response
645
622
  currentListeners()?.onResponse?.invoke(responsePayload(response))
646
623
  if (intent.getBooleanExtra(EXTRA_FOREGROUND, true)) {
@@ -708,7 +685,6 @@ class HybridOneNotifications :
708
685
  private const val E_CATEGORY = "E_NOTIFICATIONS_CATEGORY"
709
686
  private const val DEFAULT_CHANNEL_ID = "default"
710
687
  private const val DEFAULT_ACTION_IDENTIFIER = "expo.modules.notifications.actions.DEFAULT"
711
- private const val ACTION_TAP = "dev.onejs.onenative.NOTIFICATION_TAP"
712
688
  private const val EXTRA_TAP = "dev.onejs.onenative.EXTRA_TAP"
713
689
  private const val EXTRA_TITLE = "dev.onejs.onenative.EXTRA_TITLE"
714
690
  private const val EXTRA_SUBTITLE = "dev.onejs.onenative.EXTRA_SUBTITLE"
@@ -1095,15 +1071,9 @@ class HybridOneNotifications :
1095
1071
  if (highPriority) NotificationCompat.PRIORITY_HIGH
1096
1072
  else NotificationCompat.PRIORITY_DEFAULT
1097
1073
  )
1098
- val component = launch?.component
1099
- if (component != null) {
1100
- val target = Intent(ACTION_TAP)
1101
- target.component = component
1102
- target.flags =
1103
- Intent.FLAG_ACTIVITY_NEW_TASK or
1104
- Intent.FLAG_ACTIVITY_CLEAR_TOP or
1105
- Intent.FLAG_ACTIVITY_SINGLE_TOP
1106
- target.putExtra(EXTRA_TAP, true)
1074
+ if (launch?.component != null) {
1075
+ val target = Intent(context, OneNativeNotificationTapActivity::class.java)
1076
+ target.flags = Intent.FLAG_ACTIVITY_NEW_TASK
1107
1077
  target.putExtra(EXTRA_IDENTIFIER, schedule.identifier)
1108
1078
  target.putExtra(EXTRA_TITLE, schedule.title)
1109
1079
  target.putExtra(EXTRA_SUBTITLE, schedule.subtitle)
@@ -1177,7 +1147,11 @@ class HybridOneNotifications :
1177
1147
  context,
1178
1148
  (schedule.identifier + ":" + action.identifier).hashCode(),
1179
1149
  target,
1180
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
1150
+ // the system writes a typed reply into the intent, so a
1151
+ // text-input action needs a mutable one (refused otherwise).
1152
+ PendingIntent.FLAG_UPDATE_CURRENT or
1153
+ if (action.textInputPlaceholder != null) PendingIntent.FLAG_MUTABLE
1154
+ else PendingIntent.FLAG_IMMUTABLE
1181
1155
  )
1182
1156
  val builder =
1183
1157
  androidx.core.app.NotificationCompat.Action.Builder(0, action.buttonTitle, pending)
@@ -1194,6 +1168,46 @@ class HybridOneNotifications :
1194
1168
  return builder.build()
1195
1169
  }
1196
1170
 
1171
+ // a notification tap or action, from the extras every tap intent carries.
1172
+ private fun tapResponse(intent: Intent, userText: String?): TapResponse? {
1173
+ val identifier = intent.getStringExtra(EXTRA_IDENTIFIER) ?: return null
1174
+ return TapResponse(
1175
+ identifier,
1176
+ intent.getStringExtra(EXTRA_TITLE),
1177
+ intent.getStringExtra(EXTRA_SUBTITLE),
1178
+ intent.getStringExtra(EXTRA_BODY),
1179
+ intent.getStringExtra(EXTRA_DATA) ?: "{}",
1180
+ intent.getBooleanExtra(EXTRA_SOUND, false),
1181
+ if (intent.hasExtra(EXTRA_BADGE)) intent.getIntExtra(EXTRA_BADGE, 0) else null,
1182
+ intent.getStringExtra(EXTRA_TRIGGER) ?: IMMEDIATE_TRIGGER_JSON,
1183
+ System.currentTimeMillis(),
1184
+ intent.getStringExtra(EXTRA_ACTION) ?: DEFAULT_ACTION_IDENTIFIER,
1185
+ userText,
1186
+ intent.getStringExtra(EXTRA_CATEGORY)
1187
+ )
1188
+ }
1189
+
1190
+ // a notification body tap, from OneNativeNotificationTapActivity before
1191
+ // the app opens. react native drops an onNewIntent that arrives before
1192
+ // its context is ready, which is how android hands the tap to an app
1193
+ // activity it recreates after the process died, so the response is
1194
+ // recorded on the process here and the app opens without it.
1195
+ fun handleTap(context: Context, intent: Intent) {
1196
+ val response = tapResponse(intent, null) ?: return
1197
+ lastResponse = response
1198
+ instance?.let { live ->
1199
+ live.currentListeners()?.onResponse?.invoke(live.responsePayload(response))
1200
+ }
1201
+ val launch =
1202
+ context.packageManager.getLaunchIntentForPackage(context.packageName) ?: return
1203
+ launch.addFlags(
1204
+ Intent.FLAG_ACTIVITY_NEW_TASK or
1205
+ Intent.FLAG_ACTIVITY_CLEAR_TOP or
1206
+ Intent.FLAG_ACTIVITY_SINGLE_TOP
1207
+ )
1208
+ context.startActivity(launch)
1209
+ }
1210
+
1197
1211
  // action-tap entry: through the live hybrid when js is up, or
1198
1212
  // recorded statically with a response-carrying launch when the
1199
1213
  // process started for this broadcast. the activity harvest reads
@@ -1206,24 +1220,8 @@ class HybridOneNotifications :
1206
1220
  }
1207
1221
  val results = androidx.core.app.RemoteInput.getResultsFromIntent(intent)
1208
1222
  val response =
1209
- TapResponse(
1210
- intent.getStringExtra(EXTRA_IDENTIFIER) ?: return,
1211
- intent.getStringExtra(EXTRA_TITLE),
1212
- intent.getStringExtra(EXTRA_SUBTITLE),
1213
- intent.getStringExtra(EXTRA_BODY),
1214
- intent.getStringExtra(EXTRA_DATA) ?: "{}",
1215
- intent.getBooleanExtra(EXTRA_SOUND, false),
1216
- if (intent.hasExtra(EXTRA_BADGE)) {
1217
- intent.getIntExtra(EXTRA_BADGE, 0)
1218
- } else {
1219
- null
1220
- },
1221
- intent.getStringExtra(EXTRA_TRIGGER) ?: IMMEDIATE_TRIGGER_JSON,
1222
- System.currentTimeMillis(),
1223
- intent.getStringExtra(EXTRA_ACTION) ?: DEFAULT_ACTION_IDENTIFIER,
1224
- results?.getCharSequence(EXTRA_USER_TEXT)?.toString(),
1225
- intent.getStringExtra(EXTRA_CATEGORY)
1226
- )
1223
+ tapResponse(intent, results?.getCharSequence(EXTRA_USER_TEXT)?.toString())
1224
+ ?: return
1227
1225
  lastResponse = response
1228
1226
  if (intent.getBooleanExtra(EXTRA_FOREGROUND, true)) {
1229
1227
  foregroundWithResponse(context, response, results)
@@ -0,0 +1,16 @@
1
+ package dev.onejs.onenative
2
+
3
+ import android.app.Activity
4
+ import android.os.Bundle
5
+ import com.margelo.nitro.one.HybridOneNotifications
6
+
7
+ // a scheduled notification's body tap opens this invisible activity first: it
8
+ // records the response before any app activity sees the tap, then opens the
9
+ // app. never exported, so only the notification's own pending intent reaches it.
10
+ class OneNativeNotificationTapActivity : Activity() {
11
+ override fun onCreate(savedInstanceState: Bundle?) {
12
+ super.onCreate(savedInstanceState)
13
+ HybridOneNotifications.handleTap(this, intent)
14
+ finish()
15
+ }
16
+ }
@@ -8,7 +8,6 @@ import androidx.compose.runtime.LaunchedEffect
8
8
  import androidx.compose.runtime.getValue
9
9
  import androidx.compose.runtime.key
10
10
  import androidx.compose.runtime.mutableStateOf
11
- import androidx.compose.runtime.remember
12
11
  import androidx.compose.runtime.setValue
13
12
  import androidx.compose.runtime.snapshotFlow
14
13
  import androidx.compose.ui.Modifier
@@ -16,7 +15,8 @@ import androidx.compose.ui.graphics.Color
16
15
  import androidx.compose.ui.platform.ComposeView
17
16
  import androidx.compose.ui.platform.ViewCompositionStrategy
18
17
  import androidx.lifecycle.LifecycleOwner
19
- import androidx.lifecycle.ViewTreeLifecycleOwner
18
+ import androidx.lifecycle.findViewTreeLifecycleOwner
19
+ import androidx.lifecycle.setViewTreeLifecycleOwner
20
20
  import com.facebook.react.bridge.ReadableArray
21
21
  import com.facebook.react.uimanager.ThemedReactContext
22
22
  import com.facebook.react.uimanager.UIManagerHelper
@@ -237,10 +237,14 @@ class OneNativeUiMapView(context: Context) : FrameLayout(context) {
237
237
  cameraPositionState.position =
238
238
  CameraPosition.fromLatLngZoom(LatLng(latitude, longitude), zoom.toFloat())
239
239
  }
240
- var gestureMove by remember { mutableStateOf(false) }
241
240
  LaunchedEffect(cameraPositionState) {
241
+ var gestureMove = false
242
242
  snapshotFlow { cameraPositionState.isMoving }.collect { moving ->
243
- if (!moving && gestureMove) {
243
+ if (moving) {
244
+ gestureMove =
245
+ cameraPositionState.cameraMoveStartedReason ==
246
+ CameraMoveStartedReason.GESTURE
247
+ } else if (gestureMove) {
244
248
  gestureMove = false
245
249
  val position = cameraPositionState.position
246
250
  handleCameraMove(
@@ -255,9 +259,6 @@ class OneNativeUiMapView(context: Context) : FrameLayout(context) {
255
259
  modifier = Modifier.fillMaxSize(),
256
260
  cameraPositionState = cameraPositionState,
257
261
  onMapClick = { point -> handleMapClick(point.latitude, point.longitude) },
258
- onCameraMoveStarted = { reason ->
259
- gestureMove = reason == CameraMoveStartedReason.GESTURE
260
- },
261
262
  ) {
262
263
  markers.forEach { marker ->
263
264
  key(marker.id, marker.latitude, marker.longitude, marker.title, marker.tint) {
@@ -314,9 +315,9 @@ class OneNativeUiMapView(context: Context) : FrameLayout(context) {
314
315
  // published here instead. retried on attach: the activity can be null
315
316
  // while the view is constructed.
316
317
  private fun ensureLifecycleOwner() {
317
- if (ViewTreeLifecycleOwner.get(this) != null) return
318
+ if (findViewTreeLifecycleOwner() != null) return
318
319
  val activity = (context as? ThemedReactContext)?.currentActivity as? LifecycleOwner ?: return
319
- ViewTreeLifecycleOwner.set(this, activity)
320
+ setViewTreeLifecycleOwner(activity)
320
321
  }
321
322
 
322
323
  internal fun setLatitude(latitude: Double) {
@@ -76,8 +76,21 @@ function resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {
76
76
  const requestType = request.method || "GET";
77
77
  const handler = imported[requestType] || imported.default;
78
78
  if (!handler) {
79
- console.warn(`No handler found for request ${requestType}`);
80
- return;
79
+ const allowedMethods = [
80
+ "GET",
81
+ "HEAD",
82
+ "POST",
83
+ "PUT",
84
+ "DELETE",
85
+ "CONNECT",
86
+ "OPTIONS",
87
+ "TRACE",
88
+ "PATCH"
89
+ ].filter((method) => typeof imported[method] === "function").join(", ");
90
+ return new Response(null, {
91
+ status: 405,
92
+ headers: { Allow: allowedMethods }
93
+ });
81
94
  }
82
95
  const worker = env !== void 0 || executionCtx !== void 0 ? {
83
96
  env,
@@ -78,8 +78,23 @@ function resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {
78
78
  var requestType = request.method || "GET";
79
79
  var handler = imported[requestType] || imported.default;
80
80
  if (!handler) {
81
- console.warn(`No handler found for request ${requestType}`);
82
- return;
81
+ var allowedMethods = [
82
+ "GET",
83
+ "HEAD",
84
+ "POST",
85
+ "PUT",
86
+ "DELETE",
87
+ "CONNECT",
88
+ "OPTIONS",
89
+ "TRACE",
90
+ "PATCH"
91
+ ].filter(function(method) {
92
+ return typeof imported[method] === "function";
93
+ }).join(", ");
94
+ return new Response(null, {
95
+ status: 405,
96
+ headers: { Allow: allowedMethods }
97
+ });
83
98
  }
84
99
  var worker = env !== void 0 || executionCtx !== void 0 ? {
85
100
  env,
@@ -78,8 +78,23 @@ function resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {
78
78
  var requestType = request.method || "GET";
79
79
  var handler = imported[requestType] || imported.default;
80
80
  if (!handler) {
81
- console.warn(`No handler found for request ${requestType}`);
82
- return;
81
+ var allowedMethods = [
82
+ "GET",
83
+ "HEAD",
84
+ "POST",
85
+ "PUT",
86
+ "DELETE",
87
+ "CONNECT",
88
+ "OPTIONS",
89
+ "TRACE",
90
+ "PATCH"
91
+ ].filter(function(method) {
92
+ return typeof imported[method] === "function";
93
+ }).join(", ");
94
+ return new Response(null, {
95
+ status: 405,
96
+ headers: { Allow: allowedMethods }
97
+ });
83
98
  }
84
99
  var worker = env !== void 0 || executionCtx !== void 0 ? {
85
100
  env,
@@ -1 +1 @@
1
- {"version":3,"file":"resolveResponse.native.js","names":[],"sources":["cjs/vite/resolveResponse.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar resolveResponse_exports = {};\n__export(resolveResponse_exports, {\n resolveAPIEndpoint: () => resolveAPIEndpoint,\n resolveResponse: () => resolveResponse,\n withRequestContext: () => withRequestContext\n});\nmodule.exports = __toCommonJS(resolveResponse_exports);\nvar import_isResponse = require(\"../utils/isResponse\");\nvar import_one_server_only = require(\"./one-server-only\");\nvar _nextId = 1;\nfunction createId() {\n return {\n _id: _nextId++\n };\n}\nasync function resolveResponse(getResponse) {\n var store = import_one_server_only.requestAsyncLocalStore !== null && import_one_server_only.requestAsyncLocalStore !== void 0 ? import_one_server_only.requestAsyncLocalStore : globalThis[\"__vxrnrequestAsyncLocalStore\"];\n if (store) {\n var id = createId();\n var response;\n await store.run(id, async function() {\n try {\n response = await getResponse();\n response = await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if ((0, import_isResponse.isResponse)(err)) {\n response = err;\n } else {\n throw err;\n }\n }\n });\n return response;\n }\n return (0, import_one_server_only.runWithAsyncLocalContext)(async function(id2) {\n try {\n var response2 = await getResponse();\n return await getResponseWithAddedHeaders(response2, id2);\n } catch (err) {\n if ((0, import_isResponse.isResponse)(err)) {\n return err;\n }\n throw err;\n }\n });\n}\nfunction withRequestContext(fn) {\n var store = import_one_server_only.requestAsyncLocalStore;\n if (store) {\n var id = createId();\n return store.run(id, fn);\n }\n return fn();\n}\nfunction resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {\n return resolveResponse(async function() {\n var imported = await runEndpoint();\n var requestType = request.method || \"GET\";\n var handler = imported[requestType] || imported.default;\n if (!handler) {\n console.warn(`No handler found for request ${requestType}`);\n return;\n }\n var worker = env !== void 0 || executionCtx !== void 0 ? {\n env,\n executionCtx\n } : void 0;\n return await handler(request, {\n params,\n worker\n });\n });\n}\nasync function getResponseWithAddedHeaders(response, id) {\n var _globalThis___vxrnasyncHeadersCache;\n var cache = (_globalThis___vxrnasyncHeadersCache = globalThis[\"__vxrnasyncHeadersCache\"]) !== null && _globalThis___vxrnasyncHeadersCache !== void 0 ? _globalThis___vxrnasyncHeadersCache : import_one_server_only.asyncHeadersCache;\n var asyncHeaders = cache.get(id);\n if (asyncHeaders) {\n try {\n if (response instanceof Response) {\n var cloned = response.clone();\n var headers = new Headers();\n (0, import_one_server_only.mergeHeaders)(headers, cloned.headers);\n (0, import_one_server_only.mergeHeaders)(headers, asyncHeaders);\n response = new Response(cloned.body, {\n status: cloned.status,\n statusText: cloned.statusText,\n headers\n });\n } else {\n if (response && typeof response === \"object\") {\n response = Response.json(response, {\n headers: asyncHeaders\n });\n } else {\n var headers1 = new Headers(asyncHeaders);\n if (!headers1.has(\"content-type\")) {\n headers1.set(\"content-type\", \"text/html\");\n }\n response = new Response(response, {\n headers: headers1\n });\n }\n }\n } catch (err) {\n console.error(` [one] error adding headers: ${err}`);\n }\n }\n return response;\n}\n//# sourceMappingURL=resolveResponse.js.map\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolveResponse.native.js","names":[],"sources":["cjs/vite/resolveResponse.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar resolveResponse_exports = {};\n__export(resolveResponse_exports, {\n resolveAPIEndpoint: () => resolveAPIEndpoint,\n resolveResponse: () => resolveResponse,\n withRequestContext: () => withRequestContext\n});\nmodule.exports = __toCommonJS(resolveResponse_exports);\nvar import_isResponse = require(\"../utils/isResponse\");\nvar import_one_server_only = require(\"./one-server-only\");\nvar _nextId = 1;\nfunction createId() {\n return {\n _id: _nextId++\n };\n}\nasync function resolveResponse(getResponse) {\n var store = import_one_server_only.requestAsyncLocalStore !== null && import_one_server_only.requestAsyncLocalStore !== void 0 ? import_one_server_only.requestAsyncLocalStore : globalThis[\"__vxrnrequestAsyncLocalStore\"];\n if (store) {\n var id = createId();\n var response;\n await store.run(id, async function() {\n try {\n response = await getResponse();\n response = await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if ((0, import_isResponse.isResponse)(err)) {\n response = err;\n } else {\n throw err;\n }\n }\n });\n return response;\n }\n return (0, import_one_server_only.runWithAsyncLocalContext)(async function(id2) {\n try {\n var response2 = await getResponse();\n return await getResponseWithAddedHeaders(response2, id2);\n } catch (err) {\n if ((0, import_isResponse.isResponse)(err)) {\n return err;\n }\n throw err;\n }\n });\n}\nfunction withRequestContext(fn) {\n var store = import_one_server_only.requestAsyncLocalStore;\n if (store) {\n var id = createId();\n return store.run(id, fn);\n }\n return fn();\n}\nfunction resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {\n return resolveResponse(async function() {\n var imported = await runEndpoint();\n var requestType = request.method || \"GET\";\n var handler = imported[requestType] || imported.default;\n if (!handler) {\n var allowedMethods = [\n \"GET\",\n \"HEAD\",\n \"POST\",\n \"PUT\",\n \"DELETE\",\n \"CONNECT\",\n \"OPTIONS\",\n \"TRACE\",\n \"PATCH\"\n ].filter(function(method) {\n return typeof imported[method] === \"function\";\n }).join(\", \");\n return new Response(null, {\n status: 405,\n headers: {\n Allow: allowedMethods\n }\n });\n }\n var worker = env !== void 0 || executionCtx !== void 0 ? {\n env,\n executionCtx\n } : void 0;\n return await handler(request, {\n params,\n worker\n });\n });\n}\nasync function getResponseWithAddedHeaders(response, id) {\n var _globalThis___vxrnasyncHeadersCache;\n var cache = (_globalThis___vxrnasyncHeadersCache = globalThis[\"__vxrnasyncHeadersCache\"]) !== null && _globalThis___vxrnasyncHeadersCache !== void 0 ? _globalThis___vxrnasyncHeadersCache : import_one_server_only.asyncHeadersCache;\n var asyncHeaders = cache.get(id);\n if (asyncHeaders) {\n try {\n if (response instanceof Response) {\n var cloned = response.clone();\n var headers = new Headers();\n (0, import_one_server_only.mergeHeaders)(headers, cloned.headers);\n (0, import_one_server_only.mergeHeaders)(headers, asyncHeaders);\n response = new Response(cloned.body, {\n status: cloned.status,\n statusText: cloned.statusText,\n headers\n });\n } else {\n if (response && typeof response === \"object\") {\n response = Response.json(response, {\n headers: asyncHeaders\n });\n } else {\n var headers1 = new Headers(asyncHeaders);\n if (!headers1.has(\"content-type\")) {\n headers1.set(\"content-type\", \"text/html\");\n }\n response = new Response(response, {\n headers: headers1\n });\n }\n }\n } catch (err) {\n console.error(` [one] error adding headers: ${err}`);\n }\n }\n return response;\n}\n//# sourceMappingURL=resolveResponse.js.map\n"],"mappings":"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"}
@@ -50,8 +50,21 @@ function resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {
50
50
  const requestType = request.method || "GET";
51
51
  const handler = imported[requestType] || imported.default;
52
52
  if (!handler) {
53
- console.warn(`No handler found for request ${requestType}`);
54
- return;
53
+ const allowedMethods = [
54
+ "GET",
55
+ "HEAD",
56
+ "POST",
57
+ "PUT",
58
+ "DELETE",
59
+ "CONNECT",
60
+ "OPTIONS",
61
+ "TRACE",
62
+ "PATCH"
63
+ ].filter((method) => typeof imported[method] === "function").join(", ");
64
+ return new Response(null, {
65
+ status: 405,
66
+ headers: { Allow: allowedMethods }
67
+ });
55
68
  }
56
69
  const worker = env !== void 0 || executionCtx !== void 0 ? {
57
70
  env,
@@ -1 +1 @@
1
- {"version":3,"file":"resolveResponse.js","names":[],"sources":["esm/vite/resolveResponse.js"],"sourcesContent":["import { isResponse } from \"../utils/isResponse\";\nimport {\n asyncHeadersCache,\n mergeHeaders,\n requestAsyncLocalStore,\n runWithAsyncLocalContext\n} from \"./one-server-only\";\nlet _nextId = 1;\nfunction createId() {\n return { _id: _nextId++ };\n}\nasync function resolveResponse(getResponse) {\n const store = requestAsyncLocalStore ?? globalThis[\"__vxrnrequestAsyncLocalStore\"];\n if (store) {\n const id = createId();\n let response;\n await store.run(id, async () => {\n try {\n response = await getResponse();\n response = await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if (isResponse(err)) {\n response = err;\n } else {\n throw err;\n }\n }\n });\n return response;\n }\n return runWithAsyncLocalContext(async (id) => {\n try {\n const response = await getResponse();\n return await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if (isResponse(err)) {\n return err;\n }\n throw err;\n }\n });\n}\nfunction withRequestContext(fn) {\n const store = requestAsyncLocalStore;\n if (store) {\n const id = createId();\n return store.run(id, fn);\n }\n return fn();\n}\nfunction resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {\n return resolveResponse(async () => {\n const imported = await runEndpoint();\n const requestType = request.method || \"GET\";\n const handler = imported[requestType] || imported.default;\n if (!handler) {\n console.warn(`No handler found for request ${requestType}`);\n return;\n }\n const worker = env !== void 0 || executionCtx !== void 0 ? { env, executionCtx } : void 0;\n return await handler(request, { params, worker });\n });\n}\nasync function getResponseWithAddedHeaders(response, id) {\n const cache = globalThis[\"__vxrnasyncHeadersCache\"] ?? asyncHeadersCache;\n const asyncHeaders = cache.get(id);\n if (asyncHeaders) {\n try {\n if (response instanceof Response) {\n const cloned = response.clone();\n const headers = new Headers();\n mergeHeaders(headers, cloned.headers);\n mergeHeaders(headers, asyncHeaders);\n response = new Response(cloned.body, {\n status: cloned.status,\n statusText: cloned.statusText,\n headers\n });\n } else {\n if (response && typeof response === \"object\") {\n response = Response.json(response, { headers: asyncHeaders });\n } else {\n const headers = new Headers(asyncHeaders);\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"text/html\");\n }\n response = new Response(response, { headers });\n }\n }\n } catch (err) {\n console.error(` [one] error adding headers: ${err}`);\n }\n }\n return response;\n}\nexport {\n resolveAPIEndpoint,\n resolveResponse,\n withRequestContext\n};\n//# sourceMappingURL=resolveResponse.js.map\n"],"mappings":";;;;AAOA,IAAI,UAAU;AACd,SAAS,WAAW;CAClB,OAAO,EAAE,KAAK,UAAU;AAC1B;AACA,eAAe,gBAAgB,aAAa;CAC1C,MAAM,QAAQ,0BAA0B,WAAW;CACnD,IAAI,OAAO;EACT,MAAM,KAAK,SAAS;EACpB,IAAI;EACJ,MAAM,MAAM,IAAI,IAAI,YAAY;GAC9B,IAAI;IACF,WAAW,MAAM,YAAY;IAC7B,WAAW,MAAM,4BAA4B,UAAU,EAAE;GAC3D,SAAS,KAAK;IACZ,IAAI,WAAW,GAAG,GAAG;KACnB,WAAW;IACb,OAAO;KACL,MAAM;IACR;GACF;EACF,CAAC;EACD,OAAO;CACT;CACA,OAAO,yBAAyB,OAAO,OAAO;EAC5C,IAAI;GACF,MAAM,WAAW,MAAM,YAAY;GACnC,OAAO,MAAM,4BAA4B,UAAU,EAAE;EACvD,SAAS,KAAK;GACZ,IAAI,WAAW,GAAG,GAAG;IACnB,OAAO;GACT;GACA,MAAM;EACR;CACF,CAAC;AACH;AACA,SAAS,mBAAmB,IAAI;CAC9B,MAAM,QAAQ;CACd,IAAI,OAAO;EACT,MAAM,KAAK,SAAS;EACpB,OAAO,MAAM,IAAI,IAAI,EAAE;CACzB;CACA,OAAO,GAAG;AACZ;AACA,SAAS,mBAAmB,aAAa,SAAS,QAAQ,KAAK,cAAc;CAC3E,OAAO,gBAAgB,YAAY;EACjC,MAAM,WAAW,MAAM,YAAY;EACnC,MAAM,cAAc,QAAQ,UAAU;EACtC,MAAM,UAAU,SAAS,gBAAgB,SAAS;EAClD,IAAI,CAAC,SAAS;GACZ,QAAQ,KAAK,gCAAgC,aAAa;GAC1D;EACF;EACA,MAAM,SAAS,QAAQ,KAAK,KAAK,iBAAiB,KAAK,IAAI;GAAE;GAAK;EAAa,IAAI,KAAK;EACxF,OAAO,MAAM,QAAQ,SAAS;GAAE;GAAQ;EAAO,CAAC;CAClD,CAAC;AACH;AACA,eAAe,4BAA4B,UAAU,IAAI;CACvD,MAAM,QAAQ,WAAW,8BAA8B;CACvD,MAAM,eAAe,MAAM,IAAI,EAAE;CACjC,IAAI,cAAc;EAChB,IAAI;GACF,IAAI,oBAAoB,UAAU;IAChC,MAAM,SAAS,SAAS,MAAM;IAC9B,MAAM,UAAU,IAAI,QAAQ;IAC5B,aAAa,SAAS,OAAO,OAAO;IACpC,aAAa,SAAS,YAAY;IAClC,WAAW,IAAI,SAAS,OAAO,MAAM;KACnC,QAAQ,OAAO;KACf,YAAY,OAAO;KACnB;IACF,CAAC;GACH,OAAO;IACL,IAAI,YAAY,OAAO,aAAa,UAAU;KAC5C,WAAW,SAAS,KAAK,UAAU,EAAE,SAAS,aAAa,CAAC;IAC9D,OAAO;KACL,MAAM,UAAU,IAAI,QAAQ,YAAY;KACxC,IAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;MAChC,QAAQ,IAAI,gBAAgB,WAAW;KACzC;KACA,WAAW,IAAI,SAAS,UAAU,EAAE,QAAQ,CAAC;IAC/C;GACF;EACF,SAAS,KAAK;GACZ,QAAQ,MAAM,gCAAgC,KAAK;EACrD;CACF;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"resolveResponse.js","names":[],"sources":["esm/vite/resolveResponse.js"],"sourcesContent":["import { isResponse } from \"../utils/isResponse\";\nimport {\n asyncHeadersCache,\n mergeHeaders,\n requestAsyncLocalStore,\n runWithAsyncLocalContext\n} from \"./one-server-only\";\nlet _nextId = 1;\nfunction createId() {\n return { _id: _nextId++ };\n}\nasync function resolveResponse(getResponse) {\n const store = requestAsyncLocalStore ?? globalThis[\"__vxrnrequestAsyncLocalStore\"];\n if (store) {\n const id = createId();\n let response;\n await store.run(id, async () => {\n try {\n response = await getResponse();\n response = await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if (isResponse(err)) {\n response = err;\n } else {\n throw err;\n }\n }\n });\n return response;\n }\n return runWithAsyncLocalContext(async (id) => {\n try {\n const response = await getResponse();\n return await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if (isResponse(err)) {\n return err;\n }\n throw err;\n }\n });\n}\nfunction withRequestContext(fn) {\n const store = requestAsyncLocalStore;\n if (store) {\n const id = createId();\n return store.run(id, fn);\n }\n return fn();\n}\nfunction resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {\n return resolveResponse(async () => {\n const imported = await runEndpoint();\n const requestType = request.method || \"GET\";\n const handler = imported[requestType] || imported.default;\n if (!handler) {\n const allowedMethods = [\n \"GET\",\n \"HEAD\",\n \"POST\",\n \"PUT\",\n \"DELETE\",\n \"CONNECT\",\n \"OPTIONS\",\n \"TRACE\",\n \"PATCH\"\n ].filter((method) => typeof imported[method] === \"function\").join(\", \");\n return new Response(null, {\n status: 405,\n headers: { Allow: allowedMethods }\n });\n }\n const worker = env !== void 0 || executionCtx !== void 0 ? { env, executionCtx } : void 0;\n return await handler(request, { params, worker });\n });\n}\nasync function getResponseWithAddedHeaders(response, id) {\n const cache = globalThis[\"__vxrnasyncHeadersCache\"] ?? asyncHeadersCache;\n const asyncHeaders = cache.get(id);\n if (asyncHeaders) {\n try {\n if (response instanceof Response) {\n const cloned = response.clone();\n const headers = new Headers();\n mergeHeaders(headers, cloned.headers);\n mergeHeaders(headers, asyncHeaders);\n response = new Response(cloned.body, {\n status: cloned.status,\n statusText: cloned.statusText,\n headers\n });\n } else {\n if (response && typeof response === \"object\") {\n response = Response.json(response, { headers: asyncHeaders });\n } else {\n const headers = new Headers(asyncHeaders);\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"text/html\");\n }\n response = new Response(response, { headers });\n }\n }\n } catch (err) {\n console.error(` [one] error adding headers: ${err}`);\n }\n }\n return response;\n}\nexport {\n resolveAPIEndpoint,\n resolveResponse,\n withRequestContext\n};\n//# sourceMappingURL=resolveResponse.js.map\n"],"mappings":";;;;AAOA,IAAI,UAAU;AACd,SAAS,WAAW;CAClB,OAAO,EAAE,KAAK,UAAU;AAC1B;AACA,eAAe,gBAAgB,aAAa;CAC1C,MAAM,QAAQ,0BAA0B,WAAW;CACnD,IAAI,OAAO;EACT,MAAM,KAAK,SAAS;EACpB,IAAI;EACJ,MAAM,MAAM,IAAI,IAAI,YAAY;GAC9B,IAAI;IACF,WAAW,MAAM,YAAY;IAC7B,WAAW,MAAM,4BAA4B,UAAU,EAAE;GAC3D,SAAS,KAAK;IACZ,IAAI,WAAW,GAAG,GAAG;KACnB,WAAW;IACb,OAAO;KACL,MAAM;IACR;GACF;EACF,CAAC;EACD,OAAO;CACT;CACA,OAAO,yBAAyB,OAAO,OAAO;EAC5C,IAAI;GACF,MAAM,WAAW,MAAM,YAAY;GACnC,OAAO,MAAM,4BAA4B,UAAU,EAAE;EACvD,SAAS,KAAK;GACZ,IAAI,WAAW,GAAG,GAAG;IACnB,OAAO;GACT;GACA,MAAM;EACR;CACF,CAAC;AACH;AACA,SAAS,mBAAmB,IAAI;CAC9B,MAAM,QAAQ;CACd,IAAI,OAAO;EACT,MAAM,KAAK,SAAS;EACpB,OAAO,MAAM,IAAI,IAAI,EAAE;CACzB;CACA,OAAO,GAAG;AACZ;AACA,SAAS,mBAAmB,aAAa,SAAS,QAAQ,KAAK,cAAc;CAC3E,OAAO,gBAAgB,YAAY;EACjC,MAAM,WAAW,MAAM,YAAY;EACnC,MAAM,cAAc,QAAQ,UAAU;EACtC,MAAM,UAAU,SAAS,gBAAgB,SAAS;EAClD,IAAI,CAAC,SAAS;GACZ,MAAM,iBAAiB;IACrB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF,CAAC,CAAC,QAAQ,WAAW,OAAO,SAAS,YAAY,UAAU,CAAC,CAAC,KAAK,IAAI;GACtE,OAAO,IAAI,SAAS,MAAM;IACxB,QAAQ;IACR,SAAS,EAAE,OAAO,eAAe;GACnC,CAAC;EACH;EACA,MAAM,SAAS,QAAQ,KAAK,KAAK,iBAAiB,KAAK,IAAI;GAAE;GAAK;EAAa,IAAI,KAAK;EACxF,OAAO,MAAM,QAAQ,SAAS;GAAE;GAAQ;EAAO,CAAC;CAClD,CAAC;AACH;AACA,eAAe,4BAA4B,UAAU,IAAI;CACvD,MAAM,QAAQ,WAAW,8BAA8B;CACvD,MAAM,eAAe,MAAM,IAAI,EAAE;CACjC,IAAI,cAAc;EAChB,IAAI;GACF,IAAI,oBAAoB,UAAU;IAChC,MAAM,SAAS,SAAS,MAAM;IAC9B,MAAM,UAAU,IAAI,QAAQ;IAC5B,aAAa,SAAS,OAAO,OAAO;IACpC,aAAa,SAAS,YAAY;IAClC,WAAW,IAAI,SAAS,OAAO,MAAM;KACnC,QAAQ,OAAO;KACf,YAAY,OAAO;KACnB;IACF,CAAC;GACH,OAAO;IACL,IAAI,YAAY,OAAO,aAAa,UAAU;KAC5C,WAAW,SAAS,KAAK,UAAU,EAAE,SAAS,aAAa,CAAC;IAC9D,OAAO;KACL,MAAM,UAAU,IAAI,QAAQ,YAAY;KACxC,IAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;MAChC,QAAQ,IAAI,gBAAgB,WAAW;KACzC;KACA,WAAW,IAAI,SAAS,UAAU,EAAE,QAAQ,CAAC;IAC/C;GACF;EACF,SAAS,KAAK;GACZ,QAAQ,MAAM,gCAAgC,KAAK;EACrD;CACF;CACA,OAAO;AACT"}
@@ -50,8 +50,23 @@ function resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {
50
50
  var requestType = request.method || "GET";
51
51
  var handler = imported[requestType] || imported.default;
52
52
  if (!handler) {
53
- console.warn(`No handler found for request ${requestType}`);
54
- return;
53
+ var allowedMethods = [
54
+ "GET",
55
+ "HEAD",
56
+ "POST",
57
+ "PUT",
58
+ "DELETE",
59
+ "CONNECT",
60
+ "OPTIONS",
61
+ "TRACE",
62
+ "PATCH"
63
+ ].filter(function(method) {
64
+ return typeof imported[method] === "function";
65
+ }).join(", ");
66
+ return new Response(null, {
67
+ status: 405,
68
+ headers: { Allow: allowedMethods }
69
+ });
55
70
  }
56
71
  var worker = env !== void 0 || executionCtx !== void 0 ? {
57
72
  env,
@@ -1 +1 @@
1
- {"version":3,"file":"resolveResponse.native.js","names":[],"sources":["esm/vite/resolveResponse.native.js"],"sourcesContent":["import { isResponse } from \"../utils/isResponse\";\nimport { asyncHeadersCache, mergeHeaders, requestAsyncLocalStore, runWithAsyncLocalContext } from \"./one-server-only\";\nvar _nextId = 1;\nfunction createId() {\n return {\n _id: _nextId++\n };\n}\nasync function resolveResponse(getResponse) {\n var store = requestAsyncLocalStore !== null && requestAsyncLocalStore !== void 0 ? requestAsyncLocalStore : globalThis[\"__vxrnrequestAsyncLocalStore\"];\n if (store) {\n var id = createId();\n var response;\n await store.run(id, async function() {\n try {\n response = await getResponse();\n response = await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if (isResponse(err)) {\n response = err;\n } else {\n throw err;\n }\n }\n });\n return response;\n }\n return runWithAsyncLocalContext(async function(id2) {\n try {\n var response2 = await getResponse();\n return await getResponseWithAddedHeaders(response2, id2);\n } catch (err) {\n if (isResponse(err)) {\n return err;\n }\n throw err;\n }\n });\n}\nfunction withRequestContext(fn) {\n var store = requestAsyncLocalStore;\n if (store) {\n var id = createId();\n return store.run(id, fn);\n }\n return fn();\n}\nfunction resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {\n return resolveResponse(async function() {\n var imported = await runEndpoint();\n var requestType = request.method || \"GET\";\n var handler = imported[requestType] || imported.default;\n if (!handler) {\n console.warn(`No handler found for request ${requestType}`);\n return;\n }\n var worker = env !== void 0 || executionCtx !== void 0 ? {\n env,\n executionCtx\n } : void 0;\n return await handler(request, {\n params,\n worker\n });\n });\n}\nasync function getResponseWithAddedHeaders(response, id) {\n var _globalThis___vxrnasyncHeadersCache;\n var cache = (_globalThis___vxrnasyncHeadersCache = globalThis[\"__vxrnasyncHeadersCache\"]) !== null && _globalThis___vxrnasyncHeadersCache !== void 0 ? _globalThis___vxrnasyncHeadersCache : asyncHeadersCache;\n var asyncHeaders = cache.get(id);\n if (asyncHeaders) {\n try {\n if (response instanceof Response) {\n var cloned = response.clone();\n var headers = new Headers();\n mergeHeaders(headers, cloned.headers);\n mergeHeaders(headers, asyncHeaders);\n response = new Response(cloned.body, {\n status: cloned.status,\n statusText: cloned.statusText,\n headers\n });\n } else {\n if (response && typeof response === \"object\") {\n response = Response.json(response, {\n headers: asyncHeaders\n });\n } else {\n var headers1 = new Headers(asyncHeaders);\n if (!headers1.has(\"content-type\")) {\n headers1.set(\"content-type\", \"text/html\");\n }\n response = new Response(response, {\n headers: headers1\n });\n }\n }\n } catch (err) {\n console.error(` [one] error adding headers: ${err}`);\n }\n }\n return response;\n}\nexport {\n resolveAPIEndpoint,\n resolveResponse,\n withRequestContext\n};\n//# sourceMappingURL=resolveResponse.js.map\n"],"mappings":";;;;AAEA,IAAI,UAAU;AACd,SAAS,WAAW;CAClB,OAAO,EACL,KAAK,UACP;AACF;AACA,eAAe,gBAAgB,aAAa;CAC1C,IAAI,QAAQ,2BAA2B,QAAQ,2BAA2B,KAAK,IAAI,yBAAyB,WAAW;CACvH,IAAI,OAAO;EACT,IAAI,KAAK,SAAS;EAClB,IAAI;EACJ,MAAM,MAAM,IAAI,IAAI,iBAAiB;GACnC,IAAI;IACF,WAAW,MAAM,YAAY;IAC7B,WAAW,MAAM,4BAA4B,UAAU,EAAE;GAC3D,SAAS,KAAK;IACZ,IAAI,WAAW,GAAG,GAAG;KACnB,WAAW;IACb,OAAO;KACL,MAAM;IACR;GACF;EACF,CAAC;EACD,OAAO;CACT;CACA,OAAO,yBAAyB,eAAe,KAAK;EAClD,IAAI;GACF,IAAI,YAAY,MAAM,YAAY;GAClC,OAAO,MAAM,4BAA4B,WAAW,GAAG;EACzD,SAAS,KAAK;GACZ,IAAI,WAAW,GAAG,GAAG;IACnB,OAAO;GACT;GACA,MAAM;EACR;CACF,CAAC;AACH;AACA,SAAS,mBAAmB,IAAI;CAC9B,IAAI,QAAQ;CACZ,IAAI,OAAO;EACT,IAAI,KAAK,SAAS;EAClB,OAAO,MAAM,IAAI,IAAI,EAAE;CACzB;CACA,OAAO,GAAG;AACZ;AACA,SAAS,mBAAmB,aAAa,SAAS,QAAQ,KAAK,cAAc;CAC3E,OAAO,gBAAgB,iBAAiB;EACtC,IAAI,WAAW,MAAM,YAAY;EACjC,IAAI,cAAc,QAAQ,UAAU;EACpC,IAAI,UAAU,SAAS,gBAAgB,SAAS;EAChD,IAAI,CAAC,SAAS;GACZ,QAAQ,KAAK,gCAAgC,aAAa;GAC1D;EACF;EACA,IAAI,SAAS,QAAQ,KAAK,KAAK,iBAAiB,KAAK,IAAI;GACvD;GACA;EACF,IAAI,KAAK;EACT,OAAO,MAAM,QAAQ,SAAS;GAC5B;GACA;EACF,CAAC;CACH,CAAC;AACH;AACA,eAAe,4BAA4B,UAAU,IAAI;CACvD,IAAI;CACJ,IAAI,SAAS,sCAAsC,WAAW,gCAAgC,QAAQ,wCAAwC,KAAK,IAAI,sCAAsC;CAC7L,IAAI,eAAe,MAAM,IAAI,EAAE;CAC/B,IAAI,cAAc;EAChB,IAAI;GACF,IAAI,oBAAoB,UAAU;IAChC,IAAI,SAAS,SAAS,MAAM;IAC5B,IAAI,UAAU,IAAI,QAAQ;IAC1B,aAAa,SAAS,OAAO,OAAO;IACpC,aAAa,SAAS,YAAY;IAClC,WAAW,IAAI,SAAS,OAAO,MAAM;KACnC,QAAQ,OAAO;KACf,YAAY,OAAO;KACnB;IACF,CAAC;GACH,OAAO;IACL,IAAI,YAAY,OAAO,aAAa,UAAU;KAC5C,WAAW,SAAS,KAAK,UAAU,EACjC,SAAS,aACX,CAAC;IACH,OAAO;KACL,IAAI,WAAW,IAAI,QAAQ,YAAY;KACvC,IAAI,CAAC,SAAS,IAAI,cAAc,GAAG;MACjC,SAAS,IAAI,gBAAgB,WAAW;KAC1C;KACA,WAAW,IAAI,SAAS,UAAU,EAChC,SAAS,SACX,CAAC;IACH;GACF;EACF,SAAS,KAAK;GACZ,QAAQ,MAAM,gCAAgC,KAAK;EACrD;CACF;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"resolveResponse.native.js","names":[],"sources":["esm/vite/resolveResponse.native.js"],"sourcesContent":["import { isResponse } from \"../utils/isResponse\";\nimport { asyncHeadersCache, mergeHeaders, requestAsyncLocalStore, runWithAsyncLocalContext } from \"./one-server-only\";\nvar _nextId = 1;\nfunction createId() {\n return {\n _id: _nextId++\n };\n}\nasync function resolveResponse(getResponse) {\n var store = requestAsyncLocalStore !== null && requestAsyncLocalStore !== void 0 ? requestAsyncLocalStore : globalThis[\"__vxrnrequestAsyncLocalStore\"];\n if (store) {\n var id = createId();\n var response;\n await store.run(id, async function() {\n try {\n response = await getResponse();\n response = await getResponseWithAddedHeaders(response, id);\n } catch (err) {\n if (isResponse(err)) {\n response = err;\n } else {\n throw err;\n }\n }\n });\n return response;\n }\n return runWithAsyncLocalContext(async function(id2) {\n try {\n var response2 = await getResponse();\n return await getResponseWithAddedHeaders(response2, id2);\n } catch (err) {\n if (isResponse(err)) {\n return err;\n }\n throw err;\n }\n });\n}\nfunction withRequestContext(fn) {\n var store = requestAsyncLocalStore;\n if (store) {\n var id = createId();\n return store.run(id, fn);\n }\n return fn();\n}\nfunction resolveAPIEndpoint(runEndpoint, request, params, env, executionCtx) {\n return resolveResponse(async function() {\n var imported = await runEndpoint();\n var requestType = request.method || \"GET\";\n var handler = imported[requestType] || imported.default;\n if (!handler) {\n var allowedMethods = [\n \"GET\",\n \"HEAD\",\n \"POST\",\n \"PUT\",\n \"DELETE\",\n \"CONNECT\",\n \"OPTIONS\",\n \"TRACE\",\n \"PATCH\"\n ].filter(function(method) {\n return typeof imported[method] === \"function\";\n }).join(\", \");\n return new Response(null, {\n status: 405,\n headers: {\n Allow: allowedMethods\n }\n });\n }\n var worker = env !== void 0 || executionCtx !== void 0 ? {\n env,\n executionCtx\n } : void 0;\n return await handler(request, {\n params,\n worker\n });\n });\n}\nasync function getResponseWithAddedHeaders(response, id) {\n var _globalThis___vxrnasyncHeadersCache;\n var cache = (_globalThis___vxrnasyncHeadersCache = globalThis[\"__vxrnasyncHeadersCache\"]) !== null && _globalThis___vxrnasyncHeadersCache !== void 0 ? _globalThis___vxrnasyncHeadersCache : asyncHeadersCache;\n var asyncHeaders = cache.get(id);\n if (asyncHeaders) {\n try {\n if (response instanceof Response) {\n var cloned = response.clone();\n var headers = new Headers();\n mergeHeaders(headers, cloned.headers);\n mergeHeaders(headers, asyncHeaders);\n response = new Response(cloned.body, {\n status: cloned.status,\n statusText: cloned.statusText,\n headers\n });\n } else {\n if (response && typeof response === \"object\") {\n response = Response.json(response, {\n headers: asyncHeaders\n });\n } else {\n var headers1 = new Headers(asyncHeaders);\n if (!headers1.has(\"content-type\")) {\n headers1.set(\"content-type\", \"text/html\");\n }\n response = new Response(response, {\n headers: headers1\n });\n }\n }\n } catch (err) {\n console.error(` [one] error adding headers: ${err}`);\n }\n }\n return response;\n}\nexport {\n resolveAPIEndpoint,\n resolveResponse,\n withRequestContext\n};\n//# sourceMappingURL=resolveResponse.js.map\n"],"mappings":";;;;AAEA,IAAI,UAAU;AACd,SAAS,WAAW;CAClB,OAAO,EACL,KAAK,UACP;AACF;AACA,eAAe,gBAAgB,aAAa;CAC1C,IAAI,QAAQ,2BAA2B,QAAQ,2BAA2B,KAAK,IAAI,yBAAyB,WAAW;CACvH,IAAI,OAAO;EACT,IAAI,KAAK,SAAS;EAClB,IAAI;EACJ,MAAM,MAAM,IAAI,IAAI,iBAAiB;GACnC,IAAI;IACF,WAAW,MAAM,YAAY;IAC7B,WAAW,MAAM,4BAA4B,UAAU,EAAE;GAC3D,SAAS,KAAK;IACZ,IAAI,WAAW,GAAG,GAAG;KACnB,WAAW;IACb,OAAO;KACL,MAAM;IACR;GACF;EACF,CAAC;EACD,OAAO;CACT;CACA,OAAO,yBAAyB,eAAe,KAAK;EAClD,IAAI;GACF,IAAI,YAAY,MAAM,YAAY;GAClC,OAAO,MAAM,4BAA4B,WAAW,GAAG;EACzD,SAAS,KAAK;GACZ,IAAI,WAAW,GAAG,GAAG;IACnB,OAAO;GACT;GACA,MAAM;EACR;CACF,CAAC;AACH;AACA,SAAS,mBAAmB,IAAI;CAC9B,IAAI,QAAQ;CACZ,IAAI,OAAO;EACT,IAAI,KAAK,SAAS;EAClB,OAAO,MAAM,IAAI,IAAI,EAAE;CACzB;CACA,OAAO,GAAG;AACZ;AACA,SAAS,mBAAmB,aAAa,SAAS,QAAQ,KAAK,cAAc;CAC3E,OAAO,gBAAgB,iBAAiB;EACtC,IAAI,WAAW,MAAM,YAAY;EACjC,IAAI,cAAc,QAAQ,UAAU;EACpC,IAAI,UAAU,SAAS,gBAAgB,SAAS;EAChD,IAAI,CAAC,SAAS;GACZ,IAAI,iBAAiB;IACnB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF,CAAC,CAAC,OAAO,SAAS,QAAQ;IACxB,OAAO,OAAO,SAAS,YAAY;GACrC,CAAC,CAAC,CAAC,KAAK,IAAI;GACZ,OAAO,IAAI,SAAS,MAAM;IACxB,QAAQ;IACR,SAAS,EACP,OAAO,eACT;GACF,CAAC;EACH;EACA,IAAI,SAAS,QAAQ,KAAK,KAAK,iBAAiB,KAAK,IAAI;GACvD;GACA;EACF,IAAI,KAAK;EACT,OAAO,MAAM,QAAQ,SAAS;GAC5B;GACA;EACF,CAAC;CACH,CAAC;AACH;AACA,eAAe,4BAA4B,UAAU,IAAI;CACvD,IAAI;CACJ,IAAI,SAAS,sCAAsC,WAAW,gCAAgC,QAAQ,wCAAwC,KAAK,IAAI,sCAAsC;CAC7L,IAAI,eAAe,MAAM,IAAI,EAAE;CAC/B,IAAI,cAAc;EAChB,IAAI;GACF,IAAI,oBAAoB,UAAU;IAChC,IAAI,SAAS,SAAS,MAAM;IAC5B,IAAI,UAAU,IAAI,QAAQ;IAC1B,aAAa,SAAS,OAAO,OAAO;IACpC,aAAa,SAAS,YAAY;IAClC,WAAW,IAAI,SAAS,OAAO,MAAM;KACnC,QAAQ,OAAO;KACf,YAAY,OAAO;KACnB;IACF,CAAC;GACH,OAAO;IACL,IAAI,YAAY,OAAO,aAAa,UAAU;KAC5C,WAAW,SAAS,KAAK,UAAU,EACjC,SAAS,aACX,CAAC;IACH,OAAO;KACL,IAAI,WAAW,IAAI,QAAQ,YAAY;KACvC,IAAI,CAAC,SAAS,IAAI,cAAc,GAAG;MACjC,SAAS,IAAI,gBAAgB,WAAW;KAC1C;KACA,WAAW,IAAI,SAAS,UAAU,EAChC,SAAS,SACX,CAAC;IACH;GACF;EACF,SAAS,KAAK;GACZ,QAAQ,MAAM,gCAAgC,KAAK;EACrD;CACF;CACA,OAAO;AACT"}
@@ -12,9 +12,10 @@ swift build --triple arm64-apple-ios17.0-simulator \
12
12
  --package-path packages/one/ios/Tests/ImageManipulator
13
13
  ```
14
14
 
15
- The real `SDWebImageWebPCoder` call shape (`sharedCoder`, `.webP`,
15
+ The real `SDWebImageWebPCoder` call shape (`shared`, `.webP`,
16
16
  `.encodeCompressionQuality`) was read off the vendored 0.15.0 pod headers, not
17
- the stub. The stub only proves the production file is internally consistent.
17
+ the stub; Xcode 27 imports the header's `sharedCoder` class property as
18
+ `shared`. The stub only proves the production file is internally consistent.
18
19
  Real WebP bytes, flip pixels, and validation codes are proven by the
19
20
  native-features `image-manipulator` fixture on the iOS 27 simulator and
20
21
  Android 37 emulator; this harness does not prove transport, sandbox behavior,
@@ -12,7 +12,7 @@ public struct SDImageCoderOption: Hashable {
12
12
  }
13
13
 
14
14
  public final class SDImageWebPCoder {
15
- public static let sharedCoder = SDImageWebPCoder()
15
+ public static let shared = SDImageWebPCoder()
16
16
  public func encodedData(
17
17
  with image: UIImage?,
18
18
  format: SDImageFormat,
@@ -3,6 +3,21 @@ import React
3
3
 
4
4
  // RNSScreen accessed via NSClassFromString without direct import
5
5
  import UIKit
6
+ import os
7
+
8
+ // one json line per UIKit call into the zoom providers, at debug level, which
9
+ // costs nothing until a log stream asks for it. tests/native-features reads
10
+ // these to prove UIKit invoked the real providers.
11
+ private let zoomCallbackLog = Logger(subsystem: "dev.onestack.one", category: "zoom")
12
+
13
+ private func logZoomCallback(_ event: @escaping @autoclosure () -> [String: Any]) {
14
+ zoomCallbackLog.debug("\(zoomCallbackJSON(event()), privacy: .public)")
15
+ }
16
+
17
+ private func zoomCallbackJSON(_ event: [String: Any]) -> String {
18
+ guard let data = try? JSONSerialization.data(withJSONObject: event) else { return "{}" }
19
+ return String(decoding: data, as: UTF8.self)
20
+ }
6
21
 
7
22
  // MARK: - singleton manager for zoom transition repositories
8
23
 
@@ -303,21 +318,29 @@ class ZoomTransitionEnablerView: RCTView {
303
318
  // keep destination geometry through dismissal after React removes its detector.
304
319
  var destinationAlignmentRect: CGRect?
305
320
  options.alignmentRectProvider = { context in
306
- guard let sourceInfo = self.sourceRepository.getSource(
307
- identifier: self._zoomTransitionSourceIdentifier)
308
- else { return nil }
309
- guard let alignmentView = self.alignmentViewRepository.get(
310
- identifier: self._zoomTransitionSourceIdentifier)
311
- else { return destinationAlignmentRect ?? sourceInfo.alignment }
312
-
313
- let rect = alignmentView.convert(
314
- alignmentView.bounds, to: context.zoomedViewController.view)
315
- if sourceInfo.animateAspectRatioChange, let sourceView = sourceInfo.view {
316
- destinationAlignmentRect = self.calculateAdjustedRect(rect, toMatch: sourceView.bounds.size)
317
- } else {
318
- destinationAlignmentRect = rect
319
- }
320
- return destinationAlignmentRect
321
+ let alignment: CGRect? = {
322
+ guard let sourceInfo = self.sourceRepository.getSource(
323
+ identifier: self._zoomTransitionSourceIdentifier)
324
+ else { return nil }
325
+ guard let alignmentView = self.alignmentViewRepository.get(
326
+ identifier: self._zoomTransitionSourceIdentifier)
327
+ else { return destinationAlignmentRect ?? sourceInfo.alignment }
328
+
329
+ let rect = alignmentView.convert(
330
+ alignmentView.bounds, to: context.zoomedViewController.view)
331
+ if sourceInfo.animateAspectRatioChange, let sourceView = sourceInfo.view {
332
+ destinationAlignmentRect = self.calculateAdjustedRect(rect, toMatch: sourceView.bounds.size)
333
+ } else {
334
+ destinationAlignmentRect = rect
335
+ }
336
+ return destinationAlignmentRect
337
+ }()
338
+ logZoomCallback([
339
+ "kind": "alignment",
340
+ "identifier": self._zoomTransitionSourceIdentifier,
341
+ "rect": alignment.map { [$0.origin.x, $0.origin.y, $0.width, $0.height] as Any } ?? NSNull(),
342
+ ])
343
+ return alignment
321
344
  }
322
345
 
323
346
  if let rect = _dismissalBoundsRect {
@@ -334,6 +357,7 @@ class ZoomTransitionEnablerView: RCTView {
334
357
  controller.preferredTransition = .zoom(options: options) { _ in
335
358
  let sourceInfo = self.sourceRepository.getSource(
336
359
  identifier: self._zoomTransitionSourceIdentifier)
360
+ logZoomCallback(self.sourceCallbackEvent(sourceInfo?.view))
337
361
  guard let view = sourceInfo?.view else {
338
362
  NSLog("[one] No source view found for identifier %@.", self._zoomTransitionSourceIdentifier)
339
363
  return nil
@@ -349,6 +373,19 @@ class ZoomTransitionEnablerView: RCTView {
349
373
  }
350
374
  }
351
375
 
376
+ private func sourceCallbackEvent(_ view: UIView?) -> [String: Any] {
377
+ var event: [String: Any] = ["kind": "source", "identifier": _zoomTransitionSourceIdentifier]
378
+ guard let view else {
379
+ event["view"] = "0x0"
380
+ return event
381
+ }
382
+ event["view"] = String(format: "0x%lx", Int(bitPattern: Unmanaged.passUnretained(view).toOpaque()))
383
+ event["testID"] = view.accessibilityIdentifier ?? NSNull()
384
+ event["mounted"] = view.window != nil
385
+ event["bounds"] = NSCoder.string(for: view.bounds)
386
+ return event
387
+ }
388
+
352
389
  private func calculateAdjustedRect(_ rect: CGRect, toMatch sourceSize: CGSize) -> CGRect {
353
390
  guard sourceSize.width > 0, sourceSize.height > 0, rect.width > 0, rect.height > 0 else {
354
391
  return rect
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "description": "One is a React framework for web, iOS, and Android apps.",
5
5
  "license": "BSD-3-Clause",
6
6
  "sideEffects": [
@@ -236,18 +236,18 @@
236
236
  "@react-navigation/native-stack": "8.0.0-alpha.59",
237
237
  "@react-navigation/routers": "8.0.0-alpha.21",
238
238
  "@ungap/structured-clone": "^1.2.0",
239
- "@vxrn/color-scheme": "2.7.2",
240
- "@vxrn/compiler": "2.7.2",
241
- "@vxrn/resolve": "2.7.2",
242
- "@vxrn/tslib-lite": "2.7.2",
243
- "@vxrn/use-isomorphic-layout-effect": "2.7.2",
244
- "@vxrn/utils": "2.7.2",
245
- "@vxrn/vite-plugin-metro": "2.7.2",
239
+ "@vxrn/color-scheme": "2.7.4",
240
+ "@vxrn/compiler": "2.7.4",
241
+ "@vxrn/resolve": "2.7.4",
242
+ "@vxrn/tslib-lite": "2.7.4",
243
+ "@vxrn/use-isomorphic-layout-effect": "2.7.4",
244
+ "@vxrn/utils": "2.7.4",
245
+ "@vxrn/vite-plugin-metro": "2.7.4",
246
246
  "babel-dead-code-elimination": "1.0.10",
247
247
  "babel-plugin-module-resolver": "^5.0.2",
248
248
  "citty": "^0.1.6",
249
249
  "core-js": "^3.38.1",
250
- "create-vxrn": "2.7.2",
250
+ "create-vxrn": "2.7.4",
251
251
  "escape-string-regexp": "^5.0.0",
252
252
  "fast-deep-equal": "^3.1.3",
253
253
  "fast-glob": "^3.3.3",
@@ -269,7 +269,7 @@
269
269
  "tsconfig-paths": "^4",
270
270
  "use-latest-callback": "^0.2.3",
271
271
  "vite": "^8.2.2",
272
- "vxrn": "2.7.2",
272
+ "vxrn": "2.7.4",
273
273
  "web-streams-polyfill": "^4.3.0",
274
274
  "ws": "^8.21.0",
275
275
  "xxhashjs": "^0.2.2"
@@ -325,19 +325,19 @@
325
325
  }
326
326
  },
327
327
  "devDependencies": {
328
- "@tamagui/sheet": "3.0.10",
328
+ "@tamagui/sheet": "3.0.13",
329
329
  "@callstack/liquid-glass": "^0.8.1",
330
330
  "@react-native/babel-plugin-codegen": "0.87.1",
331
331
  "@react-native/codegen": "^0.87.1",
332
332
  "@react-navigation/core": "8.0.0-alpha.41",
333
333
  "@react-navigation/drawer": "8.0.0-alpha.58",
334
334
  "@react-navigation/native": "8.0.0-alpha.51",
335
- "@tamagui/build": "3.0.10",
335
+ "@tamagui/build": "3.0.13",
336
336
  "@types/node": "^24.10.0",
337
337
  "@types/react-dom": "^19.2.2",
338
338
  "@types/react-test-renderer": "^19.1.0",
339
339
  "@types/xxhashjs": "^0.2.4",
340
- "@vxrn/emitter": "2.7.2",
340
+ "@vxrn/emitter": "2.7.4",
341
341
  "depcheck": "^1.4.7",
342
342
  "esbuild": "^0.25.12",
343
343
  "immer": "^10.1.1",
@@ -356,7 +356,7 @@
356
356
  "typescript": "7.0.2",
357
357
  "vitest": "^4.1.0",
358
358
  "yoga-layout": "^3.2.1",
359
- "@tamagui/web": "3.0.10"
359
+ "@tamagui/web": "3.0.13"
360
360
  },
361
361
  "publishConfig": {
362
362
  "access": "public"
@@ -513,7 +513,7 @@
513
513
  }
514
514
  }
515
515
  },
516
- "releaseSourceCommit": "660240b2552fe6d8d3903e927907c43ec5e3ba1e",
516
+ "releaseSourceCommit": "f60870e3a32efb3f3577234b92e5b7de663b12b7",
517
517
  "repository": {
518
518
  "type": "git",
519
519
  "url": "git+https://github.com/onejs/one.git",
@@ -1,5 +1,8 @@
1
1
  import { describe, expect, it, vi, beforeEach } from 'vitest'
2
2
  import { createHandleRequest } from './createDevHandleRequest'
3
+ import { resolveAPIRoute } from './createHandleRequest'
4
+ import type { Middleware } from './createMiddleware'
5
+ import type { RouteInfoCompiled } from './server/createRoutesManifest'
3
6
 
4
7
  // Mock the manifest. Specific routes come before dynamic ones, matching how
5
8
  // the real manifest is ordered after matchers.sortRoutes().
@@ -355,3 +358,98 @@ describe('createHandleRequest', () => {
355
358
  })
356
359
  })
357
360
  })
361
+
362
+ describe('API method contract', () => {
363
+ const route = {
364
+ file: 'app/api/link+api.ts',
365
+ page: '/api/link',
366
+ namedRegex: '^/api/link$',
367
+ routeKeys: {},
368
+ type: 'api',
369
+ middlewares: [{ contextKey: 'app/_middleware.ts' }],
370
+ } as RouteInfoCompiled
371
+
372
+ function dispatch(exports: Record<string, unknown>, method: string, middleware = true) {
373
+ const request = createRequest('/api/link', method)
374
+ return resolveAPIRoute(
375
+ {
376
+ handleAPI: async () => exports,
377
+ loadMiddleware: async () => ({
378
+ default: (async ({ request, next }) => {
379
+ if (request.method === 'OPTIONS') {
380
+ return new Response(null, { status: 204 })
381
+ }
382
+ const response = await next()
383
+ if (!response) throw new Error('expected endpoint response')
384
+ response.headers.set('x-middleware', 'ran')
385
+ return response
386
+ }) satisfies Middleware,
387
+ }),
388
+ },
389
+ request,
390
+ new URL(request.url),
391
+ middleware ? route : { ...route, middlewares: [] }
392
+ )
393
+ }
394
+
395
+ it.each([true, false])(
396
+ 'rejects missing methods with middleware=%s',
397
+ async (middleware) => {
398
+ const POST = vi.fn(() => new Response('authentication required', { status: 401 }))
399
+ const exports = { POST, helper: () => {}, GET: undefined }
400
+ const response = await dispatch(exports, 'GET', middleware)
401
+ expect(response.status).toBe(405)
402
+ expect(response.headers.get('allow')).toBe('POST')
403
+ expect(POST).not.toHaveBeenCalled()
404
+ if (middleware) expect(response.headers.get('x-middleware')).toBe('ran')
405
+ const supported = await dispatch(exports, 'POST', middleware)
406
+ expect(supported.status).toBe(401)
407
+ expect(await supported.text()).toBe('authentication required')
408
+ expect(POST).toHaveBeenCalledOnce()
409
+ }
410
+ )
411
+
412
+ it('preserves middleware preflight short circuit', async () => {
413
+ const OPTIONS = vi.fn(() => new Response(null, { status: 202 }))
414
+ expect((await dispatch({ OPTIONS }, 'OPTIONS')).status).toBe(204)
415
+ expect(OPTIONS).not.toHaveBeenCalled()
416
+ })
417
+
418
+ it('preserves named methods ahead of default and default catch-all', async () => {
419
+ const fallback = vi.fn(
420
+ (request: Request) => new Response(request.method, { status: 202 })
421
+ )
422
+ const GET = vi.fn(() => new Response('named'))
423
+ expect(await (await dispatch({ GET, default: fallback }, 'GET')).text()).toBe('named')
424
+ for (const method of ['POST', 'HEAD', 'OPTIONS']) {
425
+ expect((await dispatch({ GET, default: fallback }, method, false)).status).toBe(202)
426
+ }
427
+ expect(GET).toHaveBeenCalledOnce()
428
+ expect(fallback).toHaveBeenCalledTimes(3)
429
+ })
430
+
431
+ it('requires explicit HEAD and OPTIONS exports and preserves their responses', async () => {
432
+ const GET = vi.fn(() => new Response('get'))
433
+ for (const method of ['HEAD', 'OPTIONS']) {
434
+ const missing = await dispatch({ GET }, method, false)
435
+ expect(missing.status).toBe(405)
436
+ expect(missing.headers.get('allow')).toBe('GET')
437
+ const explicit = await dispatch(
438
+ {
439
+ GET,
440
+ [method]: () =>
441
+ new Response(null, {
442
+ status: 204,
443
+ headers: { 'x-method': method },
444
+ }),
445
+ },
446
+ method,
447
+ false
448
+ )
449
+ expect(explicit.status).toBe(204)
450
+ expect(explicit.headers.get('x-method')).toBe(method)
451
+ expect(await explicit.text()).toBe('')
452
+ }
453
+ expect(GET).not.toHaveBeenCalled()
454
+ })
455
+ })
@@ -74,8 +74,23 @@ export function resolveAPIEndpoint(
74
74
  const requestType = request.method || 'GET'
75
75
  const handler = imported[requestType] || imported.default
76
76
  if (!handler) {
77
- console.warn(`No handler found for request ${requestType}`)
78
- return
77
+ const allowedMethods = [
78
+ 'GET',
79
+ 'HEAD',
80
+ 'POST',
81
+ 'PUT',
82
+ 'DELETE',
83
+ 'CONNECT',
84
+ 'OPTIONS',
85
+ 'TRACE',
86
+ 'PATCH',
87
+ ]
88
+ .filter((method) => typeof imported[method] === 'function')
89
+ .join(', ')
90
+ return new Response(null, {
91
+ status: 405,
92
+ headers: { Allow: allowedMethods },
93
+ })
79
94
  }
80
95
  const worker =
81
96
  env !== undefined || executionCtx !== undefined ? { env, executionCtx } : undefined
@@ -1 +1 @@
1
- {"version":3,"file":"resolveResponse.d.ts","sourceRoot":"","sources":["../../src/vite/resolveResponse.ts"],"names":[],"mappings":"AAeA,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,gBAkCzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOtE;AAED,wBAAgB,kBAAkB,CAEhC,WAAW,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,GAAG,CAAC,EAAE,OAAO,EACb,YAAY,CAAC,EAAE,OAAO,gBAcvB"}
1
+ {"version":3,"file":"resolveResponse.d.ts","sourceRoot":"","sources":["../../src/vite/resolveResponse.ts"],"names":[],"mappings":"AAeA,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,gBAkCzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOtE;AAED,wBAAgB,kBAAkB,CAEhC,WAAW,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,GAAG,CAAC,EAAE,OAAO,EACb,YAAY,CAAC,EAAE,OAAO,gBA6BvB"}