diff --git a/README.md b/README.md index 66c168c..39aab03 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,12 @@ ns1.register({ Hyperschema.toDisk(schema) ``` +If you want to generate as ESM, simply use `import` instead of `require` above or set the option explictly in `toDisk` like so + +```js +Hyperschema.toDisk(schema, { esm: true }) +``` + `index.js` will contain generated `compact-encoding` definitions. You can then load/use them as follows: ```js const c = require('compact-encoding') diff --git a/index.js b/builder.cjs similarity index 97% rename from index.js rename to builder.cjs index 5738e21..061ea2d 100644 --- a/index.js +++ b/builder.cjs @@ -287,6 +287,8 @@ module.exports = class Hyperschema { this.initializing = false } + static esm = false + _getFullyQualifiedName (description) { if (description.namespace === null) return description.name return '@' + description.namespace + '/' + description.name @@ -344,11 +346,16 @@ module.exports = class Hyperschema { return json } - toCode () { - return generateCode(this) + toCode ({ esm = this.constructor.esm } = {}) { + return generateCode(this, { esm }) } - static toDisk (hyperschema, dir) { + static toDisk (hyperschema, dir, opts) { + if (typeof dir === 'object' && dir) { + opts = dir + dir = null + } + if (!dir) dir = hyperschema.dir fs.mkdirSync(dir, { recursive: true }) @@ -356,7 +363,7 @@ module.exports = class Hyperschema { const codePath = p.join(p.resolve(dir), CODE_FILE_NAME) fs.writeFileSync(jsonPath, JSON.stringify(hyperschema.toJSON(), null, 2), { encoding: 'utf-8' }) - fs.writeFileSync(codePath, hyperschema.toCode(), { encoding: 'utf-8' }) + fs.writeFileSync(codePath, hyperschema.toCode(opts), { encoding: 'utf-8' }) } static from (json) { diff --git a/builder.mjs b/builder.mjs new file mode 100644 index 0000000..46dcb4d --- /dev/null +++ b/builder.mjs @@ -0,0 +1,7 @@ +import Hyperschema from './builder.cjs' + +class ESMHyperschema extends Hyperschema { + static esm = true +} + +export default ESMHyperschema diff --git a/lib/codegen.js b/lib/codegen.js index 4092f48..15f6922 100644 --- a/lib/codegen.js +++ b/lib/codegen.js @@ -1,7 +1,7 @@ const gen = require('generate-object-property') const s = require('generate-string') -module.exports = function generateSchema (hyperschema) { +module.exports = function generateSchema (hyperschema, { esm = false } = {}) { const structs = [] const structsByName = new Map() @@ -30,7 +30,13 @@ module.exports = function generateSchema (hyperschema) { str += '/* eslint-disable quotes */\n' str += '\n' str += `const VERSION = ${hyperschema.version}\n` - str += 'const { c } = require(\'hyperschema/runtime\')\n' + + if (esm) { + str += 'import { c } from \'hyperschema/runtime\')\n' + } else { + str += 'const { c } = require(\'hyperschema/runtime\')\n' + } + str += '\n' str += '// eslint-disable-next-line no-unused-vars\n' str += 'let version = VERSION\n' @@ -102,7 +108,14 @@ module.exports = function generateSchema (hyperschema) { str += ' }\n' str += '}\n' str += '\n' - str += 'module.exports = { resolveStruct: getStruct, getStruct, getEnum, getEncoding, encode, decode, setVersion, version }\n' + str += 'const resolveStruct = getStruct // compat\n' + str += '\n' + + if (esm) { + str += 'export { resolveStruct, getStruct, getEnum, getEncoding, encode, decode, setVersion, version }\n' + } else { + str += 'module.exports = { resolveStruct, getStruct, getEnum, getEncoding, encode, decode, setVersion, version }\n' + } return str diff --git a/package.json b/package.json index cc99f76..ade2ebd 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,33 @@ "name": "hyperschema", "version": "1.5.0", "description": "Create registries of declarative compact-encoding schemas", - "main": "index.js", "files": [ - "lib/**", - "index.js", + "lib/*.js", + "builder.js", + "builder.cjs", + "runtime.cjs", "runtime.js" ], + "exports": { + ".": { + "import": "./builder.mjs", + "default": "./builder.cjs" + }, + "./runtime": { + "import": "./runtime.mjs", + "default": "./runtime.cjs" + } + }, + "imports": { + "fs": { + "bare": "bare-fs", + "default": "fs" + }, + "path": { + "bare": "bare-path", + "default": "path" + } + }, "scripts": { "test": "standard && brittle test/index.js", "test:bare": "standard && bare test/index.js" @@ -28,16 +49,6 @@ "generate-object-property": "^2.0.0", "generate-string": "^1.0.1" }, - "imports": { - "fs": { - "bare": "bare-fs", - "default": "fs" - }, - "path": { - "bare": "bare-path", - "default": "path" - } - }, "devDependencies": { "brittle": "^3.7.0", "standard": "^17.1.0", diff --git a/runtime.js b/runtime.cjs similarity index 100% rename from runtime.js rename to runtime.cjs diff --git a/runtime.mjs b/runtime.mjs new file mode 100644 index 0000000..4e646e7 --- /dev/null +++ b/runtime.mjs @@ -0,0 +1,3 @@ +import compact from 'compact-encoding' + +export const c = compact diff --git a/test/helpers/index.js b/test/helpers/index.js index f273f1e..8b0899f 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -2,7 +2,7 @@ const p = require('path') const fs = require('fs') const tmp = require('test-tmp') -const Hyperschema = require('../..') +const Hyperschema = require('../../builder.cjs') class TestBuilder { constructor (dir, test) { @@ -37,9 +37,9 @@ async function makeDir (t) { const dir = await tmp(t, { dir: p.join(__dirname, '../test-storage') }) // Copy the runtime into the tmp dir so that we don't need to override it in the codegen - const runtimePath = p.join(dir, 'node_modules', 'hyperschema', 'runtime.js') + const runtimePath = p.join(dir, 'node_modules', 'hyperschema', 'runtime.cjs') await fs.promises.mkdir(p.dirname(runtimePath), { recursive: true }) - await fs.promises.copyFile(p.resolve(dir, '../../../runtime.js'), runtimePath) + await fs.promises.copyFile(p.resolve(dir, '../../../runtime.cjs'), runtimePath) return dir }