@sveltejs/adapter-vercel 1.0.0-next.3 → 1.0.0-next.33
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/README.md +12 -6
- package/files/entry.js +33 -0
- package/index.d.ts +4 -0
- package/index.js +75 -41
- package/package.json +34 -23
- package/CHANGELOG.md +0 -41
- package/files/index.js +0 -270
- package/files/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,15 +4,21 @@ Adapter for Svelte apps that creates a Vercel app, using a function for dynamic
|
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
npm install --save-dev @sveltejs/adapter-vercel
|
|
9
|
-
```
|
|
7
|
+
Add `"@sveltejs/adapter-vercel": "next"` to the `devDependencies` in your `package.json` and run `npm install`.
|
|
10
8
|
|
|
11
9
|
Then in your `svelte.config.js`:
|
|
12
10
|
|
|
13
11
|
```js
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
import vercel from '@sveltejs/adapter-vercel';
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
kit: {
|
|
16
|
+
...
|
|
17
|
+
adapter: vercel()
|
|
18
|
+
}
|
|
17
19
|
};
|
|
18
20
|
```
|
|
21
|
+
|
|
22
|
+
## Changelog
|
|
23
|
+
|
|
24
|
+
[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/adapter-vercel/CHANGELOG.md).
|
package/files/entry.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { __fetch_polyfill } from '@sveltejs/kit/install-fetch';
|
|
2
|
+
import { getRawBody } from '@sveltejs/kit/node';
|
|
3
|
+
import { App } from 'APP';
|
|
4
|
+
import { manifest } from 'MANIFEST';
|
|
5
|
+
|
|
6
|
+
__fetch_polyfill();
|
|
7
|
+
|
|
8
|
+
const app = new App(manifest);
|
|
9
|
+
|
|
10
|
+
export default async (req, res) => {
|
|
11
|
+
let body;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
body = await getRawBody(req);
|
|
15
|
+
} catch (err) {
|
|
16
|
+
res.statusCode = err.status || 400;
|
|
17
|
+
return res.end(err.reason || 'Invalid request body');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const rendered = await app.render({
|
|
21
|
+
url: req.url,
|
|
22
|
+
method: req.method,
|
|
23
|
+
headers: req.headers,
|
|
24
|
+
rawBody: body
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
if (rendered) {
|
|
28
|
+
const { status, headers, body } = rendered;
|
|
29
|
+
return res.writeHead(status, headers).end(body);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return res.writeHead(404).end();
|
|
33
|
+
};
|
package/index.d.ts
ADDED
package/index.js
CHANGED
|
@@ -1,43 +1,77 @@
|
|
|
1
|
-
import { writeFileSync
|
|
2
|
-
import {
|
|
1
|
+
import { writeFileSync } from 'fs';
|
|
2
|
+
import { relative } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
4
|
+
import esbuild from 'esbuild';
|
|
5
|
+
|
|
6
|
+
// By writing to .output, we opt in to the Vercel filesystem API:
|
|
7
|
+
// https://vercel.com/docs/file-system-api
|
|
8
|
+
const VERCEL_OUTPUT = '.output';
|
|
9
|
+
|
|
10
|
+
/** @type {import('.')} **/
|
|
11
|
+
export default function () {
|
|
12
|
+
return {
|
|
13
|
+
name: '@sveltejs/adapter-vercel',
|
|
14
|
+
|
|
15
|
+
async adapt(builder) {
|
|
16
|
+
const tmp = builder.getBuildDirectory('vercel-tmp');
|
|
17
|
+
|
|
18
|
+
builder.rimraf(VERCEL_OUTPUT);
|
|
19
|
+
builder.rimraf(tmp);
|
|
20
|
+
|
|
21
|
+
builder.log.minor('Prerendering static pages...');
|
|
22
|
+
await builder.prerender({
|
|
23
|
+
dest: `${VERCEL_OUTPUT}/static`
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
builder.log.minor('Generating serverless function...');
|
|
27
|
+
|
|
28
|
+
const files = fileURLToPath(new URL('./files', import.meta.url));
|
|
29
|
+
const relativePath = relative(tmp, builder.getServerDirectory());
|
|
30
|
+
|
|
31
|
+
builder.copy(files, tmp, {
|
|
32
|
+
replace: {
|
|
33
|
+
APP: `${relativePath}/app.js`,
|
|
34
|
+
MANIFEST: './manifest.js'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
writeFileSync(
|
|
39
|
+
`${tmp}/manifest.js`,
|
|
40
|
+
`export const manifest = ${builder.generateManifest({
|
|
41
|
+
relativePath
|
|
42
|
+
})};\n`
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
await esbuild.build({
|
|
46
|
+
entryPoints: [`${tmp}/entry.js`],
|
|
47
|
+
outfile: `${VERCEL_OUTPUT}/server/pages/__render.js`,
|
|
48
|
+
target: 'node14',
|
|
49
|
+
bundle: true,
|
|
50
|
+
platform: 'node'
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
writeFileSync(
|
|
54
|
+
`${VERCEL_OUTPUT}/server/pages/package.json`,
|
|
55
|
+
JSON.stringify({ type: 'commonjs' })
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
builder.log.minor('Copying assets...');
|
|
59
|
+
builder.writeClient(`${VERCEL_OUTPUT}/static`);
|
|
60
|
+
builder.writeStatic(`${VERCEL_OUTPUT}/static`);
|
|
61
|
+
|
|
62
|
+
builder.log.minor('Writing manifests...');
|
|
63
|
+
writeFileSync(
|
|
64
|
+
`${VERCEL_OUTPUT}/routes-manifest.json`,
|
|
65
|
+
JSON.stringify({
|
|
66
|
+
version: 3,
|
|
67
|
+
dynamicRoutes: [
|
|
68
|
+
{
|
|
69
|
+
page: '/__render',
|
|
70
|
+
regex: '^/.*'
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
43
77
|
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
2
|
+
"name": "@sveltejs/adapter-vercel",
|
|
3
|
+
"version": "1.0.0-next.33",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/sveltejs/kit",
|
|
7
|
+
"directory": "packages/adapter-vercel"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"homepage": "https://kit.svelte.dev",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./index.js"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"main": "index.js",
|
|
19
|
+
"types": "index.d.ts",
|
|
20
|
+
"files": [
|
|
21
|
+
"files",
|
|
22
|
+
"index.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"esbuild": "^0.13.15"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@sveltejs/kit": "1.0.0-next.208"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"lint": "eslint --ignore-path .gitignore \"**/*.{ts,js,svelte}\" && npm run check-format",
|
|
32
|
+
"format": "npm run check-format -- --write",
|
|
33
|
+
"check-format": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# @sveltejs/adapter-vercel
|
|
2
|
-
|
|
3
|
-
## 1.0.0-next.3
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- 8123929: Fix adapter-vercel using the wrong directory
|
|
8
|
-
- Updated dependencies [73dd998]
|
|
9
|
-
- Updated dependencies [b800049]
|
|
10
|
-
- @sveltejs/app-utils@1.0.0-next.2
|
|
11
|
-
|
|
12
|
-
## 1.0.0-next.2
|
|
13
|
-
|
|
14
|
-
### Patch Changes
|
|
15
|
-
|
|
16
|
-
- Fix adapters and convert to ES modules
|
|
17
|
-
|
|
18
|
-
## 1.0.0-next.1
|
|
19
|
-
|
|
20
|
-
### Patch Changes
|
|
21
|
-
|
|
22
|
-
- Update to new adapter API
|
|
23
|
-
|
|
24
|
-
## 0.0.3
|
|
25
|
-
|
|
26
|
-
### Patch Changes
|
|
27
|
-
|
|
28
|
-
- 67eaeea: Move app-utils stuff into subpackages
|
|
29
|
-
|
|
30
|
-
## 0.0.2
|
|
31
|
-
|
|
32
|
-
### Patch Changes
|
|
33
|
-
|
|
34
|
-
- Use setup
|
|
35
|
-
|
|
36
|
-
## 0.0.1
|
|
37
|
-
|
|
38
|
-
### Patch Changes
|
|
39
|
-
|
|
40
|
-
- 0320208: Rename 'server route' to 'endpoint'
|
|
41
|
-
- 5ca907c: Use shared mkdirp helper
|
package/files/index.js
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import { parse, URLSearchParams } from 'url';
|
|
2
|
-
|
|
3
|
-
function read_only_form_data() {
|
|
4
|
-
/** @type {Map<string, string[]>} */
|
|
5
|
-
const map = new Map();
|
|
6
|
-
|
|
7
|
-
return {
|
|
8
|
-
/**
|
|
9
|
-
* @param {string} key
|
|
10
|
-
* @param {string} value
|
|
11
|
-
*/
|
|
12
|
-
append(key, value) {
|
|
13
|
-
if (map.has(key)) {
|
|
14
|
-
map.get(key).push(value);
|
|
15
|
-
} else {
|
|
16
|
-
map.set(key, [value]);
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
data: new ReadOnlyFormData(map)
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
class ReadOnlyFormData {
|
|
25
|
-
/** @type {Map<string, string[]>} */
|
|
26
|
-
#map;
|
|
27
|
-
|
|
28
|
-
/** @param {Map<string, string[]>} map */
|
|
29
|
-
constructor(map) {
|
|
30
|
-
this.#map = map;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** @param {string} key */
|
|
34
|
-
get(key) {
|
|
35
|
-
const value = this.#map.get(key);
|
|
36
|
-
return value && value[0];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** @param {string} key */
|
|
40
|
-
getAll(key) {
|
|
41
|
-
return this.#map.get(key);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** @param {string} key */
|
|
45
|
-
has(key) {
|
|
46
|
-
return this.#map.has(key);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
*[Symbol.iterator]() {
|
|
50
|
-
for (const [key, value] of this.#map) {
|
|
51
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
52
|
-
yield [key, value[i]];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
*entries() {
|
|
58
|
-
for (const [key, value] of this.#map) {
|
|
59
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
60
|
-
yield [key, value[i]];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
*keys() {
|
|
66
|
-
for (const [key, value] of this.#map) {
|
|
67
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
68
|
-
yield key;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
*values() {
|
|
74
|
-
for (const [, value] of this.#map) {
|
|
75
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
76
|
-
yield value;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** @param {import('http').IncomingMessage} req */
|
|
83
|
-
function get_body(req) {
|
|
84
|
-
const headers = req.headers;
|
|
85
|
-
const has_body =
|
|
86
|
-
headers['content-type'] !== undefined &&
|
|
87
|
-
// https://github.com/jshttp/type-is/blob/c1f4388c71c8a01f79934e68f630ca4a15fffcd6/index.js#L81-L95
|
|
88
|
-
(headers['transfer-encoding'] !== undefined || !isNaN(Number(headers['content-length'])));
|
|
89
|
-
|
|
90
|
-
if (!has_body) return Promise.resolve(undefined);
|
|
91
|
-
|
|
92
|
-
const [type, ...directives] = headers['content-type'].split(/;\s*/);
|
|
93
|
-
|
|
94
|
-
switch (type) {
|
|
95
|
-
case 'application/octet-stream':
|
|
96
|
-
return get_buffer(req);
|
|
97
|
-
|
|
98
|
-
case 'text/plain':
|
|
99
|
-
return get_text(req);
|
|
100
|
-
|
|
101
|
-
case 'application/json':
|
|
102
|
-
return get_json(req);
|
|
103
|
-
|
|
104
|
-
case 'application/x-www-form-urlencoded':
|
|
105
|
-
return get_urlencoded(req);
|
|
106
|
-
|
|
107
|
-
case 'multipart/form-data': {
|
|
108
|
-
const boundary = directives.find((directive) => directive.startsWith('boundary='));
|
|
109
|
-
if (!boundary) throw new Error('Missing boundary');
|
|
110
|
-
return get_multipart(req, boundary.slice('boundary='.length));
|
|
111
|
-
}
|
|
112
|
-
default:
|
|
113
|
-
throw new Error(`Invalid Content-Type ${type}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** @param {import('http').IncomingMessage} req */
|
|
118
|
-
async function get_json(req) {
|
|
119
|
-
return JSON.parse(await get_text(req));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** @param {import('http').IncomingMessage} req */
|
|
123
|
-
async function get_urlencoded(req) {
|
|
124
|
-
const text = await get_text(req);
|
|
125
|
-
|
|
126
|
-
const { data, append } = read_only_form_data();
|
|
127
|
-
|
|
128
|
-
text
|
|
129
|
-
.replace(/\+/g, ' ')
|
|
130
|
-
.split('&')
|
|
131
|
-
.forEach((str) => {
|
|
132
|
-
const [key, value] = str.split('=');
|
|
133
|
-
append(decodeURIComponent(key), decodeURIComponent(value));
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
return data;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* @param {import('http').IncomingMessage} req
|
|
141
|
-
* @param {string} boundary
|
|
142
|
-
*/
|
|
143
|
-
async function get_multipart(req, boundary) {
|
|
144
|
-
const text = await get_text(req);
|
|
145
|
-
const parts = text.split(`--${boundary}`);
|
|
146
|
-
|
|
147
|
-
const nope = () => {
|
|
148
|
-
throw new Error('Malformed form data');
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
if (parts[0] !== '' || parts[parts.length - 1].trim() !== '--') {
|
|
152
|
-
nope();
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const { data, append } = read_only_form_data();
|
|
156
|
-
|
|
157
|
-
parts.slice(1, -1).forEach((part) => {
|
|
158
|
-
const match = /\s*([\s\S]+?)\r\n\r\n([\s\S]*)\s*/.exec(part);
|
|
159
|
-
const raw_headers = match[1];
|
|
160
|
-
const body = match[2].trim();
|
|
161
|
-
|
|
162
|
-
let key;
|
|
163
|
-
raw_headers.split('\r\n').forEach((str) => {
|
|
164
|
-
const [raw_header, ...raw_directives] = str.split('; ');
|
|
165
|
-
let [name, value] = raw_header.split(': ');
|
|
166
|
-
|
|
167
|
-
name = name.toLowerCase();
|
|
168
|
-
|
|
169
|
-
/** @type {Record<string, string>} */
|
|
170
|
-
const directives = {};
|
|
171
|
-
raw_directives.forEach((raw_directive) => {
|
|
172
|
-
const [name, value] = raw_directive.split('=');
|
|
173
|
-
directives[name] = JSON.parse(value); // TODO is this right?
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
if (name === 'content-disposition') {
|
|
177
|
-
if (value !== 'form-data') nope();
|
|
178
|
-
|
|
179
|
-
if (directives.filename) {
|
|
180
|
-
// TODO we probably don't want to do this automatically
|
|
181
|
-
throw new Error('File upload is not yet implemented');
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (directives.name) {
|
|
185
|
-
key = directives.name;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
if (!key) nope();
|
|
191
|
-
|
|
192
|
-
append(key, body);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
return data;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* @param {import('http').IncomingMessage} req
|
|
200
|
-
* @returns {Promise<string>}
|
|
201
|
-
*/
|
|
202
|
-
function get_text(req) {
|
|
203
|
-
return new Promise((fulfil, reject) => {
|
|
204
|
-
let data = '';
|
|
205
|
-
|
|
206
|
-
req.on('error', reject);
|
|
207
|
-
|
|
208
|
-
req.on('data', (chunk) => {
|
|
209
|
-
data += chunk;
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
req.on('end', () => {
|
|
213
|
-
fulfil(data);
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* @param {import('http').IncomingMessage} req
|
|
220
|
-
* @returns {Promise<ArrayBuffer>}
|
|
221
|
-
*/
|
|
222
|
-
function get_buffer(req) {
|
|
223
|
-
return new Promise((fulfil, reject) => {
|
|
224
|
-
let data = new Uint8Array(0);
|
|
225
|
-
|
|
226
|
-
req.on('error', reject);
|
|
227
|
-
|
|
228
|
-
req.on('data', (chunk) => {
|
|
229
|
-
const new_data = new Uint8Array(data.length + chunk.length);
|
|
230
|
-
|
|
231
|
-
for (let i = 0; i < data.length; i += 1) {
|
|
232
|
-
new_data[i] = data[i];
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
for (let i = 0; i < chunk.length; i += 1) {
|
|
236
|
-
new_data[i + data.length] = chunk[i];
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
data = new_data;
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
req.on('end', () => {
|
|
243
|
-
fulfil(data.buffer);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const app = require('./server/app.js');
|
|
249
|
-
|
|
250
|
-
var index = async (req, res) => {
|
|
251
|
-
const { pathname, query = '' } = parse(req.url || '');
|
|
252
|
-
|
|
253
|
-
const rendered = await app.render({
|
|
254
|
-
method: req.method,
|
|
255
|
-
headers: req.headers,
|
|
256
|
-
path: pathname,
|
|
257
|
-
query: new URLSearchParams(query),
|
|
258
|
-
body: await get_body(req)
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
if (rendered) {
|
|
262
|
-
const { status, headers, body } = rendered;
|
|
263
|
-
return res.writeHead(status, headers).end(body);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return res.writeHead(404).end();
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
export default index;
|
|
270
|
-
//# sourceMappingURL=index.js.map
|
package/files/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../app-utils/http/get_body/read_only_form_data.js","../../app-utils/http/get_body/index.js","../src/index.js"],"sourcesContent":["export function read_only_form_data() {\n\t/** @type {Map<string, string[]>} */\n\tconst map = new Map();\n\n\treturn {\n\t\t/**\n\t\t * @param {string} key\n\t\t * @param {string} value\n\t\t */\n\t\tappend(key, value) {\n\t\t\tif (map.has(key)) {\n\t\t\t\tmap.get(key).push(value);\n\t\t\t} else {\n\t\t\t\tmap.set(key, [value]);\n\t\t\t}\n\t\t},\n\n\t\tdata: new ReadOnlyFormData(map)\n\t};\n}\n\nclass ReadOnlyFormData {\n\t/** @type {Map<string, string[]>} */\n\t#map;\n\n\t/** @param {Map<string, string[]>} map */\n\tconstructor(map) {\n\t\tthis.#map = map;\n\t}\n\n\t/** @param {string} key */\n\tget(key) {\n\t\tconst value = this.#map.get(key);\n\t\treturn value && value[0];\n\t}\n\n\t/** @param {string} key */\n\tgetAll(key) {\n\t\treturn this.#map.get(key);\n\t}\n\n\t/** @param {string} key */\n\thas(key) {\n\t\treturn this.#map.has(key);\n\t}\n\n\t*[Symbol.iterator]() {\n\t\tfor (const [key, value] of this.#map) {\n\t\t\tfor (let i = 0; i < value.length; i += 1) {\n\t\t\t\tyield [key, value[i]];\n\t\t\t}\n\t\t}\n\t}\n\n\t*entries() {\n\t\tfor (const [key, value] of this.#map) {\n\t\t\tfor (let i = 0; i < value.length; i += 1) {\n\t\t\t\tyield [key, value[i]];\n\t\t\t}\n\t\t}\n\t}\n\n\t*keys() {\n\t\tfor (const [key, value] of this.#map) {\n\t\t\tfor (let i = 0; i < value.length; i += 1) {\n\t\t\t\tyield key;\n\t\t\t}\n\t\t}\n\t}\n\n\t*values() {\n\t\tfor (const [, value] of this.#map) {\n\t\t\tfor (let i = 0; i < value.length; i += 1) {\n\t\t\t\tyield value;\n\t\t\t}\n\t\t}\n\t}\n}\n","import { read_only_form_data } from './read_only_form_data.js';\n\n/** @param {import('http').IncomingMessage} req */\nexport function get_body(req) {\n\tconst headers = req.headers;\n\tconst has_body =\n\t\theaders['content-type'] !== undefined &&\n\t\t// https://github.com/jshttp/type-is/blob/c1f4388c71c8a01f79934e68f630ca4a15fffcd6/index.js#L81-L95\n\t\t(headers['transfer-encoding'] !== undefined || !isNaN(Number(headers['content-length'])));\n\n\tif (!has_body) return Promise.resolve(undefined);\n\n\tconst [type, ...directives] = headers['content-type'].split(/;\\s*/);\n\n\tswitch (type) {\n\t\tcase 'application/octet-stream':\n\t\t\treturn get_buffer(req);\n\n\t\tcase 'text/plain':\n\t\t\treturn get_text(req);\n\n\t\tcase 'application/json':\n\t\t\treturn get_json(req);\n\n\t\tcase 'application/x-www-form-urlencoded':\n\t\t\treturn get_urlencoded(req);\n\n\t\tcase 'multipart/form-data': {\n\t\t\tconst boundary = directives.find((directive) => directive.startsWith('boundary='));\n\t\t\tif (!boundary) throw new Error('Missing boundary');\n\t\t\treturn get_multipart(req, boundary.slice('boundary='.length));\n\t\t}\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid Content-Type ${type}`);\n\t}\n}\n\n/** @param {import('http').IncomingMessage} req */\nasync function get_json(req) {\n\treturn JSON.parse(await get_text(req));\n}\n\n/** @param {import('http').IncomingMessage} req */\nasync function get_urlencoded(req) {\n\tconst text = await get_text(req);\n\n\tconst { data, append } = read_only_form_data();\n\n\ttext\n\t\t.replace(/\\+/g, ' ')\n\t\t.split('&')\n\t\t.forEach((str) => {\n\t\t\tconst [key, value] = str.split('=');\n\t\t\tappend(decodeURIComponent(key), decodeURIComponent(value));\n\t\t});\n\n\treturn data;\n}\n\n/**\n * @param {import('http').IncomingMessage} req\n * @param {string} boundary\n */\nasync function get_multipart(req, boundary) {\n\tconst text = await get_text(req);\n\tconst parts = text.split(`--${boundary}`);\n\n\tconst nope = () => {\n\t\tthrow new Error('Malformed form data');\n\t};\n\n\tif (parts[0] !== '' || parts[parts.length - 1].trim() !== '--') {\n\t\tnope();\n\t}\n\n\tconst { data, append } = read_only_form_data();\n\n\tparts.slice(1, -1).forEach((part) => {\n\t\tconst match = /\\s*([\\s\\S]+?)\\r\\n\\r\\n([\\s\\S]*)\\s*/.exec(part);\n\t\tconst raw_headers = match[1];\n\t\tconst body = match[2].trim();\n\n\t\tlet key;\n\n\t\t/** @type {Record<string, string>} */\n\t\tconst headers = {};\n\t\traw_headers.split('\\r\\n').forEach((str) => {\n\t\t\tconst [raw_header, ...raw_directives] = str.split('; ');\n\t\t\tlet [name, value] = raw_header.split(': ');\n\n\t\t\tname = name.toLowerCase();\n\t\t\theaders[name] = value;\n\n\t\t\t/** @type {Record<string, string>} */\n\t\t\tconst directives = {};\n\t\t\traw_directives.forEach((raw_directive) => {\n\t\t\t\tconst [name, value] = raw_directive.split('=');\n\t\t\t\tdirectives[name] = JSON.parse(value); // TODO is this right?\n\t\t\t});\n\n\t\t\tif (name === 'content-disposition') {\n\t\t\t\tif (value !== 'form-data') nope();\n\n\t\t\t\tif (directives.filename) {\n\t\t\t\t\t// TODO we probably don't want to do this automatically\n\t\t\t\t\tthrow new Error('File upload is not yet implemented');\n\t\t\t\t}\n\n\t\t\t\tif (directives.name) {\n\t\t\t\t\tkey = directives.name;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif (!key) nope();\n\n\t\tappend(key, body);\n\t});\n\n\treturn data;\n}\n\n/**\n * @param {import('http').IncomingMessage} req\n * @returns {Promise<string>}\n */\nfunction get_text(req) {\n\treturn new Promise((fulfil, reject) => {\n\t\tlet data = '';\n\n\t\treq.on('error', reject);\n\n\t\treq.on('data', (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\n\t\treq.on('end', () => {\n\t\t\tfulfil(data);\n\t\t});\n\t});\n}\n\n/**\n * @param {import('http').IncomingMessage} req\n * @returns {Promise<ArrayBuffer>}\n */\nfunction get_buffer(req) {\n\treturn new Promise((fulfil, reject) => {\n\t\tlet data = new Uint8Array(0);\n\n\t\treq.on('error', reject);\n\n\t\treq.on('data', (chunk) => {\n\t\t\tconst new_data = new Uint8Array(data.length + chunk.length);\n\n\t\t\tfor (let i = 0; i < data.length; i += 1) {\n\t\t\t\tnew_data[i] = data[i];\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < chunk.length; i += 1) {\n\t\t\t\tnew_data[i + data.length] = chunk[i];\n\t\t\t}\n\n\t\t\tdata = new_data;\n\t\t});\n\n\t\treq.on('end', () => {\n\t\t\tfulfil(data.buffer);\n\t\t});\n\t});\n}\n","import { parse, URLSearchParams } from 'url';\nimport { get_body } from '@sveltejs/app-utils/http';\n\nconst app = require('./server/app.js');\n\nexport default async (req, res) => {\n\tconst { pathname, query = '' } = parse(req.url || '');\n\n\tconst rendered = await app.render({\n\t\tmethod: req.method,\n\t\theaders: req.headers,\n\t\tpath: pathname,\n\t\tquery: new URLSearchParams(query),\n\t\tbody: await get_body(req)\n\t});\n\n\tif (rendered) {\n\t\tconst { status, headers, body } = rendered;\n\t\treturn res.writeHead(status, headers).end(body);\n\t}\n\n\treturn res.writeHead(404).end();\n};\n"],"names":[],"mappings":"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"}
|