New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

edgekit

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

edgekit - npm Package Compare versions

Comparing version 0.1.5 to 0.1.6

28

node/mod.js

@@ -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,

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 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc