Comparing version 0.1.5 to 0.1.6
@@ -1,5 +0,3 @@ | ||
// from https://github.com/sveltejs/kit/blob/master/packages/kit/src/node/index.js | ||
import { webcrypto as crypto } from 'node:crypto'; | ||
import { URLPattern } from 'urlpattern-polyfill/urlpattern'; | ||
// Credits to SvelteKit team | ||
// https://github.com/sveltejs/kit/blob/master/packages/kit/src/node/index.js | ||
/** @param {import('http').IncomingMessage} req */ | ||
@@ -92,3 +90,4 @@ function get_raw_body(req) { | ||
res.end(); | ||
} else { | ||
} | ||
else { | ||
next(); | ||
@@ -100,21 +99,6 @@ } | ||
next(); | ||
} else { | ||
} | ||
else { | ||
res.end(); | ||
} | ||
} | ||
const polyfills = { | ||
crypto, | ||
URLPattern, | ||
}; | ||
export function install_polyfills() { | ||
for (const [k, v] of Object.entries(polyfills)) { | ||
// eslint-disable-next-line no-undef | ||
Object.defineProperty(globalThis, k, { | ||
enumerable: true, | ||
configurable: true, | ||
value: v, | ||
}); | ||
} | ||
} |
{ | ||
"name": "edgekit", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"sideEffects": false, | ||
"type": "module", | ||
"sideEffects": false, | ||
"license": "MIT", | ||
"homepage": "https://edgekit.deno.dev", | ||
"engines": { | ||
"node": ">=18.0.0" | ||
"node": ">=20.0.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/alpineland/edgekit", | ||
"directory": "modules/edgekit" | ||
"url": "https://github.com/alpineland/edgekit" | ||
}, | ||
"files": [ | ||
"*", | ||
"**/*.js", | ||
"!**/_testdata", | ||
"!**/*.test.js", | ||
"!tsconfig.json" | ||
"!**/*.test.js" | ||
], | ||
"types": "./runtime/index.d.ts", | ||
"exports": { | ||
@@ -28,6 +25,2 @@ ".": { | ||
}, | ||
"./node": { | ||
"types": "./node/index.d.ts", | ||
"import": "./node/mod.js" | ||
}, | ||
"./vite": { | ||
@@ -39,4 +32,4 @@ "types": "./vite/index.d.ts", | ||
"dependencies": { | ||
"urlpattern-polyfill": "5.0.6" | ||
"devalue": "^4.3.2" | ||
} | ||
} |
@@ -1,7 +0,120 @@ | ||
export * from './csp.js'; | ||
export * from './hash.js'; | ||
export * as http_status from './http_status.js'; | ||
export * as http_status_text from './http_status_text.js'; | ||
export * from './respond.js'; | ||
export * from './client.js'; | ||
export * from './server.js'; | ||
import * as devalue from 'devalue'; | ||
import { _, build_id } from 'edgekit:metadata'; | ||
const BASE_URL = import.meta.env.BASE_URL.replace(/\/$/, ''); | ||
/** | ||
* Start the client side script to run either hydration or app mounting. This | ||
* function should be called in the entry file that will be run on the client | ||
* side. | ||
* | ||
* ```ts | ||
* // entry_client.ts | ||
* import { start_client } from 'edgekit'; | ||
* | ||
* start_client((target, hydrate) => { | ||
* new App({ target, hydrate }) | ||
* }) | ||
* ``` | ||
* | ||
* @param {import('./index').StartClientFn} fn | ||
*/ | ||
export function start_client(fn) { | ||
const el = document.getElementById(build_id); | ||
if (!el) throw new Error(`target element with id ${build_id} not found`); | ||
const tc = el.lastElementChild?.textContent; | ||
/** @type {[boolean, unknown]} */ | ||
const injected = tc ? devalue.parse(tc) : []; | ||
fn(el, ...injected); | ||
} | ||
/** | ||
* Render the complete HTML to be sent. | ||
* | ||
* @param {Object} options | ||
* @param {string} options.url Current request url | ||
* @param {string} [options.body] HTML body | ||
* @param {string | HTMLResult} [options.head] HTML head | ||
* @param {boolean} [options.csr] | ||
* @param {unknown} [options.data] Any fetched data | ||
*/ | ||
export function render_html({ | ||
url, | ||
body = '', | ||
head = '', | ||
csr = false, | ||
data = null, | ||
}) { | ||
const { entries, tmpl } = _; | ||
const prefix = import.meta.env.PROD | ||
? (new URL(url).pathname | ||
.slice(BASE_URL.length) | ||
.split('/') | ||
.slice(2) | ||
.map(() => '..') | ||
.join('/') + '' || '.') + '/' | ||
: ''; | ||
const js_scripts = entries.js.map((js) => | ||
`<script type="module" async src="${prefix}${js}"></script>` | ||
).join('\n'); | ||
const css_links = | ||
entries.css.map((css) => `<link rel="stylesheet" href="${prefix}${css}">`) | ||
.join('\n\t') + '\n'; | ||
const script = csr | ||
? js_scripts | ||
+ `<script type="application/json">` | ||
+ devalue.stringify([csr, data]) | ||
+ `</script>` | ||
: ''; | ||
// TODO: generate preload links | ||
body = `<div id="${build_id}">${body}${script}</div>`; | ||
if (typeof head === 'string') { | ||
return tmpl(body, css_links + head); | ||
} | ||
return tmpl( | ||
body, | ||
css_links + head.headTags, | ||
head.htmlAttrs, | ||
head.bodyAttrs, | ||
); | ||
} | ||
/** | ||
* Serialise the Content Security Policy Directives to be directly used as | ||
* header value. | ||
* | ||
* @param {import('./index').CSPDirectives} [csp] | ||
*/ | ||
export function serialise_csp(csp) { | ||
csp = { | ||
'default-src': [`'self'`], | ||
...csp, | ||
}; | ||
return Object.entries(csp) | ||
.filter(([, v]) => v !== undefined) | ||
.map(([k, v]) => `${k} ${v.join(' ')}`) | ||
.join('; '); | ||
} | ||
/** | ||
* Check if the requested url is for assets or not. | ||
* | ||
* @param {URL} url | ||
*/ | ||
export function is_assets_path(url) { | ||
return url.pathname.slice(BASE_URL.length).startsWith(`/${_.assets_dir}`); | ||
} | ||
/** | ||
* @typedef HTMLResult | ||
* @property {string} htmlAttrs | ||
* @property {string} bodyAttrs | ||
* @property {string} headTags | ||
*/ |
@@ -1,25 +0,19 @@ | ||
import { handler } from 'edgekit:entry-server'; | ||
import { manifest } from 'edgekit:manifest'; | ||
import * as path from 'https://deno.land/std@0.152.0/path/mod.ts'; | ||
import { serve } from 'https://deno.land/std@0.152.0/http/server.ts'; | ||
import { serveFile } from 'https://deno.land/std@0.152.0/http/file_server.ts'; | ||
import { is_assets_path } from 'edgekit'; | ||
import { handler } from 'edgekit:entry_server'; | ||
// @ts-expect-error This is Deno | ||
import * as path from 'https://deno.land/std@0.205.0/path/mod.ts'; | ||
// @ts-expect-error This is Deno | ||
import { serveFile } from 'https://deno.land/std@0.205.0/http/file_server.ts'; | ||
const _dirname = path.dirname(path.fromFileUrl(import.meta.url)); | ||
const dirname = path.dirname(path.fromFileUrl(import.meta.url)); | ||
serve((request, conn_info) => { | ||
const url = new URL(request.url); | ||
// @ts-expect-error This is Deno | ||
Deno.serve((req) => { | ||
const url = new URL(req.url); | ||
if (url.pathname.startsWith('/' + manifest.namespace)) { | ||
return serveFile( | ||
request, | ||
path.join( | ||
_dirname, | ||
'..', | ||
manifest.client_outdir, | ||
url.pathname.replace(/^\//, ''), | ||
), | ||
); | ||
if (is_assets_path(url)) { | ||
return serveFile(req, path.join(dirname, '..', url.pathname)); | ||
} | ||
return handler({ request, url, platform: { conn_info } }); | ||
return handler(req); | ||
}); |
@@ -7,6 +7,16 @@ import * as path from 'node:path'; | ||
/** @returns {import('vite').Plugin} */ | ||
/** | ||
* A Vite plugin for Deno Deploy. | ||
* | ||
* @returns {import('vite').Plugin} | ||
*/ | ||
export function edgekit_deno() { | ||
const name = 'edgekit:deno'; | ||
if (!process.env.DENO) { | ||
return { name }; | ||
} | ||
return { | ||
name: 'edgekit:deno', | ||
name, | ||
apply: is_server_build, | ||
@@ -17,3 +27,3 @@ | ||
build: { | ||
outDir: '.deno', | ||
outDir: 'dist/deno', | ||
rollupOptions: { | ||
@@ -28,2 +38,6 @@ input: { | ||
}, | ||
define: { | ||
// Deno has global `window` object | ||
'typeof window': '"undefined"', | ||
}, | ||
ssr: { | ||
@@ -30,0 +44,0 @@ noExternal: true, |
303
vite/mod.js
import * as fs from 'node:fs'; | ||
import * as path from 'node:path'; | ||
import { pathToFileURL } from 'node:url'; | ||
import { get_request, install_polyfills, set_response } from '../node/mod.js'; | ||
import { get_entry, mkdirp, stringify_manifest } from './utils.js'; | ||
import { get_request, set_response } from '../node/mod.js'; | ||
import { get_entry, mkdirp, stringify_metadata } from './utils.js'; | ||
/** @typedef {import('./index').PluginOptions} PluginOptions */ | ||
export { edgekit }; | ||
export { edgekit_deno } from './deno/vite_plugin.js'; | ||
export { edgekit_netlify } from './netlify/vite_plugin.js'; | ||
export { edgekit_vercel } from './vercel/vite_plugin.js'; | ||
const DOT_EDGEKIT = 'node_modules/.edgekit/'; | ||
const EDGEKIT_MANIFEST = DOT_EDGEKIT + 'manifest.mjs'; | ||
/** | ||
* @param {PluginOptions} [options] | ||
* @returns {import('vite').Plugin} | ||
*/ | ||
export function edgekit(options) { | ||
/** @type {Required<PluginOptions>} */ | ||
const opts = { | ||
entry_client: './app/entry-client', | ||
entry_server: './app/entry-server', | ||
...options, | ||
}; | ||
function edgekit() { | ||
/** @type {string} */ | ||
let entry_client_file; | ||
/** @type {string} */ | ||
let template; | ||
let entry_server_file; | ||
/** @type {string} */ | ||
let template = ''; | ||
/** @type {import('vite').ResolvedConfig} */ | ||
@@ -31,6 +29,6 @@ let vite_config; | ||
/** @type {string} */ | ||
let entry_client_filename; | ||
let dot_edgekit; | ||
/** @type {string} */ | ||
let entry_server_filename; | ||
let dot_edgekit_metadata; | ||
@@ -40,72 +38,58 @@ return { | ||
config({ build, root = process.cwd() }, { command }) { | ||
opts.entry_client = get_entry(path.resolve(root, opts.entry_client)); | ||
opts.entry_server = get_entry(path.resolve(root, opts.entry_server)); | ||
config({ build, root = process.cwd(), publicDir }, { command }) { | ||
entry_client_file = get_entry(path.resolve(root, 'src/entry_client')); | ||
entry_server_file = get_entry(path.resolve(root, 'src/entry_server')); | ||
dot_edgekit = path.join(root, `node_modules/.edgekit`); | ||
dot_edgekit_metadata = path.join(dot_edgekit, 'metadata.mjs'); | ||
if (command === 'build') { | ||
const ssr = !!build?.ssr; | ||
// respect user configured outDir | ||
const outDir = build?.outDir || ssr ? 'dist/node' : 'dist'; | ||
// respect user configured assetsDir | ||
const assetsDir = build?.assetsDir || '_edk'; | ||
const output = { | ||
entryFileNames: ssr | ||
? `[name].js` | ||
: path.posix.join(assetsDir, `[name]-[hash].js`), | ||
chunkFileNames: ssr | ||
? `chunks/[name].js` | ||
: path.posix.join(assetsDir, `c/[name]-[hash].js`), // c for chunks | ||
// this is required to set to match client/server assets build | ||
assetFileNames: path.posix.join(assetsDir, `a/[name]-[hash].[ext]`), // a for assets | ||
}; | ||
if (ssr) { | ||
entry_server_filename = path | ||
.basename(opts.entry_server) | ||
.replace(path.extname(opts.entry_server), ''); | ||
return { | ||
publicDir: false, | ||
build: { | ||
assetsDir, | ||
outDir: '.node', | ||
rollupOptions: { | ||
input: opts.entry_server, | ||
output, | ||
}, | ||
}, | ||
define: { | ||
'typeof window': '"undefined"', | ||
'typeof document': '"undefined"', | ||
}, | ||
resolve: { | ||
alias: { | ||
'edgekit:entry-server': opts.entry_server, | ||
'edgekit:manifest': path.resolve(root, EDGEKIT_MANIFEST), | ||
}, | ||
}, | ||
}; | ||
} else { | ||
entry_client_filename = path | ||
.basename(opts.entry_client) | ||
.replace(path.extname(opts.entry_client), ''); | ||
return { | ||
base: './', | ||
build: { | ||
assetsDir, | ||
rollupOptions: { | ||
input: { | ||
return { | ||
publicDir: ssr ? false : publicDir, | ||
build: { | ||
manifest: ssr ? false : '.vite/manifest.json', | ||
assetsDir, | ||
outDir, | ||
rollupOptions: { | ||
input: ssr | ||
? entry_server_file | ||
: { | ||
__edgekit_html__: 'index.html', | ||
[entry_client_filename]: opts.entry_client, | ||
entry_client: entry_client_file, | ||
}, | ||
output, | ||
onwarn(warning, warn) { | ||
if (!warning.message.includes('__edgekit_html__')) { | ||
warn(warning); | ||
} | ||
}, | ||
output: { | ||
entryFileNames: ssr | ||
? `[name].js` | ||
: path.posix.join(assetsDir, `[name]_[hash].js`), | ||
chunkFileNames: ssr | ||
? `chunks/[name].js` | ||
: path.posix.join(assetsDir, `c/[name]_[hash].js`), // c for chunks | ||
// this is required to set to match client/server assets build | ||
assetFileNames: path.posix.join( | ||
assetsDir, | ||
`a/[name]_[hash].[ext]`, // a for assets | ||
), | ||
}, | ||
}, | ||
}; | ||
} | ||
} else { | ||
}, | ||
resolve: { | ||
alias: ssr | ||
? { | ||
// resolve from fs when in SSR build | ||
'edgekit:entry_server': entry_server_file, | ||
'edgekit:metadata': dot_edgekit_metadata, | ||
} | ||
: undefined, | ||
}, | ||
}; | ||
} | ||
// DEV | ||
else { | ||
return { | ||
@@ -115,3 +99,3 @@ appType: 'custom', | ||
rollupOptions: { | ||
input: opts.entry_client, | ||
input: entry_client_file, | ||
}, | ||
@@ -135,7 +119,8 @@ }, | ||
configureServer(server) { | ||
install_polyfills(); | ||
return () => { | ||
server.middlewares.use(async (req, res) => { | ||
try { | ||
if (!req.url || !req.method) throw new Error('incomplete request'); | ||
if (!req.url) { | ||
throw new Error('incomplete request'); | ||
} | ||
@@ -154,12 +139,7 @@ const { config } = server; | ||
/** @type {import('edgekit').StartServerFn} */ | ||
const handler = (await server.ssrLoadModule(opts.entry_server)) | ||
.handler; | ||
const { handler } = | ||
/** @type {import('edgekit:entry_server')} */ (await server | ||
.ssrLoadModule(entry_server_file)); | ||
const resp = await handler({ | ||
request, | ||
url: new URL(request.url), | ||
seg: {}, | ||
platform: {}, | ||
}); | ||
const resp = await handler(request); | ||
@@ -169,3 +149,4 @@ if (resp) { | ||
} | ||
} catch (/** @type {any} */ e) { | ||
} | ||
catch (/** @type {any} */ e) { | ||
server.ssrFixStacktrace(e); | ||
@@ -180,13 +161,14 @@ res.statusCode = 500; | ||
async configurePreviewServer(server) { | ||
install_polyfills(); | ||
const { server_main } = await import( | ||
pathToFileURL(path.resolve(vite_config.root, EDGEKIT_MANIFEST)).href | ||
const { entry_server_fp } = await import( | ||
pathToFileURL(dot_edgekit_metadata).href | ||
); | ||
const { handler } = await import(pathToFileURL(server_main).href); | ||
const { handler } = | ||
/** @type {import('edgekit:entry_server')} */ (await import( | ||
pathToFileURL(entry_server_fp).href | ||
)); | ||
return () => { | ||
server.middlewares.use(async (req, res) => { | ||
try { | ||
if (!req.url || !req.method) throw new Error('incomplete request'); | ||
const protocol = vite_config.preview.https ? 'https' : 'http'; | ||
@@ -196,8 +178,3 @@ const origin = protocol + '://' + req.headers.host; | ||
const request = get_request(origin, req); | ||
const resp = await handler({ | ||
request, | ||
url: new URL(request.url), | ||
seg: {}, | ||
platform: {}, | ||
}); | ||
const resp = await handler(request); | ||
@@ -207,3 +184,4 @@ if (resp) { | ||
} | ||
} catch (/** @type {any} */ e) { | ||
} | ||
catch (/** @type {any} */ e) { | ||
res.statusCode = e.status || 400; | ||
@@ -217,3 +195,4 @@ res.end(e.reason || 'invalid requst body'); | ||
resolveId(id) { | ||
if (vite_config.command === 'serve' && id === 'edgekit:manifest') { | ||
// Exclude EdgeKit virtual modules in SSR build | ||
if (!vite_config.build.ssr && id === 'edgekit:metadata') { | ||
return '\0' + id; | ||
@@ -224,9 +203,8 @@ } | ||
load(id) { | ||
if (vite_config.command === 'serve' && id === '\0' + 'edgekit:manifest') { | ||
return stringify_manifest( | ||
// Exclude EdgeKit virtual modules in SSR build | ||
if (!vite_config.build.ssr && id === '\0' + 'edgekit:metadata') { | ||
return stringify_metadata({ | ||
entries: { js: [entry_client_file], css: [] }, | ||
template, | ||
vite_config.build.assetsDir, | ||
opts.entry_client, | ||
vite_config.build.outDir, | ||
); | ||
}); | ||
} | ||
@@ -238,46 +216,73 @@ }, | ||
handler(_, bundle) { | ||
mkdirp(path.resolve(vite_config.root, DOT_EDGEKIT)); | ||
if (!vite_config.build.ssr) { | ||
for (const k in bundle) { | ||
const chunk = bundle[k]; | ||
if (chunk.type === 'asset' && chunk.fileName === 'index.html') { | ||
template = /** @type {string} */ (chunk.source); | ||
delete bundle[k]; // remove index.html file | ||
} | ||
} | ||
} | ||
}, | ||
}, | ||
writeBundle(_, bundle) { | ||
mkdirp(dot_edgekit); | ||
if (vite_config.build.ssr) { | ||
for (const k in bundle) { | ||
const val = bundle[k]; | ||
const chunk = bundle[k]; | ||
if (vite_config.build.ssr) { | ||
if (val.name === entry_server_filename) { | ||
fs.appendFileSync( | ||
path.resolve(vite_config.root, EDGEKIT_MANIFEST), | ||
`\nexport const server_main = ${JSON.stringify( | ||
if (chunk.name === 'entry_server') { | ||
fs.appendFileSync( | ||
dot_edgekit_metadata, | ||
`export const entry_server_fp = ${ | ||
JSON.stringify( | ||
path.resolve( | ||
vite_config.root, | ||
vite_config.build.outDir, | ||
val.fileName, | ||
chunk.fileName, | ||
), | ||
)};`, | ||
'utf-8', | ||
); | ||
} | ||
} else { | ||
if (val.name === entry_client_filename) { | ||
entry_client_filename = val.fileName; | ||
} | ||
if (val.type === 'asset' && val.fileName === 'index.html') { | ||
template = /** @type {string} */ (val.source); | ||
delete bundle[k]; | ||
} | ||
) | ||
};\n`, | ||
'utf-8', | ||
); | ||
} | ||
} | ||
if (!vite_config.build.ssr) { | ||
fs.writeFileSync( | ||
path.resolve(vite_config.root, EDGEKIT_MANIFEST), | ||
stringify_manifest( | ||
template, | ||
vite_config.build.assetsDir, | ||
entry_client_filename, | ||
} | ||
else { | ||
const manifest = /** @type {ViteManifestChunk[]} */ (Object.values( | ||
JSON.parse(fs.readFileSync( | ||
path.join( | ||
vite_config.build.outDir, | ||
/** @type {string} */ (vite_config.build.manifest), | ||
), | ||
'utf-8', | ||
); | ||
)), | ||
)); | ||
const entries = { | ||
js: /** @type {string[]} */ ([]), | ||
css: /** @type {string[]} */ ([]), | ||
}; | ||
for (const entry of manifest) { | ||
if (entry.isEntry) { | ||
entries.js.push(entry.file); | ||
if (entry.css?.length) { | ||
entries.css.push(...entry.css); | ||
} | ||
} | ||
} | ||
}, | ||
fs.writeFileSync( | ||
dot_edgekit_metadata, | ||
stringify_metadata({ | ||
assets_dir: vite_config.build.assetsDir, | ||
entries, | ||
template, | ||
}), | ||
'utf-8', | ||
); | ||
} | ||
}, | ||
@@ -287,4 +292,12 @@ }; | ||
export { edgekit_deno } from './deno/vite_plugin.js'; | ||
export { edgekit_netlify } from './netlify/vite_plugin.js'; | ||
export { edgekit_vercel } from './vercel/vite_plugin.js'; | ||
/** | ||
* @typedef ViteManifestChunk | ||
* @property {string} [src] | ||
* @property {string} file | ||
* @property {string[]} [css] | ||
* @property {string[]} [assets] | ||
* @property {boolean} [isEntry] | ||
* @property {boolean} [isDynamicEntry] | ||
* @property {string[]} [imports] | ||
* @property {string[]} [dynamicImports] | ||
*/ |
@@ -1,12 +0,16 @@ | ||
import { handler } from 'edgekit:entry-server'; | ||
import { manifest } from 'edgekit:manifest'; | ||
import { is_assets_path } from 'edgekit'; | ||
import { handler } from 'edgekit:entry_server'; | ||
export default async function (request, context) { | ||
/** | ||
* @param {Request} request | ||
* @param {import('@netlify/edge-functions').Context} context | ||
*/ | ||
export default async function(request, context) { | ||
const url = new URL(request.url); | ||
if (url.pathname.startsWith('/' + manifest.namespace)) { | ||
if (is_assets_path(url)) { | ||
return context.next(); | ||
} | ||
return await handler({ request, url, platform: { context } }); | ||
return handler(request); | ||
} |
@@ -18,6 +18,16 @@ import * as path from 'node:path'; | ||
/** @returns {import('vite').Plugin} */ | ||
/** | ||
* A Vite plugin that outputs Netlify Edge Functions. | ||
* | ||
* @returns {import('vite').Plugin} | ||
*/ | ||
export function edgekit_netlify() { | ||
const name = 'edgekit:netlify'; | ||
if (!process.env.NETLIFY) { | ||
return { name }; | ||
} | ||
return { | ||
name: 'edgekit:netlify', | ||
name, | ||
apply: is_server_build, | ||
@@ -24,0 +34,0 @@ |
import * as fs from 'node:fs'; | ||
import * as path from 'node:path'; | ||
const s = JSON.stringify; | ||
const BUILD_ID = crypto.randomUUID().slice(0, 8); | ||
const tmpl = (body = '', head = '', html_attrs = '', body_attrs = '') => | ||
// @ts-expect-error tp is provided via virtual module during dev and | ||
// from transformed index.html at build time. | ||
tp | ||
export { get_entry, is_server_build, mkdirp, stringify_metadata }; | ||
function stringify_metadata({ | ||
assets_dir = '', | ||
template = '', | ||
entries = { | ||
js: /** @type {string[]} */ ([]), | ||
css: /** @type {string[]} */ ([]), | ||
}, | ||
} = {}) { | ||
return ( | ||
`export const build_id = ${s(BUILD_ID)};\n` | ||
+ `const t = ${s(template)};\n` | ||
+ `export const _ = { | ||
assets_dir: ${s(assets_dir)}, | ||
entries: ${s(entries)}, | ||
tmpl: ${tmpl}, | ||
};\n` | ||
); | ||
} | ||
function tmpl(body = '', head = '', html_attrs = '', body_attrs = '') { | ||
// @ts-expect-error This `t` is from above metadata. | ||
return /** @type {string} */ (t) | ||
.replace('<html', '<html ' + html_attrs) | ||
@@ -14,19 +34,2 @@ .replace('<body', '<body ' + body_attrs) | ||
.replace('</body>', body + '</body>'); | ||
/** | ||
* @param {string} template | ||
* @param {string} namespace | ||
* @param {string} ec | ||
* @param {string} client_outdir | ||
*/ | ||
export function stringify_manifest(template, namespace, ec, client_outdir) { | ||
return ( | ||
`const tp = ${s(template)};\n` + | ||
`export const manifest = { | ||
namespace: ${s(namespace)}, | ||
client_outdir: ${s(client_outdir)}, | ||
_ec: ${s(ec)}, | ||
_tmpl: ${tmpl}, | ||
};` | ||
); | ||
} | ||
@@ -38,3 +41,3 @@ | ||
*/ | ||
export function get_entry(entry, exts = ['.js', '.ts']) { | ||
function get_entry(entry, exts = ['.js', '.ts']) { | ||
for (const ext of exts) { | ||
@@ -55,20 +58,8 @@ if (entry.endsWith(ext)) { | ||
/** @param {string} input */ | ||
export function make_rollup_input(input) { | ||
const basename = path.basename(input); | ||
if (basename.endsWith('.js') || basename.endsWith('.ts')) { | ||
return { | ||
[basename.replace(path.extname(input), '')]: input, | ||
}; | ||
} | ||
return { | ||
[basename]: get_entry(input), | ||
}; | ||
} | ||
/** @param {string} dir */ | ||
export function mkdirp(dir) { | ||
function mkdirp(dir) { | ||
try { | ||
fs.mkdirSync(dir, { recursive: true }); | ||
} catch (/** @type {any} */ e) { | ||
} | ||
catch (/** @type {any} */ e) { | ||
if (e.code === 'EEXIST') return; | ||
@@ -83,4 +74,4 @@ throw e; | ||
*/ | ||
export function is_server_build({ build }, { command }) { | ||
function is_server_build({ build }, { command }) { | ||
return !!build?.ssr && command === 'build'; | ||
} |
@@ -1,6 +0,3 @@ | ||
import { handler } from 'edgekit:entry-server'; | ||
import { handler } from 'edgekit:entry_server'; | ||
export default async function (request) { | ||
const url = new URL(request.url); | ||
return await handler({ request, url }); | ||
} | ||
export default handler; |
@@ -6,8 +6,7 @@ import * as path from 'node:path'; | ||
const VC_CONFIG = { | ||
runtime: 'edge', | ||
entrypoint: 'main.js', | ||
}; | ||
/** @returns {import('vite').Plugin} */ | ||
/** | ||
* A Vite plugin that outputs according to [Vercel Build Output API (v3)](https://vercel.com/docs/build-output-api/v3). | ||
* | ||
* @returns {import('vite').Plugin} | ||
*/ | ||
export function edgekit_vercel() { | ||
@@ -17,4 +16,10 @@ /** @type {import('vite').ResolvedConfig} */ | ||
const name = 'edgekit:vercel'; | ||
if (!process.env.VERCEL) { | ||
return { name }; | ||
} | ||
return { | ||
name: 'edgekit:vercel', | ||
name, | ||
apply: 'build', | ||
@@ -32,9 +37,9 @@ | ||
? { | ||
'functions/main.func/main': path.resolve(_dirname, 'edge.js'), | ||
} | ||
'functions/main.func/main': path.resolve(_dirname, 'edge.js'), | ||
} | ||
: undefined, | ||
output: ssr | ||
? { | ||
inlineDynamicImports: true, | ||
} | ||
inlineDynamicImports: true, | ||
} | ||
: undefined, | ||
@@ -56,2 +61,3 @@ }, | ||
if (vite_config.build.ssr) { | ||
// https://vercel.com/docs/build-output-api/v3/configuration | ||
this.emitFile({ | ||
@@ -85,3 +91,10 @@ type: 'asset', | ||
fileName: 'functions/main.func/.vc-config.json', | ||
source: JSON.stringify(VC_CONFIG, null, '\t'), | ||
source: JSON.stringify( | ||
{ | ||
runtime: 'edge', | ||
entrypoint: 'main.js', | ||
}, | ||
null, | ||
'\t', | ||
), | ||
}); | ||
@@ -88,0 +101,0 @@ } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
19998
12
720
3
+ Addeddevalue@^4.3.2
+ Addeddevalue@4.3.3(transitive)
- Removedurlpattern-polyfill@5.0.6
- Removedurlpattern-polyfill@5.0.6(transitive)