@expo/server
Advanced tools
Comparing version 0.0.1-canary-20240228-7cee619 to 0.0.1-canary-20240305-e60019e
@@ -1,19 +0,28 @@ | ||
/// <reference types="node" /> | ||
import { Request, RequestInfo, RequestInit, Response, ResponseInit } from '@remix-run/node'; | ||
import { URL } from 'node:url'; | ||
import { ExpoRouterServerManifestV1FunctionRoute } from './types'; | ||
declare const Response: { | ||
prototype: Response; | ||
new (body?: BodyInit | null, init?: ResponseInit): Response; | ||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/error_static) */ | ||
error(): Response; | ||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/json_static) */ | ||
json(data: any, init?: ResponseInit): Response; | ||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/redirect_static) */ | ||
redirect(url: string | URL, status?: number): Response; | ||
}; | ||
declare global { | ||
/** @deprecated */ | ||
var ExpoRequest: typeof Request; | ||
/** @deprecated */ | ||
var ExpoResponse: typeof Response; | ||
} | ||
/** @deprecated */ | ||
export declare const ExpoRequest: { | ||
new (input: URL | RequestInfo, init?: RequestInit | undefined): Request; | ||
prototype: Request; | ||
}; | ||
/** @deprecated */ | ||
export declare const ExpoResponse: { | ||
new (input: URL | RequestInfo, init?: RequestInit | undefined): Request; | ||
prototype: Request; | ||
}; | ||
export declare function installGlobals(): void; | ||
export declare class ExpoResponse extends Response { | ||
static json(data?: any, init?: ResponseInit): ExpoResponse; | ||
} | ||
export declare const NON_STANDARD_SYMBOL: unique symbol; | ||
export declare class ExpoURL extends URL { | ||
static from(url: string, config: ExpoRouterServerManifestV1FunctionRoute): ExpoURL; | ||
} | ||
export declare class ExpoRequest extends Request { | ||
[NON_STANDARD_SYMBOL]: { | ||
url: ExpoURL; | ||
}; | ||
constructor(info: RequestInfo, init?: RequestInit); | ||
get expoUrl(): ExpoURL; | ||
} | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ExpoRequest = exports.ExpoURL = exports.NON_STANDARD_SYMBOL = exports.ExpoResponse = exports.installGlobals = void 0; | ||
exports.installGlobals = exports.ExpoResponse = exports.ExpoRequest = void 0; | ||
/* eslint-disable no-var */ | ||
const node_1 = require("@remix-run/node"); | ||
const node_url_1 = require("node:url"); | ||
// Ensure these are available for the API Routes. | ||
/** @deprecated */ | ||
exports.ExpoRequest = Request; | ||
/** @deprecated */ | ||
exports.ExpoResponse = Request; | ||
function installGlobals() { | ||
(0, node_1.installGlobals)(); | ||
// @ts-expect-error | ||
global.Request = ExpoRequest; | ||
// @ts-expect-error | ||
global.Response = ExpoResponse; | ||
// @ts-expect-error | ||
global.ExpoResponse = ExpoResponse; | ||
// @ts-expect-error | ||
global.ExpoRequest = ExpoRequest; | ||
} | ||
exports.installGlobals = installGlobals; | ||
class ExpoResponse extends node_1.Response { | ||
// TODO: Drop when we upgrade to node-fetch v3 | ||
static json(data = undefined, init = {}) { | ||
const body = JSON.stringify(data); | ||
if (body === undefined) { | ||
throw new TypeError('data is not JSON serializable'); | ||
} | ||
const headers = new node_1.Headers(init?.headers); | ||
if (!headers.has('content-type')) { | ||
headers.set('content-type', 'application/json'); | ||
} | ||
return new ExpoResponse(body, { | ||
...init, | ||
headers, | ||
}); | ||
global.ExpoRequest = Request; | ||
global.ExpoResponse = Response; | ||
if (typeof Response.error !== 'function') { | ||
Response.error = function error() { | ||
return new Response(null, { status: 500 }); | ||
}; | ||
} | ||
} | ||
exports.ExpoResponse = ExpoResponse; | ||
exports.NON_STANDARD_SYMBOL = Symbol('non-standard'); | ||
class ExpoURL extends node_url_1.URL { | ||
static from(url, config) { | ||
const expoUrl = new ExpoURL(url); | ||
const match = config.namedRegex.exec(expoUrl.pathname); | ||
if (match?.groups) { | ||
for (const [key, value] of Object.entries(match.groups)) { | ||
const namedKey = config.routeKeys[key]; | ||
expoUrl.searchParams.set(namedKey, value); | ||
if (typeof Response.json !== 'function') { | ||
Response.json = function json(data, init) { | ||
return new Response(JSON.stringify(data), init); | ||
}; | ||
} | ||
if (typeof Response.redirect !== 'function') { | ||
Response.redirect = function redirect(url, status) { | ||
if (!status) | ||
status = 302; | ||
switch (status) { | ||
case 301: | ||
case 302: | ||
case 303: | ||
case 307: | ||
case 308: | ||
return new Response(null, { | ||
headers: { Location: new URL(url).toString() }, | ||
status, | ||
}); | ||
default: | ||
throw new RangeError(`Invalid status code ${status}`); | ||
} | ||
} | ||
return expoUrl; | ||
} | ||
} | ||
exports.ExpoURL = ExpoURL; | ||
class ExpoRequest extends node_1.Request { | ||
[exports.NON_STANDARD_SYMBOL]; | ||
constructor(info, init) { | ||
super(info, init); | ||
this[exports.NON_STANDARD_SYMBOL] = { | ||
url: new ExpoURL(typeof info !== 'string' && 'url' in info ? info.url : String(info)), | ||
}; | ||
} | ||
get expoUrl() { | ||
return this[exports.NON_STANDARD_SYMBOL].url; | ||
} | ||
} | ||
exports.ExpoRequest = ExpoRequest; | ||
exports.installGlobals = installGlobals; | ||
//# sourceMappingURL=environment.js.map |
import '@expo/server/install'; | ||
import { Response } from '@remix-run/node'; | ||
import type { ExpoRoutesManifestV1, RouteInfo } from 'expo-router/build/routes-manifest'; | ||
import { ExpoRequest, ExpoResponse } from './environment'; | ||
export declare function getRoutesManifest(distFolder: string): ExpoRoutesManifestV1<RegExp>; | ||
export declare function createRequestHandler(distFolder: string, { getRoutesManifest: getInternalRoutesManifest, getHtml, getApiRoute, logApiRouteExecutionError, }?: { | ||
getHtml?: (request: ExpoRequest, route: RouteInfo<RegExp>) => Promise<string | ExpoResponse | null>; | ||
getHtml?: (request: Request, route: RouteInfo<RegExp>) => Promise<string | Response | null>; | ||
getRoutesManifest?: (distFolder: string) => Promise<ExpoRoutesManifestV1<RegExp> | null>; | ||
getApiRoute?: (route: RouteInfo<RegExp>) => Promise<any>; | ||
logApiRouteExecutionError?: (error: Error) => void; | ||
}): (request: ExpoRequest) => Promise<Response>; | ||
export { ExpoResponse, ExpoRequest }; | ||
}): (request: Request) => Promise<Response>; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ExpoRequest = exports.ExpoResponse = exports.createRequestHandler = exports.getRoutesManifest = void 0; | ||
exports.createRequestHandler = exports.getRoutesManifest = void 0; | ||
require("@expo/server/install"); | ||
@@ -12,5 +12,2 @@ const fs_1 = __importDefault(require("fs")); | ||
const url_1 = require("url"); | ||
const environment_1 = require("./environment"); | ||
Object.defineProperty(exports, "ExpoRequest", { enumerable: true, get: function () { return environment_1.ExpoRequest; } }); | ||
Object.defineProperty(exports, "ExpoResponse", { enumerable: true, get: function () { return environment_1.ExpoResponse; } }); | ||
const debug = require('debug')('expo:server'); | ||
@@ -48,3 +45,3 @@ function getProcessedManifest(path) { | ||
// TODO: Reuse this for dev as well | ||
function createRequestHandler(distFolder, { getRoutesManifest: getInternalRoutesManifest, getHtml = async (request, route) => { | ||
function createRequestHandler(distFolder, { getRoutesManifest: getInternalRoutesManifest, getHtml = async (_request, route) => { | ||
// serve a static file | ||
@@ -73,15 +70,10 @@ const filePath = path_1.default.join(distFolder, route.page + '.html'); | ||
const params = {}; | ||
const url = request.url; | ||
const expoUrl = new environment_1.ExpoURL(url); | ||
const match = config.namedRegex.exec(expoUrl.pathname); | ||
const url = new url_1.URL(request.url); | ||
const match = config.namedRegex.exec(url.pathname); | ||
if (match?.groups) { | ||
for (const [key, value] of Object.entries(match.groups)) { | ||
const namedKey = config.routeKeys[key]; | ||
expoUrl.searchParams.set(namedKey, value); | ||
params[namedKey] = value; | ||
} | ||
} | ||
request[environment_1.NON_STANDARD_SYMBOL] = { | ||
url: expoUrl, | ||
}; | ||
return params; | ||
@@ -97,3 +89,3 @@ } | ||
// Development error when Expo Router is not setup. | ||
return new environment_1.ExpoResponse('No routes manifest found', { | ||
return new Response('No routes manifest found', { | ||
status: 404, | ||
@@ -124,3 +116,3 @@ headers: { | ||
if (!contents) { | ||
return new environment_1.ExpoResponse('Not found', { | ||
return new Response('Not found', { | ||
status: 404, | ||
@@ -132,6 +124,6 @@ headers: { | ||
} | ||
else if (contents instanceof environment_1.ExpoResponse) { | ||
else if (contents instanceof Response) { | ||
return contents; | ||
} | ||
return new environment_1.ExpoResponse(contents, { | ||
return new Response(contents, { | ||
status: 200, | ||
@@ -150,3 +142,3 @@ headers: { | ||
const func = await getApiRoute(route); | ||
if (func instanceof environment_1.ExpoResponse) { | ||
if (func instanceof Response) { | ||
return func; | ||
@@ -156,3 +148,3 @@ } | ||
if (!routeHandler) { | ||
return new environment_1.ExpoResponse('Method not allowed', { | ||
return new Response('Method not allowed', { | ||
status: 405, | ||
@@ -174,3 +166,3 @@ headers: { | ||
} | ||
return new environment_1.ExpoResponse('Internal server error', { | ||
return new Response('Internal server error', { | ||
status: 500, | ||
@@ -194,3 +186,3 @@ headers: { | ||
if (!contents) { | ||
return new environment_1.ExpoResponse('Not found', { | ||
return new Response('Not found', { | ||
status: 404, | ||
@@ -202,6 +194,6 @@ headers: { | ||
} | ||
else if (contents instanceof environment_1.ExpoResponse) { | ||
else if (contents instanceof Response) { | ||
return contents; | ||
} | ||
return new environment_1.ExpoResponse(contents, { | ||
return new Response(contents, { | ||
status: 404, | ||
@@ -214,3 +206,3 @@ headers: { | ||
// 404 | ||
const response = new environment_1.ExpoResponse('Not found', { | ||
const response = new Response('Not found', { | ||
status: 404, | ||
@@ -217,0 +209,0 @@ headers: { |
@@ -1,5 +0,3 @@ | ||
import { Headers, Response } from '@remix-run/node'; | ||
import type * as express from 'express'; | ||
import { createRequestHandler as createExpoHandler } from '..'; | ||
import { ExpoRequest } from '../environment'; | ||
export type RequestHandler = (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void>; | ||
@@ -13,3 +11,3 @@ /** | ||
export declare function convertHeaders(requestHeaders: express.Request['headers']): Headers; | ||
export declare function convertRequest(req: express.Request, res: express.Response): ExpoRequest; | ||
export declare function convertRequest(req: express.Request, res: express.Response): Request; | ||
export declare function respond(res: express.Response, expoRes: Response): Promise<void>; |
@@ -6,3 +6,2 @@ "use strict"; | ||
const __1 = require(".."); | ||
const environment_1 = require("../environment"); | ||
/** | ||
@@ -31,3 +30,3 @@ * Returns a request handler for Express that serves the response using Remix. | ||
function convertHeaders(requestHeaders) { | ||
const headers = new node_1.Headers(); | ||
const headers = new Headers(); | ||
for (const [key, values] of Object.entries(requestHeaders)) { | ||
@@ -51,3 +50,3 @@ if (values) { | ||
// Abort action/loaders once we can no longer write a response | ||
const controller = new node_1.AbortController(); | ||
const controller = new AbortController(); | ||
res.on('close', () => controller.abort()); | ||
@@ -62,5 +61,7 @@ const init = { | ||
if (req.method !== 'GET' && req.method !== 'HEAD') { | ||
init.body = req; | ||
init.body = (0, node_1.createReadableStreamFromReadable)(req); | ||
// @ts-expect-error | ||
init.duplex = 'half'; | ||
} | ||
return new environment_1.ExpoRequest(url.href, init); | ||
return new Request(url.href, init); | ||
} | ||
@@ -71,6 +72,4 @@ exports.convertRequest = convertRequest; | ||
res.status(expoRes.status); | ||
for (const [key, values] of Object.entries(expoRes.headers.raw())) { | ||
for (const value of values) { | ||
res.append(key, value); | ||
} | ||
for (const [key, value] of expoRes.headers.entries()) { | ||
res.append(key, value); | ||
} | ||
@@ -77,0 +76,0 @@ if (expoRes.body) { |
/// <reference types="node" /> | ||
import { Headers } from '@remix-run/node'; | ||
import * as http from 'http'; | ||
import { createRequestHandler as createExpoHandler } from '..'; | ||
import { ExpoRequest, ExpoResponse } from '../environment'; | ||
type NextFunction = (err?: any) => void; | ||
@@ -14,5 +12,5 @@ export type RequestHandler = (req: http.IncomingMessage, res: http.ServerResponse, next: NextFunction) => Promise<void>; | ||
}, setup?: Parameters<typeof createExpoHandler>[1]): RequestHandler; | ||
export declare function convertRequest(req: http.IncomingMessage, res: http.ServerResponse): ExpoRequest; | ||
export declare function convertRequest(req: http.IncomingMessage, res: http.ServerResponse): Request; | ||
export declare function convertHeaders(requestHeaders: http.IncomingHttpHeaders): Headers; | ||
export declare function respond(res: http.ServerResponse, expoRes: ExpoResponse): Promise<void>; | ||
export declare function respond(res: http.ServerResponse, expoRes: Response): Promise<void>; | ||
export {}; |
@@ -6,3 +6,2 @@ "use strict"; | ||
const __1 = require(".."); | ||
const environment_1 = require("../environment"); | ||
/** | ||
@@ -34,3 +33,3 @@ * Returns a request handler for http that serves the response using Remix. | ||
// Abort action/loaders once we can no longer write a response | ||
const controller = new node_1.AbortController(); | ||
const controller = new AbortController(); | ||
res.on('close', () => controller.abort()); | ||
@@ -45,9 +44,11 @@ const init = { | ||
if (req.method !== 'GET' && req.method !== 'HEAD') { | ||
init.body = req; | ||
init.body = (0, node_1.createReadableStreamFromReadable)(req); | ||
// @ts-expect-error | ||
init.duplex = 'half'; | ||
} | ||
return new environment_1.ExpoRequest(url.href, init); | ||
return new Request(url.href, init); | ||
} | ||
exports.convertRequest = convertRequest; | ||
function convertHeaders(requestHeaders) { | ||
const headers = new node_1.Headers(); | ||
const headers = new Headers(); | ||
for (const [key, values] of Object.entries(requestHeaders)) { | ||
@@ -71,6 +72,4 @@ if (values) { | ||
res.statusCode = expoRes.status; | ||
for (const [key, values] of Object.entries(expoRes.headers.raw())) { | ||
for (const value of values) { | ||
res.appendHeader(key, value); | ||
} | ||
for (const [key, value] of expoRes.headers.entries()) { | ||
res.appendHeader(key, value); | ||
} | ||
@@ -77,0 +76,0 @@ if (expoRes.body) { |
import type { HandlerEvent, HandlerResponse } from '@netlify/functions'; | ||
import { Headers } from '@remix-run/node'; | ||
import { ExpoRequest, ExpoResponse } from '../environment'; | ||
export declare function createRequestHandler({ build }: { | ||
build: string; | ||
}): (event: HandlerEvent) => Promise<HandlerResponse>; | ||
export declare function respond(res: ExpoResponse): Promise<HandlerResponse>; | ||
export declare function respond(res: Response): Promise<HandlerResponse>; | ||
export declare function createHeaders(requestHeaders: HandlerEvent['multiValueHeaders']): Headers; | ||
export declare function convertRequest(event: HandlerEvent): ExpoRequest; | ||
export declare function convertRequest(event: HandlerEvent): Request; | ||
export declare function isBinaryType(contentType: string | null | undefined): boolean; |
@@ -7,3 +7,2 @@ "use strict"; | ||
const __1 = require(".."); | ||
const environment_1 = require("../environment"); | ||
function createRequestHandler({ build }) { | ||
@@ -29,6 +28,9 @@ const handleRequest = (0, __1.createRequestHandler)(build); | ||
} | ||
const multiValueHeaders = res.headers.raw(); | ||
const headers = {}; | ||
for (const [key, value] of res.headers.entries()) { | ||
headers[key] = value; | ||
} | ||
return { | ||
statusCode: res.status, | ||
multiValueHeaders, | ||
headers, | ||
body, | ||
@@ -40,3 +42,3 @@ isBase64Encoded, | ||
function createHeaders(requestHeaders) { | ||
const headers = new node_1.Headers(); | ||
const headers = new Headers(); | ||
for (const [key, values] of Object.entries(requestHeaders)) { | ||
@@ -100,4 +102,6 @@ if (values) { | ||
: event.body; | ||
// @ts-expect-error | ||
init.duplex = 'half'; | ||
} | ||
return new environment_1.ExpoRequest(url.href, init); | ||
return new Request(url.href, init); | ||
} | ||
@@ -104,0 +108,0 @@ exports.convertRequest = convertRequest; |
/// <reference types="node" /> | ||
import { Headers } from '@remix-run/node'; | ||
import * as http from 'http'; | ||
import { ExpoRequest, ExpoResponse } from '../environment'; | ||
export type RequestHandler = (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>; | ||
@@ -14,3 +12,3 @@ /** | ||
export declare function convertHeaders(requestHeaders: http.IncomingMessage['headers']): Headers; | ||
export declare function convertRequest(req: http.IncomingMessage, res: http.ServerResponse): ExpoRequest; | ||
export declare function respond(res: http.ServerResponse, expoRes: ExpoResponse): Promise<void>; | ||
export declare function convertRequest(req: http.IncomingMessage, res: http.ServerResponse): Request; | ||
export declare function respond(res: http.ServerResponse, expoRes: Response): Promise<void>; |
@@ -9,3 +9,2 @@ "use strict"; | ||
const __1 = require(".."); | ||
const environment_1 = require("../environment"); | ||
/** | ||
@@ -23,3 +22,3 @@ * Returns a request handler for Vercel's Node.js runtime that serves the | ||
function convertHeaders(requestHeaders) { | ||
const headers = new node_1.Headers(); | ||
const headers = new Headers(); | ||
for (const [key, values] of Object.entries(requestHeaders)) { | ||
@@ -46,3 +45,3 @@ if (values) { | ||
// Abort action/loaders once we can no longer write a response | ||
const controller = new node_1.AbortController(); | ||
const controller = new AbortController(); | ||
res.on('close', () => controller.abort()); | ||
@@ -57,5 +56,7 @@ const init = { | ||
if (req.method !== 'GET' && req.method !== 'HEAD') { | ||
init.body = req; | ||
init.body = (0, node_1.createReadableStreamFromReadable)(req); | ||
// @ts-expect-error | ||
init.duplex = 'half'; | ||
} | ||
return new environment_1.ExpoRequest(url.href, init); | ||
return new Request(url.href, init); | ||
} | ||
@@ -65,3 +66,3 @@ exports.convertRequest = convertRequest; | ||
res.statusMessage = expoRes.statusText; | ||
res.writeHead(expoRes.status, expoRes.statusText, expoRes.headers.raw()); | ||
res.writeHead(expoRes.status, expoRes.statusText, [...expoRes.headers.entries()]); | ||
if (expoRes.body) { | ||
@@ -68,0 +69,0 @@ await (0, node_1.writeReadableStreamToWritable)(expoRes.body, res); |
{ | ||
"name": "@expo/server", | ||
"version": "0.0.1-canary-20240228-7cee619", | ||
"version": "0.0.1-canary-20240305-e60019e", | ||
"description": "Server API for Expo Router projects", | ||
@@ -29,6 +29,7 @@ "main": "build/index.js", | ||
"adapter", | ||
"install.d.ts", | ||
"install.js" | ||
], | ||
"dependencies": { | ||
"@remix-run/node": "^1.19.3", | ||
"@remix-run/node": "^2.7.2", | ||
"abort-controller": "^3.0.0", | ||
@@ -45,3 +46,3 @@ "debug": "^4.3.4", | ||
}, | ||
"gitHead": "7cee6192338de34ad301922c0cd6f4a4645c0fa9" | ||
"gitHead": "e60019e11a6d46e330b57b18c64468a58d589875" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
31
47477
+ Added@remix-run/node@2.15.2(transitive)
+ Added@remix-run/router@1.21.0(transitive)
+ Added@remix-run/server-runtime@2.15.2(transitive)
+ Added@types/cookie@0.6.0(transitive)
+ Addedcookie@0.6.0(transitive)
+ Addedturbo-stream@2.4.0(transitive)
+ Addedundici@6.21.1(transitive)
- Removed@remix-run/node@1.19.3(transitive)
- Removed@remix-run/router@1.7.2(transitive)
- Removed@remix-run/server-runtime@1.19.3(transitive)
- Removed@types/cookie@0.4.1(transitive)
- Removedcookie@0.4.2(transitive)
Updated@remix-run/node@^2.7.2