From 4e87195739f2a5d9a05451b48773c8afdc680765 Mon Sep 17 00:00:00 2001 From: akiyamn Date: Sun, 24 Sep 2023 23:22:21 +1000 Subject: Initial commit (by create-cloudflare CLI) --- .../node-modules-polyfill/src/index.test.ts | 200 +++++++++++++++++++++ .../node-modules-polyfill/src/index.ts | 133 ++++++++++++++ .../node-modules-polyfill/src/polyfills.ts | 151 ++++++++++++++++ 3 files changed, 484 insertions(+) create mode 100644 node_modules/@esbuild-plugins/node-modules-polyfill/src/index.test.ts create mode 100644 node_modules/@esbuild-plugins/node-modules-polyfill/src/index.ts create mode 100644 node_modules/@esbuild-plugins/node-modules-polyfill/src/polyfills.ts (limited to 'node_modules/@esbuild-plugins/node-modules-polyfill/src') diff --git a/node_modules/@esbuild-plugins/node-modules-polyfill/src/index.test.ts b/node_modules/@esbuild-plugins/node-modules-polyfill/src/index.test.ts new file mode 100644 index 0000000..92792e6 --- /dev/null +++ b/node_modules/@esbuild-plugins/node-modules-polyfill/src/index.test.ts @@ -0,0 +1,200 @@ +import { build } from 'esbuild' +import { writeFiles } from 'test-support' +import fs from 'fs' +import NodeModulesPolyfillsPlugin from '.' +import NodeGlobalsPolyfillsPlugin from '@esbuild-plugins/node-globals-polyfill' + +require('debug').enable(require('../package.json').name) + +test('works', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': `import {x} from './utils'; console.log(x);`, + 'utils.ts': `import path from 'path'; import { Buffer } from 'buffer'; export const x = path.resolve(Buffer.from('x').toString());`, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + eval(res.outputFiles[0].text) + // console.log(res.outputFiles[0].text) + unlink() +}) + +test('works with SafeBuffer and other package consumers', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': `import {Buffer as SafeBuffer} from './safe-buffer'; console.log(SafeBuffer);`, + 'safe-buffer.ts': fs + .readFileSync(require.resolve('safe-buffer')) + .toString(), + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + // console.log( + // res.outputFiles[0].text + // .split('\n') + // .map((x, i) => i + ' ' + x) + // .join('\n'), + // ) + eval(res.outputFiles[0].text) + unlink() +}) + +test('events works', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': ` + import EventEmitter from 'events'; + + class Test extends EventEmitter { + constructor() { }; + } + console.log(Test) + `, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + // console.log(res.outputFiles[0].text) + eval(res.outputFiles[0].text) + unlink() +}) + +test('require can use default export', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': ` + const assert = require('assert') + // console.log(assert) + assert('ok') + `, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + // console.log(res.outputFiles[0].text) + eval(res.outputFiles[0].text) + unlink() +}) + +test.skip('crypto', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': `import { randomBytes } from 'crypto'; console.log(randomBytes(20).toString('hex'))`, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + eval(res.outputFiles[0].text) + // console.log(res.outputFiles[0].text) + unlink() +}) +test.skip('fs', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': `import { readFile } from 'fs'; console.log(readFile(''))`, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + eval(res.outputFiles[0].text) + // console.log(res.outputFiles[0].text) + unlink() +}) + +test('does not include global keyword', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': `import {x} from './utils'; console.log(x);`, + 'utils.ts': `import path from 'path'; import { Buffer } from 'buffer'; export const x = path.resolve(Buffer.from('x').toString());`, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin()], + }) + const text = res.outputFiles[0].text + eval(text) + expect(text).not.toContain(/\bglobal\b/) + // console.log(res.outputFiles[0].text) + unlink() +}) + +test('works with globals polyfills', async () => { + const { + unlink, + paths: [ENTRY], + } = await writeFiles({ + 'entry.ts': `import {x} from './utils'; console.log(x);`, + 'utils.ts': `import path from 'path'; import { Buffer } from 'buffer'; export const x = path.resolve(Buffer.from('x').toString());`, + }) + // const outfile = randomOutputFile() + const res = await build({ + entryPoints: [ENTRY], + write: false, + format: 'esm', + target: 'es2017', + bundle: true, + plugins: [NodeModulesPolyfillsPlugin(), NodeGlobalsPolyfillsPlugin()], + }) + const text = res.outputFiles[0].text + eval(text) + console.log(text) + // console.log(res.outputFiles[0].text) + unlink() +}) diff --git a/node_modules/@esbuild-plugins/node-modules-polyfill/src/index.ts b/node_modules/@esbuild-plugins/node-modules-polyfill/src/index.ts new file mode 100644 index 0000000..f7397e4 --- /dev/null +++ b/node_modules/@esbuild-plugins/node-modules-polyfill/src/index.ts @@ -0,0 +1,133 @@ +import { OnResolveArgs, Plugin } from 'esbuild' +import escapeStringRegexp from 'escape-string-regexp' +import fs from 'fs' +import path from 'path' +import esbuild from 'esbuild' +import { builtinsPolyfills } from './polyfills' + +// import { NodeResolvePlugin } from '@esbuild-plugins/node-resolve' +const NAME = 'node-modules-polyfills' +const NAMESPACE = NAME + +function removeEndingSlash(importee) { + if (importee && importee.slice(-1) === '/') { + importee = importee.slice(0, -1) + } + return importee +} + +export interface NodePolyfillsOptions { + name?: string + namespace?: string +} + +export function NodeModulesPolyfillPlugin( + options: NodePolyfillsOptions = {}, +): Plugin { + const { namespace = NAMESPACE, name = NAME } = options + if (namespace.endsWith('commonjs')) { + throw new Error(`namespace ${namespace} must not end with commonjs`) + } + // this namespace is needed to make ES modules expose their default export to require: require('assert') will give you import('assert').default + const commonjsNamespace = namespace + '-commonjs' + const polyfilledBuiltins = builtinsPolyfills() + const polyfilledBuiltinsNames = [...polyfilledBuiltins.keys()] + + return { + name, + setup: function setup({ onLoad, onResolve, initialOptions }) { + // polyfills contain global keyword, it must be defined + if (initialOptions?.define && !initialOptions.define?.global) { + initialOptions.define['global'] = 'globalThis' + } else if (!initialOptions?.define) { + initialOptions.define = { global: 'globalThis' } + } + + // TODO these polyfill module cannot import anything, is that ok? + async function loader( + args: esbuild.OnLoadArgs, + ): Promise { + try { + const argsPath = args.path.replace(/^node:/, '') + const isCommonjs = args.namespace.endsWith('commonjs') + + const resolved = polyfilledBuiltins.get( + removeEndingSlash(argsPath), + ) + const contents = await ( + await fs.promises.readFile(resolved) + ).toString() + let resolveDir = path.dirname(resolved) + + if (isCommonjs) { + return { + loader: 'js', + contents: commonJsTemplate({ + importPath: argsPath, + }), + resolveDir, + } + } + return { + loader: 'js', + contents, + resolveDir, + } + } catch (e) { + console.error('node-modules-polyfill', e) + return { + contents: `export {}`, + loader: 'js', + } + } + } + onLoad({ filter: /.*/, namespace }, loader) + onLoad({ filter: /.*/, namespace: commonjsNamespace }, loader) + const filter = new RegExp( + [ + ...polyfilledBuiltinsNames, + ...polyfilledBuiltinsNames.map((n) => `node:${n}`), + ] + .map(escapeStringRegexp) + .join('|'), // TODO builtins could end with slash, keep in mind in regex + ) + async function resolver(args: OnResolveArgs) { + const argsPath = args.path.replace(/^node:/, '') + const ignoreRequire = args.namespace === commonjsNamespace + + if (!polyfilledBuiltins.has(argsPath)) { + return + } + + const isCommonjs = + !ignoreRequire && args.kind === 'require-call' + + return { + namespace: isCommonjs ? commonjsNamespace : namespace, + path: argsPath, + } + } + onResolve({ filter }, resolver) + // onResolve({ filter: /.*/, namespace }, resolver) + }, + } +} + +function commonJsTemplate({ importPath }) { + return ` +const polyfill = require('${importPath}') + +if (polyfill && polyfill.default) { + module.exports = polyfill.default + for (let k in polyfill) { + module.exports[k] = polyfill[k] + } +} else if (polyfill) { + module.exports = polyfill +} + + +` +} + +export default NodeModulesPolyfillPlugin diff --git a/node_modules/@esbuild-plugins/node-modules-polyfill/src/polyfills.ts b/node_modules/@esbuild-plugins/node-modules-polyfill/src/polyfills.ts new file mode 100644 index 0000000..cea5f8d --- /dev/null +++ b/node_modules/@esbuild-plugins/node-modules-polyfill/src/polyfills.ts @@ -0,0 +1,151 @@ +// Taken from https://github.com/ionic-team/rollup-plugin-node-polyfills/blob/master/src/modules.ts + +import { NodePolyfillsOptions } from '.' + +const EMPTY_PATH = require.resolve( + 'rollup-plugin-node-polyfills/polyfills/empty.js', +) + +export function builtinsPolyfills() { + const libs = new Map() + + libs.set( + 'process', + require.resolve('rollup-plugin-node-polyfills/polyfills/process-es6'), + ) + libs.set( + 'buffer', + require.resolve('rollup-plugin-node-polyfills/polyfills/buffer-es6'), + ) + libs.set( + 'util', + require.resolve('rollup-plugin-node-polyfills/polyfills/util'), + ) + libs.set('sys', libs.get('util')) + libs.set( + 'events', + require.resolve('rollup-plugin-node-polyfills/polyfills/events'), + ) + libs.set( + 'stream', + require.resolve('rollup-plugin-node-polyfills/polyfills/stream'), + ) + libs.set( + 'path', + require.resolve('rollup-plugin-node-polyfills/polyfills/path'), + ) + libs.set( + 'querystring', + require.resolve('rollup-plugin-node-polyfills/polyfills/qs'), + ) + libs.set( + 'punycode', + require.resolve('rollup-plugin-node-polyfills/polyfills/punycode'), + ) + libs.set( + 'url', + require.resolve('rollup-plugin-node-polyfills/polyfills/url'), + ) + libs.set( + 'string_decoder', + require.resolve( + 'rollup-plugin-node-polyfills/polyfills/string-decoder', + ), + ) + libs.set( + 'http', + require.resolve('rollup-plugin-node-polyfills/polyfills/http'), + ) + libs.set( + 'https', + require.resolve('rollup-plugin-node-polyfills/polyfills/http'), + ) + libs.set('os', require.resolve('rollup-plugin-node-polyfills/polyfills/os')) + libs.set( + 'assert', + require.resolve('rollup-plugin-node-polyfills/polyfills/assert'), + ) + libs.set( + 'constants', + require.resolve('rollup-plugin-node-polyfills/polyfills/constants'), + ) + libs.set( + '_stream_duplex', + require.resolve( + 'rollup-plugin-node-polyfills/polyfills/readable-stream/duplex', + ), + ) + libs.set( + '_stream_passthrough', + require.resolve( + 'rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough', + ), + ) + libs.set( + '_stream_readable', + require.resolve( + 'rollup-plugin-node-polyfills/polyfills/readable-stream/readable', + ), + ) + libs.set( + '_stream_writable', + require.resolve( + 'rollup-plugin-node-polyfills/polyfills/readable-stream/writable', + ), + ) + libs.set( + '_stream_transform', + require.resolve( + 'rollup-plugin-node-polyfills/polyfills/readable-stream/transform', + ), + ) + libs.set( + 'timers', + require.resolve('rollup-plugin-node-polyfills/polyfills/timers'), + ) + libs.set( + 'console', + require.resolve('rollup-plugin-node-polyfills/polyfills/console'), + ) + libs.set('vm', require.resolve('rollup-plugin-node-polyfills/polyfills/vm')) + libs.set( + 'zlib', + require.resolve('rollup-plugin-node-polyfills/polyfills/zlib'), + ) + libs.set( + 'tty', + require.resolve('rollup-plugin-node-polyfills/polyfills/tty'), + ) + libs.set( + 'domain', + require.resolve('rollup-plugin-node-polyfills/polyfills/domain'), + ) + + // not shimmed + libs.set('dns', EMPTY_PATH) + libs.set('dgram', EMPTY_PATH) + libs.set('child_process', EMPTY_PATH) + libs.set('cluster', EMPTY_PATH) + libs.set('module', EMPTY_PATH) + libs.set('net', EMPTY_PATH) + libs.set('readline', EMPTY_PATH) + libs.set('repl', EMPTY_PATH) + libs.set('tls', EMPTY_PATH) + libs.set('fs', EMPTY_PATH) + libs.set('crypto', EMPTY_PATH) + + // libs.set( + // 'fs', + // require.resolve('rollup-plugin-node-polyfills/polyfills/browserify-fs'), + // ) + + // TODO enable crypto and fs https://github.com/ionic-team/rollup-plugin-node-polyfills/issues/20 + // libs.set( + // 'crypto', + // require.resolve( + // 'rollup-plugin-node-polyfills/polyfills/crypto-browserify', + // ), + // ) + + return libs +} -- cgit v1.2.3