novac 2.0.1 → 2.2.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/LICENSE +1 -1
- package/README.md +1574 -597
- package/bin/novac +468 -171
- package/bin/nvc +522 -0
- package/bin/nvml +78 -17
- package/demo.nv +0 -0
- package/demo_builtins.nv +0 -0
- package/demo_http.nv +0 -0
- package/examples/bf.nv +69 -0
- package/examples/math.nv +21 -0
- package/kits/birdAPI/kitdef.js +954 -0
- package/kits/kitRNG/kitdef.js +740 -0
- package/kits/kitSSH/kitdef.js +1272 -0
- package/kits/kitadb/kitdef.js +606 -0
- package/kits/kitai/kitdef.js +2185 -0
- package/kits/kitansi/kitdef.js +1402 -0
- package/kits/kitcanvas/kitdef.js +914 -0
- package/kits/kitclippy/kitdef.js +925 -0
- package/kits/kitformat/kitdef.js +1485 -0
- package/kits/kitgps/kitdef.js +1862 -0
- package/kits/kitlibproc/kitdef.js +3 -2
- package/kits/kitmatrix/ex.js +19 -0
- package/kits/kitmatrix/kitdef.js +960 -0
- package/kits/kitmorse/kitdef.js +229 -0
- package/kits/kitmpatch/kitdef.js +906 -0
- package/kits/kitnet/kitdef.js +1401 -0
- package/kits/kitnovacweb/README.md +1416 -143
- package/kits/kitnovacweb/kitdef.js +92 -2
- package/kits/kitnovacweb/nvml/executor.js +578 -176
- package/kits/kitnovacweb/nvml/index.js +2 -2
- package/kits/kitnovacweb/nvml/lexer.js +72 -69
- package/kits/kitnovacweb/nvml/parser.js +328 -159
- package/kits/kitnovacweb/nvml/renderer.js +770 -270
- package/kits/kitparse/kitdef.js +1688 -0
- package/kits/kitproto/kitdef.js +613 -0
- package/kits/kitqr/kitdef.js +637 -0
- package/kits/kitregex++/kitdef.js +1353 -0
- package/kits/kitrequire/kitdef.js +1599 -0
- package/kits/kitx11/kitdef.js +1 -0
- package/kits/kitx11/kitx11.js +2472 -0
- package/kits/kitx11/kitx11_conn.js +948 -0
- package/kits/kitx11/kitx11_worker.js +121 -0
- package/kits/libtea/kitdef.js +2691 -0
- package/kits/libterm/ex.js +285 -0
- package/kits/libterm/kitdef.js +1927 -0
- package/novac/LICENSE +21 -0
- package/novac/README.md +1823 -0
- package/novac/bin/novac +950 -0
- package/novac/bin/nvc +522 -0
- package/novac/bin/nvml +542 -0
- package/novac/demo.nv +245 -0
- package/novac/demo_builtins.nv +209 -0
- package/novac/demo_http.nv +62 -0
- package/novac/examples/bf.nv +69 -0
- package/novac/examples/math.nv +21 -0
- package/novac/kits/kitai/kitdef.js +2185 -0
- package/novac/kits/kitansi/kitdef.js +1402 -0
- package/novac/kits/kitformat/kitdef.js +1485 -0
- package/novac/kits/kitgps/kitdef.js +1862 -0
- package/novac/kits/kitlibfs/kitdef.js +231 -0
- package/{examples/example-project/nova_modules → novac/kits}/kitlibproc/kitdef.js +3 -2
- package/novac/kits/kitmatrix/ex.js +19 -0
- package/novac/kits/kitmatrix/kitdef.js +960 -0
- package/novac/kits/kitmpatch/kitdef.js +906 -0
- package/novac/kits/kitnovacweb/README.md +1572 -0
- package/novac/kits/kitnovacweb/demo.nv +12 -0
- package/novac/kits/kitnovacweb/demo.nvml +71 -0
- package/novac/kits/kitnovacweb/index.nova +12 -0
- package/novac/kits/kitnovacweb/kitdef.js +692 -0
- package/novac/kits/kitnovacweb/nova.kit.json +8 -0
- package/novac/kits/kitnovacweb/nvml/executor.js +739 -0
- package/novac/kits/kitnovacweb/nvml/index.js +67 -0
- package/novac/kits/kitnovacweb/nvml/lexer.js +263 -0
- package/novac/kits/kitnovacweb/nvml/parser.js +508 -0
- package/novac/kits/kitnovacweb/nvml/renderer.js +924 -0
- package/novac/kits/kitparse/kitdef.js +1688 -0
- package/novac/kits/kitregex++/kitdef.js +1353 -0
- package/novac/kits/kitrequire/kitdef.js +1599 -0
- package/novac/kits/kitx11/kitdef.js +1 -0
- package/novac/kits/kitx11/kitx11.js +2472 -0
- package/novac/kits/kitx11/kitx11_conn.js +948 -0
- package/novac/kits/kitx11/kitx11_worker.js +121 -0
- package/novac/kits/libtea/tf.js +2691 -0
- package/novac/kits/libterm/ex.js +285 -0
- package/novac/kits/libterm/kitdef.js +1927 -0
- package/novac/node_modules/chalk/license +9 -0
- package/novac/node_modules/chalk/package.json +83 -0
- package/novac/node_modules/chalk/readme.md +297 -0
- package/novac/node_modules/chalk/source/index.d.ts +325 -0
- package/novac/node_modules/chalk/source/index.js +225 -0
- package/novac/node_modules/chalk/source/utilities.js +33 -0
- package/novac/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/novac/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/novac/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/novac/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/novac/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/novac/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/novac/node_modules/commander/LICENSE +22 -0
- package/novac/node_modules/commander/Readme.md +1176 -0
- package/novac/node_modules/commander/esm.mjs +16 -0
- package/novac/node_modules/commander/index.js +24 -0
- package/novac/node_modules/commander/lib/argument.js +150 -0
- package/novac/node_modules/commander/lib/command.js +2777 -0
- package/novac/node_modules/commander/lib/error.js +39 -0
- package/novac/node_modules/commander/lib/help.js +747 -0
- package/novac/node_modules/commander/lib/option.js +380 -0
- package/novac/node_modules/commander/lib/suggestSimilar.js +101 -0
- package/novac/node_modules/commander/package-support.json +19 -0
- package/novac/node_modules/commander/package.json +82 -0
- package/novac/node_modules/commander/typings/esm.d.mts +3 -0
- package/novac/node_modules/commander/typings/index.d.ts +1113 -0
- package/novac/node_modules/node-addon-api/LICENSE.md +9 -0
- package/novac/node_modules/node-addon-api/README.md +95 -0
- package/novac/node_modules/node-addon-api/common.gypi +21 -0
- package/novac/node_modules/node-addon-api/except.gypi +25 -0
- package/novac/node_modules/node-addon-api/index.js +14 -0
- package/novac/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
- package/novac/node_modules/node-addon-api/napi-inl.h +7165 -0
- package/novac/node_modules/node-addon-api/napi.h +3364 -0
- package/novac/node_modules/node-addon-api/node_addon_api.gyp +42 -0
- package/novac/node_modules/node-addon-api/node_api.gyp +9 -0
- package/novac/node_modules/node-addon-api/noexcept.gypi +26 -0
- package/novac/node_modules/node-addon-api/package-support.json +21 -0
- package/novac/node_modules/node-addon-api/package.json +480 -0
- package/novac/node_modules/node-addon-api/tools/README.md +73 -0
- package/novac/node_modules/node-addon-api/tools/check-napi.js +99 -0
- package/novac/node_modules/node-addon-api/tools/clang-format.js +71 -0
- package/novac/node_modules/node-addon-api/tools/conversion.js +301 -0
- package/novac/node_modules/serialize-javascript/LICENSE +27 -0
- package/novac/node_modules/serialize-javascript/README.md +149 -0
- package/novac/node_modules/serialize-javascript/index.js +297 -0
- package/novac/node_modules/serialize-javascript/package.json +33 -0
- package/novac/package.json +27 -0
- package/novac/scripts/update-bin.js +24 -0
- package/novac/src/core/bstd.js +1035 -0
- package/novac/src/core/config.js +155 -0
- package/novac/src/core/describe.js +187 -0
- package/novac/src/core/emitter.js +499 -0
- package/novac/src/core/error.js +86 -0
- package/novac/src/core/executor.js +5606 -0
- package/novac/src/core/formatter.js +686 -0
- package/novac/src/core/lexer.js +1026 -0
- package/novac/src/core/nova_builtins.js +717 -0
- package/novac/src/core/nova_thread_worker.js +166 -0
- package/novac/src/core/parser.js +2181 -0
- package/novac/src/core/types.js +112 -0
- package/novac/src/index.js +28 -0
- package/novac/src/runtime/stdlib.js +244 -0
- package/package.json +6 -3
- package/scripts/update-bin.js +0 -0
- package/src/core/bstd.js +838 -362
- package/src/core/executor.js +2578 -170
- package/src/core/lexer.js +502 -54
- package/src/core/nova_builtins.js +21 -3
- package/src/core/parser.js +413 -72
- package/src/core/types.js +30 -2
- package/src/index.js +0 -0
- package/examples/example-project/README.md +0 -3
- package/examples/example-project/src/main.nova +0 -3
- package/src/core/environment.js +0 -0
- /package/{examples/example-project/bin/example-project.nv → novac/node_modules/node-addon-api/nothing.c} +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Descend into a directory structure and, for each file matching *.node, output
|
|
3
|
+
// based on the imports found in the file whether it's an N-API module or not.
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
// Read the output of the command, break it into lines, and use the reducer to
|
|
9
|
+
// decide whether the file is an N-API module or not.
|
|
10
|
+
function checkFile (file, command, argv, reducer) {
|
|
11
|
+
const child = require('child_process').spawn(command, argv, {
|
|
12
|
+
stdio: ['inherit', 'pipe', 'inherit']
|
|
13
|
+
});
|
|
14
|
+
let leftover = '';
|
|
15
|
+
let isNapi;
|
|
16
|
+
child.stdout.on('data', (chunk) => {
|
|
17
|
+
if (isNapi === undefined) {
|
|
18
|
+
chunk = (leftover + chunk.toString()).split(/[\r\n]+/);
|
|
19
|
+
leftover = chunk.pop();
|
|
20
|
+
isNapi = chunk.reduce(reducer, isNapi);
|
|
21
|
+
if (isNapi !== undefined) {
|
|
22
|
+
child.kill();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
child.on('close', (code, signal) => {
|
|
27
|
+
if ((code === null && signal !== null) || (code !== 0)) {
|
|
28
|
+
console.log(
|
|
29
|
+
command + ' exited with code: ' + code + ' and signal: ' + signal);
|
|
30
|
+
} else {
|
|
31
|
+
// Green if it's a N-API module, red otherwise.
|
|
32
|
+
console.log(
|
|
33
|
+
'\x1b[' + (isNapi ? '42' : '41') + 'm' +
|
|
34
|
+
(isNapi ? ' N-API' : 'Not N-API') +
|
|
35
|
+
'\x1b[0m: ' + file);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Use nm -a to list symbols.
|
|
41
|
+
function checkFileUNIX (file) {
|
|
42
|
+
checkFile(file, 'nm', ['-a', file], (soFar, line) => {
|
|
43
|
+
if (soFar === undefined) {
|
|
44
|
+
line = line.match(/([0-9a-f]*)? ([a-zA-Z]) (.*$)/);
|
|
45
|
+
if (line[2] === 'U') {
|
|
46
|
+
if (/^napi/.test(line[3])) {
|
|
47
|
+
soFar = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return soFar;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Use dumpbin /imports to list symbols.
|
|
56
|
+
function checkFileWin32 (file) {
|
|
57
|
+
checkFile(file, 'dumpbin', ['/imports', file], (soFar, line) => {
|
|
58
|
+
if (soFar === undefined) {
|
|
59
|
+
line = line.match(/([0-9a-f]*)? +([a-zA-Z0-9]) (.*$)/);
|
|
60
|
+
if (line && /^napi/.test(line[line.length - 1])) {
|
|
61
|
+
soFar = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return soFar;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Descend into a directory structure and pass each file ending in '.node' to
|
|
69
|
+
// one of the above checks, depending on the OS.
|
|
70
|
+
function recurse (top) {
|
|
71
|
+
fs.readdir(top, (error, items) => {
|
|
72
|
+
if (error) {
|
|
73
|
+
throw new Error('error reading directory ' + top + ': ' + error);
|
|
74
|
+
}
|
|
75
|
+
items.forEach((item) => {
|
|
76
|
+
item = path.join(top, item);
|
|
77
|
+
fs.stat(item, ((item) => (error, stats) => {
|
|
78
|
+
if (error) {
|
|
79
|
+
throw new Error('error about ' + item + ': ' + error);
|
|
80
|
+
}
|
|
81
|
+
if (stats.isDirectory()) {
|
|
82
|
+
recurse(item);
|
|
83
|
+
} else if (/[.]node$/.test(item) &&
|
|
84
|
+
// Explicitly ignore files called 'nothing.node' because they are
|
|
85
|
+
// artefacts of node-addon-api having identified a version of
|
|
86
|
+
// Node.js that ships with a correct implementation of N-API.
|
|
87
|
+
path.basename(item) !== 'nothing.node') {
|
|
88
|
+
process.platform === 'win32'
|
|
89
|
+
? checkFileWin32(item)
|
|
90
|
+
: checkFileUNIX(item);
|
|
91
|
+
}
|
|
92
|
+
})(item));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Start with the directory given on the command line or the current directory
|
|
98
|
+
// if nothing was given.
|
|
99
|
+
recurse(process.argv.length > 3 ? process.argv[2] : '.');
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const spawn = require('child_process').spawnSync;
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const filesToCheck = ['*.h', '*.cc'];
|
|
7
|
+
const FORMAT_START = process.env.FORMAT_START || 'main';
|
|
8
|
+
|
|
9
|
+
function main (args) {
|
|
10
|
+
let fix = false;
|
|
11
|
+
while (args.length > 0) {
|
|
12
|
+
switch (args[0]) {
|
|
13
|
+
case '-f':
|
|
14
|
+
case '--fix':
|
|
15
|
+
fix = true;
|
|
16
|
+
break;
|
|
17
|
+
default:
|
|
18
|
+
}
|
|
19
|
+
args.shift();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const clangFormatPath = path.dirname(require.resolve('clang-format'));
|
|
23
|
+
const binary = process.platform === 'win32'
|
|
24
|
+
? 'node_modules\\.bin\\clang-format.cmd'
|
|
25
|
+
: 'node_modules/.bin/clang-format';
|
|
26
|
+
const options = ['--binary=' + binary, '--style=file'];
|
|
27
|
+
if (fix) {
|
|
28
|
+
options.push(FORMAT_START);
|
|
29
|
+
} else {
|
|
30
|
+
options.push('--diff', FORMAT_START);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const gitClangFormatPath = path.join(clangFormatPath, 'bin/git-clang-format');
|
|
34
|
+
const result = spawn(
|
|
35
|
+
'python',
|
|
36
|
+
[gitClangFormatPath, ...options, '--', ...filesToCheck],
|
|
37
|
+
{ encoding: 'utf-8' }
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (result.stderr) {
|
|
41
|
+
console.error('Error running git-clang-format:', result.stderr);
|
|
42
|
+
return 2;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const clangFormatOutput = result.stdout.trim();
|
|
46
|
+
// Bail fast if in fix mode.
|
|
47
|
+
if (fix) {
|
|
48
|
+
console.log(clangFormatOutput);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
// Detect if there is any complains from clang-format
|
|
52
|
+
if (
|
|
53
|
+
clangFormatOutput !== '' &&
|
|
54
|
+
clangFormatOutput !== 'no modified files to format' &&
|
|
55
|
+
clangFormatOutput !== 'clang-format did not modify any files'
|
|
56
|
+
) {
|
|
57
|
+
console.error(clangFormatOutput);
|
|
58
|
+
const fixCmd = 'npm run lint:fix';
|
|
59
|
+
console.error(`
|
|
60
|
+
ERROR: please run "${fixCmd}" to format changes in your commit
|
|
61
|
+
Note that when running the command locally, please keep your local
|
|
62
|
+
main branch and working branch up to date with nodejs/node-addon-api
|
|
63
|
+
to exclude un-related complains.
|
|
64
|
+
Or you can run "env FORMAT_START=upstream/main ${fixCmd}".`);
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (require.main === module) {
|
|
70
|
+
process.exitCode = main(process.argv.slice(2));
|
|
71
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
const dir = args[0];
|
|
10
|
+
if (!dir) {
|
|
11
|
+
console.log('Usage: node ' + path.basename(__filename) + ' <target-dir>');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const NodeApiVersion = require('../').version;
|
|
16
|
+
|
|
17
|
+
const disable = args[1];
|
|
18
|
+
let ConfigFileOperations;
|
|
19
|
+
if (disable !== '--disable' && dir !== '--disable') {
|
|
20
|
+
ConfigFileOperations = {
|
|
21
|
+
'package.json': [
|
|
22
|
+
[/([ ]*)"dependencies": {/g, '$1"dependencies": {\n$1 "node-addon-api": "' + NodeApiVersion + '",'],
|
|
23
|
+
[/[ ]*"nan": *"[^"]+"(,|)[\n\r]/g, '']
|
|
24
|
+
],
|
|
25
|
+
'binding.gyp': [
|
|
26
|
+
[/([ ]*)'include_dirs': \[/g, '$1\'include_dirs\': [\n$1 \'<!(node -p "require(\\\'node-addon-api\\\').include_dir")\','],
|
|
27
|
+
[/([ ]*)"include_dirs": \[/g, '$1"include_dirs": [\n$1 "<!(node -p \\"require(\'node-addon-api\').include_dir\\")",'],
|
|
28
|
+
[/[ ]*("|')<!\(node -e ("|'|\\"|\\')require\(("|'|\\"|\\')nan("|'|\\"|\\')\)("|'|\\"|\\')\)("|')(,|)[\r\n]/g, ''],
|
|
29
|
+
[/([ ]*)("|')target_name("|'): ("|')(.+?)("|'),/g, '$1$2target_name$2: $4$5$6,\n $2cflags!$2: [ $2-fno-exceptions$2 ],\n $2cflags_cc!$2: [ $2-fno-exceptions$2 ],\n $2xcode_settings$2: { $2GCC_ENABLE_CPP_EXCEPTIONS$2: $2YES$2,\n $2CLANG_CXX_LIBRARY$2: $2libc++$2,\n $2MACOSX_DEPLOYMENT_TARGET$2: $210.7$2,\n },\n $2msvs_settings$2: {\n $2VCCLCompilerTool$2: { $2ExceptionHandling$2: 1 },\n },']
|
|
30
|
+
]
|
|
31
|
+
};
|
|
32
|
+
} else {
|
|
33
|
+
ConfigFileOperations = {
|
|
34
|
+
'package.json': [
|
|
35
|
+
[/([ ]*)"dependencies": {/g, '$1"dependencies": {\n$1 "node-addon-api": "' + NodeApiVersion + '",'],
|
|
36
|
+
[/[ ]*"nan": *"[^"]+"(,|)[\n\r]/g, '']
|
|
37
|
+
],
|
|
38
|
+
'binding.gyp': [
|
|
39
|
+
[/([ ]*)'include_dirs': \[/g, '$1\'include_dirs\': [\n$1 \'<!(node -p "require(\\\'node-addon-api\\\').include_dir")\','],
|
|
40
|
+
[/([ ]*)"include_dirs": \[/g, '$1"include_dirs": [\n$1 "<!(node -p \'require(\\"node-addon-api\\").include_dir\')",'],
|
|
41
|
+
[/[ ]*("|')<!\(node -e ("|'|\\"|\\')require\(("|'|\\"|\\')nan("|'|\\"|\\')\)("|'|\\"|\\')\)("|')(,|)[\r\n]/g, ''],
|
|
42
|
+
[/([ ]*)("|')target_name("|'): ("|')(.+?)("|'),/g, '$1$2target_name$2: $4$5$6,\n $2cflags!$2: [ $2-fno-exceptions$2 ],\n $2cflags_cc!$2: [ $2-fno-exceptions$2 ],\n $2defines$2: [ $2NAPI_DISABLE_CPP_EXCEPTIONS$2 ],\n $2conditions$2: [\n [\'OS=="win"\', { $2defines$2: [ $2_HAS_EXCEPTIONS=1$2 ] }]\n ]']
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const SourceFileOperations = [
|
|
48
|
+
[/Nan::SetMethod\(target,[\s]*"(.*)"[\s]*,[\s]*([^)]+)\)/g, 'exports.Set(Napi::String::New(env, "$1"), Napi::Function::New(env, $2))'],
|
|
49
|
+
|
|
50
|
+
[/v8::Local<v8::FunctionTemplate>\s+(\w+)\s*=\s*Nan::New<FunctionTemplate>\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {'],
|
|
51
|
+
[/Local<FunctionTemplate>\s+(\w+)\s*=\s*Nan::New<FunctionTemplate>\([\w\d:]+\);\s+(\w+)\.Reset\((\1)\);\s+\1->SetClassName\((Nan::String::New|Nan::New<(v8::)*String>)\("(.+?)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$6", {'],
|
|
52
|
+
[/Local<FunctionTemplate>\s+(\w+)\s*=\s*Nan::New<FunctionTemplate>\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {'],
|
|
53
|
+
[/Nan::New<v8::FunctionTemplate>\(([\w\d:]+)\)->GetFunction\(\)/g, 'Napi::Function::New(env, $1)'],
|
|
54
|
+
[/Nan::New<FunctionTemplate>\(([\w\d:]+)\)->GetFunction()/g, 'Napi::Function::New(env, $1);'],
|
|
55
|
+
[/Nan::New<v8::FunctionTemplate>\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)'],
|
|
56
|
+
[/Nan::New<FunctionTemplate>\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)'],
|
|
57
|
+
|
|
58
|
+
// FunctionTemplate to FunctionReference
|
|
59
|
+
[/Nan::Persistent<(v8::)*FunctionTemplate>/g, 'Napi::FunctionReference'],
|
|
60
|
+
[/Nan::Persistent<(v8::)*Function>/g, 'Napi::FunctionReference'],
|
|
61
|
+
[/v8::Local<v8::FunctionTemplate>/g, 'Napi::FunctionReference'],
|
|
62
|
+
[/Local<FunctionTemplate>/g, 'Napi::FunctionReference'],
|
|
63
|
+
[/v8::FunctionTemplate/g, 'Napi::FunctionReference'],
|
|
64
|
+
[/FunctionTemplate/g, 'Napi::FunctionReference'],
|
|
65
|
+
|
|
66
|
+
[/([ ]*)Nan::SetPrototypeMethod\(\w+, "(\w+)", (\w+)\);/g, '$1InstanceMethod("$2", &$3),'],
|
|
67
|
+
[/([ ]*)(?:\w+\.Reset\(\w+\);\s+)?\(target\)\.Set\("(\w+)",\s*Nan::GetFunction\((\w+)\)\);/gm,
|
|
68
|
+
'});\n\n' +
|
|
69
|
+
'$1constructor = Napi::Persistent($3);\n' +
|
|
70
|
+
'$1constructor.SuppressDestruct();\n' +
|
|
71
|
+
'$1target.Set("$2", $3);'],
|
|
72
|
+
|
|
73
|
+
// TODO: Other attribute combinations
|
|
74
|
+
[/static_cast<PropertyAttribute>\(ReadOnly\s*\|\s*DontDelete\)/gm,
|
|
75
|
+
'static_cast<napi_property_attributes>(napi_enumerable | napi_configurable)'],
|
|
76
|
+
|
|
77
|
+
[/([\w\d:<>]+?)::Cast\((.+?)\)/g, '$2.As<$1>()'],
|
|
78
|
+
|
|
79
|
+
[/\*Nan::Utf8String\(([^)]+)\)/g, '$1->As<Napi::String>().Utf8Value().c_str()'],
|
|
80
|
+
[/Nan::Utf8String +(\w+)\(([^)]+)\)/g, 'std::string $1 = $2.As<Napi::String>()'],
|
|
81
|
+
[/Nan::Utf8String/g, 'std::string'],
|
|
82
|
+
|
|
83
|
+
[/v8::String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)'],
|
|
84
|
+
[/String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)'],
|
|
85
|
+
[/\.length\(\)/g, '.Length()'],
|
|
86
|
+
|
|
87
|
+
[/Nan::MakeCallback\(([^,]+),[\s\\]+([^,]+),/gm, '$2.MakeCallback($1,'],
|
|
88
|
+
|
|
89
|
+
[/class\s+(\w+)\s*:\s*public\s+Nan::ObjectWrap/g, 'class $1 : public Napi::ObjectWrap<$1>'],
|
|
90
|
+
[/(\w+)\(([^)]*)\)\s*:\s*Nan::ObjectWrap\(\)\s*(,)?/gm, '$1($2) : Napi::ObjectWrap<$1>()$3'],
|
|
91
|
+
|
|
92
|
+
// HandleOKCallback to OnOK
|
|
93
|
+
[/HandleOKCallback/g, 'OnOK'],
|
|
94
|
+
// HandleErrorCallback to OnError
|
|
95
|
+
[/HandleErrorCallback/g, 'OnError'],
|
|
96
|
+
|
|
97
|
+
// ex. .As<Function>() to .As<Napi::Object>()
|
|
98
|
+
[/\.As<v8::(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>\(\)/g, '.As<Napi::$1>()'],
|
|
99
|
+
[/\.As<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>\(\)/g, '.As<Napi::$1>()'],
|
|
100
|
+
|
|
101
|
+
// ex. Nan::New<Number>(info[0]) to Napi::Number::New(info[0])
|
|
102
|
+
[/Nan::New<(v8::)*Integer>\((.+?)\)/g, 'Napi::Number::New(env, $2)'],
|
|
103
|
+
[/Nan::New\(([0-9.]+)\)/g, 'Napi::Number::New(env, $1)'],
|
|
104
|
+
[/Nan::New<(v8::)*String>\("(.+?)"\)/g, 'Napi::String::New(env, "$2")'],
|
|
105
|
+
[/Nan::New\("(.+?)"\)/g, 'Napi::String::New(env, "$1")'],
|
|
106
|
+
[/Nan::New<(v8::)*(.+?)>\(\)/g, 'Napi::$2::New(env)'],
|
|
107
|
+
[/Nan::New<(.+?)>\(\)/g, 'Napi::$1::New(env)'],
|
|
108
|
+
[/Nan::New<(v8::)*(.+?)>\(/g, 'Napi::$2::New(env, '],
|
|
109
|
+
[/Nan::New<(.+?)>\(/g, 'Napi::$1::New(env, '],
|
|
110
|
+
[/Nan::NewBuffer\(/g, 'Napi::Buffer<char>::New(env, '],
|
|
111
|
+
// TODO: Properly handle this
|
|
112
|
+
[/Nan::New\(/g, 'Napi::New(env, '],
|
|
113
|
+
|
|
114
|
+
[/\.IsInt32\(\)/g, '.IsNumber()'],
|
|
115
|
+
[/->IsInt32\(\)/g, '.IsNumber()'],
|
|
116
|
+
|
|
117
|
+
[/(.+?)->BooleanValue\(\)/g, '$1.As<Napi::Boolean>().Value()'],
|
|
118
|
+
[/(.+?)->Int32Value\(\)/g, '$1.As<Napi::Number>().Int32Value()'],
|
|
119
|
+
[/(.+?)->Uint32Value\(\)/g, '$1.As<Napi::Number>().Uint32Value()'],
|
|
120
|
+
[/(.+?)->IntegerValue\(\)/g, '$1.As<Napi::Number>().Int64Value()'],
|
|
121
|
+
[/(.+?)->NumberValue\(\)/g, '$1.As<Napi::Number>().DoubleValue()'],
|
|
122
|
+
|
|
123
|
+
// ex. Nan::To<bool>(info[0]) to info[0].Value()
|
|
124
|
+
[/Nan::To<v8::(Boolean|String|Number|Object|Array|Symbol|Function)>\((.+?)\)/g, '$2.To<Napi::$1>()'],
|
|
125
|
+
[/Nan::To<(Boolean|String|Number|Object|Array|Symbol|Function)>\((.+?)\)/g, '$2.To<Napi::$1>()'],
|
|
126
|
+
// ex. Nan::To<bool>(info[0]) to info[0].As<Napi::Boolean>().Value()
|
|
127
|
+
[/Nan::To<bool>\((.+?)\)/g, '$1.As<Napi::Boolean>().Value()'],
|
|
128
|
+
// ex. Nan::To<int>(info[0]) to info[0].As<Napi::Number>().Int32Value()
|
|
129
|
+
[/Nan::To<int>\((.+?)\)/g, '$1.As<Napi::Number>().Int32Value()'],
|
|
130
|
+
// ex. Nan::To<int32_t>(info[0]) to info[0].As<Napi::Number>().Int32Value()
|
|
131
|
+
[/Nan::To<int32_t>\((.+?)\)/g, '$1.As<Napi::Number>().Int32Value()'],
|
|
132
|
+
// ex. Nan::To<uint32_t>(info[0]) to info[0].As<Napi::Number>().Uint32Value()
|
|
133
|
+
[/Nan::To<uint32_t>\((.+?)\)/g, '$1.As<Napi::Number>().Uint32Value()'],
|
|
134
|
+
// ex. Nan::To<int64_t>(info[0]) to info[0].As<Napi::Number>().Int64Value()
|
|
135
|
+
[/Nan::To<int64_t>\((.+?)\)/g, '$1.As<Napi::Number>().Int64Value()'],
|
|
136
|
+
// ex. Nan::To<float>(info[0]) to info[0].As<Napi::Number>().FloatValue()
|
|
137
|
+
[/Nan::To<float>\((.+?)\)/g, '$1.As<Napi::Number>().FloatValue()'],
|
|
138
|
+
// ex. Nan::To<double>(info[0]) to info[0].As<Napi::Number>().DoubleValue()
|
|
139
|
+
[/Nan::To<double>\((.+?)\)/g, '$1.As<Napi::Number>().DoubleValue()'],
|
|
140
|
+
|
|
141
|
+
[/Nan::New\((\w+)\)->HasInstance\((\w+)\)/g, '$2.InstanceOf($1.Value())'],
|
|
142
|
+
|
|
143
|
+
[/Nan::Has\(([^,]+),\s*/gm, '($1).Has('],
|
|
144
|
+
[/\.Has\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Has($1)'],
|
|
145
|
+
[/\.Has\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Has($1)'],
|
|
146
|
+
|
|
147
|
+
[/Nan::Get\(([^,]+),\s*/gm, '($1).Get('],
|
|
148
|
+
[/\.Get\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Get($1)'],
|
|
149
|
+
[/\.Get\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Get($1)'],
|
|
150
|
+
|
|
151
|
+
[/Nan::Set\(([^,]+),\s*/gm, '($1).Set('],
|
|
152
|
+
[/\.Set\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\s*,/gm, '.Set($1,'],
|
|
153
|
+
[/\.Set\([\s|\\]*Nan::New\(([^)]+)\)\s*,/gm, '.Set($1,'],
|
|
154
|
+
|
|
155
|
+
// ex. node::Buffer::HasInstance(info[0]) to info[0].IsBuffer()
|
|
156
|
+
[/node::Buffer::HasInstance\((.+?)\)/g, '$1.IsBuffer()'],
|
|
157
|
+
// ex. node::Buffer::Length(info[0]) to info[0].Length()
|
|
158
|
+
[/node::Buffer::Length\((.+?)\)/g, '$1.As<Napi::Buffer<char>>().Length()'],
|
|
159
|
+
// ex. node::Buffer::Data(info[0]) to info[0].Data()
|
|
160
|
+
[/node::Buffer::Data\((.+?)\)/g, '$1.As<Napi::Buffer<char>>().Data()'],
|
|
161
|
+
[/Nan::CopyBuffer\(/g, 'Napi::Buffer::Copy(env, '],
|
|
162
|
+
|
|
163
|
+
// Nan::AsyncQueueWorker(worker)
|
|
164
|
+
[/Nan::AsyncQueueWorker\((.+)\);/g, '$1.Queue();'],
|
|
165
|
+
[/Nan::(Undefined|Null|True|False)\(\)/g, 'env.$1()'],
|
|
166
|
+
|
|
167
|
+
// Nan::ThrowError(error) to Napi::Error::New(env, error).ThrowAsJavaScriptException()
|
|
168
|
+
[/([ ]*)return Nan::Throw(\w*?)Error\((.+?)\);/g, '$1Napi::$2Error::New(env, $3).ThrowAsJavaScriptException();\n$1return env.Null();'],
|
|
169
|
+
[/Nan::Throw(\w*?)Error\((.+?)\);\n(\s*)return;/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n$3return env.Null();'],
|
|
170
|
+
[/Nan::Throw(\w*?)Error\((.+?)\);/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n'],
|
|
171
|
+
// Nan::RangeError(error) to Napi::RangeError::New(env, error)
|
|
172
|
+
[/Nan::(\w*?)Error\((.+)\)/g, 'Napi::$1Error::New(env, $2)'],
|
|
173
|
+
|
|
174
|
+
[/Nan::Set\((.+?),\n* *(.+?),\n* *(.+?),\n* *(.+?)\)/g, '$1.Set($2, $3, $4)'],
|
|
175
|
+
|
|
176
|
+
[/Nan::(Escapable)?HandleScope\s+(\w+)\s*;/g, 'Napi::$1HandleScope $2(env);'],
|
|
177
|
+
[/Nan::(Escapable)?HandleScope/g, 'Napi::$1HandleScope'],
|
|
178
|
+
[/Nan::ForceSet\(([^,]+), ?/g, '$1->DefineProperty('],
|
|
179
|
+
[/\.ForceSet\(Napi::String::New\(env, "(\w+)"\),\s*?/g, '.DefineProperty("$1", '],
|
|
180
|
+
// [ /Nan::GetPropertyNames\(([^,]+)\)/, '$1->GetPropertyNames()' ],
|
|
181
|
+
[/Nan::Equals\(([^,]+),/g, '$1.StrictEquals('],
|
|
182
|
+
|
|
183
|
+
[/(.+)->Set\(/g, '$1.Set('],
|
|
184
|
+
|
|
185
|
+
[/Nan::Callback/g, 'Napi::FunctionReference'],
|
|
186
|
+
|
|
187
|
+
[/Nan::Persistent<Object>/g, 'Napi::ObjectReference'],
|
|
188
|
+
[/Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target/g, 'Napi::Env& env, Napi::Object& target'],
|
|
189
|
+
|
|
190
|
+
[/(\w+)\*\s+(\w+)\s*=\s*Nan::ObjectWrap::Unwrap<\w+>\(info\.This\(\)\);/g, '$1* $2 = this;'],
|
|
191
|
+
[/Nan::ObjectWrap::Unwrap<(\w+)>\((.*)\);/g, '$2.Unwrap<$1>();'],
|
|
192
|
+
|
|
193
|
+
[/Nan::NAN_METHOD_RETURN_TYPE/g, 'void'],
|
|
194
|
+
[/NAN_INLINE/g, 'inline'],
|
|
195
|
+
|
|
196
|
+
[/Nan::NAN_METHOD_ARGS_TYPE/g, 'const Napi::CallbackInfo&'],
|
|
197
|
+
[/NAN_METHOD\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'],
|
|
198
|
+
[/static\s*NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'],
|
|
199
|
+
[/NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'],
|
|
200
|
+
[/static\s*NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)'],
|
|
201
|
+
[/NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)'],
|
|
202
|
+
[/void Init\((v8::)*Local<(v8::)*Object> exports\)/g, 'Napi::Object Init(Napi::Env env, Napi::Object exports)'],
|
|
203
|
+
[/NAN_MODULE_INIT\(([\w\d:]+?)\);/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports);'],
|
|
204
|
+
[/NAN_MODULE_INIT\(([\w\d:]+?)\)/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports)'],
|
|
205
|
+
|
|
206
|
+
[/::(Init(?:ialize)?)\(target\)/g, '::$1(env, target, module)'],
|
|
207
|
+
[/constructor_template/g, 'constructor'],
|
|
208
|
+
|
|
209
|
+
[/Nan::FunctionCallbackInfo<(v8::)?Value>[ ]*& [ ]*info\)[ ]*{\n*([ ]*)/gm, 'Napi::CallbackInfo& info) {\n$2Napi::Env env = info.Env();\n$2'],
|
|
210
|
+
[/Nan::FunctionCallbackInfo<(v8::)*Value>\s*&\s*info\);/g, 'Napi::CallbackInfo& info);'],
|
|
211
|
+
[/Nan::FunctionCallbackInfo<(v8::)*Value>\s*&/g, 'Napi::CallbackInfo&'],
|
|
212
|
+
|
|
213
|
+
[/Buffer::HasInstance\(([^)]+)\)/g, '$1.IsBuffer()'],
|
|
214
|
+
|
|
215
|
+
[/info\[(\d+)\]->/g, 'info[$1].'],
|
|
216
|
+
[/info\[([\w\d]+)\]->/g, 'info[$1].'],
|
|
217
|
+
[/info\.This\(\)->/g, 'info.This().'],
|
|
218
|
+
[/->Is(Object|String|Int32|Number)\(\)/g, '.Is$1()'],
|
|
219
|
+
[/info.GetReturnValue\(\).SetUndefined\(\)/g, 'return env.Undefined()'],
|
|
220
|
+
[/info\.GetReturnValue\(\)\.Set\(((\n|.)+?)\);/g, 'return $1;'],
|
|
221
|
+
|
|
222
|
+
// ex. Local<Value> to Napi::Value
|
|
223
|
+
[/v8::Local<v8::(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>/g, 'Napi::$1'],
|
|
224
|
+
[/Local<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>/g, 'Napi::$1'],
|
|
225
|
+
|
|
226
|
+
// Declare an env in helper functions that take a Napi::Value
|
|
227
|
+
[/(\w+)\(Napi::Value (\w+)(,\s*[^()]+)?\)\s*{\n*([ ]*)/gm, '$1(Napi::Value $2$3) {\n$4Napi::Env env = $2.Env();\n$4'],
|
|
228
|
+
|
|
229
|
+
// delete #include <node.h> and/or <v8.h>
|
|
230
|
+
[/#include +(<|")(?:node|nan).h("|>)/g, '#include $1napi.h$2\n#include $1uv.h$2'],
|
|
231
|
+
// NODE_MODULE to NODE_API_MODULE
|
|
232
|
+
[/NODE_MODULE/g, 'NODE_API_MODULE'],
|
|
233
|
+
[/Nan::/g, 'Napi::'],
|
|
234
|
+
[/nan.h/g, 'napi.h'],
|
|
235
|
+
|
|
236
|
+
// delete .FromJust()
|
|
237
|
+
[/\.FromJust\(\)/g, ''],
|
|
238
|
+
// delete .ToLocalCheck()
|
|
239
|
+
[/\.ToLocalChecked\(\)/g, ''],
|
|
240
|
+
[/^.*->SetInternalFieldCount\(.*$/gm, ''],
|
|
241
|
+
|
|
242
|
+
// replace using node; and/or using v8; to using Napi;
|
|
243
|
+
[/using (node|v8);/g, 'using Napi;'],
|
|
244
|
+
[/using namespace (node|Nan|v8);/g, 'using namespace Napi;'],
|
|
245
|
+
// delete using v8::Local;
|
|
246
|
+
[/using v8::Local;\n/g, ''],
|
|
247
|
+
// replace using v8::XXX; with using Napi::XXX
|
|
248
|
+
[/using v8::([A-Za-z]+);/g, 'using Napi::$1;']
|
|
249
|
+
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
const paths = listFiles(dir);
|
|
253
|
+
paths.forEach(function (dirEntry) {
|
|
254
|
+
const filename = dirEntry.split('\\').pop().split('/').pop();
|
|
255
|
+
|
|
256
|
+
// Check whether the file is a source file or a config file
|
|
257
|
+
// then execute function accordingly
|
|
258
|
+
const sourcePattern = /.+\.h|.+\.cc|.+\.cpp/;
|
|
259
|
+
if (sourcePattern.test(filename)) {
|
|
260
|
+
convertFile(dirEntry, SourceFileOperations);
|
|
261
|
+
} else if (ConfigFileOperations[filename] != null) {
|
|
262
|
+
convertFile(dirEntry, ConfigFileOperations[filename]);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
function listFiles (dir, filelist) {
|
|
267
|
+
const files = fs.readdirSync(dir);
|
|
268
|
+
filelist = filelist || [];
|
|
269
|
+
files.forEach(function (file) {
|
|
270
|
+
if (file === 'node_modules') {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (fs.statSync(path.join(dir, file)).isDirectory()) {
|
|
275
|
+
filelist = listFiles(path.join(dir, file), filelist);
|
|
276
|
+
} else {
|
|
277
|
+
filelist.push(path.join(dir, file));
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
return filelist;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function convert (content, operations) {
|
|
284
|
+
for (let i = 0; i < operations.length; i++) {
|
|
285
|
+
const operation = operations[i];
|
|
286
|
+
content = content.replace(operation[0], operation[1]);
|
|
287
|
+
}
|
|
288
|
+
return content;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function convertFile (fileName, operations) {
|
|
292
|
+
fs.readFile(fileName, 'utf-8', function (err, file) {
|
|
293
|
+
if (err) throw err;
|
|
294
|
+
|
|
295
|
+
file = convert(file, operations);
|
|
296
|
+
|
|
297
|
+
fs.writeFile(fileName, file, function (err) {
|
|
298
|
+
if (err) throw err;
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Copyright 2014 Yahoo! Inc.
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright
|
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer in the
|
|
12
|
+
documentation and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
* Neither the name of the Yahoo! Inc. nor the
|
|
15
|
+
names of its contributors may be used to endorse or promote products
|
|
16
|
+
derived from this software without specific prior written permission.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
19
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
20
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL YAHOO! INC. BE LIABLE FOR ANY
|
|
22
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
24
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
25
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Serialize JavaScript
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
Serialize JavaScript to a _superset_ of JSON that includes regular expressions, dates and functions.
|
|
5
|
+
|
|
6
|
+
[![npm Version][npm-badge]][npm]
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The code in this package began its life as an internal module to [express-state][]. To expand its usefulness, it now lives as `serialize-javascript` — an independent package on npm.
|
|
12
|
+
|
|
13
|
+
You're probably wondering: **What about `JSON.stringify()`!?** We've found that sometimes we need to serialize JavaScript **functions**, **regexps**, **dates**, **sets** or **maps**. A great example is a web app that uses client-side URL routing where the route definitions are regexps that need to be shared from the server to the client.
|
|
14
|
+
|
|
15
|
+
The string returned from this package's single export function is literal JavaScript which can be saved to a `.js` file, or be embedded into an HTML document by making the content of a `<script>` element.
|
|
16
|
+
|
|
17
|
+
> **HTML characters and JavaScript line terminators are escaped automatically.**
|
|
18
|
+
|
|
19
|
+
Please note that serialization for ES6 Sets & Maps requires support for `Array.from` (not available in IE or Node < 0.12), or an `Array.from` polyfill.
|
|
20
|
+
|
|
21
|
+
> [!WARNING]
|
|
22
|
+
> It may be tempting to use this package as a way to pass arbitrary functions into [worker threads][], since you cannot pass them directly via `postMessage()`. However, passing functions between worker threads is not possible in the general case. This package lets you serialize *some* functions, but it has limitations.
|
|
23
|
+
>
|
|
24
|
+
> For instance, if a function references something from outside the function body, it will not run properly if serialized and deserialized. This could include [closed-over variables][] or imports from other packages. For a serialized function to run properly, it must be entirely self-contained.
|
|
25
|
+
>
|
|
26
|
+
> In general, it is not possible to send arbitrary JavaScript to a worker thread, and pretend it's running the same way it would run on the main thread. This package doesn't let you do that.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Install using npm:
|
|
31
|
+
|
|
32
|
+
```shell
|
|
33
|
+
$ npm install serialize-javascript
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
var serialize = require('serialize-javascript');
|
|
40
|
+
|
|
41
|
+
serialize({
|
|
42
|
+
str : 'string',
|
|
43
|
+
num : 0,
|
|
44
|
+
obj : {foo: 'foo'},
|
|
45
|
+
arr : [1, 2, 3],
|
|
46
|
+
bool : true,
|
|
47
|
+
nil : null,
|
|
48
|
+
undef: undefined,
|
|
49
|
+
inf : Infinity,
|
|
50
|
+
date : new Date("Thu, 28 Apr 2016 22:02:17 GMT"),
|
|
51
|
+
map : new Map([['hello', 'world']]),
|
|
52
|
+
set : new Set([123, 456]),
|
|
53
|
+
fn : function echo(arg) { return arg; },
|
|
54
|
+
re : /([^\s]+)/g,
|
|
55
|
+
big : BigInt(10),
|
|
56
|
+
url : new URL('https://example.com/'),
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The above will produce the following string output:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"undef":undefined,"inf":Infinity,"date":new Date("2016-04-28T22:02:17.000Z"),"map":new Map([["hello","world"]]),"set":new Set([123,456]),"fn":function echo(arg) { return arg; },"re":new RegExp("([^\\\\s]+)", "g"),"big":BigInt("10"),"url":new URL("https://example.com/")}'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Note: to produce a beautified string, you can pass an optional second argument to `serialize()` to define the number of spaces to be used for the indentation.
|
|
67
|
+
|
|
68
|
+
### Automatic Escaping of HTML Characters
|
|
69
|
+
|
|
70
|
+
A primary feature of this package is to serialize code to a string of literal JavaScript which can be embedded in an HTML document by adding it as the contents of the `<script>` element. In order to make this safe, HTML characters and JavaScript line terminators are escaped automatically.
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
serialize({
|
|
74
|
+
haxorXSS: '</script>'
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The above will produce the following string, HTML-escaped output which is safe to put into an HTML document as it will not cause the inline script element to terminate:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
'{"haxorXSS":"\\u003C\\u002Fscript\\u003E"}'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> You can pass an optional `unsafe` argument to `serialize()` for straight serialization.
|
|
85
|
+
|
|
86
|
+
### Options
|
|
87
|
+
|
|
88
|
+
The `serialize()` function accepts an `options` object as its second argument. All options are being defaulted to `undefined`:
|
|
89
|
+
|
|
90
|
+
#### `options.space`
|
|
91
|
+
|
|
92
|
+
This option is the same as the `space` argument that can be passed to [`JSON.stringify`][JSON.stringify]. It can be used to add whitespace and indentation to the serialized output to make it more readable.
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
serialize(obj, {space: 2});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### `options.isJSON`
|
|
99
|
+
|
|
100
|
+
This option is a signal to `serialize()` that the object being serialized does not contain any function or regexps values. This enables a hot-path that allows serialization to be over 3x faster. If you're serializing a lot of data, and know its pure JSON, then you can enable this option for a speed-up.
|
|
101
|
+
|
|
102
|
+
**Note:** That when using this option, the output will still be escaped to protect against XSS.
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
serialize(obj, {isJSON: true});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### `options.unsafe`
|
|
109
|
+
|
|
110
|
+
This option is to signal `serialize()` that we want to do a straight conversion, without the XSS protection. This options needs to be explicitly set to `true`. HTML characters and JavaScript line terminators will not be escaped. You will have to roll your own.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
serialize(obj, {unsafe: true});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### `options.ignoreFunction`
|
|
117
|
+
|
|
118
|
+
This option is to signal `serialize()` that we do not want serialize JavaScript function.
|
|
119
|
+
Just treat function like `JSON.stringify` do, but other features will work as expected.
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
serialize(obj, {ignoreFunction: true});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Deserializing
|
|
126
|
+
|
|
127
|
+
For some use cases you might also need to deserialize the string. This is explicitly not part of this module. However, you can easily write it yourself:
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
function deserialize(serializedJavascript){
|
|
131
|
+
return eval('(' + serializedJavascript + ')');
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Note:** Don't forget the parentheses around the serialized javascript, as the opening bracket `{` will be considered to be the start of a body.
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
This software is free to use under the Yahoo! Inc. BSD license.
|
|
140
|
+
See the [LICENSE file][LICENSE] for license text and copyright information.
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
[npm]: https://www.npmjs.org/package/serialize-javascript
|
|
144
|
+
[npm-badge]: https://img.shields.io/npm/v/serialize-javascript.svg?style=flat-square
|
|
145
|
+
[express-state]: https://github.com/yahoo/express-state
|
|
146
|
+
[JSON.stringify]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
|
|
147
|
+
[LICENSE]: https://github.com/yahoo/serialize-javascript/blob/main/LICENSE
|
|
148
|
+
[worker threads]: https://nodejs.org/api/worker_threads.html
|
|
149
|
+
[closed-over variables]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures
|