|
1 | 1 | import { join } from 'path'
|
2 |
| -import { writeFileSync, readFileSync } from 'fs' |
| 2 | +import { writeFileSync, readFileSync, existsSync } from 'fs' |
3 | 3 | import sjcl from 'sjcl'
|
4 | 4 | import cheerio from 'cheerio'
|
| 5 | +import { applyToDefaults } from '@hapi/hoek' |
5 | 6 |
|
6 |
| -/** @type {import('.')} */ |
7 |
| -export default function ({ pages = 'build', assets = pages, fallback } = {}) { |
8 |
| - function generate_manifest (html) { |
9 |
| - return JSON.stringify({ |
10 |
| - browser_action: { |
11 |
| - default_title: 'SvelteKit', |
12 |
| - default_popup: 'index.html' |
13 |
| - }, |
14 |
| - content_security_policy: generate_csp(html), |
15 |
| - manifest_version: 2, |
16 |
| - name: 'TODO', |
17 |
| - version: '0.1' |
18 |
| - }) |
19 |
| - }; |
20 |
| - |
21 |
| - function hash_script (s) { |
22 |
| - const hashed = sjcl.hash.sha256.hash(s); |
23 |
| - return sjcl.codec.base64.fromBits(hashed); |
| 7 | +const manifest_filename = 'manifest.json' |
| 8 | + |
| 9 | +function hash_script (s) { |
| 10 | + const hashed = sjcl.hash.sha256.hash(s); |
| 11 | + return sjcl.codec.base64.fromBits(hashed); |
| 12 | +} |
| 13 | + |
| 14 | +function generate_csp (html) { |
| 15 | + const $ = cheerio.load(html) |
| 16 | + const csp_hashes = $('script[type="module"]') |
| 17 | + .map((i, el) => hash_script($(el).get()[0].children[0].data)) |
| 18 | + .toArray() |
| 19 | + .map(h => `'sha256-${h}'`) |
| 20 | + .join(' ') |
| 21 | + return `script-src 'self' ${csp_hashes}; object-src 'self'` |
| 22 | +} |
| 23 | + |
| 24 | +function generate_manifest (html) { |
| 25 | + return { |
| 26 | + browser_action: { |
| 27 | + default_title: 'SvelteKit', |
| 28 | + default_popup: 'index.html' |
| 29 | + }, |
| 30 | + content_security_policy: generate_csp(html), |
| 31 | + manifest_version: 2, |
| 32 | + name: 'TODO', |
| 33 | + version: '0.1' |
24 | 34 | }
|
| 35 | +} |
25 | 36 |
|
26 |
| - function generate_csp (html) { |
27 |
| - const $ = cheerio.load(html) |
28 |
| - const csp_hashes = $('script[type="module"]') |
29 |
| - .map((i, el) => hash_script($(el).get()[0].children[0].data)) |
30 |
| - .toArray() |
31 |
| - .map(h => `'sha256-${h}'`) |
32 |
| - .join(' ') |
33 |
| - return `script-src 'self' ${csp_hashes}; object-src 'self'` |
| 37 | +function load_manifest () { |
| 38 | + if (existsSync(manifest_filename)) { |
| 39 | + return JSON.parse(readFileSync(manifest_filename, 'utf-8')) |
34 | 40 | }
|
35 | 41 |
|
| 42 | + return {} |
| 43 | +} |
| 44 | + |
| 45 | +/** @type {import('.')} */ |
| 46 | +export default function ({ pages = 'build', assets = pages, fallback } = {}) { |
36 | 47 | return {
|
37 | 48 | name: 'sveltekit-adapter-browser-extension',
|
38 | 49 |
|
39 | 50 | async adapt({ utils }) {
|
| 51 | + const provided_manifest = load_manifest() |
| 52 | + |
40 | 53 | utils.rimraf(assets)
|
41 | 54 | utils.rimraf(pages)
|
42 | 55 |
|
43 |
| - utils.copy_static_files(assets); |
44 |
| - utils.copy_client_files(assets); |
| 56 | + utils.copy_static_files(assets) |
| 57 | + utils.copy_client_files(assets) |
45 | 58 |
|
46 | 59 | await utils.prerender({
|
47 | 60 | fallback,
|
48 | 61 | all: !fallback,
|
49 | 62 | dest: pages
|
50 | 63 | })
|
51 | 64 |
|
52 |
| - const indexPage = join(assets, 'index.html') |
53 |
| - const index = readFileSync(indexPage) |
| 65 | + const index_page = join(assets, 'index.html') |
| 66 | + const index = readFileSync(index_page) |
| 67 | + |
| 68 | + const generated_manifest = generate_manifest(index.toString()) |
| 69 | + const merged_manifest = applyToDefaults(generated_manifest, provided_manifest, { nullOverride: true }) |
54 | 70 |
|
55 |
| - writeFileSync(join(assets, 'manifest.json'), generate_manifest(index.toString())) |
| 71 | + writeFileSync(join(assets, manifest_filename), JSON.stringify(merged_manifest)) |
56 | 72 | utils.rimraf(join(assets, '_app'))
|
57 | 73 | }
|
58 | 74 | }
|
|
0 commit comments