diff --git a/README.md b/README.md
index acec985..6454900 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
-[![Node.js CI](https://github.com/juanelas/bigint-mod-arith/workflows/build/badge.svg)](https://github.com/juanelas/bigint-mod-arith/actions?query=workflow%3A%22build%22)
+[![Node.js CI](https://github.com/juanelas/bigint-mod-arith/actions/workflows/nodejs.yml/badge.svg)](https://github.com/juanelas/bigint-mod-arith/actions/workflows/nodejs.yml)
[![Coverage Status](https://coveralls.io/repos/github/juanelas/bigint-mod-arith/badge.svg?branch=master)](https://coveralls.io/github/juanelas/bigint-mod-arith?branch=master)
# bigint-mod-arith
@@ -24,7 +24,7 @@ Then either require (Node.js CJS):
const bigintModArith = require('bigint-mod-arith')
```
-> **Node >=10.4 <11**. `bigint-mod-arith` uses workers to speed up some operations. Workers are enabled by default with Node.js from version 11. In order to use them with Node >=10.4 and <11, you need to execute node with the flag `--experimental-worker`, and require the .js file manually (otherwise .cjs is required by default and would not be supported by the workers)
+> **Node >=10.4 <11**. `bigint-mod-arith` uses workers to speed up some operations. Workers are enabled by default with Node.js from version 11. In order to use them with Node >=10.4 and <11, you need to execute node with the flag `--experimental-worker`, and require the `.js` file manually (otherwise `.cjs` is required by default and would not be supported by the workers)
>
> ```javascript
> const bigintCryptoUtils = require('bigint-crypto-utils/dist/cjs/index.node') // ONLY FOR node >=10.4 <11 !
diff --git a/build/bin/mocha-ts.cjs b/build/bin/mocha-ts.cjs
index 1914e20..2a96f20 100644
--- a/build/bin/mocha-ts.cjs
+++ b/build/bin/mocha-ts.cjs
@@ -1,75 +1,166 @@
#! /usr/bin/env node
+const fs = require('fs')
const path = require('path')
-const childProcess = require('child_process')
+const glob = require('glob')
+const minimatch = require('minimatch')
+const rimraf = require('rimraf')
+const runScript = require('../run-script.cjs')
const rootDir = path.join(__dirname, '../..')
-const mochaTsRelativeDir = '.mocha-ts'
-const minimatch = require('minimatch')
-const glob = require('glob')
-// First let us prepare the args to pass to mocha.
-// ts.files will be replaced by their js-transpiled counterparts
-// a watch file to our semaphore will be added
-const processedArgs = processArgs(process.argv.slice(2))
+const pkgJson = require(path.join(rootDir, 'package.json'))
-// Now we can run a script and invoke a callback when complete, e.g.
-runScript(path.join(rootDir, 'node_modules/mocha/bin/mocha'), processedArgs)
+const mochaTsRelativeDir = pkgJson.directories['mocha-ts']
+const mochaTsDir = path.join(rootDir, mochaTsRelativeDir)
-function processArgs (args) {
- args = process.argv.slice(2).map(arg => {
- // Let us first remove surrounding quotes in string (it gives issues in windows)
- arg = arg.replace(/^['"]/, '').replace(/['"]$/, '')
- const filenames = glob.sync(arg, { cwd: rootDir, matchBase: true })
- if (filenames.length > 0) {
- return filenames.map(file => {
- const isTsTestFile = minimatch(file, '{test/**/*.ts,src/**/*.spec.ts}', { matchBase: true })
- if (isTsTestFile) {
- return `${mochaTsRelativeDir}/${file.slice(0, -3)}.js`
- }
- return file
- })
- }
- return arg
- })
+// clean .mocha-ts directory
+rimraf.sync(mochaTsDir)
- const processedArgs = []
+const semaphorePath = `${mochaTsRelativeDir}/semaphore`
- let addSemaphore = false
- let semaphoreAdded = false
- for (const arg of args) {
- if (Array.isArray(arg)) {
- processedArgs.push(...arg)
- } else {
- processedArgs.push(arg)
- if (arg === '--watch' || arg === '-w') {
- addSemaphore = true
- } else if (arg === '--watch-files') {
- processedArgs.push(`${mochaTsRelativeDir}/semaphore`)
- semaphoreAdded = true
+const tempDir = mochaTsDir
+fs.mkdirSync(tempDir, { recursive: true })
+
+const usage = `Usage: mocha-ts [options] [spec]
+
+mocha against ts tests and modules
+
+Arguments:
+ spec One or more files, directories, or globs to test (default:
+ "{src/ts/**/*.spec.ts,test/**/*.ts}")
+
+Options:
+ -w, --watch run in watch mode. Since mocha only supports CJS in watch
+ mode. This option implies -cjs as well (default: false)
+ -cjs, --commonjs run tests against the CJS bundle instead of the ESM one
+ (default: false)
+ -h, --help display help for command
+
+`
+
+function parse () {
+ const args = process.argv.slice(2)
+
+ const help = getBooleanOption(args, '--help', '-h')
+ if (help) {
+ console.log(usage)
+ process.exit()
+ }
+
+ const requiredFile = getOption(args, '--require')
+
+ const watch = getBooleanOption(args, '--watch', '-w')
+
+ const commonjs = getBooleanOption(args, '--commonjs', '-cjs')
+ if (commonjs === false && watch === true) {
+ console.log('ERROR: mocha in watch mode only supports commonjs')
+ console.log(usage)
+ process.exit(1)
+ }
+
+ let testsGlob = (args.pop() ?? '').replace(/^['"]/, '').replace(/['"]$/, '') // Let us remove surrounding quotes in string (it gives issues in windows)
+ if (testsGlob === '') {
+ testsGlob = '{src/ts/**/*.spec.ts,test/**/*.ts}'
+ }
+
+ const mochaArgs = []
+
+ if (requiredFile !== '') {
+ mochaArgs.push('--require')
+ mochaArgs.push(requiredFile)
+ }
+ mochaArgs.push('--require')
+ mochaArgs.push('build/testing/mocha/mocha-init.cjs')
+
+ if (watch) {
+ mochaArgs.push('-w')
+ mochaArgs.push('--watch-files')
+ mochaArgs.push(semaphorePath)
+ }
+
+ if (testsGlob.substring(0, 1) === '-') {
+ console.log(usage)
+ process.exit(9)
+ }
+ let filenames = []
+ try {
+ filenames = glob.sync(testsGlob, { cwd: rootDir, matchBase: true })
+ } catch (error) {}
+ if (filenames.length === 0) {
+ console.error('invalid or empty glob pattern: ' + testsGlob)
+ console.log()
+ console.log(usage)
+ process.exit(9)
+ }
+
+ const testFiles = []
+ const jsTestFiles = []
+
+ if (filenames.length > 0) {
+ filenames.forEach(file => {
+ const isTsTestFile = minimatch(file, '{test/**/*.ts,src/**/*.spec.ts}', { matchBase: true })
+ if (isTsTestFile) {
+ testFiles.push(file)
+ const extension = commonjs ? 'cjs' : 'js'
+ jsTestFiles.push(`${mochaTsRelativeDir}/${file.slice(0, -3)}.${extension}`)
}
- }
- }
- if (addSemaphore === true || semaphoreAdded === false) {
- processedArgs.push('--watch-files')
- processedArgs.push(`${mochaTsRelativeDir}/semaphore`)
+ })
}
+ mochaArgs.push(...jsTestFiles)
- return processedArgs
+ return {
+ mochaArgs,
+ testFiles,
+ commonjs
+ }
}
-function runScript (scriptPath, args) {
- const mochaCmd = childProcess.fork(scriptPath, args, {
- cwd: rootDir
- })
+const processedArgs = parse()
+const commonjs = processedArgs.commonjs
+const testFiles = processedArgs.testFiles
+const mochaArgs = processedArgs.mochaArgs
- mochaCmd.on('error', (error) => {
- throw error
- })
+// prepare setup for mocha (it should be written to a JSON file that will be loaded by the mocha-init.cjs)
+const mochaSetup = {
+ testFiles,
+ commonjs
+}
+fs.writeFileSync(path.join(tempDir, 'testSetup.json'), JSON.stringify(mochaSetup, undefined, 2), { encoding: 'utf-8' })
- // execute the callback once the process has finished running
- mochaCmd.on('exit', function (code) {
- if (code !== 0) {
- throw new Error('exit code ' + code)
+if (commonjs) {
+ console.log('\x1b[33mℹ [mocha-ts] Running tests against the CommonJS module \x1b[0m\n')
+} else {
+ console.log('\x1b[33mℹ [mocha-ts] Running tests against the ESM module \x1b[0m\n')
+}
+
+const rollupBuilder = require('../testing/mocha/builders/RollupBuilder.cjs').rollupBuilder
+
+rollupBuilder.start({ commonjs, watch: false }).then(() => {
+ rollupBuilder.close()
+ const testsBuilder = require('../testing/mocha/builders/TestsBuilder.cjs').testBuilder
+ testsBuilder.start({ commonjs, testFiles }).then(() => {
+ testsBuilder.close()
+ // Now run mocha
+ runScript(path.join(rootDir, 'node_modules/mocha/bin/mocha'), mochaArgs)
+ })
+})
+
+function getBooleanOption (args, ...optionNames) {
+ let found = false
+ optionNames.forEach((option) => {
+ const index = args.indexOf(option)
+ if (index > -1) {
+ found = true
+ args.splice(index, 1)
}
})
+ return found
+}
+
+function getOption (args, option) {
+ const index = args.indexOf(option)
+ if (index > -1 && index < args.length - 2) {
+ return args.splice(index, 2)[1]
+ }
+ return ''
}
diff --git a/build/build.docs.cjs b/build/build.docs.cjs
index 197fde9..adaf354 100644
--- a/build/build.docs.cjs
+++ b/build/build.docs.cjs
@@ -3,7 +3,9 @@
const fs = require('fs')
const TypeDoc = require('typedoc')
const path = require('path')
+const json5 = require('json5')
const pkgJson = require('../package.json')
+const rimraf = require('rimraf')
const rootDir = path.join(__dirname, '..')
@@ -14,15 +16,25 @@ function camelise (str) {
})
}
+const tsConfigPath = path.join(rootDir, 'tsconfig.json')
+const tempTsConfigPath = path.join(rootDir, '.tsconfig.json')
+
async function typedoc () {
const app = new TypeDoc.Application()
+ // prepare tsconfig
+ const tsConfig = json5.parse(fs.readFileSync(tsConfigPath, 'utf8'))
+ tsConfig.include = ['src/ts/**/*', 'build/typings/**/*.d.ts']
+ tsConfig.exclude = ['src/**/*.spec.ts']
+ fs.writeFileSync(tempTsConfigPath, JSON.stringify(tsConfig, undefined, 2))
+
// If you want TypeDoc to load tsconfig.json / typedoc.json files
app.options.addReader(new TypeDoc.TSConfigReader())
app.options.addReader(new TypeDoc.TypeDocReader())
app.bootstrap({
// typedoc options here
+ tsconfig: tempTsConfigPath,
entryPoints: ['src/ts/index.ts'],
plugin: ['typedoc-plugin-markdown'],
includeVersion: true,
@@ -84,7 +96,7 @@ if (repoProvider) {
iifeBundle = `[IIFE bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${iifeBundlePath})`
esmBundle = `[ESM bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${esmBundlePath})`
umdBundle = `[UMD bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${umdBundlePath})`
- workflowBadget = `[![Node.js CI](https://github.com/${repoUsername}/${repoName}/workflows/build/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions?query=workflow%3A%22build%22)`
+ workflowBadget = `[![Node.js CI](https://github.com/${repoUsername}/${repoName}/actions/workflows/nodejs.yml/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions/workflows/nodejs.yml)`
coverallsBadge = `[![Coverage Status](https://coveralls.io/repos/github/${repoUsername}/${repoName}/badge.svg?branch=master)](https://coveralls.io/github/${repoUsername}/${repoName}?branch=master)`
break
@@ -117,3 +129,5 @@ const readmeFile = path.join(rootDir, 'README.md')
fs.writeFileSync(readmeFile, template)
typedoc()
+
+rimraf.sync(tempTsConfigPath)
diff --git a/build/rollup.config.js b/build/rollup.config.js
index 7d00eea..f19f4cc 100644
--- a/build/rollup.config.js
+++ b/build/rollup.config.js
@@ -8,8 +8,8 @@ import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import { join } from 'path'
-import { existsSync } from 'fs-extra'
-import { directories, name as _name, dependencies, peerDependencies, exports } from '../package.json'
+import { existsSync } from 'fs'
+import { directories, name as _name, exports } from '../package.json'
import { compile } from './rollup-plugin-dts.js'
const rootDir = join(__dirname, '..')
@@ -37,8 +37,6 @@ const tsBundleOptions = {
exclude: ['src/**/*.spec.ts']
}
-const external = [...Object.keys(dependencies || {}), ...Object.keys(peerDependencies || {})]
-
const sourcemapOutputOptions = {
sourcemap: 'inline',
sourcemapExcludeSources: true
@@ -54,83 +52,9 @@ function compileDts () {
}
export default [
- { // ESM for browsers and declarations
+ { // Node ESM with declarations
input: input,
output: [
- {
- file: join(rootDir, exports['.'].default),
- ...sourcemapOutputOptions,
- format: 'es'
- }
- ],
- plugins: [
- replace({
- IS_BROWSER: true,
- preventAssignment: true
- }),
- typescriptPlugin(tsBundleOptions),
- compileDts(),
- json()
- ],
- external
- },
- { // Browser bundles
- input: input,
- output: [
- {
- file: join(dstDir, 'bundles/iife.js'),
- format: 'iife',
- name: pkgCamelisedName,
- plugins: [terser()]
- },
- {
- file: join(dstDir, 'bundles/esm.js'),
- ...sourcemapOutputOptions,
- format: 'es'
- },
- {
- file: join(dstDir, 'bundles/esm.min.js'),
- format: 'es',
- plugins: [terser()]
- },
- {
- file: join(dstDir, 'bundles/umd.js'),
- format: 'umd',
- name: pkgCamelisedName,
- plugins: [terser()]
- }
- ],
- plugins: [
- replace({
- IS_BROWSER: true,
- preventAssignment: true
- }),
- typescriptPlugin(tsBundleOptions),
- resolve({
- browser: true,
- exportConditions: ['browser', 'default'],
- mainFields: ['browser', 'main']
- }),
- commonjs({
- // namedExports: {
- // 'bn.js': ['BN'],
- // 'hash.js': ['hmac', 'ripemd160', 'sha256', 'sha512'],
- // elliptic: ['ec'],
- // 'scrypt-js': ['scrypt', 'syncScrypt']
- // }
- }),
- json()
- ]
- },
- { // Node
- input: input,
- output: [
- {
- file: join(rootDir, exports['.'].node.require),
- ...sourcemapOutputOptions,
- format: 'cjs',
- exports: 'auto'
- },
{
file: join(rootDir, exports['.'].node.import),
...sourcemapOutputOptions,
@@ -143,9 +67,111 @@ export default [
preventAssignment: true
}),
typescriptPlugin(tsBundleOptions),
+ compileDts(),
+ // resolve({
+ // browser: false,
+ // exportConditions: ['node']
+ // }),
commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
json()
+ ]
+ },
+ { // Node CJS
+ input: input,
+ output: [
+ {
+ file: join(rootDir, exports['.'].node.require),
+ ...sourcemapOutputOptions,
+ format: 'cjs',
+ exports: 'auto'
+ }
],
- external
+ plugins: [
+ // replace({
+ // 'await import(': 'require(',
+ // delimiters: ['', ''],
+ // preventAssignment: true
+ // }),
+ replace({
+ IS_BROWSER: false,
+ preventAssignment: true
+ }),
+ typescriptPlugin(tsBundleOptions),
+ // resolve({
+ // browser: false,
+ // exportConditions: ['node']
+ // }),
+ commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
+ json()
+ ]
+ },
+ { // ESM for browsers
+ input: input,
+ output: [
+ {
+ file: join(rootDir, exports['.'].default),
+ ...sourcemapOutputOptions,
+ format: 'es'
+ },
+ {
+ file: join(dstDir, 'bundles/esm.js'),
+ ...sourcemapOutputOptions,
+ format: 'es'
+ },
+ {
+ file: join(dstDir, 'bundles/esm.min.js'),
+ format: 'es',
+ plugins: [terser()]
+ }
+ ],
+ plugins: [
+ replace({
+ IS_BROWSER: true,
+ preventAssignment: true
+ }),
+ typescriptPlugin(tsBundleOptions),
+ resolve({
+ browser: true,
+ exportConditions: ['browser', 'default']
+ }),
+ commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
+ json()
+ ]
+ },
+ { // Browser bundles
+ input: input,
+ output: [
+ {
+ file: join(dstDir, 'bundles/iife.js'),
+ format: 'iife',
+ name: pkgCamelisedName,
+ plugins: [terser()]
+ },
+ {
+ file: join(dstDir, 'bundles/umd.js'),
+ format: 'umd',
+ name: pkgCamelisedName,
+ plugins: [terser()]
+ }
+ ],
+ plugins: [
+ // replace({
+ // 'await import(': 'require(',
+ // delimiters: ['', ''],
+ // preventAssignment: true
+ // }),
+ replace({
+ IS_BROWSER: true,
+ preventAssignment: true
+ }),
+ typescriptPlugin(tsBundleOptions),
+ resolve({
+ browser: true,
+ exportConditions: ['browser', 'default'],
+ mainFields: ['browser', 'module', 'main']
+ }),
+ commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
+ json()
+ ]
}
]
diff --git a/build/run-script.cjs b/build/run-script.cjs
new file mode 100644
index 0000000..a09e482
--- /dev/null
+++ b/build/run-script.cjs
@@ -0,0 +1,26 @@
+const childProcess = require('child_process')
+
+const rootDir = require('path').join(__dirname, '../')
+
+function runScript (scriptPath, args) {
+ return new Promise((resolve, reject) => {
+ const cmd = childProcess.fork(scriptPath, args, {
+ cwd: rootDir
+ })
+
+ cmd.on('error', (error) => {
+ reject(error)
+ })
+
+ // execute the callback once the process has finished running
+ cmd.on('exit', function (code) {
+ if (code !== 0) {
+ const error = new Error('exit code ' + code)
+ reject(error)
+ }
+ resolve()
+ })
+ })
+}
+
+module.exports = runScript
diff --git a/build/testing/browser/index.cjs b/build/testing/browser/index.cjs
index 3ad5a5f..6453247 100644
--- a/build/testing/browser/index.cjs
+++ b/build/testing/browser/index.cjs
@@ -29,11 +29,11 @@ const browserTests = async (
}
if (ignore) return
- let text = (message.args().length > 0) ? message.args()[0]._remoteObject.value : message.text()
+ let text = (message.args().length > 0) ? message.args()[0].remoteObject().value : message.text()
const args = []
if (message.args() !== undefined && message.args().length > 1) {
for (let i = 1; i < message.args().length; i++) {
- args.push(message.args()[i]._remoteObject.value)
+ args.push(message.args()[i].remoteObject().value)
}
}
diff --git a/build/testing/browser/server.cjs b/build/testing/browser/server.cjs
index d777eeb..a0ca662 100644
--- a/build/testing/browser/server.cjs
+++ b/build/testing/browser/server.cjs
@@ -13,6 +13,7 @@ const multi = require('@rollup/plugin-multi-entry')
const typescriptPlugin = require('@rollup/plugin-typescript')
const commonjs = require('@rollup/plugin-commonjs')
const json = require('@rollup/plugin-json')
+const runScript = require('../../run-script.cjs')
const rootDir = path.join(__dirname, '..', '..', '..')
@@ -40,10 +41,6 @@ const indexHtml = `
timeout: 90000
})
-