@react-router/node
Advanced tools
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import cookieSignature from 'cookie-signature'; | ||
| const sign = async (value, secret) => { | ||
| return cookieSignature.sign(value, secret); | ||
| }; | ||
| const unsign = async (signed, secret) => { | ||
| return cookieSignature.unsign(signed, secret); | ||
| }; | ||
| export { sign, unsign }; |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import { File, Headers, Request, Response, fetch, FormData } from 'undici'; | ||
| function installGlobals() { | ||
| global.File = File; | ||
| // @ts-ignore - this shows as an error in VSCode but is not an error via TSC so we can't use `ts-expect-error` | ||
| global.Headers = Headers; | ||
| // @ts-expect-error - overriding globals | ||
| global.Request = Request; | ||
| // @ts-expect-error - overriding globals | ||
| global.Response = Response; | ||
| // @ts-expect-error - overriding globals | ||
| global.fetch = fetch; | ||
| // @ts-expect-error - overriding globals | ||
| global.FormData = FormData; | ||
| } | ||
| export { installGlobals }; |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import { createCookieFactory, createCookieSessionStorageFactory, createSessionStorageFactory, createMemorySessionStorageFactory } from 'react-router'; | ||
| import { sign, unsign } from './crypto.mjs'; | ||
| const createCookie = createCookieFactory({ | ||
| sign, | ||
| unsign | ||
| }); | ||
| const createCookieSessionStorage = createCookieSessionStorageFactory(createCookie); | ||
| const createSessionStorage = createSessionStorageFactory(createCookie); | ||
| const createMemorySessionStorage = createMemorySessionStorageFactory(createSessionStorage); | ||
| export { createCookie, createCookieSessionStorage, createMemorySessionStorage, createSessionStorage }; |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| export { installGlobals } from './globals.mjs'; | ||
| export { createFileSessionStorage } from './sessions/fileStorage.mjs'; | ||
| export { NodeOnDiskFile, createFileUploadHandler as unstable_createFileUploadHandler } from './upload/fileUploadHandler.mjs'; | ||
| export { createCookie, createCookieSessionStorage, createMemorySessionStorage, createSessionStorage } from './implementations.mjs'; | ||
| export { createReadableStreamFromReadable, readableStreamToString, writeAsyncIterableToWritable, writeReadableStreamToWritable } from './stream.mjs'; |
| export {}; |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| 'use strict'; | ||
| var globals = require('./globals.js'); | ||
| globals.installGlobals(); |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import { installGlobals } from './globals.mjs'; | ||
| installGlobals(); |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import * as crypto from 'node:crypto'; | ||
| import { promises } from 'node:fs'; | ||
| import * as path from 'node:path'; | ||
| import { createSessionStorage } from '../implementations.mjs'; | ||
| /** | ||
| * Creates a SessionStorage that stores session data on a filesystem. | ||
| * | ||
| * The advantage of using this instead of cookie session storage is that | ||
| * files may contain much more data than cookies. | ||
| * | ||
| * @see https://remix.run/utils/sessions#createfilesessionstorage-node | ||
| */ | ||
| function createFileSessionStorage({ | ||
| cookie, | ||
| dir | ||
| }) { | ||
| return createSessionStorage({ | ||
| cookie, | ||
| async createData(data, expires) { | ||
| let content = JSON.stringify({ | ||
| data, | ||
| expires | ||
| }); | ||
| while (true) { | ||
| // TODO: Once Node v19 is supported we should use the globally provided | ||
| // Web Crypto API's crypto.getRandomValues() function here instead. | ||
| let randomBytes = crypto.webcrypto.getRandomValues(new Uint8Array(8)); | ||
| // This storage manages an id space of 2^64 ids, which is far greater | ||
| // than the maximum number of files allowed on an NTFS or ext4 volume | ||
| // (2^32). However, the larger id space should help to avoid collisions | ||
| // with existing ids when creating new sessions, which speeds things up. | ||
| let id = Buffer.from(randomBytes).toString("hex"); | ||
| try { | ||
| let file = getFile(dir, id); | ||
| await promises.mkdir(path.dirname(file), { | ||
| recursive: true | ||
| }); | ||
| await promises.writeFile(file, content, { | ||
| encoding: "utf-8", | ||
| flag: "wx" | ||
| }); | ||
| return id; | ||
| } catch (error) { | ||
| if (error.code !== "EEXIST") throw error; | ||
| } | ||
| } | ||
| }, | ||
| async readData(id) { | ||
| try { | ||
| let file = getFile(dir, id); | ||
| let content = JSON.parse(await promises.readFile(file, "utf-8")); | ||
| let data = content.data; | ||
| let expires = typeof content.expires === "string" ? new Date(content.expires) : null; | ||
| if (!expires || expires > new Date()) { | ||
| return data; | ||
| } | ||
| // Remove expired session data. | ||
| if (expires) await promises.unlink(file); | ||
| return null; | ||
| } catch (error) { | ||
| if (error.code !== "ENOENT") throw error; | ||
| return null; | ||
| } | ||
| }, | ||
| async updateData(id, data, expires) { | ||
| let content = JSON.stringify({ | ||
| data, | ||
| expires | ||
| }); | ||
| let file = getFile(dir, id); | ||
| await promises.mkdir(path.dirname(file), { | ||
| recursive: true | ||
| }); | ||
| await promises.writeFile(file, content, "utf-8"); | ||
| }, | ||
| async deleteData(id) { | ||
| // Return early if the id is empty, otherwise we'll end up trying to | ||
| // unlink the dir, which will cause the EPERM error. | ||
| if (!id) { | ||
| return; | ||
| } | ||
| try { | ||
| await promises.unlink(getFile(dir, id)); | ||
| } catch (error) { | ||
| if (error.code !== "ENOENT") throw error; | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| function getFile(dir, id) { | ||
| // Divide the session id up into a directory (first 2 bytes) and filename | ||
| // (remaining 6 bytes) to reduce the chance of having very large directories, | ||
| // which should speed up file access. This is a maximum of 2^16 directories, | ||
| // each with 2^48 files. | ||
| return path.join(dir, id.slice(0, 4), id.slice(4)); | ||
| } | ||
| export { createFileSessionStorage, getFile }; |
+139
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import { Stream } from 'node:stream'; | ||
| async function writeReadableStreamToWritable(stream, writable) { | ||
| let reader = stream.getReader(); | ||
| let flushable = writable; | ||
| try { | ||
| while (true) { | ||
| let { | ||
| done, | ||
| value | ||
| } = await reader.read(); | ||
| if (done) { | ||
| writable.end(); | ||
| break; | ||
| } | ||
| writable.write(value); | ||
| if (typeof flushable.flush === "function") { | ||
| flushable.flush(); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| writable.destroy(error); | ||
| throw error; | ||
| } | ||
| } | ||
| async function writeAsyncIterableToWritable(iterable, writable) { | ||
| try { | ||
| for await (let chunk of iterable) { | ||
| writable.write(chunk); | ||
| } | ||
| writable.end(); | ||
| } catch (error) { | ||
| writable.destroy(error); | ||
| throw error; | ||
| } | ||
| } | ||
| async function readableStreamToString(stream, encoding) { | ||
| let reader = stream.getReader(); | ||
| let chunks = []; | ||
| while (true) { | ||
| let { | ||
| done, | ||
| value | ||
| } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| if (value) { | ||
| chunks.push(value); | ||
| } | ||
| } | ||
| return Buffer.concat(chunks).toString(encoding); | ||
| } | ||
| const createReadableStreamFromReadable = source => { | ||
| let pump = new StreamPump(source); | ||
| let stream = new ReadableStream(pump, pump); | ||
| return stream; | ||
| }; | ||
| class StreamPump { | ||
| constructor(stream) { | ||
| this.highWaterMark = stream.readableHighWaterMark || new Stream.Readable().readableHighWaterMark; | ||
| this.accumalatedSize = 0; | ||
| this.stream = stream; | ||
| this.enqueue = this.enqueue.bind(this); | ||
| this.error = this.error.bind(this); | ||
| this.close = this.close.bind(this); | ||
| } | ||
| size(chunk) { | ||
| return (chunk === null || chunk === void 0 ? void 0 : chunk.byteLength) || 0; | ||
| } | ||
| start(controller) { | ||
| this.controller = controller; | ||
| this.stream.on("data", this.enqueue); | ||
| this.stream.once("error", this.error); | ||
| this.stream.once("end", this.close); | ||
| this.stream.once("close", this.close); | ||
| } | ||
| pull() { | ||
| this.resume(); | ||
| } | ||
| cancel(reason) { | ||
| if (this.stream.destroy) { | ||
| this.stream.destroy(reason); | ||
| } | ||
| this.stream.off("data", this.enqueue); | ||
| this.stream.off("error", this.error); | ||
| this.stream.off("end", this.close); | ||
| this.stream.off("close", this.close); | ||
| } | ||
| enqueue(chunk) { | ||
| if (this.controller) { | ||
| try { | ||
| let bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk); | ||
| let available = (this.controller.desiredSize || 0) - bytes.byteLength; | ||
| this.controller.enqueue(bytes); | ||
| if (available <= 0) { | ||
| this.pause(); | ||
| } | ||
| } catch (error) { | ||
| this.controller.error(new Error("Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object")); | ||
| this.cancel(); | ||
| } | ||
| } | ||
| } | ||
| pause() { | ||
| if (this.stream.pause) { | ||
| this.stream.pause(); | ||
| } | ||
| } | ||
| resume() { | ||
| if (this.stream.readable && this.stream.resume) { | ||
| this.stream.resume(); | ||
| } | ||
| } | ||
| close() { | ||
| if (this.controller) { | ||
| this.controller.close(); | ||
| delete this.controller; | ||
| } | ||
| } | ||
| error(error) { | ||
| if (this.controller) { | ||
| this.controller.error(error); | ||
| delete this.controller; | ||
| } | ||
| } | ||
| } | ||
| export { createReadableStreamFromReadable, readableStreamToString, writeAsyncIterableToWritable, writeReadableStreamToWritable }; |
| /** | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
| * Copyright (c) Remix Software Inc. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE.md file in the root directory of this source tree. | ||
| * | ||
| * @license MIT | ||
| */ | ||
| import { randomBytes } from 'node:crypto'; | ||
| import { createWriteStream, statSync, createReadStream } from 'node:fs'; | ||
| import { mkdir, rm, unlink, stat } from 'node:fs/promises'; | ||
| import { tmpdir } from 'node:os'; | ||
| import { resolve, dirname, basename, extname } from 'node:path'; | ||
| import { finished } from 'node:stream'; | ||
| import { promisify } from 'node:util'; | ||
| import { MaxPartSizeExceededError } from 'react-router'; | ||
| import * as streamSlice from 'stream-slice'; | ||
| import { createReadableStreamFromReadable, readableStreamToString } from '../stream.mjs'; | ||
| let defaultFilePathResolver = ({ | ||
| filename | ||
| }) => { | ||
| let ext = filename ? extname(filename) : ""; | ||
| return "upload_" + randomBytes(4).readUInt32LE(0) + ext; | ||
| }; | ||
| async function uniqueFile(filepath) { | ||
| let ext = extname(filepath); | ||
| let uniqueFilepath = filepath; | ||
| for (let i = 1; await stat(uniqueFilepath).then(() => true).catch(() => false); i++) { | ||
| uniqueFilepath = (ext ? filepath.slice(0, -ext.length) : filepath) + `-${new Date().getTime()}${ext}`; | ||
| } | ||
| return uniqueFilepath; | ||
| } | ||
| function createFileUploadHandler({ | ||
| directory = tmpdir(), | ||
| avoidFileConflicts = true, | ||
| file = defaultFilePathResolver, | ||
| filter, | ||
| maxPartSize = 3000000 | ||
| } = {}) { | ||
| return async ({ | ||
| name, | ||
| filename, | ||
| contentType, | ||
| data | ||
| }) => { | ||
| if (!filename || filter && !(await filter({ | ||
| name, | ||
| filename, | ||
| contentType | ||
| }))) { | ||
| return undefined; | ||
| } | ||
| let dir = typeof directory === "string" ? directory : directory({ | ||
| name, | ||
| filename, | ||
| contentType | ||
| }); | ||
| if (!dir) { | ||
| return undefined; | ||
| } | ||
| let filedir = resolve(dir); | ||
| let path = typeof file === "string" ? file : file({ | ||
| name, | ||
| filename, | ||
| contentType | ||
| }); | ||
| if (!path) { | ||
| return undefined; | ||
| } | ||
| let filepath = resolve(filedir, path); | ||
| if (avoidFileConflicts) { | ||
| filepath = await uniqueFile(filepath); | ||
| } | ||
| await mkdir(dirname(filepath), { | ||
| recursive: true | ||
| }).catch(() => {}); | ||
| let writeFileStream = createWriteStream(filepath); | ||
| let size = 0; | ||
| let deleteFile = false; | ||
| try { | ||
| for await (let chunk of data) { | ||
| size += chunk.byteLength; | ||
| if (size > maxPartSize) { | ||
| deleteFile = true; | ||
| throw new MaxPartSizeExceededError(name, maxPartSize); | ||
| } | ||
| writeFileStream.write(chunk); | ||
| } | ||
| } finally { | ||
| writeFileStream.end(); | ||
| await promisify(finished)(writeFileStream); | ||
| if (deleteFile) { | ||
| await rm(filepath).catch(() => {}); | ||
| } | ||
| } | ||
| // TODO: remove this typecast once TS fixed File class regression | ||
| // https://github.com/microsoft/TypeScript/issues/52166 | ||
| return new NodeOnDiskFile(filepath, contentType); | ||
| }; | ||
| } | ||
| // TODO: remove this `Omit` usage once TS fixed File class regression | ||
| // https://github.com/microsoft/TypeScript/issues/52166 | ||
| class NodeOnDiskFile { | ||
| lastModified = 0; | ||
| webkitRelativePath = ""; | ||
| // TODO: remove this property once TS fixed File class regression | ||
| // https://github.com/microsoft/TypeScript/issues/52166 | ||
| prototype = File.prototype; | ||
| constructor(filepath, type, slicer) { | ||
| this.filepath = filepath; | ||
| this.type = type; | ||
| this.slicer = slicer; | ||
| this.name = basename(filepath); | ||
| } | ||
| get size() { | ||
| let stats = statSync(this.filepath); | ||
| if (this.slicer) { | ||
| let slice = this.slicer.end - this.slicer.start; | ||
| return slice < 0 ? 0 : slice > stats.size ? stats.size : slice; | ||
| } | ||
| return stats.size; | ||
| } | ||
| slice(start, end, type) { | ||
| var _this$slicer; | ||
| if (typeof start === "number" && start < 0) start = this.size + start; | ||
| if (typeof end === "number" && end < 0) end = this.size + end; | ||
| let startOffset = ((_this$slicer = this.slicer) === null || _this$slicer === void 0 ? void 0 : _this$slicer.start) || 0; | ||
| start = startOffset + (start || 0); | ||
| end = startOffset + (end || this.size); | ||
| return new NodeOnDiskFile(this.filepath, typeof type === "string" ? type : this.type, { | ||
| start, | ||
| end | ||
| } | ||
| // TODO: remove this typecast once TS fixed File class regression | ||
| // https://github.com/microsoft/TypeScript/issues/52166 | ||
| ); | ||
| } | ||
| async arrayBuffer() { | ||
| let stream = createReadStream(this.filepath); | ||
| if (this.slicer) { | ||
| stream = stream.pipe(streamSlice.slice(this.slicer.start, this.slicer.end)); | ||
| } | ||
| return new Promise((resolve, reject) => { | ||
| let buf = []; | ||
| stream.on("data", chunk => buf.push(chunk)); | ||
| stream.on("end", () => resolve(Buffer.concat(buf))); | ||
| stream.on("error", err => reject(err)); | ||
| }); | ||
| } | ||
| stream() { | ||
| let stream = createReadStream(this.filepath); | ||
| if (this.slicer) { | ||
| stream = stream.pipe(streamSlice.slice(this.slicer.start, this.slicer.end)); | ||
| } | ||
| return createReadableStreamFromReadable(stream); | ||
| } | ||
| async text() { | ||
| return readableStreamToString(this.stream()); | ||
| } | ||
| get [Symbol.toStringTag]() { | ||
| return "File"; | ||
| } | ||
| remove() { | ||
| return unlink(this.filepath); | ||
| } | ||
| getFilePath() { | ||
| return this.filepath; | ||
| } | ||
| } | ||
| export { NodeOnDiskFile, createFileUploadHandler }; |
+1
-1
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -4,0 +4,0 @@ * Copyright (c) Remix Software Inc. |
+1
-1
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -4,0 +4,0 @@ * Copyright (c) Remix Software Inc. |
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -4,0 +4,0 @@ * Copyright (c) Remix Software Inc. |
+1
-1
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -4,0 +4,0 @@ * Copyright (c) Remix Software Inc. |
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -21,17 +21,17 @@ * Copyright (c) Remix Software Inc. | ||
| function _interopNamespace(e) { | ||
| if (e && e.__esModule) return e; | ||
| var n = Object.create(null); | ||
| if (e) { | ||
| Object.keys(e).forEach(function (k) { | ||
| if (k !== 'default') { | ||
| var d = Object.getOwnPropertyDescriptor(e, k); | ||
| Object.defineProperty(n, k, d.get ? d : { | ||
| enumerable: true, | ||
| get: function () { return e[k]; } | ||
| }); | ||
| } | ||
| if (e && e.__esModule) return e; | ||
| var n = Object.create(null); | ||
| if (e) { | ||
| Object.keys(e).forEach(function (k) { | ||
| if (k !== 'default') { | ||
| var d = Object.getOwnPropertyDescriptor(e, k); | ||
| Object.defineProperty(n, k, d.get ? d : { | ||
| enumerable: true, | ||
| get: function () { return e[k]; } | ||
| }); | ||
| } | ||
| n["default"] = e; | ||
| return Object.freeze(n); | ||
| } | ||
| }); | ||
| } | ||
| n["default"] = e; | ||
| return Object.freeze(n); | ||
| } | ||
@@ -94,2 +94,3 @@ | ||
| } | ||
| // Remove expired session data. | ||
@@ -96,0 +97,0 @@ if (expires) await node_fs.promises.unlink(file); |
+1
-1
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -4,0 +4,0 @@ * Copyright (c) Remix Software Inc. |
| /** | ||
| * @react-router/node v0.0.0-experimental-4996fbe2b | ||
| * @react-router/node v0.0.0-experimental-49eef6a01 | ||
| * | ||
@@ -27,17 +27,17 @@ * Copyright (c) Remix Software Inc. | ||
| function _interopNamespace(e) { | ||
| if (e && e.__esModule) return e; | ||
| var n = Object.create(null); | ||
| if (e) { | ||
| Object.keys(e).forEach(function (k) { | ||
| if (k !== 'default') { | ||
| var d = Object.getOwnPropertyDescriptor(e, k); | ||
| Object.defineProperty(n, k, d.get ? d : { | ||
| enumerable: true, | ||
| get: function () { return e[k]; } | ||
| }); | ||
| } | ||
| if (e && e.__esModule) return e; | ||
| var n = Object.create(null); | ||
| if (e) { | ||
| Object.keys(e).forEach(function (k) { | ||
| if (k !== 'default') { | ||
| var d = Object.getOwnPropertyDescriptor(e, k); | ||
| Object.defineProperty(n, k, d.get ? d : { | ||
| enumerable: true, | ||
| get: function () { return e[k]; } | ||
| }); | ||
| } | ||
| n["default"] = e; | ||
| return Object.freeze(n); | ||
| } | ||
| }); | ||
| } | ||
| n["default"] = e; | ||
| return Object.freeze(n); | ||
| } | ||
@@ -47,2 +47,7 @@ | ||
| /** | ||
| * Chooses the path of the file to be uploaded. If a string is not | ||
| * returned the file will not be written. | ||
| */ | ||
| let defaultFilePathResolver = ({ | ||
@@ -125,2 +130,3 @@ filename | ||
| } | ||
| // TODO: remove this typecast once TS fixed File class regression | ||
@@ -131,2 +137,3 @@ // https://github.com/microsoft/TypeScript/issues/52166 | ||
| } | ||
| // TODO: remove this `Omit` usage once TS fixed File class regression | ||
@@ -137,2 +144,3 @@ // https://github.com/microsoft/TypeScript/issues/52166 | ||
| webkitRelativePath = ""; | ||
| // TODO: remove this property once TS fixed File class regression | ||
@@ -139,0 +147,0 @@ // https://github.com/microsoft/TypeScript/issues/52166 |
+18
-4
| { | ||
| "name": "@react-router/node", | ||
| "version": "0.0.0-experimental-4996fbe2b", | ||
| "version": "0.0.0-experimental-49eef6a01", | ||
| "description": "Node.js platform abstractions for React Router", | ||
@@ -16,4 +16,18 @@ "bugs": { | ||
| "typings": "dist/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/index.d.ts", | ||
| "import": "./dist/index.mjs", | ||
| "require": "./dist/index.js" | ||
| }, | ||
| "./install": { | ||
| "types": "./dist/install.d.ts", | ||
| "import": "./dist/install.mjs", | ||
| "require": "./dist/install.js" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "sideEffects": [ | ||
| "./install.js" | ||
| "./dist/install.js", | ||
| "./dist/install.mjs" | ||
| ], | ||
@@ -31,7 +45,7 @@ "dependencies": { | ||
| "typescript": "^5.1.6", | ||
| "react-router": "0.0.0-experimental-4996fbe2b" | ||
| "react-router": "0.0.0-experimental-49eef6a01" | ||
| }, | ||
| "peerDependencies": { | ||
| "typescript": "^5.1.0", | ||
| "react-router": "0.0.0-experimental-4996fbe2b" | ||
| "react-router": "0.0.0-experimental-49eef6a01" | ||
| }, | ||
@@ -38,0 +52,0 @@ "peerDependenciesMeta": { |
| export {}; |
| /* eslint-disable */ | ||
| "use strict"; | ||
| var globals = require("./dist/globals.js"); | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| globals.installGlobals(); |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
60284
36.86%28
40%1225
73.27%2
100%7
75%