@remix-run/node 0.0.0-experimental-ab9dac4f
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/LICENSE.md +7 -0
- package/README.md +13 -0
- package/base64.d.ts +2 -0
- package/base64.js +23 -0
- package/cookieSigning.d.ts +3 -0
- package/cookieSigning.js +29 -0
- package/errors.d.ts +9 -0
- package/errors.js +123 -0
- package/fetch.d.ts +16 -0
- package/fetch.js +56 -0
- package/form-data.d.ts +15 -0
- package/form-data.js +74 -0
- package/globals.d.ts +17 -0
- package/globals.js +31 -0
- package/index.d.ts +5 -0
- package/index.js +35 -0
- package/magicExports/browser/platform.js +11 -0
- package/magicExports/platform.d.ts +1 -0
- package/magicExports/platform.js +22 -0
- package/package.json +25 -0
- package/sessions/fileStorage.d.ts +20 -0
- package/sessions/fileStorage.js +137 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2021 Remix Software Inc.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Welcome to Remix!
|
|
2
|
+
|
|
3
|
+
[Remix](https://remix.run) is a web framework that helps you build better websites with React.
|
|
4
|
+
|
|
5
|
+
To get started, open a new shell and run:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
$ npx create-remix@latest
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Then follow the prompts you see in your terminal.
|
|
12
|
+
|
|
13
|
+
For more information about Remix, [visit remix.run](https://remix.run)!
|
package/base64.d.ts
ADDED
package/base64.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
function atob(a) {
|
|
16
|
+
return Buffer.from(a, "base64").toString("binary");
|
|
17
|
+
}
|
|
18
|
+
function btoa(b) {
|
|
19
|
+
return Buffer.from(b, "binary").toString("base64");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.atob = atob;
|
|
23
|
+
exports.btoa = btoa;
|
package/cookieSigning.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var cookieSignature = require('cookie-signature');
|
|
16
|
+
|
|
17
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
18
|
+
|
|
19
|
+
var cookieSignature__default = /*#__PURE__*/_interopDefaultLegacy(cookieSignature);
|
|
20
|
+
|
|
21
|
+
const sign = async (value, secret) => {
|
|
22
|
+
return cookieSignature__default["default"].sign(value, secret);
|
|
23
|
+
};
|
|
24
|
+
const unsign = async (signed, secret) => {
|
|
25
|
+
return cookieSignature__default["default"].unsign(signed, secret);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.sign = sign;
|
|
29
|
+
exports.unsign = unsign;
|
package/errors.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NullableMappedPosition } from "source-map";
|
|
2
|
+
import { SourceMapConsumer } from "source-map";
|
|
3
|
+
export declare const UNKNOWN_LOCATION_POSITION = "<unknown location>";
|
|
4
|
+
export declare function formatServerError(error: Error): Promise<Error>;
|
|
5
|
+
export declare function formatStackTrace(error: Error): Promise<string | undefined>;
|
|
6
|
+
export declare function mapToSourceFile(cache: Map<string, SourceMapConsumer>, stackLine: string): Promise<string>;
|
|
7
|
+
export declare function relativeFilename(filename: string): string;
|
|
8
|
+
export declare function getOriginalSourcePosition(smc: SourceMapConsumer, line: number, column: number): NullableMappedPosition;
|
|
9
|
+
export declare function getSourceContentForPosition(smc: SourceMapConsumer, pos: NullableMappedPosition): string;
|
package/errors.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var fs = require('fs');
|
|
16
|
+
var fsp = require('fs/promises');
|
|
17
|
+
var path = require('path');
|
|
18
|
+
var sourceMap = require('source-map');
|
|
19
|
+
|
|
20
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
21
|
+
|
|
22
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
23
|
+
var fsp__default = /*#__PURE__*/_interopDefaultLegacy(fsp);
|
|
24
|
+
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
25
|
+
|
|
26
|
+
const ROOT = process.cwd() + path__default["default"].sep;
|
|
27
|
+
const SOURCE_PATTERN = /(?<at>\s+at.+)\((?<filename>.+):(?<line>\d+):(?<column>\d+)\)/;
|
|
28
|
+
const UNKNOWN_LOCATION_POSITION = "<unknown location>";
|
|
29
|
+
async function formatServerError(error) {
|
|
30
|
+
try {
|
|
31
|
+
error.stack = await formatStackTrace(error);
|
|
32
|
+
} catch {}
|
|
33
|
+
|
|
34
|
+
return error;
|
|
35
|
+
}
|
|
36
|
+
async function formatStackTrace(error) {
|
|
37
|
+
var _error$stack;
|
|
38
|
+
|
|
39
|
+
const cache = new Map();
|
|
40
|
+
const lines = ((_error$stack = error.stack) === null || _error$stack === void 0 ? void 0 : _error$stack.split("\n")) || [];
|
|
41
|
+
const promises = lines.map(line => mapToSourceFile(cache, line));
|
|
42
|
+
const stack = (await Promise.all(promises)).join("\n") || error.stack;
|
|
43
|
+
return stack;
|
|
44
|
+
}
|
|
45
|
+
async function mapToSourceFile(cache, stackLine) {
|
|
46
|
+
let match = SOURCE_PATTERN.exec(stackLine);
|
|
47
|
+
|
|
48
|
+
if (!(match !== null && match !== void 0 && match.groups)) {
|
|
49
|
+
// doesn't match pattern but may still have a filename
|
|
50
|
+
return relativeFilename(stackLine);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let {
|
|
54
|
+
at,
|
|
55
|
+
filename
|
|
56
|
+
} = match.groups;
|
|
57
|
+
let line = match.groups.line;
|
|
58
|
+
let column = match.groups.column;
|
|
59
|
+
let mapFilename = `${filename}.map`;
|
|
60
|
+
let smc = cache.get(mapFilename);
|
|
61
|
+
filename = relativeFilename(filename);
|
|
62
|
+
|
|
63
|
+
if (!smc) {
|
|
64
|
+
if (await fileExists(mapFilename)) {
|
|
65
|
+
// read source map and setup consumer
|
|
66
|
+
const map = JSON.parse(await fsp__default["default"].readFile(mapFilename, "utf-8"));
|
|
67
|
+
map.sourceRoot = path__default["default"].dirname(mapFilename);
|
|
68
|
+
smc = await new sourceMap.SourceMapConsumer(map);
|
|
69
|
+
cache.set(mapFilename, smc);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (smc) {
|
|
74
|
+
const pos = getOriginalSourcePosition(smc, parseInt(line, 10), parseInt(column, 10));
|
|
75
|
+
|
|
76
|
+
if (pos.source) {
|
|
77
|
+
filename = relativeFilename(pos.source);
|
|
78
|
+
line = pos.line || "?";
|
|
79
|
+
column = pos.column || "?";
|
|
80
|
+
at = ` at \`${getSourceContentForPosition(smc, pos)}\` `;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return `${at}(${filename}:${line}:${column})`;
|
|
85
|
+
}
|
|
86
|
+
function relativeFilename(filename) {
|
|
87
|
+
if (filename.includes("route-module:")) {
|
|
88
|
+
filename = filename.substring(filename.indexOf("route-module:"));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return filename.replace("route-module:", "").replace(ROOT, "./");
|
|
92
|
+
}
|
|
93
|
+
function getOriginalSourcePosition(smc, line, column) {
|
|
94
|
+
return smc.originalPositionFor({
|
|
95
|
+
line,
|
|
96
|
+
column
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function getSourceContentForPosition(smc, pos) {
|
|
100
|
+
let src = null;
|
|
101
|
+
|
|
102
|
+
if (pos !== null && pos !== void 0 && pos.source && typeof pos.line === "number") {
|
|
103
|
+
src = smc.sourceContentFor(pos.source);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!src) {
|
|
107
|
+
return UNKNOWN_LOCATION_POSITION;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return src.split("\n")[pos.line - 1].trim();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function fileExists(filename) {
|
|
114
|
+
return fsp__default["default"].access(filename, fs__default["default"].constants.F_OK).then(() => true).catch(() => false);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
exports.UNKNOWN_LOCATION_POSITION = UNKNOWN_LOCATION_POSITION;
|
|
118
|
+
exports.formatServerError = formatServerError;
|
|
119
|
+
exports.formatStackTrace = formatStackTrace;
|
|
120
|
+
exports.getOriginalSourcePosition = getOriginalSourcePosition;
|
|
121
|
+
exports.getSourceContentForPosition = getSourceContentForPosition;
|
|
122
|
+
exports.mapToSourceFile = mapToSourceFile;
|
|
123
|
+
exports.relativeFilename = relativeFilename;
|
package/fetch.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RequestInfo, RequestInit, Response } from "node-fetch";
|
|
2
|
+
import { Request as NodeRequest } from "node-fetch";
|
|
3
|
+
import { RemixFormData } from "./form-data";
|
|
4
|
+
export type { HeadersInit, RequestInfo, RequestInit, ResponseInit } from "node-fetch";
|
|
5
|
+
export { Headers, Response } from "node-fetch";
|
|
6
|
+
export declare class Request extends NodeRequest {
|
|
7
|
+
formData(): Promise<RemixFormData>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A `fetch` function for node that matches the web Fetch API. Based on
|
|
11
|
+
* `node-fetch`.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/node-fetch/node-fetch
|
|
14
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
|
|
15
|
+
*/
|
|
16
|
+
export declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
package/fetch.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var nodeFetch = require('node-fetch');
|
|
16
|
+
var formData = require('./form-data.js');
|
|
17
|
+
|
|
18
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
19
|
+
|
|
20
|
+
var nodeFetch__default = /*#__PURE__*/_interopDefaultLegacy(nodeFetch);
|
|
21
|
+
|
|
22
|
+
class Request extends nodeFetch.Request {
|
|
23
|
+
async formData() {
|
|
24
|
+
let body = await this.clone().text();
|
|
25
|
+
return new formData.RemixFormData(body);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A `fetch` function for node that matches the web Fetch API. Based on
|
|
31
|
+
* `node-fetch`.
|
|
32
|
+
*
|
|
33
|
+
* @see https://github.com/node-fetch/node-fetch
|
|
34
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
function fetch(input, init) {
|
|
38
|
+
// Default to { compress: false } so responses can be proxied through more
|
|
39
|
+
// easily in loaders. Otherwise the response stream encoding will not match
|
|
40
|
+
// the Content-Encoding response header.
|
|
41
|
+
return nodeFetch__default["default"](input, {
|
|
42
|
+
compress: false,
|
|
43
|
+
...init
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Object.defineProperty(exports, 'Headers', {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function () { return nodeFetch.Headers; }
|
|
50
|
+
});
|
|
51
|
+
Object.defineProperty(exports, 'Response', {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function () { return nodeFetch.Response; }
|
|
54
|
+
});
|
|
55
|
+
exports.Request = Request;
|
|
56
|
+
exports.fetch = fetch;
|
package/form-data.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class RemixFormData implements FormData {
|
|
2
|
+
private _params;
|
|
3
|
+
constructor(body?: string);
|
|
4
|
+
append(name: string, value: string | Blob, fileName?: string): void;
|
|
5
|
+
delete(name: string): void;
|
|
6
|
+
get(name: string): FormDataEntryValue | null;
|
|
7
|
+
getAll(name: string): FormDataEntryValue[];
|
|
8
|
+
has(name: string): boolean;
|
|
9
|
+
set(name: string, value: string | Blob, fileName?: string): void;
|
|
10
|
+
forEach(callbackfn: (value: FormDataEntryValue, key: string, parent: FormData) => void, thisArg?: any): void;
|
|
11
|
+
entries(): IterableIterator<[string, FormDataEntryValue]>;
|
|
12
|
+
keys(): IterableIterator<string>;
|
|
13
|
+
values(): IterableIterator<FormDataEntryValue>;
|
|
14
|
+
[Symbol.iterator](): IterableIterator<[string, FormDataEntryValue]>;
|
|
15
|
+
}
|
package/form-data.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
class RemixFormData {
|
|
16
|
+
constructor(body) {
|
|
17
|
+
this._params = new URLSearchParams(body);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
append(name, value, fileName) {
|
|
21
|
+
if (typeof value !== "string") {
|
|
22
|
+
throw new Error("formData.append can only accept a string");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this._params.append(name, value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
delete(name) {
|
|
29
|
+
this._params.delete(name);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get(name) {
|
|
33
|
+
return this._params.get(name);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getAll(name) {
|
|
37
|
+
return this._params.getAll(name);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
has(name) {
|
|
41
|
+
return this._params.has(name);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
set(name, value, fileName) {
|
|
45
|
+
if (typeof value !== "string") {
|
|
46
|
+
throw new Error("formData.set can only accept a string");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this._params.set(name, value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
forEach(callbackfn, thisArg) {
|
|
53
|
+
this._params.forEach(callbackfn, thisArg);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
entries() {
|
|
57
|
+
return this._params.entries();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
keys() {
|
|
61
|
+
return this._params.keys();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
values() {
|
|
65
|
+
return this._params.values();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
*[Symbol.iterator]() {
|
|
69
|
+
yield* this._params;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
exports.RemixFormData = RemixFormData;
|
package/globals.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { InternalSignFunctionDoNotUseMe, InternalUnsignFunctionDoNotUseMe } from "@remix-run/server-runtime/cookieSigning";
|
|
2
|
+
import { atob, btoa } from "./base64";
|
|
3
|
+
declare global {
|
|
4
|
+
namespace NodeJS {
|
|
5
|
+
interface Global {
|
|
6
|
+
atob: typeof atob;
|
|
7
|
+
btoa: typeof btoa;
|
|
8
|
+
Headers: typeof Headers;
|
|
9
|
+
Request: typeof Request;
|
|
10
|
+
Response: typeof Response;
|
|
11
|
+
fetch: typeof fetch;
|
|
12
|
+
sign: InternalSignFunctionDoNotUseMe;
|
|
13
|
+
unsign: InternalUnsignFunctionDoNotUseMe;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export declare function installGlobals(): void;
|
package/globals.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var base64 = require('./base64.js');
|
|
16
|
+
var cookieSigning = require('./cookieSigning.js');
|
|
17
|
+
var fetch = require('./fetch.js');
|
|
18
|
+
var nodeFetch = require('node-fetch');
|
|
19
|
+
|
|
20
|
+
function installGlobals() {
|
|
21
|
+
global.atob = base64.atob;
|
|
22
|
+
global.btoa = base64.btoa;
|
|
23
|
+
global.Headers = nodeFetch.Headers;
|
|
24
|
+
global.Request = fetch.Request;
|
|
25
|
+
global.Response = nodeFetch.Response;
|
|
26
|
+
global.fetch = fetch.fetch;
|
|
27
|
+
global.sign = cookieSigning.sign;
|
|
28
|
+
global.unsign = cookieSigning.unsign;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
exports.installGlobals = installGlobals;
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { formatServerError } from "./errors";
|
|
2
|
+
export type { HeadersInit, RequestInfo, RequestInit, ResponseInit } from "./fetch";
|
|
3
|
+
export { Headers, Request, Response, fetch } from "./fetch";
|
|
4
|
+
export { installGlobals } from "./globals";
|
|
5
|
+
export { createFileSessionStorage } from "./sessions/fileStorage";
|
package/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var errors = require('./errors.js');
|
|
16
|
+
var fetch = require('./fetch.js');
|
|
17
|
+
var globals = require('./globals.js');
|
|
18
|
+
var fileStorage = require('./sessions/fileStorage.js');
|
|
19
|
+
var nodeFetch = require('node-fetch');
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
exports.formatServerError = errors.formatServerError;
|
|
24
|
+
exports.Request = fetch.Request;
|
|
25
|
+
exports.fetch = fetch.fetch;
|
|
26
|
+
exports.installGlobals = globals.installGlobals;
|
|
27
|
+
exports.createFileSessionStorage = fileStorage.createFileSessionStorage;
|
|
28
|
+
Object.defineProperty(exports, 'Headers', {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () { return nodeFetch.Headers; }
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, 'Response', {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function () { return nodeFetch.Response; }
|
|
35
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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 { createFileSessionStorage } from '@remix-run/node';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createFileSessionStorage } from "@remix-run/node";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var node = require('@remix-run/node');
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
Object.defineProperty(exports, 'createFileSessionStorage', {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return node.createFileSessionStorage; }
|
|
22
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@remix-run/node",
|
|
3
|
+
"description": "Node.js platform abstractions for Remix",
|
|
4
|
+
"version": "0.0.0-experimental-ab9dac4f",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/remix-run/remix",
|
|
9
|
+
"directory": "packages/remix-node"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/remix-run/remix/issues"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@remix-run/server-runtime": "0.0.0-experimental-ab9dac4f",
|
|
16
|
+
"@types/node-fetch": "^2.5.12",
|
|
17
|
+
"cookie-signature": "^1.1.0",
|
|
18
|
+
"node-fetch": "^2.6.1",
|
|
19
|
+
"source-map": "^0.7.3"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/cookie-signature": "^1.0.3"
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false
|
|
25
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SessionStorage, SessionIdStorageStrategy } from "@remix-run/server-runtime";
|
|
2
|
+
interface FileSessionStorageOptions {
|
|
3
|
+
/**
|
|
4
|
+
* The Cookie used to store the session id on the client, or options used
|
|
5
|
+
* to automatically create one.
|
|
6
|
+
*/
|
|
7
|
+
cookie?: SessionIdStorageStrategy["cookie"];
|
|
8
|
+
/**
|
|
9
|
+
* The directory to use to store session files.
|
|
10
|
+
*/
|
|
11
|
+
dir: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a SessionStorage that stores session data on a filesystem.
|
|
15
|
+
*
|
|
16
|
+
* The advantage of using this instead of cookie session storage is that
|
|
17
|
+
* files may contain much more data than cookies.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createFileSessionStorage({ cookie, dir }: FileSessionStorageOptions): SessionStorage;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @remix-run/node v0.0.0-experimental-ab9dac4f
|
|
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
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var crypto = require('crypto');
|
|
16
|
+
var fs = require('fs');
|
|
17
|
+
var path = require('path');
|
|
18
|
+
var serverRuntime = require('@remix-run/server-runtime');
|
|
19
|
+
|
|
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
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
n["default"] = e;
|
|
35
|
+
return Object.freeze(n);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
39
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a SessionStorage that stores session data on a filesystem.
|
|
43
|
+
*
|
|
44
|
+
* The advantage of using this instead of cookie session storage is that
|
|
45
|
+
* files may contain much more data than cookies.
|
|
46
|
+
*/
|
|
47
|
+
function createFileSessionStorage({
|
|
48
|
+
cookie,
|
|
49
|
+
dir
|
|
50
|
+
}) {
|
|
51
|
+
return serverRuntime.createSessionStorage({
|
|
52
|
+
cookie,
|
|
53
|
+
|
|
54
|
+
async createData(data, expires) {
|
|
55
|
+
let content = JSON.stringify({
|
|
56
|
+
data,
|
|
57
|
+
expires
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
while (true) {
|
|
61
|
+
// TODO: Once node v16 is available on AWS we should use the webcrypto
|
|
62
|
+
// API's crypto.getRandomValues() function here instead.
|
|
63
|
+
let randomBytes = crypto__namespace.randomBytes(8); // This storage manages an id space of 2^64 ids, which is far greater
|
|
64
|
+
// than the maximum number of files allowed on an NTFS or ext4 volume
|
|
65
|
+
// (2^32). However, the larger id space should help to avoid collisions
|
|
66
|
+
// with existing ids when creating new sessions, which speeds things up.
|
|
67
|
+
|
|
68
|
+
let id = Buffer.from(randomBytes).toString("hex");
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
let file = getFile(dir, id);
|
|
72
|
+
await fs.promises.mkdir(path__namespace.dirname(file), {
|
|
73
|
+
recursive: true
|
|
74
|
+
});
|
|
75
|
+
await fs.promises.writeFile(file, content, {
|
|
76
|
+
encoding: "utf-8",
|
|
77
|
+
flag: "wx"
|
|
78
|
+
});
|
|
79
|
+
return id;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error.code !== "EEXIST") throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
async readData(id) {
|
|
87
|
+
try {
|
|
88
|
+
let file = getFile(dir, id);
|
|
89
|
+
let content = JSON.parse(await fs.promises.readFile(file, "utf-8"));
|
|
90
|
+
let data = content.data;
|
|
91
|
+
let expires = typeof content.expires === "string" ? new Date(content.expires) : null;
|
|
92
|
+
|
|
93
|
+
if (!expires || expires > new Date()) {
|
|
94
|
+
return data;
|
|
95
|
+
} // Remove expired session data.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if (expires) await fs.promises.unlink(file);
|
|
99
|
+
return null;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error.code !== "ENOENT") throw error;
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
async updateData(id, data, expires) {
|
|
107
|
+
let content = JSON.stringify({
|
|
108
|
+
data,
|
|
109
|
+
expires
|
|
110
|
+
});
|
|
111
|
+
let file = getFile(dir, id);
|
|
112
|
+
await fs.promises.mkdir(path__namespace.dirname(file), {
|
|
113
|
+
recursive: true
|
|
114
|
+
});
|
|
115
|
+
await fs.promises.writeFile(file, content, "utf-8");
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
async deleteData(id) {
|
|
119
|
+
try {
|
|
120
|
+
await fs.promises.unlink(getFile(dir, id));
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error.code !== "ENOENT") throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function getFile(dir, id) {
|
|
130
|
+
// Divide the session id up into a directory (first 2 bytes) and filename
|
|
131
|
+
// (remaining 6 bytes) to reduce the chance of having very large directories,
|
|
132
|
+
// which should speed up file access. This is a maximum of 2^16 directories,
|
|
133
|
+
// each with 2^48 files.
|
|
134
|
+
return path__namespace.join(dir, id.slice(0, 4), id.slice(4));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
exports.createFileSessionStorage = createFileSessionStorage;
|