diff --git a/README.md b/README.md
index e8cf2f9..232e0af 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
-[![Node.js CI](https://github.com/juanelas/bigint-crypto-utils/workflows/build/badge.svg)](https://github.com/juanelas/bigint-crypto-utils/actions?query=workflow%3A%22build%22)
+[![Node.js CI](https://github.com/juanelas/bigint-crypto-utils/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/juanelas/bigint-crypto-utils/actions/workflows/build-and-test.yml)
[![Coverage Status](https://coveralls.io/repos/github/juanelas/bigint-crypto-utils/badge.svg?branch=master)](https://coveralls.io/github/juanelas/bigint-crypto-utils?branch=master)
# bigint-crypto-utils
diff --git a/build/bin/mocha-ts.cjs b/build/bin/mocha-ts.cjs
new file mode 100644
index 0000000..2a96f20
--- /dev/null
+++ b/build/bin/mocha-ts.cjs
@@ -0,0 +1,166 @@
+#! /usr/bin/env node
+const fs = require('fs')
+const path = require('path')
+const glob = require('glob')
+const minimatch = require('minimatch')
+const rimraf = require('rimraf')
+const runScript = require('../run-script.cjs')
+
+const rootDir = path.join(__dirname, '../..')
+
+const pkgJson = require(path.join(rootDir, 'package.json'))
+
+const mochaTsRelativeDir = pkgJson.directories['mocha-ts']
+const mochaTsDir = path.join(rootDir, mochaTsRelativeDir)
+
+// clean .mocha-ts directory
+rimraf.sync(mochaTsDir)
+
+const semaphorePath = `${mochaTsRelativeDir}/semaphore`
+
+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}`)
+ }
+ })
+ }
+ mochaArgs.push(...jsTestFiles)
+
+ return {
+ mochaArgs,
+ testFiles,
+ commonjs
+ }
+}
+
+const processedArgs = parse()
+const commonjs = processedArgs.commonjs
+const testFiles = processedArgs.testFiles
+const mochaArgs = processedArgs.mochaArgs
+
+// 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' })
+
+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/bin/mocha-ts.js b/build/bin/mocha-ts.js
deleted file mode 100644
index c6961eb..0000000
--- a/build/bin/mocha-ts.js
+++ /dev/null
@@ -1,79 +0,0 @@
-#! /usr/bin/env node
-import { join, resolve } from 'path'
-import { fork } from 'child_process'
-import minimatch from 'minimatch'
-import glob from 'glob'
-import { fileURLToPath } from 'url'
-const { sync } = glob
-
-const __dirname = resolve(fileURLToPath(import.meta.url), '../')
-const rootDir = join(__dirname, '../..')
-
-const mochaTsRelativeDir = '.mocha-ts'
-
-// 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))
-
-// Now we can run a script and invoke a callback when complete, e.g.
-runScript(join(rootDir, 'node_modules/mocha/bin/mocha'), processedArgs)
-
-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 = 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
- })
-
- const processedArgs = []
-
- 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
- }
- }
- }
- if (addSemaphore === true || semaphoreAdded === false) {
- processedArgs.push('--watch-files')
- processedArgs.push(`${mochaTsRelativeDir}/semaphore`)
- }
-
- return processedArgs
-}
-
-function runScript (scriptPath, args) {
- const mochaCmd = fork(scriptPath, args, {
- cwd: rootDir
- })
-
- mochaCmd.on('error', (error) => {
- throw error
- })
-
- // execute the callback once the process has finished running
- mochaCmd.on('exit', function (code) {
- if (code !== 0) {
- throw new Error('exit code ' + code)
- }
- })
-}
diff --git a/build/build.docs.cjs b/build/build.docs.cjs
index 197fde9..5db44d1 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/build-and-test.yml/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions/workflows/build-and-test.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 ee22fe5..77fa866 100644
--- a/build/rollup.config.js
+++ b/build/rollup.config.js
@@ -52,7 +52,7 @@ function compileDts () {
}
export default [
- { // ESM for browsers and declarations
+ { // Browser ESM bundle
input: input,
output: [
{
@@ -102,11 +102,6 @@ export default [
}
],
plugins: [
- replace({
- 'await import(': 'require(',
- delimiters: ['', ''],
- preventAssignment: true
- }),
replace({
IS_BROWSER: true,
preventAssignment: true
@@ -150,7 +145,7 @@ export default [
json()
]
},
- { // Node ESM
+ { // Node ESM and type declarations
input: input,
output: [
{
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
})
-