', 'the output filename', 'dist/worker.js')
- .option('-w, --watch', 'enable watch mode', false)
- .action((main, command) => {
- loadEnv();
- currentCommand = new BuildCommand({
- entry: main[0],
- outFile: command.outFile,
- watch: command.watch
- });
- currentCommand.execute();
- });
-
-program
- .command('info')
- .description('Prints debugging information about the local environment')
- .action(function () {
- console.log(chalk.bold('\nEnvironment Info:'));
- envinfo
- .run({
- System: ['OS', 'CPU'],
- Binaries: ['Node', 'Yarn', 'npm'],
- Browsers: ['Chrome', 'Edge', 'Firefox', 'Safari'],
- npmPackages: ['@cfworker/dev'],
- npmGlobalPackages: ['@cfworker/dev']
- })
- .then(console.log);
- });
-
-program
- .command('help [command]')
- .description('display help information for a command')
- .action(command => {
- const cmd =
- commands.find(
- c => typeof c.name === 'function' && c.name() === command
- ) || program;
- cmd.help();
- });
-
-program.on('--help', function () {
- console.log('');
- console.log(
- ' Run `' +
- chalk.bold('cfworker help ') +
- '` for more information on specific commands'
- );
- console.log('');
-});
-
-// // Make test the default command except for --help
-// var args = process.argv;
-// if (args[2] === '--help' || args[2] === '-h') args[2] = 'help';
-// if (!args[2] || !commands.some(c => c.name() === args[2])) {
-// args.splice(2, 0, 'test');
-// }
-
-program.parse(process.argv);
diff --git a/packages/dev/src/cli/deploy-command.js b/packages/dev/src/cli/deploy-command.js
deleted file mode 100644
index f32b0b52..00000000
--- a/packages/dev/src/cli/deploy-command.js
+++ /dev/null
@@ -1,191 +0,0 @@
-import chalk from 'chalk';
-import { Bundler } from '../bundler.js';
-import {
- deploy,
- deployToWorkersDev,
- getWorkersDevSubdomain
-} from '../cloudflare-api.js';
-import { KV } from '../kv.js';
-import { logger } from '../logger.js';
-import { StaticSite } from '../static-site.js';
-
-export class DeployDevCommand {
- /**
- * @param {{ project: string; entry: string; watch: boolean; site?: string; kv: string[]; }} args
- */
- constructor(args) {
- const {
- CLOUDFLARE_EMAIL,
- CLOUDFLARE_ACCOUNT_ID,
- CLOUDFLARE_API_KEY,
- CLOUDFLARE_WORKERS_DEV_PROJECT = args.project
- } = process.env;
-
- if (!CLOUDFLARE_API_KEY) {
- throw new Error(
- 'CLOUDFLARE_API_KEY environment variable is not defined.'
- );
- }
-
- /** XXX - if email is not specified then CLOUDFLARE_API_KEY must be an API token
- if (!CLOUDFLARE_EMAIL) {
- throw new Error('CLOUDFLARE_EMAIL environment variable is not defined.');
- }
-*/
-
- if (!CLOUDFLARE_ACCOUNT_ID) {
- throw new Error(
- 'CLOUDFLARE_ACCOUNT_ID environment variable is not defined.'
- );
- }
-
- this.accountEmail = CLOUDFLARE_EMAIL;
- this.accountId = CLOUDFLARE_ACCOUNT_ID;
- this.apiKey = CLOUDFLARE_API_KEY;
- this.project = CLOUDFLARE_WORKERS_DEV_PROJECT;
- this.watch = args.watch;
- this.bundler = new Bundler([args.entry], args.watch);
- this.site = args.site ? new StaticSite(args.site, false) : null;
- this.kv = new KV(args.kv, false);
- }
-
- async execute() {
- await Promise.all([
- this.bundler.bundle(),
- this.site ? this.site.init() : Promise.resolve(),
- this.kv.init()
- ]);
-
- logger.progress('Getting subdomain...');
- const subdomain = await getWorkersDevSubdomain(
- this.accountId,
- this.apiKey,
- this.accountEmail
- );
- const url = `https://${this.project}.${subdomain}.workers.dev`;
-
- if (this.watch) {
- const update = () => this.deploy(url);
- this.bundler.on('bundle-end', update);
- if (this.site) {
- this.site.on('change', update);
- }
- }
-
- await this.deploy(url);
- }
-
- /**
- * @param {string} url
- */
- async deploy(url) {
- const startTime = Date.now();
- logger.progress(`Deploying worker...`);
-
- await deployToWorkersDev({
- code: this.bundler.code,
- accountEmail: this.accountEmail,
- accountId: this.accountId,
- apiKey: this.apiKey,
- name: this.project,
- site: this.site,
- kv: this.kv
- });
-
- logger.success(
- `Deployed worker to ${chalk.cyan.underline(url)}`,
- Date.now() - startTime
- );
- }
-
- dispose() {
- this.bundler.dispose();
- if (this.site) {
- this.site.dispose();
- }
- this.kv.dispose();
- }
-}
-
-export class DeployCommand {
- /**
- * @param {{ entry: string; name: string; route: string; purgeCache: boolean; site?: string; kv: string[]; }} args
- */
- constructor(args) {
- const {
- CLOUDFLARE_EMAIL,
- CLOUDFLARE_ACCOUNT_ID,
- CLOUDFLARE_API_KEY,
- CLOUDFLARE_ZONE_ID
- } = process.env;
-
- /** XXX
- if (!CLOUDFLARE_EMAIL) {
- throw new Error('CLOUDFLARE_EMAIL environment variable is not defined.');
- }
-*/
- if (!CLOUDFLARE_ACCOUNT_ID) {
- throw new Error(
- 'CLOUDFLARE_ACCOUNT_ID environment variable is not defined.'
- );
- }
- if (!CLOUDFLARE_API_KEY) {
- throw new Error(
- 'CLOUDFLARE_API_KEY environment variable is not defined.'
- );
- }
- if (!CLOUDFLARE_ZONE_ID) {
- throw new Error(
- 'CLOUDFLARE_ZONE_ID environment variable is not defined.'
- );
- }
-
- this.accountEmail = CLOUDFLARE_EMAIL;
- this.accountId = CLOUDFLARE_ACCOUNT_ID;
- this.apiKey = CLOUDFLARE_API_KEY;
- this.zoneId = CLOUDFLARE_ZONE_ID;
- this.args = args;
- this.bundler = new Bundler([args.entry], false);
- this.site = args.site ? new StaticSite(args.site, false) : null;
- this.kv = new KV(args.kv, false);
- }
-
- async execute() {
- const startTime = Date.now();
-
- await Promise.all([
- this.bundler.bundle(),
- this.site ? this.site.init() : Promise.resolve(),
- this.kv.init()
- ]);
-
- logger.progress('Deploying worker...');
-
- const zoneName = await deploy({
- name: this.args.name,
- code: this.bundler.code,
- accountId: this.accountId,
- accountEmail: this.accountEmail,
- zoneId: this.zoneId,
- apiKey: this.apiKey,
- purgeCache: this.args.purgeCache,
- routePattern: this.args.route,
- site: this.site,
- kv: this.kv
- });
-
- const url = 'https://' + (this.args.route ? this.args.route : zoneName);
- logger.success(
- `Deployed worker to ${chalk.cyan.underline(url)}`,
- Date.now() - startTime
- );
- }
-
- dispose() {
- this.bundler.dispose();
- if (this.site) {
- this.site.dispose();
- }
- this.kv.dispose();
- }
-}
diff --git a/packages/dev/src/cli/index.js b/packages/dev/src/cli/index.js
deleted file mode 100755
index f8f7ebe6..00000000
--- a/packages/dev/src/cli/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-':' //# comment; exec /usr/bin/env node --experimental-json-modules --no-warnings "$0" "$@"
-
-import './commands.js';
diff --git a/packages/dev/src/cli/run-command.js b/packages/dev/src/cli/run-command.js
deleted file mode 100644
index d9937c15..00000000
--- a/packages/dev/src/cli/run-command.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import chalk from 'chalk';
-import { Bundler } from '../bundler.js';
-import { KV } from '../kv.js';
-import { logger } from '../logger.js';
-import { StaticSite } from '../static-site.js';
-import { WorkerHost } from '../worker-host.js';
-
-/**
- * @typedef {object} RunCommandArgs
- * @property {string} entry
- * @property {number} port
- * @property {boolean} watch
- * @property {boolean} inspect
- * @property {boolean} check
- * @property {string} [site]
- * @property {string[]} kv
- */
-
-/**
- * Bundle and run a worker script
- */
-export class RunCommand {
- /**
- * @param {RunCommandArgs} args
- */
- constructor(args) {
- this.args = args;
- this.bundler = new Bundler([args.entry], args.watch, [], args.check);
- this.site = args.site ? new StaticSite(args.site, args.watch) : null;
- this.kv = new KV(args.kv, args.watch);
- this.host = new WorkerHost(args.port, args.inspect, this.site, this.kv);
- }
-
- async execute() {
- const startTime = Date.now();
-
- if (!this.args.watch) {
- this.bundler.on('bundle-error', () => process.exit(1));
- if (!this.args.inspect) {
- this.host.on('worker-error', () => process.exit(1));
- }
- }
-
- this.bundler.bundle();
- const siteInitialized = this.site ? this.site.init() : Promise.resolve();
-
- await Promise.all([
- this.host.start(),
- this.bundler.bundled,
- siteInitialized,
- this.kv.init()
- ]);
-
- await this.host.setWorkerCode(
- this.bundler.code,
- '/worker.js',
- [],
- this.site ? this.site.manifest : null,
- this.kv.namespaces
- );
-
- if (this.args.watch) {
- const update = () =>
- this.host.setWorkerCode(
- this.bundler.code,
- '/worker.js',
- [],
- this.site ? this.site.manifest : null,
- this.kv.namespaces
- );
- this.bundler.on('bundle-end', update);
- if (this.site) {
- this.site.on('change', update);
- }
- this.kv.on('change', update);
- }
-
- const url = `http://localhost:${this.args.port}/`;
- logger.success(
- `Worker running at ${chalk.cyan.underline(url)}`,
- Date.now() - startTime
- );
-
- const page = await this.host.pageReady;
- await page.evaluate(url => {
- document.body.innerHTML = `
- Worker Dev
- Worker running at ${url}.
`;
- }, url);
- }
-
- dispose() {
- this.bundler.dispose();
- this.host.dispose();
- if (this.site) {
- this.site.dispose();
- }
- this.kv.dispose();
- }
-}
diff --git a/packages/dev/src/cli/test-command.js b/packages/dev/src/cli/test-command.js
deleted file mode 100644
index fe22adc3..00000000
--- a/packages/dev/src/cli/test-command.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import { Bundler } from '../bundler.js';
-import { KV } from '../kv.js';
-import { StaticSite } from '../static-site.js';
-import { TestHost } from '../test-host.js';
-
-/**
- * @typedef {object} TestCommandArgs
- * @property {string[]} globs
- * @property {number} port
- * @property {boolean} watch
- * @property {boolean} inspect
- * @property {boolean} check
- * @property {string} [site]
- * @property {string[]} kv
- */
-
-export class TestCommand {
- /**
- * @param {TestCommandArgs} args
- */
- constructor(args) {
- this.args = args;
- const treeshake = false;
- this.bundler = new Bundler(
- args.globs,
- args.watch,
- ['mocha', 'chai'],
- args.check,
- treeshake
- );
- this.site = args.site ? new StaticSite(args.site, args.watch) : null;
- this.kv = new KV(args.kv, args.watch);
- this.testHost = new TestHost(args.port, args.inspect, this.site, this.kv);
- }
-
- async execute() {
- if (!this.args.watch) {
- this.bundler.on('bundle-error', () => process.exit(1));
- if (!this.args.inspect) {
- this.testHost.workerHost.on('worker-error', () => process.exit(1));
- }
- }
-
- const siteInitialized = this.site ? this.site.init() : Promise.resolve();
-
- await Promise.all([
- this.bundler.bundle(),
- this.testHost.start(),
- siteInitialized,
- this.kv.init()
- ]);
-
- const failures = await this.testHost.runTests(
- this.bundler.code,
- this.site ? this.site.manifest : null
- );
-
- if (this.args.watch) {
- const update = () =>
- this.testHost.runTests(
- this.bundler.code,
- this.site ? this.site.manifest : null
- );
- this.bundler.on('bundle-end', update);
- if (this.site) {
- this.site.on('change', update);
- }
- } else {
- this.dispose();
- process.exit(failures ? 1 : 0);
- }
- }
-
- dispose() {
- this.bundler.dispose();
- this.testHost.dispose();
- if (this.site) {
- this.site.dispose();
- }
- this.kv.dispose();
- }
-}
diff --git a/packages/dev/src/cloudflare-api.js b/packages/dev/src/cloudflare-api.js
deleted file mode 100644
index e7beb3fd..00000000
--- a/packages/dev/src/cloudflare-api.js
+++ /dev/null
@@ -1,486 +0,0 @@
-import FormData from 'form-data';
-import fs from 'fs-extra';
-import fetch from 'node-fetch';
-import { KV } from './kv.js';
-import { logger } from './logger.js';
-import { StaticSite } from './static-site.js';
-
-const apiBase = 'https://api.cloudflare.com/client/v4';
-
-/**
- * @param {string} apiKey Cloudflare API key
- * @param {string | undefined} accountEmail Cloudflare account email
- * @returns {Object.}
- */
-function buildAuthHeaders(apiKey, accountEmail) {
- return accountEmail
- ? {
- 'X-Auth-Email': accountEmail,
- 'X-Auth-Key': apiKey
- }
- : {
- Authorization: 'Bearer ' + apiKey
- };
-}
-
-/**
- * @param {string} accountId Cloudflare account id
- * @param {string} apiKey Cloudflare API key
- * @param {string | undefined} accountEmail Cloudflare account email
- */
-export async function getWorkersDevSubdomain(accountId, apiKey, accountEmail) {
- const response = await fetch(
- `${apiBase}/accounts/${accountId}/workers/subdomain`,
- {
- headers: buildAuthHeaders(apiKey, accountEmail)
- }
- );
- if (!response.ok) {
- throw new Error(
- `GET worker subdomain failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- /** @type {{ result: { subdomain: string; }; }} */
- const data = await response.json();
- return data.result.subdomain;
-}
-
-/**
- * @typedef {object} DeployToWorkersDevArgs
- * @property {string} code Worker javascript code
- * @property {string} name workers.dev project name
- * @property {string} accountId Cloudflare account id
- * @property {string|undefined} accountEmail Cloudflare account email
- * @property {string} apiKey Cloudflare API key
- * @property {StaticSite | null} site Workers Site
- * @property {KV} kv Workers KV
- */
-
-/**
- * Deploy to workers.dev.
- * @param {DeployToWorkersDevArgs} args
- */
-export async function deployToWorkersDev(args) {
- const site = await getSiteBindings(args);
- const kv = await getKVBindings(args);
- const form = new FormData();
- const body_part = 'worker.js';
- const metadata = {
- body_part,
- bindings: [...site.bindings, ...kv.bindings]
- };
- form.append('metadata', JSON.stringify(metadata), {
- contentType: 'application/json',
- filename: 'metadata.json'
- });
- if (site.manifest) {
- form.append('manifest', site.manifest, {
- contentType: 'text/plain',
- filename: 'manifest.json'
- });
- }
- form.append(body_part, args.code, {
- contentType: 'application/javascript',
- filename: body_part
- });
-
- const response = await fetch(
- `${apiBase}/accounts/${args.accountId}/workers/scripts/${args.name}`,
- {
- method: 'PUT',
- headers: Object.assign(
- {},
- form.getHeaders(),
- buildAuthHeaders(args.apiKey, args.accountEmail)
- ),
- body: form.getBuffer()
- }
- );
- if (!response.ok) {
- throw new Error(
- `PUT worker script failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
-
- await site.kvCleanup();
- await kv.kvCleanup();
-}
-
-/**
- * @typedef {object} DeployArgs
- * @property {string} name Worker script name
- * @property {string} code Worker javascript code
- * @property {string} routePattern Worker route pattern
- * @property {string} accountId Cloudflare account id
- * @property {string|undefined} accountEmail Cloudflare account email
- * @property {string} zoneId Cloudflare zone id
- * @property {string} apiKey Cloudflare API key
- * @property {boolean} purgeCache Whether to purge the cache (purges everything)
- * @property {StaticSite | null} site Workers Site
- * @property {KV} kv Workers KV
- */
-
-/**
- *
- * @param {DeployArgs} args
- */
-export async function deploy(args) {
- const authHeaders = buildAuthHeaders(args.apiKey, args.accountEmail);
-
- logger.progress('Getting zone...');
- let response = await fetch(`${apiBase}/zones/${args.zoneId}`, {
- method: 'GET',
- headers: authHeaders
- });
- if (!response.ok) {
- throw new Error(
- `GET zone failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- /** @type {string} */
- const zoneName = (await response.json()).result.name;
-
- const site = await getSiteBindings(args);
- const kv = await getKVBindings(args);
-
- logger.progress('Deploying script...');
- const form = new FormData();
- const body_part = args.name;
- const metadata = {
- body_part,
- bindings: [...site.bindings, ...kv.bindings]
- };
- form.append('metadata', JSON.stringify(metadata), {
- contentType: 'application/json',
- filename: 'metadata.json'
- });
- if (site.manifest) {
- form.append('manifest', site.manifest, {
- contentType: 'text/plain',
- filename: 'manifest.json'
- });
- }
- form.append(body_part, args.code, {
- contentType: 'application/javascript',
- filename: body_part
- });
-
- response = await fetch(
- `${apiBase}/accounts/${args.accountId}/workers/scripts/${args.name}`,
- {
- method: 'PUT',
- headers: Object.assign(
- {},
- form.getHeaders(),
- buildAuthHeaders(args.apiKey, args.accountEmail)
- ),
- body: form.getBuffer()
- }
- );
-
- if (!response.ok) {
- throw new Error(
- `GET worker routes failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
-
- await site.kvCleanup();
- await kv.kvCleanup();
-
- if (args.routePattern) {
- logger.progress('Getting routes...');
- response = await fetch(`${apiBase}/zones/${args.zoneId}/workers/routes`, {
- headers: authHeaders
- });
- if (!response.ok) {
- throw new Error(
- `GET worker routes failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
-
- /** @type {{ result: { id: string; script: string; pattern: string; }[]; }} */
- const { result: routes } = await response.json();
- const route = routes.find(r => r.script === args.name);
-
- if (!route) {
- logger.progress('Adding route...');
- response = await fetch(`${apiBase}/zones/${args.zoneId}/workers/routes`, {
- method: 'POST',
- body: JSON.stringify({ pattern: args.routePattern, script: args.name }),
- headers: Object.assign(
- { 'Content-Type': 'application/json' },
- authHeaders
- )
- });
- if (!response.ok) {
- throw new Error(
- `POST worker route failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- } else if (route.pattern !== args.routePattern) {
- logger.progress('Updating route pattern...');
- response = await fetch(
- `${apiBase}/zones/${args.zoneId}/workers/routes/${route.id}`,
- {
- method: 'PUT',
- body: JSON.stringify({ pattern: args.routePattern }),
- headers: Object.assign(
- { 'Content-Type': 'application/json' },
- authHeaders
- )
- }
- );
- if (!response.ok) {
- throw new Error(
- `PUT worker route failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- }
- }
-
- if (args.purgeCache) {
- logger.progress('Purging cache...');
- response = await fetch(`${apiBase}/zones/${args.zoneId}/purge_cache`, {
- method: 'POST',
- body: JSON.stringify({ purge_everything: true }),
- headers: Object.assign(
- { 'Content-Type': 'application/json' },
- authHeaders
- )
- });
- if (!response.ok) {
- throw new Error(
- `Purge cache failed.\n${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- }
-
- return zoneName;
-}
-
-/**
- *
- * @param {string} title
- * @param {{ accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- */
-async function getNamespace(title, args) {
- const response = await fetch(
- `${apiBase}/accounts/${args.accountId}/storage/kv/namespaces?per_page=100`,
- {
- headers: buildAuthHeaders(args.apiKey, args.accountEmail)
- }
- );
- if (!response.ok) {
- throw new Error(
- `Error fetching namespaces - ${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- const data = await response.json();
- // @ts-ignore
- return data.result.find(x => x.title === title);
-}
-
-/**
- *
- * @param {string} id
- * @param {{ accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- * @returns {Promise<{ name: string; }[]>}
- */
-async function getNamespaceKeys(id, args) {
- const response = await fetch(
- `${apiBase}/accounts/${args.accountId}/storage/kv/namespaces/${id}/keys?limit=1000`,
- {
- headers: buildAuthHeaders(args.apiKey, args.accountEmail)
- }
- );
- if (!response.ok) {
- throw new Error(
- `Error fetching namespace keys - ${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- const data = await response.json();
- // @ts-ignore
- return data.result;
-}
-
-/**
- *
- * @param {string} title
- * @param {{ accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- */
-async function createNamespace(title, args) {
- const response = await fetch(
- `${apiBase}/accounts/${args.accountId}/storage/kv/namespaces`,
- {
- method: 'POST',
- headers: Object.assign(
- { 'content-type': 'application/json' },
- buildAuthHeaders(args.apiKey, args.accountEmail)
- ),
- body: JSON.stringify({ title })
- }
- );
- if (!response.ok) {
- throw new Error(
- `Error creating namespace - ${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
- const data2 = await response.json();
- return data2.result;
-}
-
-/**
- * @param {{ site: StaticSite | null; name: string; accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- * @returns {Promise<{ bindings: any[]; kvCleanup: () => Promise; manifest?: string }>}
- */
-async function getSiteBindings(args) {
- if (!args.site) {
- return { bindings: [], kvCleanup: async () => {} };
- }
-
- logger.progress('Publishing site assets to KV...');
- const title = `__${args.name}-workers_sites_assets`;
- const namespace =
- (await getNamespace(title, args)) || (await createNamespace(title, args));
-
- await publishSiteToKV(args, namespace);
-
- return {
- bindings: [
- {
- type: 'text_blob',
- name: '__STATIC_CONTENT_MANIFEST',
- part: 'manifest'
- },
- {
- type: 'kv_namespace',
- name: '__STATIC_CONTENT',
- namespace_id: namespace.id
- }
- ],
- kvCleanup: () => bulkDelete(args, namespace),
- manifest: JSON.stringify(args.site.manifest)
- };
-}
-
-/**
- * @param {{ kv: KV; name: string; accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- * @returns {Promise<{ bindings: any[]; kvCleanup: () => Promise; }>}
- */
-async function getKVBindings(args) {
- if (args.kv.namespaces.length === 0) {
- return { bindings: [], kvCleanup: async () => {} };
- }
-
- const bindings = [];
-
- for (const { name, items } of args.kv.namespaces) {
- logger.progress(`Publishing KV namespace "${name}"...`);
- const namespace =
- (await getNamespace(name, args)) || (await createNamespace(name, args));
- await bulkKV(args, namespace, items);
- bindings.push({
- type: 'kv_namespace',
- name,
- namespace_id: namespace.id
- });
- }
-
- return {
- bindings,
- kvCleanup: () => Promise.resolve() // todo
- };
-}
-
-/**
- * @param {{ site: StaticSite; name: string; accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- * @param {{ id: string; }} namespace
- */
-async function publishSiteToKV(args, namespace) {
- const items = await Promise.all(
- Object.entries(args.site.files).map(async ([key, filename]) => ({
- key,
- value: (await fs.readFile(filename)).toString('base64'),
- base64: true
- }))
- );
- await bulkKV(args, namespace, items);
-}
-
-/**
- * @param {{ accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- * @param {{ id: string; }} namespace
- * @param {import('./kv.js').KVItem[]} items
- */
-async function bulkKV(args, namespace, items) {
- const response = await fetch(
- `${apiBase}/accounts/${args.accountId}/storage/kv/namespaces/${namespace.id}/bulk`,
- {
- method: 'PUT',
- headers: Object.assign(
- { 'content-type': 'application/json' },
- buildAuthHeaders(args.apiKey, args.accountEmail)
- ),
- body: JSON.stringify(items)
- }
- );
- if (!response.ok) {
- throw new Error(
- `Error publishing items to KV - ${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
-}
-
-/**
- * @param {{ site: StaticSite; name: string; accountId: string; accountEmail: string | undefined; apiKey: string; }} args
- * @param {{ id: string; }} namespace
- */
-async function bulkDelete(args, namespace) {
- logger.progress('Removing stale site assets...');
- const keys = await getNamespaceKeys(namespace.id, args);
- const body = JSON.stringify(
- keys.filter(key => !args.site.files[key.name]).map(key => key.name)
- );
- const response = await fetch(
- `${apiBase}/accounts/${args.accountId}/storage/kv/namespaces/${namespace.id}/bulk`,
- {
- method: 'DELETE',
- headers: Object.assign(
- { 'content-type': 'application/json' },
- buildAuthHeaders(args.apiKey, args.accountEmail)
- ),
- body
- }
- );
- if (!response.ok) {
- throw new Error(
- `Error deleting stale KV - ${response.status}: ${
- response.statusText
- }\n${await response.text()}`
- );
- }
-}
diff --git a/packages/dev/src/env.js b/packages/dev/src/env.js
deleted file mode 100644
index fc03cbd0..00000000
--- a/packages/dev/src/env.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import dotenv from 'dotenv';
-import { existsSync } from 'fs';
-import { join } from 'path';
-
-export async function loadEnv(default_NODE_ENV = 'development') {
- const NODE_ENV = (process.env.NODE_ENV =
- process.env.NODE_ENV || default_NODE_ENV);
- const basenames = [
- `.env.${NODE_ENV}.local`,
- `.env.${NODE_ENV}`,
- // Don't include `.env.local` for `test` environment
- // since normally you expect tests to produce the same
- // results for everyone
- ...(NODE_ENV === 'test' ? [] : ['.env.local']),
- '.env'
- ];
-
- for (const basename of basenames) {
- const path = join(process.cwd(), basename);
- if (!existsSync(path)) {
- continue;
- }
- dotenv.config({ path });
- }
-}
diff --git a/packages/dev/src/ip.js b/packages/dev/src/ip.js
deleted file mode 100644
index 1e4465d8..00000000
--- a/packages/dev/src/ip.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import fetch from 'node-fetch';
-
-/**
- * @returns {Promise}
- */
-export async function getLocalhostIP() {
- try {
- const response = await fetch('https://get.geojs.io/v1/ip.json');
- if (!response.ok) {
- return null;
- }
- const data = await response.json();
- return data.ip;
- } catch {
- return null;
- }
-}
diff --git a/packages/dev/src/kv.js b/packages/dev/src/kv.js
deleted file mode 100644
index a7289c68..00000000
--- a/packages/dev/src/kv.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import watch from 'chokidar';
-import { EventEmitter } from 'events';
-import { promises as fs } from 'fs';
-import { basename, extname } from 'path';
-import { logger } from './logger.js';
-
-/**
- * @typedef {object} KVItem
- * @property {string} key
- * @property {string} value
- * @property {boolean} base64
- */
-
-/**
- * @typedef {object} KVNamespaceInit
- * @property {string} name
- * @property {KVItem[]} items
- */
-
-export class KV extends EventEmitter {
- debounceHandle = setTimeout(() => {}, 0);
-
- /** @type {KVNamespaceInit[]} */
- namespaces = [];
-
- /**
- * @param {string[]} filenames
- * @param {boolean} [watch]
- */
- constructor(filenames, watch = false) {
- super();
- this.filenames = filenames;
- this.watch = watch;
- }
-
- async init() {
- if (this.filenames.length === 0) {
- return;
- }
- await this.read();
- if (this.watch) {
- this.watcher = watch.watch(this.filenames, {
- ignoreInitial: true
- });
- this.watcher.on('all', () => {
- clearTimeout(this.debounceHandle);
- this.debounceHandle = setTimeout(() => this.read(), 300);
- });
- }
- }
-
- async read() {
- const startTime = Date.now();
- logger.progress(`Reading KV files...`);
- this.namespaces = await Promise.all(
- this.filenames.map(async filename => {
- const ext = extname(filename);
- const name = basename(filename, ext);
- let items = [];
- try {
- const buffer = await fs.readFile(filename);
- items = JSON.parse(buffer.toString());
- } catch (err) {
- if (err.code !== 'ENOENT') {
- throw err;
- }
- }
- return { name, items };
- })
- );
- logger.success(
- `KV ready: ${this.namespaces
- .map(x => `${x.name} (${x.items.length})`)
- .join(', ')}`,
- Date.now() - startTime
- );
- this.emit('change');
- }
-
- dispose() {
- if (this.watcher) {
- this.watcher.close();
- }
- }
-}
diff --git a/packages/dev/src/logger.js b/packages/dev/src/logger.js
deleted file mode 100644
index 0f68cf86..00000000
--- a/packages/dev/src/logger.js
+++ /dev/null
@@ -1,93 +0,0 @@
-import chalk from 'chalk';
-import ora from 'ora';
-
-/**
- * @typedef {object} Logger
- * @property {(...args: any[]) => void} log
- * @property {(message: string) => void} info
- * @property {(message: string) => void} progress
- * @property {(message: string, time?: number) => void} success
- * @property {(message: string) => void} warn
- * @property {(err: any) => void} error
- */
-
-export class ConsoleLogger {
- constructor() {
- this.spinner = ora();
- }
-
- /**
- * @param {string} message
- */
- progress(message) {
- if (this.spinner.isSpinning) {
- this.spinner.text = message;
- } else {
- this.spinner.start(message);
- }
- }
-
- /**
- * @param {any[]} args
- */
- log(...args) {
- if (this.spinner.isSpinning) {
- this.spinner.stop();
- }
- console.log(...args);
- }
-
- /**
- * @param {string} message
- */
- info(message) {
- this.spinner.info(message);
- }
-
- /**
- * @param {string} message
- * @param {number} [time]
- */
- success(message, time) {
- if (time) {
- message = `${message} ${chalk.gray(`(${prettifyTime(time)})`)}`;
- }
- this.spinner.succeed(message);
- }
-
- /**
- * @param {string} message
- */
- warn(message) {
- this.spinner.warn(message);
- }
-
- /**
- * @param {any} err
- */
- error(err) {
- const message = (err || 'Unknown error').toString();
- this.spinner.fail(message);
- }
-}
-
-/**
- * The current logger.
- * @type {Logger}
- */
-export let logger = new ConsoleLogger();
-
-/**
- * Set the logger implementation.
- * @param {Logger} value
- */
-export function setLogger(value) {
- logger = value;
-}
-
-/**
- * @param {number} time
- */
-export function prettifyTime(time) {
- return time < 1000 ? `${time}ms` : `${(time / 1000).toFixed(2)}s`;
-}
diff --git a/packages/dev/src/require-content.js b/packages/dev/src/require-content.js
deleted file mode 100644
index f708c7af..00000000
--- a/packages/dev/src/require-content.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { readFileSync } from 'fs';
-import module from 'module';
-import { extname } from 'path';
-import { fileURLToPath } from 'url';
-
-/** @type {Map} */
-const packageContent = new Map();
-
-/**
- * @param {string} id
- * @param {string} relativeTo
- */
-export function requireContent(id, relativeTo) {
- if (!packageContent.has(id)) {
- const require = module.createRequire(fileURLToPath(relativeTo));
- // @ts-ignore
- const path = require.resolve(id);
- const content = readFileSync(path).toString();
- const type =
- extname(path) === '.css' ? 'text/css' : 'application/javascript';
- packageContent.set(id, { content, type });
- }
- const result = packageContent.get(id);
- if (result === undefined) {
- throw new Error(`unable to resolve ${id} relative to ${relativeTo}.`);
- }
- return result;
-}
diff --git a/packages/dev/src/runtime/add-event-listener.js b/packages/dev/src/runtime/add-event-listener.js
deleted file mode 100644
index f9e35458..00000000
--- a/packages/dev/src/runtime/add-event-listener.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/** @type {(event: any) => void} */
-const defaultFetchHandler = event => {
- const message = 'No fetch handler attached.';
- event.respondWith(
- new Response(message, { status: 503, statusText: 'Service Unavailable' })
- );
-};
-
-/** @type {EventListener} */
-export let fetchHandler = defaultFetchHandler;
-
-/**
- * @param {string} event
- * @param {EventListener} handler
- */
-export function addEventListener(event, handler) {
- if (event === 'fetch') {
- fetchHandler = handler;
- }
-}
-
-/**
- * @param {Event} event
- */
-export function dispatchEvent(event) {
- if (event.type === 'fetch') {
- fetchHandler(event);
- }
-}
-
-export function resetFetchHandler() {
- fetchHandler = defaultFetchHandler;
-}
diff --git a/packages/dev/src/runtime/fetch-event.js b/packages/dev/src/runtime/fetch-event.js
deleted file mode 100644
index 30b6c1c8..00000000
--- a/packages/dev/src/runtime/fetch-event.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export class FetchEvent extends Event {
- /**
- * @param {Request} request
- */
- constructor(request) {
- super('fetch');
- this.request = request;
- /** @type {Promise} */
- this.__responded__ = new Promise(resolve => (this.respondWith = resolve));
- }
-
- passThroughOnException() {}
-
- waitUntil() {}
-}
diff --git a/packages/dev/src/runtime/headers.js b/packages/dev/src/runtime/headers.js
deleted file mode 100644
index bd3af3c3..00000000
--- a/packages/dev/src/runtime/headers.js
+++ /dev/null
@@ -1,103 +0,0 @@
-const forbidden = [
- // response headers
- 'set-cookie',
- // request headers
- 'accept-charset',
- 'accept-encoding',
- 'access-control-request-headers',
- 'access-control-request-method',
- 'connection',
- 'content-length',
- 'cookie',
- 'cookie2',
- 'date',
- 'dnt',
- 'expect',
- 'host',
- 'keep-alive',
- 'origin',
- 'referer',
- 'te',
- 'trailer',
- 'transfer-encoding',
- 'upgrade',
- 'via'
-];
-
-/**
- * @param {string} name
- */
-export function escapeHeaderName(name) {
- // use Header class's name normalization logic.
- if (typeof name !== 'string') {
- name = String(name);
- }
- name = name.toLowerCase();
- // remap name
- if (forbidden.includes(name)) {
- name = '__forbidden__' + name;
- }
- return name;
-}
-
-/**
- * @param {string} name
- */
-export function unescapeHeaderName(name) {
- return name.replace(/^__forbidden__/, '');
-}
-
-/**
- * @param {typeof Headers} Headers
- */
-export function wrapHeaders(Headers) {
- /** @type {('append' | 'delete' | 'get' | 'has' | 'set')[]} */
- const methods = ['append', 'delete', 'get', 'has', 'set'];
- for (const method of methods) {
- const standard = Headers.prototype[method];
- /**
- * @param {string} name
- * @param {...string} args
- */
- Headers.prototype[method] = function (name, ...args) {
- name = escapeHeaderName(name);
- // @ts-ignore
- return standard.call(this, name, ...args);
- };
- }
-
- const standardForEach = Headers.prototype.forEach;
- // @ts-ignore
- Headers.prototype.forEach = function (callbackfn) {
- standardForEach.call(this, (value, name, parent) => {
- name = unescapeHeaderName(name);
- callbackfn(value, name, parent);
- });
- };
-
- // @ts-ignore
- const standardEntries = Headers.prototype.entries;
- // @ts-ignore
- Headers.prototype.entries = function () {
- return Array.from(standardEntries.call(this)).map(([k, v]) => [
- unescapeHeaderName(k),
- v
- ]);
- };
-
- // @ts-ignore
- const standardKeys = Headers.prototype.keys;
- // @ts-ignore
- Headers.prototype.keys = function () {
- return Array.from(standardKeys.call(this)).map(unescapeHeaderName);
- };
-
- // // @ts-ignore
- // const standardIterator = Headers.prototype[Symbol.iterator];
- // // @ts-ignore
- // Headers.prototype[Symbol.iterator] = function* () {
- // for (const [k, v] of standardIterator.call(this)) {
- // yield [unescapeHeaderName(k), v];
- // }
- // };
-}
diff --git a/packages/dev/src/runtime/html-encode.js b/packages/dev/src/runtime/html-encode.js
deleted file mode 100644
index 15436dcc..00000000
--- a/packages/dev/src/runtime/html-encode.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * @type {Record}
- */
-const htmlEscapes = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
-};
-
-const reUnescapedHtml = /[&<>"']/g;
-const reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
-
-/** @param {string} string */
-export function htmlEncode(string) {
- return string && reHasUnescapedHtml.test(string)
- ? string.replace(reUnescapedHtml, chr => htmlEscapes[chr])
- : string || '';
-}
diff --git a/packages/dev/src/runtime/html-rewriter.js b/packages/dev/src/runtime/html-rewriter.js
deleted file mode 100644
index 4ecdd125..00000000
--- a/packages/dev/src/runtime/html-rewriter.js
+++ /dev/null
@@ -1,381 +0,0 @@
-///
-
-import { htmlEncode } from './html-encode.js';
-
-const encoder = new TextEncoder();
-const parser = new DOMParser();
-
-export class HTMLRewriter {
- /** @type {{selector: string; handler:ElementHandler;}[]} */
- _elements = [];
-
- /** @type {DocumentHandler[]} */
- _documents = [];
-
- /**
- * @param {string} selector
- * @param {ElementHandler} handler
- * @returns {HTMLRewriter}
- */
- on(selector, handler) {
- this._elements.push({ selector, handler });
- return this;
- }
-
- /**
- * @param {DocumentHandler} handler
- * @returns {HTMLRewriter}
- */
- onDocument(handler) {
- this._documents.push(handler);
- return this;
- }
-
- /**
- * @param {Response} response
- * @returns {Response}
- */
- transform(response) {
- const { readable, writable } = new TransformStream();
- this._transformInternal(response, writable);
- return new Response(readable, {
- headers: response.headers,
- status: response.status,
- statusText: response.statusText
- });
- }
-
- /**
- * @param {Response} response
- * @param {WritableStream} writable
- */
- async _transformInternal(response, writable) {
- const writer = writable.getWriter();
- const html = await response.text();
- const document = parser.parseFromString(html, 'text/html');
- this._walk(document);
- await writer.write(encoder.encode(document.documentElement.outerHTML));
- await writer.close();
- }
-
- /**
- * @param {Document} document
- */
- _walk(document) {
- const whatToShow =
- NodeFilter.SHOW_DOCUMENT_TYPE |
- NodeFilter.SHOW_ELEMENT |
- NodeFilter.SHOW_COMMENT |
- NodeFilter.SHOW_TEXT;
- const walker = document.createTreeWalker(
- document.documentElement,
- whatToShow
- );
- /** @type {{ node: Element | Text; mutations: ElementMutations; }[]} */
- let toMutate = [];
- /** @type {Node|null} */
- let node = walker.currentNode;
- while (node) {
- switch (node.nodeType) {
- case Node.DOCUMENT_TYPE_NODE:
- break;
- case Node.COMMENT_NODE:
- let comment;
- for (const { selector, handler } of this._elements) {
- if (node.parentElement.matches(selector)) {
- if (handler.comments) {
- comment = comment || new CFText(node);
- handler.comments(comment);
- }
- }
- }
- if (comment && comment._mutations) {
- toMutate.push({ node, mutations: comment._mutations });
- }
- break;
- case Node.TEXT_NODE:
- let text;
- for (const { selector, handler } of this._elements) {
- if (node.parentElement.matches(selector)) {
- if (handler.text) {
- text = text || new CFText(node);
- handler.text(text);
- }
- }
- }
- if (text && text._mutations) {
- toMutate.push({ node, mutations: text._mutations });
- }
- break;
- case Node.ELEMENT_NODE:
- let element;
- for (const { selector, handler } of this._elements) {
- if (node.matches(selector)) {
- if (handler.element) {
- element = element || new CFElement(node);
- handler.element(element);
- }
- }
- }
- if (element && element._mutations) {
- toMutate.push({ node, mutations: element._mutations });
- }
- break;
- default:
- throw new Error(`Unexpected nodeType ${node.nodeType}`);
- }
- node = walker.nextNode();
- }
- for (const { node, mutations } of toMutate) {
- if (!node.parentElement) {
- continue;
- }
- if (mutations.before) {
- for (const {
- content,
- contentOptions: { html }
- } of mutations.before) {
- if (html) {
- if (node.nodeType === Node.TEXT_NODE) {
- const marker = document.createElement('span');
- node.before(marker);
- marker.insertAdjacentHTML('beforebegin', content);
- marker.remove();
- } else {
- node.insertAdjacentHTML('beforebegin', content);
- }
- } else {
- node.before(content);
- }
- }
- }
- if (mutations.after) {
- for (const {
- content,
- contentOptions: { html }
- } of mutations.after) {
- if (html) {
- if (node.nodeType === Node.TEXT_NODE) {
- const marker = document.createElement('span');
- node.after(marker);
- marker.insertAdjacentHTML('afterend', content);
- marker.remove();
- } else {
- node.insertAdjacentHTML('afterend', content);
- }
- } else {
- node.after(content);
- }
- }
- }
- if (mutations.remove) {
- node.remove();
- continue;
- }
- if (mutations.replace) {
- const {
- content,
- contentOptions: { html }
- } = mutations.replace[0];
- if (html) {
- if (node.nodeType === Node.TEXT_NODE) {
- const marker = document.createElement('span');
- node.before(marker);
- marker.insertAdjacentHTML('afterend', content);
- marker.remove();
- } else {
- node.insertAdjacentHTML('afterend', content);
- }
- node.remove();
- } else {
- node.replaceWith(content);
- }
- continue;
- }
- if (mutations.setInnerContent) {
- const {
- content,
- contentOptions: { html }
- } = mutations.setInnerContent[mutations.setInnerContent.length - 1];
- if (html) {
- node.innerHTML = content;
- } else {
- node.textContent = content;
- }
- }
- if (mutations.prepend) {
- for (const {
- content,
- contentOptions: { html }
- } of mutations.prepend) {
- node.insertAdjacentHTML(
- 'afterbegin',
- html ? content : htmlEncode(content)
- );
- }
- }
- if (mutations.append) {
- for (const {
- content,
- contentOptions: { html }
- } of mutations.append) {
- node.insertAdjacentHTML(
- 'beforeend',
- html ? content : htmlEncode(content)
- );
- }
- }
- if (mutations.removeAndKeepContent) {
- while (node.childNodes.length) {
- const child = node.childNodes.item(0);
- node.removeChild(child);
- node.parentElement.insertBefore(child, node);
- }
- node.remove();
- continue;
- }
- }
- }
-}
-
-class CFText {
- /** @type {ElementMutations | undefined} */
- _mutations = undefined;
-
- /**
- * @param {Text} text
- */
- constructor(text) {
- this._node = text;
- }
-
- get removed() {
- if (this._node.removed === true) {
- return true;
- }
- let node = this._node.parentNode;
- while (node) {
- if (node.keepContent === false) {
- return true;
- }
- node = node.parentNode;
- }
- return false;
- }
-
- get text() {
- return this._node.textContent;
- }
-
- get lastInTextNode() {
- return (
- !this._node.nextSibling ||
- this._node.nextSibling.nodeType !== Node.TEXT_NODE
- );
- }
-}
-
-class CFElement {
- /** @type {ElementMutations | undefined} */
- _mutations = undefined;
-
- /**
- * @param {Element} element
- */
- constructor(element) {
- this._node = element;
- }
-
- get tagName() {
- return this._node.tagName.toLowerCase();
- }
- get attributes() {
- const length = this._node.attributes.length;
- const arr = [];
- for (let i = 0; i < length; i++) {
- const attr = this._node.attributes.item(i);
- arr.push([attr.name, attr.value]);
- }
- return arr;
- }
- get namespaceURI() {
- return this._node.namespaceURI;
- }
- get removed() {
- if (this._node.removed === true) {
- return true;
- }
- let el = this._node.parentNode;
- while (el) {
- if (el.keepContent === false) {
- return true;
- }
- el = el.parentNode;
- }
- return false;
- }
-}
-
-for (const action of ['get', 'has', 'set', 'remove']) {
- const method = `${action}Attribute`;
- /**
- * @param {...string} args
- * @this {CFElement}
- */
- function attribute(...args) {
- return this._node[method].call(this._node, ...args);
- }
- CFElement.prototype[method] = attribute;
-}
-
-/** @type {ElementMutationType[]} */
-const mutationMethods = [
- 'before',
- 'after',
- 'prepend',
- 'append',
- 'replace',
- 'setInnerContent',
- 'remove',
- 'removeAndKeepContent'
-];
-
-/** @type {ElementMutationType[]} */
-const textMutationMethods = ['before', 'after', 'replace', 'remove'];
-
-for (const method of mutationMethods) {
- /**
- * @param {string} content
- * @param {ContentOptions} contentOptions
- * @this {CFElement}
- */
- function mutate(content, contentOptions = { html: false }) {
- switch (method) {
- case 'replace':
- this._node.removed = true;
- break;
- case 'setInnerContent':
- this._node.keepContent = false;
- break;
- case 'remove':
- this._node.removed = true;
- this._node.keepContent = false;
- break;
- case 'removeAndKeepContent':
- this._node.removed = true;
- this._node.keepContent = true;
- break;
- }
- this._mutations = this._mutations || {};
- this._mutations[method] = this._mutations[method] || [];
- this._mutations[method].push({ content, contentOptions });
- }
- CFElement.prototype[method] = mutate;
- if (textMutationMethods.includes(method)) {
- CFText.prototype[method] = mutate;
- }
-}
-
-/** @typedef {'before' | 'after' | 'prepend' | 'append' | 'replace' | 'setInnerContent' | 'remove'| 'removeAndKeepContent'} ElementMutationType */
-/** @typedef {{ content: string; contentOptions: ContentOptions; }} ElementMutation */
-/** @typedef {Record} ElementMutations */
diff --git a/packages/dev/src/runtime/index.js b/packages/dev/src/runtime/index.js
deleted file mode 100644
index 30b6a94b..00000000
--- a/packages/dev/src/runtime/index.js
+++ /dev/null
@@ -1,93 +0,0 @@
-import { fetchHandler, resetFetchHandler } from './add-event-listener.js';
-import { FetchEvent } from './fetch-event.js';
-import { wrapHeaders } from './headers.js';
-import { scopeGuard } from './scope-guard.js';
-import { ServiceWorkerGlobalScope } from './service-worker-global-scope.js';
-
-wrapHeaders(Headers);
-
-const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
-
-/**
- * @param {string} code The worker script.
- * @param {string} sourcePathname Where to list the script in the chrome devtools sources tree.
- * @param {string[]} globals Names of additional globals to expose.
- * @param {Record | null} staticContentManifest Workers site manifest.
- * @param {import('../kv.js').KVNamespaceInit[]} kvNamespaces Workers KV namespaces.
- */
-export async function executeWorkerScript(
- code,
- sourcePathname,
- globals = [],
- staticContentManifest,
- kvNamespaces
-) {
- resetFetchHandler();
- const scope = new ServiceWorkerGlobalScope(
- globals,
- staticContentManifest,
- kvNamespaces
- );
- await scope.init();
- const guardedScope = new Proxy(scope, scopeGuard);
- const sourceUrl = `//# sourceURL=${location.origin}${sourcePathname}`;
- const fn = new AsyncFunction(
- '__guardedScope__',
- `with(__guardedScope__) {\n${code}\n}\n${sourceUrl}`
- );
- fn(guardedScope);
-}
-
-/**
- * @param {string} url
- * @param {string | undefined} bodyUrl
- * @param {RequestInit} init
- */
-export async function dispatchFetchEvent(url, bodyUrl, init) {
- if (bodyUrl) {
- const response = await fetch(bodyUrl);
- init.body = await response.arrayBuffer();
- }
- const request = new Request(url, init);
- Object.defineProperty(request, 'body', {
- value: init.body ?? null
- });
- // @ts-ignore
- // request.body = init.body ?? null;
- bindCfProperty(request);
- const event = new FetchEvent(request);
- fetchHandler(event);
- const response = await event.__responded__;
- const blob = await response.blob();
- const body = await new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onload = () => resolve(reader.result);
- reader.onerror = () => reject('Error reading body.');
- reader.readAsBinaryString(blob);
- });
- /** @type {Record} */
- const headers = Object.create(null);
- response.headers.forEach((v, k) => (headers[k] = v));
- return {
- status: response.status,
- statusText: response.statusText,
- headers,
- body
- };
-}
-
-/**
- * @param {Request} request
- */
-function bindCfProperty(request) {
- Object.defineProperty(request, 'cf', {
- value: {
- tlsVersion: 'TLSv1.2',
- tlsCipher: 'ECDHE-ECDSA-CHACHA20-POLY1305',
- country: 'US',
- colo: 'LAX'
- },
- writable: false,
- enumerable: false
- });
-}
diff --git a/packages/dev/src/runtime/kv.js b/packages/dev/src/runtime/kv.js
deleted file mode 100644
index e384929b..00000000
--- a/packages/dev/src/runtime/kv.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * @typedef {import("../kv").KVItem} KVItem
- */
-
-/**
- * @param {string} base64
- */
-function base64ToArrayBuffer(base64) {
- const bs = atob(base64);
- const len = bs.length;
- const bytes = new Uint8Array(len);
- for (var i = 0; i < len; i++) {
- bytes[i] = bs.charCodeAt(i);
- }
- return bytes.buffer;
-}
-
-/**
- * @param {ArrayBuffer} buffer
- */
-function arrayBufferToBase64(buffer) {
- let bs = '';
- const bytes = new Uint8Array(buffer);
- const len = bytes.byteLength;
- for (var i = 0; i < len; i++) {
- bs += String.fromCharCode(bytes[i]);
- }
- return btoa(bs);
-}
-
-export class MemoryKVNamespace {
- /**
- * @param {KVItem[]} items
- */
- constructor(items) {
- /** @type {Record} */
- this.map = {};
- items.reduce((a, b) => {
- a[b.key] = b;
- return a;
- }, this.map);
- }
-
- /**
- * @param {string} key
- * @param {'text' | 'json' | 'arrayBuffer' | 'stream'} type
- */
- get(key, type = 'text') {
- let item = this.map[key];
- if (item === undefined) {
- return Promise.resolve(null);
- }
- const response = new Response(
- item.base64 ? base64ToArrayBuffer(item.value) : item.value
- );
- switch (type) {
- case 'text':
- return response.text();
- case 'json':
- return response.json();
- case 'arrayBuffer':
- return response.arrayBuffer();
- case 'stream':
- return Promise.resolve(response.body);
- default:
- throw new Error(`Unexpected type "${type}`);
- }
- }
-
- /**
- * @param {string} key
- * @param {string | ReadableStream | ArrayBuffer | FormData} value
- * @param {{ expiration?: string | number; expirationTtl?: string | number;}} [options]
- */
- async put(key, value, options = {}) {
- this.map[key] = {
- key,
- value: arrayBufferToBase64(await new Response(value).arrayBuffer()),
- base64: true
- };
- if (options.expirationTtl) {
- setTimeout(() => this.delete(key), +options.expirationTtl);
- }
- if (options.expiration) {
- setTimeout(() => this.delete(key), +options.expiration - Date.now());
- }
- }
-
- /**
- * @param {string} key
- */
- delete(key) {
- delete this.map[key];
- return Promise.resolve();
- }
-
- list() {
- throw new Error(`${this.constructor.name} does not implement "list"`);
- }
-}
-
-export class StaticContentKVNamespace {
- /**
- * @param {string} key
- * @param {'text' | 'json' | 'arrayBuffer' | 'stream'} type
- */
- async get(key, type = 'text') {
- const response = await fetch(
- `${location.origin}/__debug__/static-content/${key}`
- );
- if (response.status === 404) {
- return null;
- }
- if (response.status !== 200) {
- throw new Error(
- `Error fetching ${key} - ${response.status}: ${response.statusText}`
- );
- }
- switch (type) {
- case 'text':
- return response.text();
- case 'json':
- return response.json();
- case 'arrayBuffer':
- return response.arrayBuffer();
- case 'stream':
- return Promise.resolve(response.body);
- default:
- throw new Error(`Unexpected type "${type}`);
- }
- }
-
- put() {
- throw new Error(`${this.constructor.name} does not implement "put"`);
- }
-
- delete() {
- throw new Error(`${this.constructor.name} does not implement "delete"`);
- }
-
- list() {
- throw new Error(`${this.constructor.name} does not implement "list"`);
- }
-}
diff --git a/packages/dev/src/runtime/scope-guard.js b/packages/dev/src/runtime/scope-guard.js
deleted file mode 100644
index 0370692b..00000000
--- a/packages/dev/src/runtime/scope-guard.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/** @type {ProxyHandler} */
-export const scopeGuard = {
- has: (obj, propertyKey) => {
- return propertyKey in obj;
- },
- get: (obj, propertyKey) => {
- if (obj.hasOwnProperty(propertyKey)) {
- return obj[propertyKey];
- }
- const error = new ReferenceError(
- `${propertyKey.toString()} is not defined`
- );
- Error.captureStackTrace(error, scopeGuard.get);
- throw error;
- },
- set: (obj, propertyKey, value) => {
- return (obj[propertyKey] = value);
- },
- deleteProperty: () => {
- throw new Error('"deleteProperty" not implemented');
- },
- ownKeys: () => {
- throw new Error('"ownKeys" not implemented');
- },
- defineProperty: () => {
- throw new Error('"defineProperty" not implemented');
- },
- getOwnPropertyDescriptor: (...args) => {
- console.log('getOwnPropertyDescriptor', ...args);
- throw new Error('"getOwnPropertyDescriptor" not implemented');
- }
-};
diff --git a/packages/dev/src/runtime/service-worker-global-scope.js b/packages/dev/src/runtime/service-worker-global-scope.js
deleted file mode 100644
index 471469bf..00000000
--- a/packages/dev/src/runtime/service-worker-global-scope.js
+++ /dev/null
@@ -1,121 +0,0 @@
-import { addEventListener, dispatchEvent } from './add-event-listener.js';
-import { FetchEvent } from './fetch-event.js';
-import { HTMLRewriter } from './html-rewriter.js';
-import { MemoryKVNamespace, StaticContentKVNamespace } from './kv.js';
-
-export class ServiceWorkerGlobalScope {
- /**
- * @param {string[]} globals additional globals to expose
- * @param {Record | null} staticContentManifest Workers site manifest.
- * @param {import('../kv.js').KVNamespaceInit[]} kvNamespaces Workers KV namespaces.
- */
- constructor(globals, staticContentManifest, kvNamespaces) {
- this.Array = Array;
- this.ArrayBuffer = ArrayBuffer;
- this.Atomics = Atomics;
- this.BigInt = BigInt;
- this.BigInt64Array = BigInt64Array;
- this.BigUint64Array = BigUint64Array;
- this.Boolean = Boolean;
- this.DataView = DataView;
- this.Date = Date;
- this.Error = Error;
- this.EvalError = EvalError;
- this.Event = Event;
- this.FetchEvent = FetchEvent;
- this.Float32Array = Float32Array;
- this.Float64Array = Float64Array;
- this.FormData = FormData;
- this.Function = Function;
- this.Headers = Headers;
- this.HTMLRewriter = HTMLRewriter;
- this.Infinity = Infinity;
- this.Int16Array = Int16Array;
- this.Int32Array = Int32Array;
- this.Int8Array = Int8Array;
- this.Intl = Intl;
- this.JSON = JSON;
- this.Map = Map;
- this.Math = Math;
- this.NaN = NaN;
- this.Number = Number;
- this.Object = Object;
- this.Promise = Promise;
- this.Proxy = Proxy;
- this.RangeError = RangeError;
- this.ReadableStream = ReadableStream;
- this.ReferenceError = ReferenceError;
- this.Reflect = Reflect;
- this.RegExp = RegExp;
- this.Request = Request;
- this.Response = Response;
- this.Set = Set;
- this.SharedArrayBuffer = SharedArrayBuffer;
- this.String = String;
- this.Symbol = Symbol;
- this.SyntaxError = SyntaxError;
- this.TextDecoder = TextDecoder;
- this.TextEncoder = TextEncoder;
- this.TransformStream = TransformStream;
- this.TypeError = TypeError;
- this.URIError = URIError;
- this.URL = URL;
- this.URLSearchParams = URLSearchParams;
- this.Uint16Array = Uint16Array;
- this.Uint32Array = Uint32Array;
- this.Uint8Array = Uint8Array;
- this.Uint8ClampedArray = Uint8ClampedArray;
- this.WeakMap = WeakMap;
- this.WebAssembly = WebAssembly;
- this.WritableStream = WritableStream;
- this.addEventListener = addEventListener;
- this.atob = atob.bind(self);
- this.btoa = btoa.bind(self);
- this.clearInterval = clearInterval.bind(self);
- this.clearTimeout = clearTimeout.bind(self);
- this.console = console;
- this.constructor = ServiceWorkerGlobalScope;
- this.crypto = crypto;
- this.caches = caches;
- this.decodeURI = decodeURI.bind(self);
- this.decodeURIComponent = decodeURIComponent.bind(self);
- this.dispatchEvent = dispatchEvent;
- this.encodeURI = encodeURI.bind(self);
- this.encodeURIComponent = encodeURIComponent.bind(self);
- this.escape = escape.bind(self);
- this.fetch = fetch.bind(self);
- this.globalThis = this;
- this.isFinite = isFinite.bind(self);
- this.isNaN = isNaN.bind(self);
- this.parseFloat = parseFloat.bind(self);
- this.parseInt = parseInt.bind(self);
- this.self = this;
- this.setInterval = setInterval.bind(self);
- this.setTimeout = setTimeout.bind(self);
- // @ts-ignore
- this.undefined = undefined;
- this.unescape = unescape.bind(self);
- // @ts-ignore
- this[Symbol.unscopables] = undefined;
-
- for (const global of globals) {
- if (self.hasOwnProperty(global)) {
- // @ts-ignore
- this[global] = self[global];
- }
- }
- if (staticContentManifest) {
- this['__STATIC_CONTENT_MANIFEST'] = JSON.stringify(staticContentManifest);
- this['__STATIC_CONTENT'] = new StaticContentKVNamespace();
- }
- for (const { name, items } of kvNamespaces) {
- // @ts-ignore
- this[name] = new MemoryKVNamespace(items);
- }
- }
-
- async init() {
- // @ts-ignore
- this.caches.default = await this.caches.open('default');
- }
-}
diff --git a/packages/dev/src/server.js b/packages/dev/src/server.js
deleted file mode 100644
index 9776cac0..00000000
--- a/packages/dev/src/server.js
+++ /dev/null
@@ -1,130 +0,0 @@
-import { EventEmitter } from 'events';
-import { createReadStream } from 'fs';
-import { createServer } from 'http';
-import { logger } from './logger.js';
-import { requireContent } from './require-content.js';
-import { StaticSite } from './static-site.js';
-
-export class Server extends EventEmitter {
- pathPrefix = '/__debug__';
- staticContentPrefix = '/static-content/';
- reqPrefix = `/req/`;
- nextReqKey = 0;
-
- indexHtml = `
-
-
-
- Worker Dev
-
-
-
-
-
-
-`;
-
- /** @type {Map} */
- reqs = new Map();
-
- /**
- * @param {number} port
- * @param {StaticSite | null} staticSite
- */
- constructor(port, staticSite) {
- super();
- this.port = port;
- this.staticSite = staticSite;
- this.server = createServer(this.requestListener);
- this.serving = new Promise(resolve => this.server.on('listening', resolve));
- }
-
- serve() {
- this.server.listen(this.port);
- return this.serving;
- }
-
- dispose() {
- return new Promise(resolve => this.server.close(resolve));
- }
-
- /**
- * @param {import('http').IncomingMessage} req
- */
- setReq(req) {
- this.nextReqKey++;
- this.reqs.set(this.nextReqKey, req);
- return `${this.pathPrefix}${this.reqPrefix}${this.nextReqKey}`;
- }
-
- /** @type {import('http').RequestListener} */
- requestListener = async (req, res) => {
- try {
- let url = req.url || '/';
-
- if (!url.startsWith(this.pathPrefix)) {
- this.emit('request', req, res);
- return;
- }
- url = url.replace(this.pathPrefix, '');
-
- if (url.startsWith(this.staticContentPrefix) && this.staticSite) {
- url = url.substr(this.staticContentPrefix.length);
- const filename = this.staticSite.files[url];
- if (filename) {
- const s = createReadStream(filename);
- res.statusCode = 200;
- // @ts-ignore
- s.pipe(res);
- } else {
- res.writeHead(404, 'Not found', { 'cache-control': 'no-store' });
- res.end();
- }
- return;
- }
-
- if (url.startsWith(this.reqPrefix)) {
- const key = +url.substr(this.reqPrefix.length);
- const req = this.reqs.get(key);
- if (!req) {
- res.writeHead(404, 'Not found', { 'cache-control': 'no-store' });
- res.end();
- return;
- }
- this.reqs.delete(key);
- res.writeHead(200);
- req.pipe(res);
- return;
- }
-
- url = url
- .replace('/runtime/', './runtime/')
- .replace('/node_modules/', '');
-
- if (url === '/') {
- res.writeHead(200, 'OK', {
- 'content-type': 'text/html',
- 'cache-control': 'no-store'
- });
- res.write(this.indexHtml);
- res.end();
- return;
- }
-
- const { content, type } = requireContent(url, import.meta.url);
- res.writeHead(200, 'OK', {
- 'content-type': type,
- 'cache-control': 'no-store'
- });
- res.write(content);
- res.end();
- } catch (err) {
- logger.error(err);
- res.writeHead(500, 'Internal Server Error', {
- 'content-type': 'text/plain'
- });
- res.write(err.toString());
- res.end();
- }
- };
-}
diff --git a/packages/dev/src/static-site.js b/packages/dev/src/static-site.js
deleted file mode 100644
index dc462456..00000000
--- a/packages/dev/src/static-site.js
+++ /dev/null
@@ -1,110 +0,0 @@
-import watch from 'chokidar';
-import { createHash } from 'crypto';
-import { EventEmitter } from 'events';
-import { createReadStream } from 'fs';
-import glob from 'glob-promise';
-import { basename, dirname, extname, join } from 'path';
-import { logger } from './logger.js';
-
-export class StaticSite extends EventEmitter {
- debounceHandle = setTimeout(() => {}, 0);
-
- ignored = ['**/node_modules/**/*'];
-
- /** @type {Record} */
- manifest = {};
-
- /** @type {Record} */
- files = {};
-
- /**
- * @param {string | null} [directory]
- * @param {boolean} [watch]
- */
- constructor(directory = null, watch = false) {
- super();
- this.directory = directory;
- this.watch = watch;
- }
-
- async init() {
- if (this.directory === null) {
- return;
- }
- await this.read();
- if (this.watch) {
- this.watcher = watch.watch(this.directory, {
- ignoreInitial: true,
- ignored: this.ignored
- });
- this.watcher.on('all', () => {
- clearTimeout(this.debounceHandle);
- this.debounceHandle = setTimeout(() => this.read(), 300);
- });
- }
- }
-
- async read() {
- if (this.directory === null) {
- throw new Error('directory is null');
- }
- const directory = this.directory;
- logger.progress(
- `Generating static site manifest for "${this.directory}"...`
- );
- const startTime = Date.now();
- const matches = await glob('**/*', {
- nodir: true,
- ignore: this.ignored,
- cwd: directory
- });
- const files = await Promise.all(
- matches.map(async filename => {
- const absoluteFilename = join(directory, filename);
- let hash = '';
- try {
- const s = createReadStream(absoluteFilename);
- const hasher = createHash('md5');
- hasher.setEncoding('hex');
- await new Promise(resolve => {
- s.on('end', resolve);
- s.pipe(hasher);
- });
- hasher.end();
- hash = hasher.read().substr(0, 10);
- } catch (err) {
- if (err.code !== 'ENOENT') {
- throw err;
- }
- }
- return {
- filename,
- hash,
- absoluteFilename
- };
- })
- );
- this.files = {};
- this.manifest = {};
- for (const { filename, absoluteFilename, hash } of files) {
- if (hash === '') {
- continue;
- }
- const ext = extname(filename);
- const key = join(
- dirname(filename),
- `${basename(filename, ext)}.${hash}${ext}`
- );
- this.files[key] = absoluteFilename;
- this.manifest[filename] = key;
- }
- logger.success(`Site manifest generated`, Date.now() - startTime);
- this.emit('change');
- }
-
- dispose() {
- if (this.watcher) {
- this.watcher.close();
- }
- }
-}
diff --git a/packages/dev/src/test-host.js b/packages/dev/src/test-host.js
deleted file mode 100644
index 1078208c..00000000
--- a/packages/dev/src/test-host.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import { EventEmitter } from 'events';
-import { KV } from './kv.js';
-import { logger } from './logger.js';
-import { StaticSite } from './static-site.js';
-import { WorkerHost } from './worker-host.js';
-
-export class TestHost extends EventEmitter {
- mochaGlobals = [
- 'afterEach',
- 'after',
- 'beforeEach',
- 'before',
- 'describe',
- 'it',
- 'xit'
- ];
- testsRan = false;
-
- /**
- * @param {number} port
- * @param {boolean} inspect
- * @param {StaticSite | null} site
- * @param {KV} kv
- */
- constructor(port, inspect, site, kv) {
- super();
- this.inspect = inspect;
- this.workerHost = new WorkerHost(port, inspect, site, kv);
- }
-
- start() {
- return this.workerHost.start();
- }
-
- dispose() {
- this.workerHost.dispose();
- }
-
- /**
- * @param {string} code
- * @param {Record | null} manifest
- */
- async runTests(code, manifest) {
- this.emit('test-start');
- const startTime = Date.now();
- const testsRan = this.testsRan;
- this.testsRan = true;
- logger.progress('Waiting for worker host...');
- const page = await this.workerHost.pageReady;
- if (testsRan) {
- logger.progress('Reloading worker host...');
- await this.workerHost.reloadPage(); // reset so that tests can be rerun.
- }
- this.testsRan = true;
- logger.progress('Loading mocha and chai...');
- await this.loadMocha(page, this.workerHost.server.pathPrefix);
- const globals = ['mocha', 'chai', ...this.mochaGlobals];
- await this.workerHost.setWorkerCode(code, '/test.js', globals, manifest);
- /** @type {number} */
- logger.progress('Running tests...');
- const failures = await page.evaluate(
- () => new Promise(resolve => mocha.run(resolve))
- );
- if (failures) {
- logger.error('Failed');
- } else {
- logger.success('Passed', Date.now() - startTime);
- }
- this.emit('test-end', failures);
- return failures;
- }
-
- /**
- * @param {import('puppeteer').Page} page
- * @param {string} pathnamePrefix
- */
- async loadMocha(page, pathnamePrefix) {
- await page.evaluate(() => (document.body.id = 'mocha'));
- await page.addStyleTag({
- url: `${pathnamePrefix}/node_modules/mocha/mocha.css`
- });
- await page.addScriptTag({
- url: `${pathnamePrefix}/node_modules/chai/chai.js`
- });
- await page.addScriptTag({
- url: `${pathnamePrefix}/node_modules/mocha/mocha.js`
- });
- await page.evaluate(
- (inspect, mochaGlobals) => {
- mocha.setup({
- ui: 'bdd',
- reporter: inspect ? 'html' : 'spec',
- color: !this.inspect
- });
-
- mocha.checkLeaks();
-
- // Expose mocha globals on the mocha object, to enable `import { describe } from 'mocha';`
- // in the browser version of mocha.
- // https://github.com/mochajs/mocha/issues/2765
- for (const name of mochaGlobals) {
- // @ts-ignore
- mocha[name] = self[name];
- }
-
- // mocha doesn't catch unhandledrejections yet.
- // https://github.com/mochajs/mocha/issues/2640
- addEventListener('unhandledrejection', event => event.reason);
- },
- this.inspect,
- this.mochaGlobals
- );
- }
-}
diff --git a/packages/dev/src/worker-host.js b/packages/dev/src/worker-host.js
deleted file mode 100644
index 2ca8f2ff..00000000
--- a/packages/dev/src/worker-host.js
+++ /dev/null
@@ -1,239 +0,0 @@
-import chalk from 'chalk';
-import { EventEmitter } from 'events';
-import puppeteer from 'puppeteer';
-import { getLocalhostIP } from './ip.js';
-import { KV } from './kv.js';
-import { logger } from './logger.js';
-import { escapeHeaderName, unescapeHeaderName } from './runtime/headers.js';
-import { Server } from './server.js';
-import { StaticSite } from './static-site.js';
-
-export class WorkerHost extends EventEmitter {
- /** @type {import('puppeteer').Browser | undefined} */
- browser = undefined;
-
- /** @type {string|null} */
- localIP = null;
-
- /** @type {Promise} */
- workerCodeSet = new Promise(resolve => this.on('worker-updated', resolve));
-
- /**
- * @param {number} port
- * @param {boolean} inspect
- * @param {StaticSite | null} site
- * @param {KV} kv
- */
- constructor(port, inspect, site, kv) {
- super();
- this.port = port;
- this.inspect = inspect;
- this.server = new Server(port, site);
- this.kv = kv;
- /** @type {Promise} */
- this.pageReady = new Promise(resolve => (this.resolvePage = resolve));
- }
-
- dispose() {
- this.server.dispose();
- this.browser && this.browser.close();
- }
-
- async start() {
- let startTime = Date.now();
- logger.progress('Starting server...');
- this.server.on('request', this.handleRequestWithWorker);
- this.server.serve();
-
- const ipPromise = getLocalhostIP();
-
- logger.progress('Starting chrome...');
- const browser = (this.browser = await puppeteer.launch({
- headless: !this.inspect,
- devtools: this.inspect,
- executablePath: puppeteer.executablePath(),
- // userDataDir: this.inspect ? './.cfworker' : undefined,
- args: [
- '--start-maximized', // https://peter.sh/experiments/chromium-command-line-switches/
- '--disable-web-security', // Cloudflare workers are not subject to CORS rules.
- '--enable-features=SharedArrayBuffer'
- ]
- }));
-
- logger.progress('Configuring host page...');
- const page = (await browser.pages())[0];
-
- await page.emulateTimezone('UTC');
-
- page.on('pageerror', e => {
- logger.error(e);
- this.emit('worker-error', e);
- });
- await page.exposeFunction('nodeConsoleLog', nodeConsoleLog);
-
- await this.server.serving;
-
- logger.progress('Loading host page...');
- await page.goto(`http://localhost:${this.port}${this.server.pathPrefix}/`, {
- waitUntil: ['load']
- });
- await this.forkConsoleLog(page);
-
- this.localIP = await ipPromise;
-
- logger.success('Worker host ready', Date.now() - startTime);
- this.resolvePage(page);
- }
-
- /**
- * @param {string} code The worker script.
- * @param {string} sourcePathname Where to list the script in the chrome devtools sources tree.
- * @param {string[]} globals Names of additional globals to expose.
- * @param {Record | null} staticContentManifest Workers site manifest.
- * @param {import('./kv.js').KVNamespaceInit[]} kvNamespaces
- */
- async setWorkerCode(
- code,
- sourcePathname = '/worker.js',
- globals = [],
- staticContentManifest = null,
- kvNamespaces = []
- ) {
- const startTime = Date.now();
- logger.progress('Updating worker script...');
- const page = await this.pageReady;
- await page.evaluate(
- async (
- code,
- sourcePathname,
- globals,
- staticContentManifest,
- kvNamespaces
- ) => {
- const { executeWorkerScript } = await import('./runtime/index.js');
- await executeWorkerScript(
- code,
- sourcePathname,
- globals,
- staticContentManifest,
- kvNamespaces
- );
- },
- code,
- sourcePathname,
- globals,
- staticContentManifest,
- kvNamespaces
- );
- logger.success('Worker script updated', Date.now() - startTime);
- this.emit('worker-updated');
- }
-
- async reloadPage() {
- const page = await this.pageReady;
- await page.reload({ waitUntil: ['load'] });
- await this.forkConsoleLog(page);
- }
-
- /**
- * @param {import('http').IncomingMessage} req
- * @param {import('http').ServerResponse} res
- */
- handleRequestWithWorker = async (req, res) => {
- const host = req.headers.host || `localhost:${this.port}`;
- const url = `http://${host}${req.url}`;
- const method = req.method || 'GET';
-
- this.emit('request-start', method, req.url);
-
- const bodyUrl =
- method === 'GET' || method === 'HEAD' ? '' : this.server.setReq(req);
-
- for (const [key, value] of Array.from(Object.entries(req.headers))) {
- const newKey = escapeHeaderName(key);
- delete req.headers[key];
- req.headers[newKey] = value;
- }
-
- if (
- this.localIP &&
- (!req.connection.remoteAddress ||
- req.connection.remoteAddress === '::1' ||
- req.connection.remoteAddress.endsWith('127.0.0.1'))
- ) {
- req.headers['CF-Connecting-IP'] = this.localIP;
- } else {
- req.headers['CF-Connecting-IP'] = req.connection.remoteAddress;
- }
-
- const init = {
- method,
- headers: req.headers
- };
-
- const page = await this.pageReady;
- await this.workerCodeSet;
- const { status, statusText, headers, body } = await page.evaluate(
- async (url, bodyUrl, init) => {
- const { dispatchFetchEvent } = await import('./runtime/index.js');
- return dispatchFetchEvent(url, bodyUrl, init);
- },
- url,
- bodyUrl,
- // @ts-ignore
- init
- );
-
- for (const [key, value] of Array.from(Object.entries(headers))) {
- const newKey = unescapeHeaderName(key);
- delete headers[key];
- headers[newKey] = value;
- }
-
- res.writeHead(status, statusText, headers);
- res.write(Buffer.from(body, 'binary'));
- res.end();
- logger.log(statusChalk(status)(`${status} ${method.padEnd(7)} ${url}`));
- this.emit('request-end', method, url, status, statusText);
- };
-
- /**
- * @param {import('puppeteer').Page} page
- */
- async forkConsoleLog(page) {
- await page.evaluate(() => {
- /** @type {('log' | 'debug' | 'info' | 'warn' | 'error')[]} */
- const methods = ['log', 'debug', 'info', 'warn', 'error'];
- for (const method of methods) {
- const browser = console[method];
- /** @type {(...args: any[]) => void} */
- console[method] = function (...args) {
- browser(...args);
- nodeConsoleLog(...args);
- };
- }
- });
- }
-}
-
-/** @type {(...args: any[]) => void} */
-const nodeConsoleLog = (...args) => logger.log(...args);
-
-/**
- * @param {number} code
- */
-function statusChalk(code) {
- if (code >= 500) {
- return chalk.red.dim;
- }
- if (code >= 400) {
- return chalk.gray.dim;
- }
- if (code >= 300) {
- return chalk.yellow.dim;
- }
- if (code >= 200) {
- return chalk.green.dim;
- }
- return chalk.blue.dim;
-}
diff --git a/packages/dev/test/index.js b/packages/dev/test/index.js
deleted file mode 100644
index b778c6d1..00000000
--- a/packages/dev/test/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import fs from 'fs-extra';
-import { setLogger } from '../src/logger.js';
-import { NullLogger } from './null-logger.js';
-
-const moduleNames = ['./run-command.spec.js', './test-command.spec.js'];
-
-async function run() {
- setLogger(new NullLogger());
- for (const moduleName of moduleNames) {
- const m = await import(moduleName);
- const methods = Object.keys(m).filter(method => /^assert/.test(method));
- for (const method of methods) {
- console.log(method);
- await fs.remove('test/fixtures');
- await m[method]();
- }
- }
- await fs.remove('test/fixtures');
-}
-
-/** @type {(err: any) => void} */
-const errorHandler = err => {
- console.error(err);
- process.exit(1);
-};
-process.on('unhandledRejection', errorHandler);
-process.on('uncaughtException', errorHandler);
-
-run();
diff --git a/packages/dev/test/null-logger.js b/packages/dev/test/null-logger.js
deleted file mode 100644
index 1bc5532c..00000000
--- a/packages/dev/test/null-logger.js
+++ /dev/null
@@ -1,34 +0,0 @@
-export class NullLogger {
- constructor() {}
-
- /**
- * @param {string} message
- */
- progress(message) {}
-
- /**
- * @param {any[]} args
- */
- log(...args) {}
-
- /**
- * @param {string} message
- */
- info(message) {}
-
- /**
- * @param {string} message
- * @param {number} [time]
- */
- success(message, time) {}
-
- /**
- * @param {string} message
- */
- warn(message) {}
-
- /**
- * @param {any} err
- */
- error(err) {}
-}
diff --git a/packages/dev/test/run-command.spec.js b/packages/dev/test/run-command.spec.js
deleted file mode 100644
index 2dafece8..00000000
--- a/packages/dev/test/run-command.spec.js
+++ /dev/null
@@ -1,296 +0,0 @@
-import assert from 'assert';
-import fs from 'fs-extra';
-import fetch from 'node-fetch';
-import { RunCommand } from '../src/cli/run-command.js';
-
-const port = 1234;
-
-export async function assertBundlesJavaScriptWorker() {
- const entry = './test/fixtures/worker.js';
- const code = `
- import { status } from './status.js';
- addEventListener('fetch', e => e.respondWith(new Response('', { status })));`;
- await fs.outputFile(entry, code);
- await fs.outputFile(
- './test/fixtures/status.js',
- 'export const status = 200;'
- );
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: false,
- kv: []
- });
- await command.execute();
- const response = await fetch('http://localhost:1234');
- assert.equal(response.status, 200);
- command.dispose();
-}
-
-export async function assertBundlesTypeScriptWorker() {
- const entry = './test/fixtures/worker.ts';
- const code = `
- import { status } from './status.js';
- // @ts-ignore
- addEventListener('fetch', e => e.respondWith(new Response('', { status })));`;
- await fs.outputFile(entry, code);
- await fs.outputFile(
- './test/fixtures/status.js',
- 'export const status = 200;'
- );
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: true,
- kv: []
- });
- await command.execute();
- const response = await fetch('http://localhost:1234');
- assert.equal(response.status, 200);
- command.dispose();
-}
-
-export async function assertRespondsWith503WhenFetchListenerIsNotAdded() {
- const entry = './test/fixtures/worker.js';
- const code = `console.log('hello world')`;
- await fs.outputFile(entry, code);
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: true,
- kv: []
- });
- await command.execute();
- const response = await fetch('http://localhost:1234');
- assert.equal(response.status, 503);
- command.dispose();
-}
-
-export async function assertWatchesForChanges() {
- const entry = './test/fixtures/worker.js';
- let code = `console.log('hello world')`;
- await fs.outputFile(entry, code);
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: true,
- check: true,
- kv: []
- });
- await command.execute();
- let response = await fetch('http://localhost:1234');
- assert.equal(response.status, 503);
-
- const updated = new Promise(resolve =>
- command.host.on('worker-updated', resolve)
- );
- code = `
- // @ts-ignore
- addEventListener('fetch', e => e.respondWith(new Response('', { status: 200 })))`;
- await fs.outputFile(entry, code);
- await updated;
- response = await fetch('http://localhost:1234');
- assert.equal(response.status, 200);
- command.dispose();
-}
-
-export async function assertCanReadRequestBody() {
- const entry = './test/fixtures/worker.js';
- const code = `
- addEventListener('fetch', async event => {
- const response = new Response(event.request.body, { status: 200, headers: { 'content-type': 'application/json' } });
- event.respondWith(response);
- });`;
- await fs.outputFile(entry, code);
- const { RunCommand } = await import('../src/cli/run-command.js');
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: true,
- kv: []
- });
- await command.execute();
- const data = { hello: 'world' };
- const response = await fetch('http://localhost:1234', {
- method: 'POST',
- body: JSON.stringify(data)
- });
- assert.equal(response.status, 200);
- assert.deepEqual(await response.json(), data);
- command.dispose();
-}
-
-export async function assertCanReadRequestCookieHeader() {
- const cookie = 'test cookie';
- const entry = './test/fixtures/worker.js';
- const code = `
- addEventListener('fetch', event => {
- const cookie = event.request.headers.get('cookie');
- const response = new Response(cookie, { status: 200 });
- event.respondWith(response);
- });`;
- await fs.outputFile(entry, code);
- const { RunCommand } = await import('../src/cli/run-command.js');
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: true,
- kv: []
- });
- await command.execute();
- const response = await fetch('http://localhost:1234', {
- headers: { cookie }
- });
- assert.equal(response.status, 200);
- assert.equal(await response.text(), cookie);
- command.dispose();
-}
-
-export async function assertCanRespondWithSetCookieHeader() {
- const cookie = 'test cookie';
- const entry = './test/fixtures/worker.js';
- const code = `
- addEventListener('fetch', event => {
- const response = new Response('', { status: 200 });
- response.headers.set('set-cookie', '${cookie}');
- event.respondWith(response);
- });`;
- await fs.outputFile(entry, code);
- const { RunCommand } = await import('../src/cli/run-command.js');
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: true,
- kv: []
- });
- await command.execute();
-
- const response = await fetch('http://localhost:1234');
- assert.equal(response.status, 200);
- assert.equal(response.headers.get('set-cookie'), 'test cookie');
- command.dispose();
-}
-
-export async function assertCanReadWriteCache() {
- const entry = './test/fixtures/worker.js';
- const code = `
- addEventListener('fetch', async e => {
- await caches.default.put('/', new Response(undefined, { status: 201, statusText: 'no content' }));
- const response = await caches.default.match('/');
- e.respondWith(response);
- });`;
- await fs.outputFile(entry, code);
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: false,
- check: false,
- kv: []
- });
- await command.execute();
- const response = await fetch('http://localhost:1234');
- assert.equal(response.status, 201);
- assert.equal(response.statusText, 'no content');
- command.dispose();
-}
-
-export async function assertCanServeStaticSite() {
- const entry = './test/fixtures/worker.js';
- const code = `
- addEventListener('fetch', async e => {
- const key = JSON.parse(__STATIC_CONTENT_MANIFEST)['index.html'];
- const body = await __STATIC_CONTENT.get(key, 'stream');
- e.respondWith(new Response(body));
- });`;
- await fs.outputFile(entry, code);
- await fs.outputFile(
- './test/fixtures/public/index.html',
- 'hello world'
- );
- await fs.outputFile(
- './test/fixtures/public/node_modules/ignored.js',
- 'var x = 1;'
- );
- await fs.outputFile('./test/fixtures/public/foo/bar.js', 'var bar = 2;');
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: true,
- check: false,
- site: 'test/fixtures/public',
- kv: []
- });
- await command.execute();
- const response = await fetch('http://localhost:1234');
- const html = await response.text();
- assert.equal(html, 'hello world');
-
- const updated = new Promise(resolve =>
- command.host.on('worker-updated', resolve)
- );
- await fs.outputFile(
- './test/fixtures/public/index.html',
- 'hello world 2'
- );
- await updated;
- const response2 = await fetch('http://localhost:1234');
- const html2 = await response2.text();
- assert.equal(html2, 'hello world 2');
-
- command.dispose();
-}
-
-export async function assertCanCreateKVNamespace() {
- const entry = './test/fixtures/worker.js';
- const code = `
- addEventListener('fetch', async e => {
- const body = await greetings.get('hello', 'text');
- e.respondWith(new Response(body));
- });`;
- await fs.outputFile(entry, code);
- await fs.outputFile(
- './test/fixtures/greetings.json',
- '[{ "key": "hello", "value": "world", "base64": false }]'
- );
- const command = new RunCommand({
- entry,
- port,
- inspect: false,
- watch: true,
- check: false,
- kv: ['./test/fixtures/greetings.json']
- });
- await command.execute();
- const response = await fetch('http://localhost:1234');
- const html = await response.text();
- assert.equal(html, 'world');
-
- const updated = new Promise(resolve =>
- command.host.on('worker-updated', resolve)
- );
- await fs.outputFile(
- './test/fixtures/greetings.json',
- '[{ "key": "hello", "value": "world 2", "base64": false }]'
- );
- await updated;
- const response2 = await fetch('http://localhost:1234');
- const html2 = await response2.text();
- assert.equal(html2, 'world 2');
-
- command.dispose();
-}
diff --git a/packages/dev/test/test-command.spec.js b/packages/dev/test/test-command.spec.js
deleted file mode 100644
index 08e02862..00000000
--- a/packages/dev/test/test-command.spec.js
+++ /dev/null
@@ -1,115 +0,0 @@
-import assert from 'assert';
-import fs from 'fs-extra';
-import { TestCommand } from '../src/cli/test-command.js';
-
-const port = 1234;
-const passingSpec = `
-import { expect } from 'chai';
-import { describe, it } from 'mocha';
-
-describe('foo', () => {
- it('bar', () => {
- expect('a').to.equal('a');
- });
-});`;
-const failingSpec = `
-import { expect } from 'chai';
-import { describe, it } from 'mocha';
-
-describe('hello', () => {
- it('world', () => {
- expect('b').to.equal('c');
- });
-});`;
-
-export async function assertBundlesJavaScriptTests() {
- await fs.outputFile('./test/fixtures/a.spec.js', passingSpec);
- await fs.outputFile('./test/fixtures/b.spec.js', failingSpec);
- const command = new TestCommand({
- globs: ['test/fixtures/*.spec.js'],
- port,
- inspect: false,
- watch: true,
- check: true,
- kv: []
- });
-
- let testEnd = new Promise(resolve =>
- command.testHost.on('test-end', resolve)
- );
- command.execute();
- assert.equal(await testEnd, 1);
-
- testEnd = new Promise(resolve => command.testHost.on('test-end', resolve));
- await fs.outputFile('./test/fixtures/b.spec.js', passingSpec);
- assert.equal(await testEnd, 0);
-
- command.dispose();
-}
-
-export async function assertBundlesTypeScriptTests() {
- await fs.outputFile('./test/fixtures/a.spec.ts', passingSpec);
- await fs.outputFile('./test/fixtures/b.spec.ts', failingSpec);
- const command = new TestCommand({
- globs: ['test/fixtures/*.spec.ts'],
- port,
- inspect: false,
- watch: true,
- check: true,
- kv: []
- });
-
- let testEnd = new Promise(resolve =>
- command.testHost.on('test-end', resolve)
- );
- command.execute();
- assert.equal(await testEnd, 1);
-
- testEnd = new Promise(resolve => command.testHost.on('test-end', resolve));
- await fs.outputFile('./test/fixtures/b.spec.ts', passingSpec);
- assert.equal(await testEnd, 0);
-
- command.dispose();
-}
-
-export async function assertSupportsStaticSiteTests() {
- const siteSpec = `
- import { expect } from 'chai';
- import { describe, it } from 'mocha';
-
- describe('manifest', () => {
- const manifest = JSON.parse(__STATIC_CONTENT_MANIFEST);
- it('has index.html', () => {
- expect(manifest['index.html']).to.equal('index.503adfccd7.html');
- });
- });`;
- await fs.outputFile('./test/fixtures/site.spec.js', siteSpec);
- await fs.outputFile(
- './test/fixtures/public/index.html',
- 'hello world'
- );
- const command = new TestCommand({
- globs: ['test/fixtures/*.spec.js'],
- port,
- inspect: false,
- watch: true,
- check: true,
- site: 'test/fixtures/public',
- kv: []
- });
-
- let testEnd = new Promise(resolve =>
- command.testHost.on('test-end', resolve)
- );
- command.execute();
- assert.equal(await testEnd, 0);
-
- testEnd = new Promise(resolve => command.testHost.on('test-end', resolve));
- await fs.outputFile(
- './test/fixtures/public/index.html',
- 'hello world 2'
- );
- assert.equal(await testEnd, 1);
-
- command.dispose();
-}
diff --git a/packages/examples/package.json b/packages/examples/package.json
index bcbe434a..d20c0651 100644
--- a/packages/examples/package.json
+++ b/packages/examples/package.json
@@ -31,11 +31,9 @@
"@cfworker/jwt": "^4.0.4",
"@cfworker/sentry": "^2.0.0",
"@cfworker/web": "^1.13.0",
- "@cfworker/worker-types": "^1.12.3",
"@cloudflare/workers-types": "^2.2.2"
},
"devDependencies": {
- "@cfworker/dev": "^1.14.2",
"typescript": "^4.8.4"
}
}
diff --git a/packages/examples/tsconfig.json b/packages/examples/tsconfig.json
index 2ba40060..441eab05 100644
--- a/packages/examples/tsconfig.json
+++ b/packages/examples/tsconfig.json
@@ -1,14 +1,9 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"composite": false
}
}
diff --git a/packages/json-schema/package.json b/packages/json-schema/package.json
index 2f7cec57..71eac11e 100644
--- a/packages/json-schema/package.json
+++ b/packages/json-schema/package.json
@@ -38,7 +38,6 @@
"test": "cfworker test test/**/*.spec.ts --nocheck"
},
"devDependencies": {
- "@cfworker/dev": "^1.14.2",
"@types/chai": "^4.3.3",
"@types/mocha": "^10.0.0",
"chai": "^4.3.6",
diff --git a/packages/json-schema/tsconfig.json b/packages/json-schema/tsconfig.json
index 376bde2c..445c7819 100644
--- a/packages/json-schema/tsconfig.json
+++ b/packages/json-schema/tsconfig.json
@@ -1,14 +1,9 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"outDir": "dist",
"rootDir": "./src"
},
diff --git a/packages/jwt/package.json b/packages/jwt/package.json
index 6b4fbfa5..1285bac7 100644
--- a/packages/jwt/package.json
+++ b/packages/jwt/package.json
@@ -34,12 +34,10 @@
"test": "cfworker test test/**/*.spec.ts --nocheck"
},
"dependencies": {
- "@cfworker/worker-types": "^1.12.3",
"@cloudflare/workers-types": "^2.2.2",
"rfc4648": "^1.5.2"
},
"devDependencies": {
- "@cfworker/dev": "^1.14.2",
"@types/chai": "^4.3.3",
"@types/mocha": "^10.0.0",
"chai": "^4.3.6",
diff --git a/packages/jwt/tsconfig.json b/packages/jwt/tsconfig.json
index 0f14d1ae..6eb602d5 100644
--- a/packages/jwt/tsconfig.json
+++ b/packages/jwt/tsconfig.json
@@ -1,17 +1,12 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"outDir": "dist",
"rootDir": "./src"
},
"include": ["src"],
- "references": [{ "path": "../base64url" }]
+ "references": []
}
diff --git a/packages/sentry/package.json b/packages/sentry/package.json
index 1908f1d1..5fa5a918 100644
--- a/packages/sentry/package.json
+++ b/packages/sentry/package.json
@@ -35,7 +35,6 @@
"test": "cfworker test test/**/*.spec.ts"
},
"dependencies": {
- "@cfworker/worker-types": "^1.12.3",
"@cloudflare/workers-types": "^2.2.2"
},
"devDependencies": {
diff --git a/packages/sentry/tsconfig.json b/packages/sentry/tsconfig.json
index 4f2df927..2f1b4f71 100644
--- a/packages/sentry/tsconfig.json
+++ b/packages/sentry/tsconfig.json
@@ -1,14 +1,9 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"outDir": "dist",
"rootDir": "./src"
},
diff --git a/packages/site/package.json b/packages/site/package.json
index 019e71f8..2b45e2ea 100644
--- a/packages/site/package.json
+++ b/packages/site/package.json
@@ -21,11 +21,9 @@
},
"dependencies": {
"@cfworker/web": "^1.12.5",
- "@cfworker/worker-types": "^1.12.3",
"@cloudflare/workers-types": "^2.2.2"
},
"devDependencies": {
- "@cfworker/dev": "^1.14.2",
"typescript": "^4.8.4"
}
}
diff --git a/packages/site/tsconfig.json b/packages/site/tsconfig.json
index 2ba40060..441eab05 100644
--- a/packages/site/tsconfig.json
+++ b/packages/site/tsconfig.json
@@ -1,14 +1,9 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"composite": false
}
}
diff --git a/packages/uuid/package.json b/packages/uuid/package.json
index 7e40b595..18d255a2 100644
--- a/packages/uuid/package.json
+++ b/packages/uuid/package.json
@@ -36,7 +36,6 @@
"test": "cfworker test test/**/*.spec.ts"
},
"devDependencies": {
- "@cfworker/dev": "^1.14.2",
"@types/chai": "^4.3.3",
"@types/mocha": "^10.0.0",
"chai": "^4.3.6",
diff --git a/packages/uuid/tsconfig.json b/packages/uuid/tsconfig.json
index 376bde2c..445c7819 100644
--- a/packages/uuid/tsconfig.json
+++ b/packages/uuid/tsconfig.json
@@ -1,14 +1,9 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"outDir": "dist",
"rootDir": "./src"
},
diff --git a/packages/web/package.json b/packages/web/package.json
index 2086916f..76f6659f 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -35,7 +35,6 @@
},
"dependencies": {
"@cfworker/json-schema": "^1.12.6",
- "@cfworker/worker-types": "^1.12.3",
"@cloudflare/workers-types": "^2.2.2",
"@types/cookie": "^0.5.1",
"@types/html-escaper": "^3.0.0",
@@ -48,7 +47,6 @@
"statuses": "^2.0.1"
},
"devDependencies": {
- "@cfworker/dev": "^1.14.2",
"@types/chai": "^4.3.3",
"@types/mocha": "^10.0.0",
"chai": "^4.3.6",
diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json
index 3ab2d932..dc8139b1 100644
--- a/packages/web/tsconfig.json
+++ b/packages/web/tsconfig.json
@@ -1,14 +1,9 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
- "target": "ES2021",
+ "target": "ESNext",
"lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": [
- "chai",
- "mocha",
- "@cfworker/worker-types",
- "@cloudflare/workers-types"
- ],
+ "types": ["chai", "mocha", "@cloudflare/workers-types"],
"outDir": "dist",
"rootDir": "./src"
},
diff --git a/packages/worker-types/CHANGELOG.md b/packages/worker-types/CHANGELOG.md
deleted file mode 100644
index b7d86ec9..00000000
--- a/packages/worker-types/CHANGELOG.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# @cfworker/worker-types
-
-## 1.12.3
-
-### Patch Changes
-
-- fc4c040: Update dependencies
-
-## 1.12.2
-
-### Patch Changes
-
-- 1748ed6: Update dependencies
-
-## 1.12.1
-
-### Patch Changes
-
-- d2390db: Update dependencies
-
-## 1.12.0
-
-### Minor Changes
-
-- 5ed7223: Downgrade @cloudflare/workers-types to 2.2.2
-
-## 1.11.0
-
-### Minor Changes
-
-- 122dcd9: Update @cloudflare/workers-types to 3.2.x and TypeScript to 4.5.x
-
-## 1.10.2
-
-### Patch Changes
-
-- 390ce91: Update Typescript to 4.5.2
diff --git a/packages/worker-types/README.md b/packages/worker-types/README.md
deleted file mode 100644
index 1380ff43..00000000
--- a/packages/worker-types/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# @cfworker/worker-types
-
-
-
-TypeScript type definitions for Cloudflare workers.
diff --git a/packages/worker-types/index.d.ts b/packages/worker-types/index.d.ts
deleted file mode 100644
index e8a8d626..00000000
--- a/packages/worker-types/index.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-interface ErrorConstructor {
- captureStackTrace(thisArg: any, func: any): void;
-}
-
-interface JsonWebKey {
- x5c?: string[];
- kid?: string;
- x5t?: string;
- n?: string;
-}
-
-interface Crypto {
- randomUUID(): string;
-}
diff --git a/packages/worker-types/package.json b/packages/worker-types/package.json
deleted file mode 100644
index 7d95e101..00000000
--- a/packages/worker-types/package.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "@cfworker/worker-types",
- "version": "1.12.3",
- "description": "TypeScript type definitions for Cloudflare workers",
- "keywords": [
- "cloudflare",
- "worker",
- "workers"
- ],
- "types": "dist/index.d.ts",
- "files": [
- "**/*.d.ts",
- "tsconfig.json",
- "README.md",
- "package.json"
- ],
- "repository": "https://github.com/cfworker/cfworker",
- "author": "Jeremy Danyow ",
- "homepage": "https://github.com/cfworker/cfworker/tree/master/packages/worker-types/README.md",
- "license": "MIT",
- "publishConfig": {
- "access": "public"
- },
- "scripts": {
- "build": "tsc --build",
- "clean": "tsc --build --clean",
- "test": "echo test"
- },
- "devDependencies": {
- "typescript": "^4.8.4"
- }
-}
diff --git a/packages/worker-types/tsconfig.json b/packages/worker-types/tsconfig.json
deleted file mode 100644
index 089d6053..00000000
--- a/packages/worker-types/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "../../tsconfig-base",
- "compilerOptions": {
- "target": "ES2021",
- "lib": ["ESNext", "WebWorker", "Webworker.Iterable"],
- "types": ["@cloudflare/workers-types"],
- "composite": false
- }
-}