@react-router/node 0.0.0-experimental-ecd35cd60 → 0.0.0-experimental-49eef6a01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/crypto.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import cookieSignature from 'cookie-signature';
12
+
13
+ const sign = async (value, secret) => {
14
+ return cookieSignature.sign(value, secret);
15
+ };
16
+ const unsign = async (signed, secret) => {
17
+ return cookieSignature.unsign(signed, secret);
18
+ };
19
+
20
+ export { sign, unsign };
package/dist/globals.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { File, Headers, Request, Response, fetch, FormData } from 'undici';
12
+
13
+ function installGlobals() {
14
+ global.File = File;
15
+ // @ts-ignore - this shows as an error in VSCode but is not an error via TSC so we can't use `ts-expect-error`
16
+ global.Headers = Headers;
17
+ // @ts-expect-error - overriding globals
18
+ global.Request = Request;
19
+ // @ts-expect-error - overriding globals
20
+ global.Response = Response;
21
+ // @ts-expect-error - overriding globals
22
+ global.fetch = fetch;
23
+ // @ts-expect-error - overriding globals
24
+ global.FormData = FormData;
25
+ }
26
+
27
+ export { installGlobals };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { createCookieFactory, createCookieSessionStorageFactory, createSessionStorageFactory, createMemorySessionStorageFactory } from 'react-router';
12
+ import { sign, unsign } from './crypto.mjs';
13
+
14
+ const createCookie = createCookieFactory({
15
+ sign,
16
+ unsign
17
+ });
18
+ const createCookieSessionStorage = createCookieSessionStorageFactory(createCookie);
19
+ const createSessionStorage = createSessionStorageFactory(createCookie);
20
+ const createMemorySessionStorage = createMemorySessionStorageFactory(createSessionStorage);
21
+
22
+ export { createCookie, createCookieSessionStorage, createMemorySessionStorage, createSessionStorage };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
package/dist/index.mjs ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ export { installGlobals } from './globals.mjs';
12
+ export { createFileSessionStorage } from './sessions/fileStorage.mjs';
13
+ export { NodeOnDiskFile, createFileUploadHandler as unstable_createFileUploadHandler } from './upload/fileUploadHandler.mjs';
14
+ export { createCookie, createCookieSessionStorage, createMemorySessionStorage, createSessionStorage } from './implementations.mjs';
15
+ export { createReadableStreamFromReadable, readableStreamToString, writeAsyncIterableToWritable, writeReadableStreamToWritable } from './stream.mjs';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ 'use strict';
12
+
13
+ var globals = require('./globals.js');
14
+
15
+ globals.installGlobals();
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { installGlobals } from './globals.mjs';
12
+
13
+ installGlobals();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -18,21 +18,21 @@ var path = require('node:path');
18
18
  var implementations = require('../implementations.js');
19
19
 
20
20
  function _interopNamespace(e) {
21
- if (e && e.__esModule) return e;
22
- var n = Object.create(null);
23
- if (e) {
24
- Object.keys(e).forEach(function (k) {
25
- if (k !== 'default') {
26
- var d = Object.getOwnPropertyDescriptor(e, k);
27
- Object.defineProperty(n, k, d.get ? d : {
28
- enumerable: true,
29
- get: function () { return e[k]; }
30
- });
31
- }
21
+ if (e && e.__esModule) return e;
22
+ var n = Object.create(null);
23
+ if (e) {
24
+ Object.keys(e).forEach(function (k) {
25
+ if (k !== 'default') {
26
+ var d = Object.getOwnPropertyDescriptor(e, k);
27
+ Object.defineProperty(n, k, d.get ? d : {
28
+ enumerable: true,
29
+ get: function () { return e[k]; }
32
30
  });
33
- }
34
- n["default"] = e;
35
- return Object.freeze(n);
31
+ }
32
+ });
33
+ }
34
+ n["default"] = e;
35
+ return Object.freeze(n);
36
36
  }
37
37
 
38
38
  var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
@@ -90,6 +90,7 @@ function createFileSessionStorage({
90
90
  if (!expires || expires > new Date()) {
91
91
  return data;
92
92
  }
93
+
93
94
  // Remove expired session data.
94
95
  if (expires) await node_fs.promises.unlink(file);
95
96
  return null;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import * as crypto from 'node:crypto';
12
+ import { promises } from 'node:fs';
13
+ import * as path from 'node:path';
14
+ import { createSessionStorage } from '../implementations.mjs';
15
+
16
+ /**
17
+ * Creates a SessionStorage that stores session data on a filesystem.
18
+ *
19
+ * The advantage of using this instead of cookie session storage is that
20
+ * files may contain much more data than cookies.
21
+ *
22
+ * @see https://remix.run/utils/sessions#createfilesessionstorage-node
23
+ */
24
+ function createFileSessionStorage({
25
+ cookie,
26
+ dir
27
+ }) {
28
+ return createSessionStorage({
29
+ cookie,
30
+ async createData(data, expires) {
31
+ let content = JSON.stringify({
32
+ data,
33
+ expires
34
+ });
35
+ while (true) {
36
+ // TODO: Once Node v19 is supported we should use the globally provided
37
+ // Web Crypto API's crypto.getRandomValues() function here instead.
38
+ let randomBytes = crypto.webcrypto.getRandomValues(new Uint8Array(8));
39
+ // This storage manages an id space of 2^64 ids, which is far greater
40
+ // than the maximum number of files allowed on an NTFS or ext4 volume
41
+ // (2^32). However, the larger id space should help to avoid collisions
42
+ // with existing ids when creating new sessions, which speeds things up.
43
+ let id = Buffer.from(randomBytes).toString("hex");
44
+ try {
45
+ let file = getFile(dir, id);
46
+ await promises.mkdir(path.dirname(file), {
47
+ recursive: true
48
+ });
49
+ await promises.writeFile(file, content, {
50
+ encoding: "utf-8",
51
+ flag: "wx"
52
+ });
53
+ return id;
54
+ } catch (error) {
55
+ if (error.code !== "EEXIST") throw error;
56
+ }
57
+ }
58
+ },
59
+ async readData(id) {
60
+ try {
61
+ let file = getFile(dir, id);
62
+ let content = JSON.parse(await promises.readFile(file, "utf-8"));
63
+ let data = content.data;
64
+ let expires = typeof content.expires === "string" ? new Date(content.expires) : null;
65
+ if (!expires || expires > new Date()) {
66
+ return data;
67
+ }
68
+ // Remove expired session data.
69
+ if (expires) await promises.unlink(file);
70
+ return null;
71
+ } catch (error) {
72
+ if (error.code !== "ENOENT") throw error;
73
+ return null;
74
+ }
75
+ },
76
+ async updateData(id, data, expires) {
77
+ let content = JSON.stringify({
78
+ data,
79
+ expires
80
+ });
81
+ let file = getFile(dir, id);
82
+ await promises.mkdir(path.dirname(file), {
83
+ recursive: true
84
+ });
85
+ await promises.writeFile(file, content, "utf-8");
86
+ },
87
+ async deleteData(id) {
88
+ // Return early if the id is empty, otherwise we'll end up trying to
89
+ // unlink the dir, which will cause the EPERM error.
90
+ if (!id) {
91
+ return;
92
+ }
93
+ try {
94
+ await promises.unlink(getFile(dir, id));
95
+ } catch (error) {
96
+ if (error.code !== "ENOENT") throw error;
97
+ }
98
+ }
99
+ });
100
+ }
101
+ function getFile(dir, id) {
102
+ // Divide the session id up into a directory (first 2 bytes) and filename
103
+ // (remaining 6 bytes) to reduce the chance of having very large directories,
104
+ // which should speed up file access. This is a maximum of 2^16 directories,
105
+ // each with 2^48 files.
106
+ return path.join(dir, id.slice(0, 4), id.slice(4));
107
+ }
108
+
109
+ export { createFileSessionStorage, getFile };
package/dist/stream.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { Stream } from 'node:stream';
12
+
13
+ async function writeReadableStreamToWritable(stream, writable) {
14
+ let reader = stream.getReader();
15
+ let flushable = writable;
16
+ try {
17
+ while (true) {
18
+ let {
19
+ done,
20
+ value
21
+ } = await reader.read();
22
+ if (done) {
23
+ writable.end();
24
+ break;
25
+ }
26
+ writable.write(value);
27
+ if (typeof flushable.flush === "function") {
28
+ flushable.flush();
29
+ }
30
+ }
31
+ } catch (error) {
32
+ writable.destroy(error);
33
+ throw error;
34
+ }
35
+ }
36
+ async function writeAsyncIterableToWritable(iterable, writable) {
37
+ try {
38
+ for await (let chunk of iterable) {
39
+ writable.write(chunk);
40
+ }
41
+ writable.end();
42
+ } catch (error) {
43
+ writable.destroy(error);
44
+ throw error;
45
+ }
46
+ }
47
+ async function readableStreamToString(stream, encoding) {
48
+ let reader = stream.getReader();
49
+ let chunks = [];
50
+ while (true) {
51
+ let {
52
+ done,
53
+ value
54
+ } = await reader.read();
55
+ if (done) {
56
+ break;
57
+ }
58
+ if (value) {
59
+ chunks.push(value);
60
+ }
61
+ }
62
+ return Buffer.concat(chunks).toString(encoding);
63
+ }
64
+ const createReadableStreamFromReadable = source => {
65
+ let pump = new StreamPump(source);
66
+ let stream = new ReadableStream(pump, pump);
67
+ return stream;
68
+ };
69
+ class StreamPump {
70
+ constructor(stream) {
71
+ this.highWaterMark = stream.readableHighWaterMark || new Stream.Readable().readableHighWaterMark;
72
+ this.accumalatedSize = 0;
73
+ this.stream = stream;
74
+ this.enqueue = this.enqueue.bind(this);
75
+ this.error = this.error.bind(this);
76
+ this.close = this.close.bind(this);
77
+ }
78
+ size(chunk) {
79
+ return (chunk === null || chunk === void 0 ? void 0 : chunk.byteLength) || 0;
80
+ }
81
+ start(controller) {
82
+ this.controller = controller;
83
+ this.stream.on("data", this.enqueue);
84
+ this.stream.once("error", this.error);
85
+ this.stream.once("end", this.close);
86
+ this.stream.once("close", this.close);
87
+ }
88
+ pull() {
89
+ this.resume();
90
+ }
91
+ cancel(reason) {
92
+ if (this.stream.destroy) {
93
+ this.stream.destroy(reason);
94
+ }
95
+ this.stream.off("data", this.enqueue);
96
+ this.stream.off("error", this.error);
97
+ this.stream.off("end", this.close);
98
+ this.stream.off("close", this.close);
99
+ }
100
+ enqueue(chunk) {
101
+ if (this.controller) {
102
+ try {
103
+ let bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
104
+ let available = (this.controller.desiredSize || 0) - bytes.byteLength;
105
+ this.controller.enqueue(bytes);
106
+ if (available <= 0) {
107
+ this.pause();
108
+ }
109
+ } catch (error) {
110
+ 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"));
111
+ this.cancel();
112
+ }
113
+ }
114
+ }
115
+ pause() {
116
+ if (this.stream.pause) {
117
+ this.stream.pause();
118
+ }
119
+ }
120
+ resume() {
121
+ if (this.stream.readable && this.stream.resume) {
122
+ this.stream.resume();
123
+ }
124
+ }
125
+ close() {
126
+ if (this.controller) {
127
+ this.controller.close();
128
+ delete this.controller;
129
+ }
130
+ }
131
+ error(error) {
132
+ if (this.controller) {
133
+ this.controller.error(error);
134
+ delete this.controller;
135
+ }
136
+ }
137
+ }
138
+
139
+ export { createReadableStreamFromReadable, readableStreamToString, writeAsyncIterableToWritable, writeReadableStreamToWritable };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/node v0.0.0-experimental-ecd35cd60
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -24,25 +24,30 @@ var streamSlice = require('stream-slice');
24
24
  var stream = require('../stream.js');
25
25
 
26
26
  function _interopNamespace(e) {
27
- if (e && e.__esModule) return e;
28
- var n = Object.create(null);
29
- if (e) {
30
- Object.keys(e).forEach(function (k) {
31
- if (k !== 'default') {
32
- var d = Object.getOwnPropertyDescriptor(e, k);
33
- Object.defineProperty(n, k, d.get ? d : {
34
- enumerable: true,
35
- get: function () { return e[k]; }
36
- });
37
- }
27
+ if (e && e.__esModule) return e;
28
+ var n = Object.create(null);
29
+ if (e) {
30
+ Object.keys(e).forEach(function (k) {
31
+ if (k !== 'default') {
32
+ var d = Object.getOwnPropertyDescriptor(e, k);
33
+ Object.defineProperty(n, k, d.get ? d : {
34
+ enumerable: true,
35
+ get: function () { return e[k]; }
38
36
  });
39
- }
40
- n["default"] = e;
41
- return Object.freeze(n);
37
+ }
38
+ });
39
+ }
40
+ n["default"] = e;
41
+ return Object.freeze(n);
42
42
  }
43
43
 
44
44
  var streamSlice__namespace = /*#__PURE__*/_interopNamespace(streamSlice);
45
45
 
46
+ /**
47
+ * Chooses the path of the file to be uploaded. If a string is not
48
+ * returned the file will not be written.
49
+ */
50
+
46
51
  let defaultFilePathResolver = ({
47
52
  filename
48
53
  }) => {
@@ -120,16 +125,19 @@ function createFileUploadHandler({
120
125
  await promises.rm(filepath).catch(() => {});
121
126
  }
122
127
  }
128
+
123
129
  // TODO: remove this typecast once TS fixed File class regression
124
130
  // https://github.com/microsoft/TypeScript/issues/52166
125
131
  return new NodeOnDiskFile(filepath, contentType);
126
132
  };
127
133
  }
134
+
128
135
  // TODO: remove this `Omit` usage once TS fixed File class regression
129
136
  // https://github.com/microsoft/TypeScript/issues/52166
130
137
  class NodeOnDiskFile {
131
138
  lastModified = 0;
132
139
  webkitRelativePath = "";
140
+
133
141
  // TODO: remove this property once TS fixed File class regression
134
142
  // https://github.com/microsoft/TypeScript/issues/52166
135
143
  prototype = File.prototype;
@@ -0,0 +1,174 @@
1
+ /**
2
+ * @react-router/node v0.0.0-experimental-49eef6a01
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { randomBytes } from 'node:crypto';
12
+ import { createWriteStream, statSync, createReadStream } from 'node:fs';
13
+ import { mkdir, rm, unlink, stat } from 'node:fs/promises';
14
+ import { tmpdir } from 'node:os';
15
+ import { resolve, dirname, basename, extname } from 'node:path';
16
+ import { finished } from 'node:stream';
17
+ import { promisify } from 'node:util';
18
+ import { MaxPartSizeExceededError } from 'react-router';
19
+ import * as streamSlice from 'stream-slice';
20
+ import { createReadableStreamFromReadable, readableStreamToString } from '../stream.mjs';
21
+
22
+ let defaultFilePathResolver = ({
23
+ filename
24
+ }) => {
25
+ let ext = filename ? extname(filename) : "";
26
+ return "upload_" + randomBytes(4).readUInt32LE(0) + ext;
27
+ };
28
+ async function uniqueFile(filepath) {
29
+ let ext = extname(filepath);
30
+ let uniqueFilepath = filepath;
31
+ for (let i = 1; await stat(uniqueFilepath).then(() => true).catch(() => false); i++) {
32
+ uniqueFilepath = (ext ? filepath.slice(0, -ext.length) : filepath) + `-${new Date().getTime()}${ext}`;
33
+ }
34
+ return uniqueFilepath;
35
+ }
36
+ function createFileUploadHandler({
37
+ directory = tmpdir(),
38
+ avoidFileConflicts = true,
39
+ file = defaultFilePathResolver,
40
+ filter,
41
+ maxPartSize = 3000000
42
+ } = {}) {
43
+ return async ({
44
+ name,
45
+ filename,
46
+ contentType,
47
+ data
48
+ }) => {
49
+ if (!filename || filter && !(await filter({
50
+ name,
51
+ filename,
52
+ contentType
53
+ }))) {
54
+ return undefined;
55
+ }
56
+ let dir = typeof directory === "string" ? directory : directory({
57
+ name,
58
+ filename,
59
+ contentType
60
+ });
61
+ if (!dir) {
62
+ return undefined;
63
+ }
64
+ let filedir = resolve(dir);
65
+ let path = typeof file === "string" ? file : file({
66
+ name,
67
+ filename,
68
+ contentType
69
+ });
70
+ if (!path) {
71
+ return undefined;
72
+ }
73
+ let filepath = resolve(filedir, path);
74
+ if (avoidFileConflicts) {
75
+ filepath = await uniqueFile(filepath);
76
+ }
77
+ await mkdir(dirname(filepath), {
78
+ recursive: true
79
+ }).catch(() => {});
80
+ let writeFileStream = createWriteStream(filepath);
81
+ let size = 0;
82
+ let deleteFile = false;
83
+ try {
84
+ for await (let chunk of data) {
85
+ size += chunk.byteLength;
86
+ if (size > maxPartSize) {
87
+ deleteFile = true;
88
+ throw new MaxPartSizeExceededError(name, maxPartSize);
89
+ }
90
+ writeFileStream.write(chunk);
91
+ }
92
+ } finally {
93
+ writeFileStream.end();
94
+ await promisify(finished)(writeFileStream);
95
+ if (deleteFile) {
96
+ await rm(filepath).catch(() => {});
97
+ }
98
+ }
99
+ // TODO: remove this typecast once TS fixed File class regression
100
+ // https://github.com/microsoft/TypeScript/issues/52166
101
+ return new NodeOnDiskFile(filepath, contentType);
102
+ };
103
+ }
104
+ // TODO: remove this `Omit` usage once TS fixed File class regression
105
+ // https://github.com/microsoft/TypeScript/issues/52166
106
+ class NodeOnDiskFile {
107
+ lastModified = 0;
108
+ webkitRelativePath = "";
109
+ // TODO: remove this property once TS fixed File class regression
110
+ // https://github.com/microsoft/TypeScript/issues/52166
111
+ prototype = File.prototype;
112
+ constructor(filepath, type, slicer) {
113
+ this.filepath = filepath;
114
+ this.type = type;
115
+ this.slicer = slicer;
116
+ this.name = basename(filepath);
117
+ }
118
+ get size() {
119
+ let stats = statSync(this.filepath);
120
+ if (this.slicer) {
121
+ let slice = this.slicer.end - this.slicer.start;
122
+ return slice < 0 ? 0 : slice > stats.size ? stats.size : slice;
123
+ }
124
+ return stats.size;
125
+ }
126
+ slice(start, end, type) {
127
+ var _this$slicer;
128
+ if (typeof start === "number" && start < 0) start = this.size + start;
129
+ if (typeof end === "number" && end < 0) end = this.size + end;
130
+ let startOffset = ((_this$slicer = this.slicer) === null || _this$slicer === void 0 ? void 0 : _this$slicer.start) || 0;
131
+ start = startOffset + (start || 0);
132
+ end = startOffset + (end || this.size);
133
+ return new NodeOnDiskFile(this.filepath, typeof type === "string" ? type : this.type, {
134
+ start,
135
+ end
136
+ }
137
+ // TODO: remove this typecast once TS fixed File class regression
138
+ // https://github.com/microsoft/TypeScript/issues/52166
139
+ );
140
+ }
141
+ async arrayBuffer() {
142
+ let stream = createReadStream(this.filepath);
143
+ if (this.slicer) {
144
+ stream = stream.pipe(streamSlice.slice(this.slicer.start, this.slicer.end));
145
+ }
146
+ return new Promise((resolve, reject) => {
147
+ let buf = [];
148
+ stream.on("data", chunk => buf.push(chunk));
149
+ stream.on("end", () => resolve(Buffer.concat(buf)));
150
+ stream.on("error", err => reject(err));
151
+ });
152
+ }
153
+ stream() {
154
+ let stream = createReadStream(this.filepath);
155
+ if (this.slicer) {
156
+ stream = stream.pipe(streamSlice.slice(this.slicer.start, this.slicer.end));
157
+ }
158
+ return createReadableStreamFromReadable(stream);
159
+ }
160
+ async text() {
161
+ return readableStreamToString(this.stream());
162
+ }
163
+ get [Symbol.toStringTag]() {
164
+ return "File";
165
+ }
166
+ remove() {
167
+ return unlink(this.filepath);
168
+ }
169
+ getFilePath() {
170
+ return this.filepath;
171
+ }
172
+ }
173
+
174
+ export { NodeOnDiskFile, createFileUploadHandler };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-router/node",
3
- "version": "0.0.0-experimental-ecd35cd60",
3
+ "version": "0.0.0-experimental-49eef6a01",
4
4
  "description": "Node.js platform abstractions for React Router",
5
5
  "bugs": {
6
6
  "url": "https://github.com/remix-run/react-router/issues"
@@ -13,8 +13,22 @@
13
13
  "license": "MIT",
14
14
  "main": "dist/index.js",
15
15
  "typings": "dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.mjs",
20
+ "require": "./dist/index.js"
21
+ },
22
+ "./install": {
23
+ "types": "./dist/install.d.ts",
24
+ "import": "./dist/install.mjs",
25
+ "require": "./dist/install.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
16
29
  "sideEffects": [
17
- "./install.js"
30
+ "./dist/install.js",
31
+ "./dist/install.mjs"
18
32
  ],
19
33
  "dependencies": {
20
34
  "@web3-storage/multipart-parser": "^1.0.0",
@@ -27,11 +41,11 @@
27
41
  "@types/cookie-signature": "^1.0.3",
28
42
  "@types/source-map-support": "^0.5.4",
29
43
  "typescript": "^5.1.6",
30
- "react-router": "0.0.0-experimental-ecd35cd60"
44
+ "react-router": "0.0.0-experimental-49eef6a01"
31
45
  },
32
46
  "peerDependencies": {
33
47
  "typescript": "^5.1.0",
34
- "react-router": "0.0.0-experimental-ecd35cd60"
48
+ "react-router": "0.0.0-experimental-49eef6a01"
35
49
  },
36
50
  "peerDependenciesMeta": {
37
51
  "typescript": {
package/install.js DELETED
@@ -1,8 +0,0 @@
1
- /* eslint-disable */
2
- "use strict";
3
-
4
- var globals = require("./dist/globals.js");
5
-
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
-
8
- globals.installGlobals();
File without changes