-
Notifications
You must be signed in to change notification settings - Fork 0
/
extension.ts
79 lines (71 loc) · 2.39 KB
/
extension.ts
1
2
3
4
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/// <reference types="node" />
import type { Plugin, ResolvedConfig } from 'vite';
import { join } from 'path';
import { cp, mkdir, readFile, rm, writeFile } from 'fs/promises';
import { existsSync } from 'fs';
const NAME = 'extension';
export function extension(): Plugin {
if (!process.env.EXTENSION_ORIGIN) return { name: 'extension' };
const origin = process.env.EXTENSION_ORIGIN;
let config!: ResolvedConfig;
let transformed = false;
return {
name: 'extension',
configResolved(c) {
config = c;
},
transform: {
order: 'pre',
handler(code, id) {
if (transformed) return;
if (!id.endsWith(`src/routes/${NAME}/+page.svelte`)) return;
transformed = true;
const match = code.match(/^[\s\t]*const\s+endpoint\s*=\s*'(.+?)';?/m);
if (!match?.index) return;
const processed =
code.slice(0, match.index) +
`const endpoint = '${new URL(match[1], origin)}';` +
code.slice(match.index + match[0].length);
return processed;
}
},
closeBundle: {
order: 'post',
async handler() {
const output = join(config.root, '.svelte-kit', 'output');
const pages = join(output, 'prerendered', 'pages');
if (!existsSync(pages)) return;
const destination = join(config.root, '.svelte-kit', 'extension');
const [html] = await Promise.all([
await readFile(join(pages, `${NAME}.html`), 'utf-8'),
reset(destination)
]);
const match = html.match(/<script>([\s\S]+?)<\/script>/);
if (match?.index) {
const script = match[1]
.replace('__sveltekit', 'const __sveltekit')
.replace('document.currentScript.parentElement', 'document.body.firstElementChild');
const processed =
html.slice(0, match.index) +
`<script type="module" src="${NAME}.js"></script>` +
html.slice(match.index + match[0].length);
await Promise.all([
writeFile(join(destination, `${NAME}.html`), processed),
writeFile(join(destination, `${NAME}.js`), script),
cp(join(output, 'client'), destination, { recursive: true }),
cp(join(config.root, 'manifest.json'), join(destination, 'manifest.json'))
]);
} else {
await Promise.all([
writeFile(join(destination, `${NAME}.html`), html),
cp(join(output, 'client'), destination, { recursive: true })
]);
}
}
}
};
}
async function reset(path: string) {
if (existsSync(path)) await rm(path, { recursive: true });
await mkdir(path);
}