@lumjs/compat 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.0.0]
10
+ ### Removed
11
+ - Literally everything from the 1.x package. It's left in the `v1` branch.
12
+ ### Added
13
+ - `exportModule()` function meant as a compatibility bridge between ES Modules
14
+ and CommonJS. It's simplistic and is only meant as a temporary measure to
15
+ add some layer of backwards-compatibility when migrating from CJS to ESM.
16
+ ### Changed
17
+ - Cleaned up README to trim anything to do with the removed sub-modules.
18
+ ### Fixed
19
+ - Added missing link references to this CHANGELOG.
20
+
9
21
  ## [1.4.0] - 2023-01-06
10
22
  ### Changed
11
23
  - Made the `v4` set not use any `ModuleBuilder` features anymore.
@@ -48,7 +60,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
48
60
  ### Added
49
61
  - Initial release.
50
62
 
51
- [Unreleased]: https://github.com/supernovus/lum.compat.js/compare/v1.3.1...HEAD
63
+ [Unreleased]: https://github.com/supernovus/lum.compat.js/compare/v2.0.0...HEAD
64
+ [2.0.0]: https://github.com/supernovus/lum.compat.js/compare/v1.4.0...v2.0.0
65
+ [1.4.0]: https://github.com/supernovus/lum.compat.js/compare/v1.3.1...v1.4.0
52
66
  [1.3.1]: https://github.com/supernovus/lum.compat.js/compare/v1.3.0...v1.3.1
53
67
  [1.3.0]: https://github.com/supernovus/lum.compat.js/compare/v1.2.0...v1.3.0
54
68
  [1.2.0]: https://github.com/supernovus/lum.compat.js/compare/v1.1.0...v1.2.0
package/README.md CHANGED
@@ -1,41 +1,20 @@
1
1
  # lum.compat.js
2
2
 
3
- As the libraries grow over time, features can change a lot, and backwards
4
- compatibility is not always easy to maintain.
3
+ Compatibility helpers.
5
4
 
6
- This library serves two purposes. The first is to be like the corresponding
7
- [lum/lum-compat](https://github.com/supernovus/lum.compat.php) PHP library,
8
- offering some generic compatibility functions.
5
+ As of version 2.0, this is a nano-package with zero dependencies that
6
+ currently provides a simple bridge between CommonJS and ES Modules.
9
7
 
10
- The second is to be a repository for some older, deprecated functionality from
11
- the [@lumjs/core](https://github.com/supernovus/lum.core.js) library.
8
+ ## Branches
12
9
 
13
- By keeping some of the old sub-modules here as optional plugins, I can keep
14
- legacy code up and running until I can rewrite it to no longer use those
15
- features.
10
+ ### `main`
16
11
 
17
- ## Entry Points
12
+ The `2.x` releases are from this branch.
18
13
 
19
- To keep features simple and separated, there's a few different entry points
20
- exported from this library.
14
+ ### `v1.x`
21
15
 
22
- ### `@lumjs/compat`
23
-
24
- The main entrypoint is reserved for generic compatibility functions.
25
-
26
- ### `@lumjs/compat/v4`
27
-
28
- The `v4` compatibility namespace. Includes all `v4` modules in one simple object.
29
-
30
- | Property | Description |
31
- | --------------- | --------------------------------------------------------- |
32
- | `descriptors` | The `v4/descriptors` module. |
33
- | `DESC` | The `v4/descriptors.DESC` factory object. |
34
- | `prop()` | The `v4/prop` module. |
35
- | `deprecated()` | The `v4/deprecated` module. |
36
- | `LoadTracker` | The `v4/loadtracker` module. |
37
- | `Promise` | The `v4/promise` module. |
38
- | `obj` | The `v4/object-helpers` module. |
16
+ The original package was a bunch of compatibility wrappers for [@lumjs/core],
17
+ and covered versions `1.0.0` through `1.4.0`.
39
18
 
40
19
  ## Official URLs
41
20
 
@@ -51,3 +30,5 @@ Timothy Totten <2010@totten.ca>
51
30
  ## License
52
31
 
53
32
  [MIT](https://spdx.org/licenses/MIT.html)
33
+
34
+ [@lumjs/core]: https://github.com/supernovus/lum.core.js
package/lib/index.js CHANGED
@@ -1,27 +1,138 @@
1
- // Compatibility jank.
2
-
3
- const semver = require('semver');
4
- const PKGJSON = 'package.json';
5
-
6
- // A super simplistic package info wrapper.
7
- class Package
8
- {
9
- constructor(pkg)
10
- {
11
- this.file = pkg+'/'+PKGJSON;
12
- this.info = require(this.file);
13
- this.version = semver.parse(this.info.version);
14
- }
1
+ /**
2
+ * Compatibility jank.
3
+ * @module @lumjs/compat
4
+ */
15
5
 
16
- satisfies(range, options)
17
- {
18
- return semver.satisfies(this.version, range, options);
19
- }
6
+ const ESM = '__esModule';
7
+ const DEF = 'default';
8
+
9
+ /**
10
+ * Make an exporter closure: `(key,value) => ...`;
11
+ *
12
+ * Properties added with the closure are configurable and enumerable,
13
+ * but not writable. It does NOT support accessors (getter/setter).
14
+ *
15
+ * This is mostly just designed for use in the exportModule() function.
16
+ * @param {(object|function)} obj - Target to export properties to.
17
+ * @returns {function}
18
+ */
19
+ function exporter(obj) {
20
+ return (key, value) => Object.defineProperty(obj, key, {
21
+ configurable: true,
22
+ enumerable: true,
23
+ value,
24
+ });
25
+ }
26
+
27
+ /**
28
+ * Property name filtering or renaming function.
29
+ * @callback module:@lumjs/compat~ExportUse
30
+ * @param {string} prop - Property name in ES Module.
31
+ * @returns {(string|false|undefined|null)} Property name for default export.
32
+ */
33
+
34
+ /**
35
+ * Export an ES Module type definition with some CommonJS compatibility.
36
+ *
37
+ * This takes an ES Module that was loaded using `require()`, and will
38
+ * attempt to create a CommonJS export that adds (most) named exports
39
+ * as properties of the default export.
40
+ *
41
+ * Example usage:
42
+ *
43
+ * ```js
44
+ * const { exportModule } = require('@lumjs/compat');
45
+ * module.exports = exportModule(require('./index.mjs'));
46
+ * ```
47
+ *
48
+ * @param {object} mod - The ES Module object.
49
+ *
50
+ * If this has a property named `default` that is either an `object`
51
+ * or a `function` then it will have properties added to it for each
52
+ * of the named exports (with a few exceptions configurable with options),
53
+ * and then the default export will be returned.
54
+ *
55
+ * NOTE: if the default export already has a property with an exported name,
56
+ * that export will be skipped rather than overwriting the existing value.
57
+ *
58
+ * If `mod.default` is NOT an object or function then the `mod` itself with
59
+ * no modifications will be the return value from this function.
60
+ *
61
+ * @param {object} [opts] Advanced options.
62
+ *
63
+ * @param {(string|symbol|false)} [opts.esmName="__esModule"] ESM Object key.
64
+ *
65
+ * If this is a string or symbol, it will be used as the name of a property
66
+ * to add to the default export that will contain the full `mod` object.
67
+ *
68
+ * Set this to `false` to disable this feature entirely.
69
+ *
70
+ * NOTE: unlike the named exports, this special property WILL overwrite an
71
+ * existing property with the same name, so be sure it's something that won't
72
+ * conflict. The default `__esModule` is meant to mask the boolean property
73
+ * of the same name that Node adds to ES Modules loaded via require().
74
+ *
75
+ * @param {boolean} [opts.skipDefault=true] Skip the `default` property?
76
+ *
77
+ * If true (default) it skips adding the `default` property, which would
78
+ * literally just be a link to itself and thus rather useless IMHO.
79
+ *
80
+ * You can set this to false if you really want the self-reference,
81
+ * or you could use `opts.map` to rename it to something else.
82
+ *
83
+ * @param {module:@lumjs/compat~ExportUse} [opts.use] Advanced use only!
84
+ *
85
+ * This will be called for every enumerable string-keyed property in `mod`.
86
+ * The context (`this`) in non-closures will be the `opts` object.
87
+ *
88
+ * It's return value will be used to determine the property name that
89
+ * will be used on the default export for the associated named export.
90
+ *
91
+ * - A `string` will be used as the property name on the default export.
92
+ * - `undefined` or `null` is the same as returning the name unchanged.
93
+ * - `false` may be used to skip adding that property entirely.
94
+ *
95
+ * For the majority of packages this feature is likely unnecessary,
96
+ * only use it if you have a really good reason to customize the exports!
97
+ *
98
+ * @returns {(object|function)} Either `mod.default` or `mod` itself.
99
+ * See above for details on how the return value is determined.
100
+ */
101
+ function exportModule(mod, opts={}) {
102
+ if (mod && typeof mod === 'object' && mod.default
103
+ && (typeof mod.default === 'object'
104
+ || typeof mod.default === 'function')
105
+ ) { // Has an object/function default export.
106
+ let modef = mod.default;
107
+ let esKey = opts.esmName ?? ESM;
108
+ let noDef = opts.skipDefault ?? true;
109
+ let use = (typeof opts.use === 'function') ? opts.use : null;
110
+ let addExport = exporter(modef);
111
+ let props = Object.keys(mod);
112
+
113
+ if (typeof esKey === 'string' || typeof esKey === 'symbol')
114
+ { // Add a reference to the full module.
115
+ addExport(esKey, mod);
116
+ }
117
+
118
+ for (let ep of props)
119
+ {
120
+ if (noDef && ep === DEF) continue;
121
+
122
+ let dp = use ? (use.call(opts, ep) ?? ep) : ep;
123
+ if (dp === false) continue;
124
+ if (Object.hasOwn(modef, dp)) continue;
125
+
126
+ let value = mod[ep];
127
+ if (value === undefined) continue;
128
+
129
+ addExport(dp, value);
130
+ }
20
131
 
21
- static new(pkg)
22
- {
23
- return new Package(pkg);
132
+ return modef;
24
133
  }
134
+
135
+ return mod;
25
136
  }
26
137
 
27
- exports.Package = Package;
138
+ module.exports = {exporter, exportModule}
package/package.json CHANGED
@@ -1,15 +1,13 @@
1
1
  {
2
2
  "name": "@lumjs/compat",
3
- "version": "1.4.0",
3
+ "version": "2.0.0",
4
4
  "main": "lib/index.js",
5
+ "engine":
6
+ {
7
+ "node": ">=22.0.0"
8
+ },
5
9
  "exports": {
6
10
  ".": "./lib/index.js",
7
- "./modulebuilder": "./lib/modulebuilder/index.js",
8
- "./modulebuilder/into-core": "./lib/modulebuilder/into-core.js",
9
- "./v4-meta": "./lib/v4/index.js",
10
- "./v4": "./lib/v4/index.js",
11
- "./v4/meta": "./lib/v4/index.js",
12
- "./v4/*": "./lib/v4/*.js",
13
11
  "./package.json": "./package.json"
14
12
  },
15
13
  "license": "MIT",
@@ -17,12 +15,7 @@
17
15
  "type": "git",
18
16
  "url": "https://github.com/supernovus/lum.compat.js.git"
19
17
  },
20
- "dependencies": {
21
- "@lumjs/core": "^1.8.0",
22
- "semver": "^7.3.7"
23
- },
24
- "scripts":
25
- {
18
+ "scripts": {
26
19
  "build-docs": "jsdoc -c ./jsdoc.json"
27
20
  }
28
21
  }
@@ -1,414 +0,0 @@
1
-
2
- const
3
- {
4
- S,F,B,
5
- isObj,needObj,needType,
6
- def,lazy
7
- } = require('@lumjs/core/types');
8
-
9
- const clone = require('@lumjs/core/obj').duplicateOne;
10
-
11
- // Methods we want to export in the functional API.
12
- const BUILD_METHODS = ['has', 'can', 'from', 'set'];
13
-
14
- // Fallback locale
15
- const DLOC = 'en-US';
16
-
17
- /**
18
- * A class to make building modules easier.
19
- *
20
- * Basically wraps calls to `require()`, `def()`, `lazy()`,
21
- * and assignments to `module.exports` into a simple set of methods.
22
- *
23
- * @exports module:@lumjs/compat/modulebuilder
24
- */
25
- class ModuleBuilder
26
- {
27
- /**
28
- * Build a new ModuleBuilder instance.
29
- *
30
- * @param {object} targetModule - The `module` context variable.
31
- * @param {object} [opts] - Options to change some default settings.
32
- * @param {boolean} [opts.configurable=false] Default `configurable` value.
33
- * @param {boolean} [opts.enumerable=true] Default `enumerable` value.
34
- * @param {boolean} [opts.writable=false] Default `writable` value.
35
- *
36
- * @param {number} [opts.nested=NESTED_ERROR] How to handle nested names.
37
- *
38
- * If the `name` parameter in either the `has()` or `can()` method is passed
39
- * as the path to a nested module with one or more `/` characters,
40
- * this mode will determine how we derive the property name.
41
- *
42
- * For each mode, we'll use an example `name` of `./some/nested/path`.
43
- *
44
- * - `ModuleBuilder.NESTED_ERROR` `[0]` (default mode)
45
- * Throw an `Error` saying paths are unhandled.
46
- * - `ModuleBuilder.NESTED_FIRST` `[1]`
47
- * Use the first (non-dot) path element, e.g. `some`
48
- * - `ModuleBuilder.NESTED_LAST` `[2]`
49
- * Use the last path element, e.g. `path`
50
- * - `ModuleBuilder.NESTED_CAMEL` `[3]`
51
- * Convert the name to camelCase, e.g. `someNestedPath`
52
- *
53
- * It's always possible to set the `conf.module` parameter manually as well,
54
- * which avoids the need to generate a separate parameter name.
55
- *
56
- * @param {(string|boolean)} [opts.withLocale=false] Use locales?
57
- *
58
- * If this is a `string` it's the name of the locale (e.g. `en-US`).
59
- *
60
- * If this is `true` we'll use the default locale as determined by
61
- * [getLocale()]{@link module:@lumjs/core/strings.getLocale}.
62
- *
63
- * If this is `false` we won't use locales (unless the `NESTED_CAMEL`
64
- * mode is in use, in which case we'll use the default locale.)
65
- *
66
- */
67
- constructor(targetModule, opts={})
68
- {
69
- needObj(opts, 'opts was not an object');
70
- needObj(targetModule, 'targetModule was not an object');
71
- needObj(targetModule.exports, 'targetModule.exports was not an object');
72
- needType(F, targetModule.require, 'targetModule.require was not a function');
73
-
74
- this.module = targetModule;
75
-
76
- this.configurable = opts.configurable ?? false;
77
- this.enumerable = opts.enumerable ?? true;
78
- this.writable = opts.writable ?? false;
79
-
80
- this.nested = opts.nested ?? ModuleBuilder.NESTED_ERROR;
81
-
82
- if (opts.withLocale)
83
- { // Initialize the strings here.
84
- this.withLocale(opts.locale);
85
- }
86
- }
87
-
88
- // Get a descriptor for a module export.
89
- requireDescriptor(name, conf={})
90
- {
91
- if (typeof conf === S)
92
- { // A quick shortcut for setting module name.
93
- conf = {module: conf};
94
- }
95
- else if (conf === true)
96
- { // Use the lowercase name as the module.
97
- conf = {module: this.$lc(name)};
98
- }
99
- else if (typeof conf.getter === F || typeof conf.setter === F)
100
- { // It's an accessor-style descriptor already.
101
- return conf;
102
- }
103
-
104
- let value = conf.value;
105
-
106
- if (value === undefined)
107
- {
108
- if (typeof conf.module === S)
109
- name = conf.module;
110
- if (!name.startsWith('./'))
111
- name = './'+name;
112
-
113
- value = this.module.require(name);
114
-
115
- if (value && conf.prop && value[conf.prop] !== undefined)
116
- {
117
- value = value[conf.prop];
118
- }
119
- }
120
-
121
- const configurable = conf.configurable ?? this.configurable;
122
- const enumerable = conf.enumerable ?? this.enumerable;
123
- const writable = conf.writable ?? this.writable;
124
-
125
- return {configurable, enumerable, writable, value};
126
- }
127
-
128
- $lc(name)
129
- {
130
- return name.toLocaleLowerCase(this.locale ?? DLOC);
131
- }
132
-
133
- // Normalize a property name.
134
- $normalizeProperty(name)
135
- {
136
- if (name.startsWith('./'))
137
- { // Get rid of the prefix.
138
- name = name.substring(2);
139
- }
140
-
141
- if (name.includes('/'))
142
- { // Multiple paths found.
143
- const names = name.split('/');
144
- if (this.nested === ModuleBuilder.NESTED_FIRST)
145
- {
146
- name = names[0];
147
- }
148
- else if (this.nested === ModuleBuilder.NESTED_LAST)
149
- {
150
- name = names[names.length-1];
151
- }
152
- else if (this.nested === ModuleBuilder.NESTED_CAMEL)
153
- {
154
- name = this.$normalizeWithCamelCase(names);
155
- }
156
- else
157
- {
158
- throw new Error("No valid nested path handling method was set");
159
- }
160
- }
161
-
162
- return name;
163
- }
164
-
165
- withLocale(loc)
166
- {
167
- if (this.strings === undefined)
168
- { // Load the strings library.
169
- this.strings = require('@lumjs/core/strings');
170
- }
171
-
172
- if (this.locale === undefined)
173
- { // Set the locale.
174
- if (typeof loc === S)
175
- { // Use an explicitly passed value.
176
- this.locale = loc;
177
- }
178
- else
179
- { // Use the default locale.
180
- this.locale = this.strings.getLocale();
181
- }
182
- }
183
- }
184
-
185
- $normalizeWithCamelCase(names)
186
- {
187
- this.withLocale();
188
- let name = names.shift().toLocaleLowerCase(this.locale);
189
- for (const path in names)
190
- {
191
- name += this.strings.ucfirst(path, true, this.locale);
192
- }
193
- return name;
194
- }
195
-
196
- /**
197
- * Export a module directly.
198
- *
199
- * @param {string} name - The property name to export.
200
- *
201
- * @param {(object|string|true)} [conf] Additional export configuration options.
202
- *
203
- * If this is a `string` instead of an `object`, it's assumed to be the
204
- * `conf.module` value.
205
- *
206
- * If this is `true` then the `conf` will be set with `module` being the
207
- * lowercase version of `name`.
208
- *
209
- * @param {string} [conf.module=`./${name}`] The module to `require()`.
210
- * @param {string} [conf.prop] If set, we want an exported property
211
- * of this name from the loaded module.
212
- *
213
- * If not set, the entire loaded module will be our exported value.
214
- *
215
- * @param {boolean} [conf.configurable=this.configurable]
216
- * Descriptor `configurable` value.
217
- * @param {boolean} [conf.enumerable=this.enumerable]
218
- * Descriptor `enumerable` value.
219
- * @param {boolean} [conf.writable=this.writable]
220
- * Descriptor `writable` value.
221
- *
222
- * @param {*} [conf.value] An explicit value to set.
223
- *
224
- * This skips the `require()` call entirely.
225
- *
226
- * @returns {object} `this`
227
- */
228
- has(name, conf={})
229
- {
230
- const pname = this.$normalizeProperty(name);
231
- const desc = this.requireDescriptor(name, conf);
232
- def(this.module.exports, pname, desc);
233
- return this;
234
- }
235
-
236
- /**
237
- * Export a lazy-loaded module.
238
- *
239
- * @param {string} name - The property name to export.
240
- *
241
- * @param {object} [conf] Additional export configuration options.
242
- *
243
- * In addition to all the options supported by
244
- * [has()]{@link module:@lumjs/core/modules#has}
245
- * this also supports one further option.
246
- *
247
- * @param {object} [conf.lazy] Advanced options for the `lazy()` call.
248
- *
249
- * If not specified, sane defaults will be used, that ensures the
250
- * `enumerable` descriptor property for the lazy getter is set the
251
- * same as the final descriptor property once its loaded.
252
- *
253
- * @returns {object} `this`
254
- */
255
- can(name, conf={})
256
- {
257
- const pname = this.$normalizeProperty(name);
258
- const enumerable = conf.enumerable ?? this.enumerable;
259
- const lazyOpts = isObj(conf.lazy) ? conf.lazy : {enumerable};
260
- const getter = () => this.requireDescriptor(name, conf);
261
- lazy(this.module.exports, pname, getter, lazyOpts);
262
- return this;
263
- }
264
-
265
- /**
266
- * Re-export some exported properties from a module.
267
- *
268
- * By default this uses `has()` to define the exports, but that
269
- * can be changed using special parameter values.
270
- *
271
- * @param {string} modname - The module to export the properties from.
272
- * @param {...any} libs - What we're exporting.
273
- *
274
- * If this is a `string` it is the name of an exported property we want to
275
- * re-export directly.
276
- *
277
- * If this is `true`, all subsequent values will be exported using `can()`.
278
- *
279
- * If this is `false`, all subsequent values will be exported using `has()`.
280
- *
281
- * If this is an `object`, then it's considered the `conf` parameter for
282
- * the `has()` or `can()` methods. If the `conf` does not have a `module`
283
- * property, the `modname` will be assigned as the `module` property.
284
- * You cannot set the `prop` property, as it's overwritten for every
285
- * exported property.
286
- *
287
- * @returns {object} `this`
288
- */
289
- from(modname, ...libs)
290
- {
291
- let func = 'has';
292
- let curConf = {module: modname};
293
- for (const lib of libs)
294
- {
295
- if (isObj(lib))
296
- { // Change the current config.
297
- curConf = clone(lib);
298
- if (curConf.module === undefined)
299
- { // Make sure the module name is assigned.
300
- curConf.module = modname;
301
- }
302
- }
303
- else if (typeof lib === B)
304
- { // Change the function we're calling.
305
- func = lib ? 'can' : 'has';
306
- }
307
- else if (typeof lib === S)
308
- {
309
- const conf = clone(curConf);
310
- conf.prop = lib;
311
- this[func](lib, conf);
312
- }
313
- else
314
- {
315
- throw new TypeError("libs must be strings, booleans, or objects");
316
- }
317
- }
318
- return this;
319
- }
320
-
321
- /**
322
- * Define an exported property in our module.
323
- *
324
- * This is literally just a wrapper around the
325
- * [def()]{@link module:@lumjs/core/types.def} method,
326
- * that passes `this.module.exports` as the `obj` parameter.
327
- *
328
- * @param {*} name - See `def()` for details.
329
- * @param {*} value - See `def()` for details.
330
- * @param {*} opts - See `def()` for details.
331
- * @returns {(object|function)} What is returned may vary:
332
- *
333
- * If the `def()` returns a *bound* copy of itself, we'll return that
334
- * bound function directly.
335
- *
336
- * In any other case, we return `this` ModuleBuilder instance.
337
- */
338
- set(name, value, opts)
339
- {
340
- const retval = def(this.module.exports, name, value, opts);
341
- if (typeof retval === F && isObj(retval.$this) && retval.$this.bound === retval)
342
- { // A bound copy was returned, we're going to return it directly.
343
- return retval;
344
- }
345
- return this;
346
- }
347
-
348
- /**
349
- * Create a functional API for the ModuleBuilder class.
350
- *
351
- * Basically makes a new `ModuleBuilder` instance, then creates standalone
352
- * closure functions that wrap the main instance methods.
353
- *
354
- * These functions can be imported into a namespace directly.
355
- * They each have a special `builder` property which is a reference
356
- * to the underlying `ModuleBuilder` instance.
357
- *
358
- * There's also a `builder` property in the exported function list,
359
- * as well as a copy of the `def()` method for quick exporting.
360
- *
361
- * Example usage:
362
- *
363
- * ```js
364
- * const {has,can,from,set}
365
- * = require('@lumjs/compat/modulebuilder').ModuleBuilder.build(module);
366
- *
367
- * // exports.foo = require('./foo');
368
- * has('foo');
369
- *
370
- * // exports.someNestedPath = require('./some/nested/path');
371
- * has('./some/nested/path');
372
- *
373
- * ```
374
- *
375
- * @param {object} targetModule - The `module` for the Builder instance.
376
- * @param {object} [opts] - Any options for the Builder instance.
377
- * @returns {object} An object containing the closure functions.
378
- */
379
- static build(targetModule, opts)
380
- {
381
- const builder = new this(targetModule, opts);
382
- const funcs = {builder, def};
383
- for (const name of BUILD_METHODS)
384
- {
385
- const func = function()
386
- {
387
- return builder[name](...arguments);
388
- }
389
- def(func, 'builder', builder);
390
- funcs[name] = func;
391
- }
392
- return funcs;
393
- }
394
-
395
- /**
396
- * A static alternative to `new ModuleBuilder()`;
397
- *
398
- * @param {object} targetModule
399
- * @param {object} [opts]
400
- * @returns {object} The new `ModuleBuilder` instance.
401
- */
402
- static new(targetModule, opts)
403
- {
404
- return new this(targetModule, opts);
405
- }
406
-
407
- }
408
-
409
- def(ModuleBuilder, 'NESTED_ERROR', 0)
410
- def(ModuleBuilder, 'NESTED_FIRST', 1);
411
- def(ModuleBuilder, 'NESTED_LAST', 2);
412
- def(ModuleBuilder, 'NESTED_CAMEL', 3);
413
-
414
- module.exports = ModuleBuilder;