@stackline/redeyed 1.0.1

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 ADDED
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on Keep a Changelog and this project follows Semantic
6
+ Versioning.
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.0.1] - 2026-08-26
11
+
12
+ ### Added
13
+
14
+ - Public token-transform playground and machine-readable documentation.
15
+ - Verbatim Esprima BSD-2-Clause redistribution terms for embedded browser
16
+ bundles.
17
+ - Pinned CI, CodeQL, and immutable npm publication workflows.
18
+ - Documentation build, crawler metadata, package checks, and production audit
19
+ gates.
20
+
21
+ ## [1.0.0] - 2026-08-26
22
+
23
+ ### Added
24
+
25
+ - Immutable, null-prototype configuration compilation.
26
+ - Safe support for shadowed and prototype-like token keys.
27
+ - Array-returning custom tokenizer support and `parserOptions`.
28
+ - Native ESM, first-party TypeScript declarations, and browser bundles.
29
+ - Differential, frozen-config, hostile-key, parser, hashbang, package, and
30
+ cardinal adoption regressions.
31
+ - Current security, migration, compatibility, and provenance documentation.
32
+
33
+ ### Changed
34
+
35
+ - Package name to `@stackline/redeyed` for independent maintenance.
36
+ - Hashbang masking to bounded string construction with no-newline support.
37
+ - Development tooling to a current, audit-clean release pipeline.
38
+ - Published files to an explicit runtime and documentation allowlist.
39
+
40
+ ### Preserved
41
+
42
+ - Callable CommonJS and UMD APIs.
43
+ - Esprima 4 default behavior.
44
+ - Existing config precedence, callbacks, token skipping, JSX/AST/nojoin, result
45
+ shape, comments, splits, and source retention.
46
+ - Original MIT copyright and permission notice.
47
+
48
+ [Unreleased]: https://github.com/alexandroit/stackline-redeyed/compare/stackline-v1.0.1...HEAD
49
+ [1.0.1]: https://github.com/alexandroit/stackline-redeyed/compare/stackline-v1.0.0...stackline-v1.0.1
50
+ [1.0.0]: https://github.com/alexandroit/stackline-redeyed/tree/stackline-v1.0.0
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright 2012 Thorsten Lorenz.
2
+ All rights reserved.
3
+
4
+ Permission is hereby granted, free of charge, to any person
5
+ obtaining a copy of this software and associated documentation
6
+ files (the "Software"), to deal in the Software without
7
+ restriction, including without limitation the rights to use,
8
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the
10
+ Software is furnished to do so, subject to the following
11
+ conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ OTHER DEALINGS IN THE SOFTWARE.
package/NOTICE ADDED
@@ -0,0 +1,9 @@
1
+ @stackline/redeyed is an independent maintained continuation of redeyed.
2
+
3
+ It is not affiliated with or endorsed by the original author. Original
4
+ copyright and MIT license terms are preserved in LICENSE.
5
+
6
+ Original project: https://github.com/thlorenz/redeyed
7
+
8
+ Browser bundles include Esprima 4.0.1. Its BSD-2-Clause redistribution terms
9
+ are preserved in THIRD_PARTY_LICENSES.md.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # @stackline/redeyed
2
+
3
+ > Source-preserving JavaScript token transforms with immutable configuration
4
+ > and pluggable parsers.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/@stackline/redeyed.svg?style=flat-square)](https://www.npmjs.com/package/@stackline/redeyed)
7
+ [![npm downloads](https://img.shields.io/npm/dm/@stackline/redeyed.svg?style=flat-square)](https://www.npmjs.com/package/@stackline/redeyed)
8
+ [![CI](https://img.shields.io/github/actions/workflow/status/alexandroit/stackline-redeyed/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/alexandroit/stackline-redeyed/actions/workflows/ci.yml)
9
+ [![license](https://img.shields.io/npm/l/@stackline/redeyed.svg?style=flat-square)](LICENSE)
10
+
11
+ **[Docs and transformer](https://alexandro.net/docs/vanilla/redeyed/)** |
12
+ **[npm](https://www.npmjs.com/package/@stackline/redeyed)** |
13
+ **[GitHub](https://github.com/alexandroit/stackline-redeyed)** |
14
+ **[Migration](MIGRATION.md)** |
15
+ **[Security](SECURITY.md)** |
16
+ **[Changelog](CHANGELOG.md)**
17
+
18
+ **Current package version:** `1.0.1`
19
+
20
+ This package is an independent, maintained continuation of
21
+ [`redeyed`](https://github.com/thlorenz/redeyed). It preserves the established
22
+ 2.1.1 callable API and Esprima defaults while removing config mutation, safely
23
+ handling property-like token names, and supporting current array-returning
24
+ tokenizers as an opt-in extension.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ npm install @stackline/redeyed
30
+ ```
31
+
32
+ Preserve existing `require('redeyed')` calls with an npm alias:
33
+
34
+ ```bash
35
+ npm install redeyed@npm:@stackline/redeyed
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```js
41
+ const redeyed = require('@stackline/redeyed')
42
+
43
+ const result = redeyed(
44
+ 'const answer = 42',
45
+ {
46
+ Keyword: { _default: '<strong>:</strong>' },
47
+ Numeric: { _default: '<mark>:</mark>' }
48
+ }
49
+ )
50
+
51
+ console.log(result.code)
52
+ // <strong>const</strong> answer = <mark>42</mark>
53
+ ```
54
+
55
+ A string transform uses `before:after`. Object and function forms are also
56
+ supported:
57
+
58
+ ```js
59
+ const config = {
60
+ Identifier: {
61
+ answer: { _before: '[', _after: ']' },
62
+ _default: (source, info) => {
63
+ return info.tokenIndex === 0 ? source.toUpperCase() : source
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ The caller's config is never changed. Frozen objects, null-prototype maps, and
70
+ token names such as `hasOwnProperty`, `__proto__`, `constructor`, and
71
+ `prototype` are processed as data.
72
+
73
+ ## API
74
+
75
+ ### `redeyed(code, config[, options])`
76
+
77
+ Returns:
78
+
79
+ ```js
80
+ {
81
+ ast,
82
+ tokens,
83
+ comments,
84
+ splits,
85
+ code
86
+ }
87
+ ```
88
+
89
+ Options:
90
+
91
+ | Option | Default | Purpose |
92
+ | --- | --- | --- |
93
+ | `buildAst` | `false` | Parse and return an AST instead of tokenizer-only operation |
94
+ | `jsx` | `false` | Enable the historical JSX parsing path |
95
+ | `nojoin` | `false` | Return splits without joining transformed code |
96
+ | `parser` | Esprima 4 | Supply an Esprima-compatible or array-returning parser |
97
+ | `parserOptions` | `{}` | Pass parser-specific settings |
98
+
99
+ Function transforms receive `(tokenSource, info)`. `info` contains the merged
100
+ token index, tokens and comments, AST when requested, and source. A transform
101
+ can return a string or:
102
+
103
+ ```js
104
+ {
105
+ replacement: 'new source',
106
+ skipPastToken: info.tokens[targetIndex]
107
+ }
108
+ ```
109
+
110
+ ## Modern Syntax
111
+
112
+ Esprima remains the default to avoid silently changing token labels and ASTs.
113
+ For modern syntax, opt in to a parser already used by your application:
114
+
115
+ ```bash
116
+ npm install espree
117
+ ```
118
+
119
+ ```js
120
+ const espree = require('espree')
121
+ const redeyed = require('@stackline/redeyed')
122
+
123
+ const result = redeyed(
124
+ 'class Box { #value = 1_000n }',
125
+ {
126
+ PrivateIdentifier: { _default: '<:>' },
127
+ Numeric: { _default: '[:]' }
128
+ },
129
+ {
130
+ parser: espree,
131
+ parserOptions: {
132
+ ecmaVersion: 'latest',
133
+ sourceType: 'module'
134
+ }
135
+ }
136
+ )
137
+ ```
138
+
139
+ Parser-specific token types remain parser-specific. Array tokenizers can expose
140
+ comments only when their return data includes comments; `buildAst: true` uses
141
+ the parser's AST tokens and comments.
142
+
143
+ ## Modules And Browser
144
+
145
+ - Callable CommonJS entry
146
+ - Native ESM default and named exports
147
+ - First-party TypeScript declarations, including TypeScript 3.9 consumers
148
+ - Self-contained browser CJS, ESM, and global bundles
149
+ - Original UMD behavior retained in `redeyed.js`
150
+ - Node.js 12 and newer at runtime
151
+
152
+ The package also exports starter configs:
153
+
154
+ ```js
155
+ const config = require('@stackline/redeyed/config')
156
+ const es5Config = require('@stackline/redeyed/config-es5')
157
+ ```
158
+
159
+ ## Package Integrity
160
+
161
+ The old 2.1.1 npm artifact includes an example that references jQuery 1.8.1.
162
+ That example is not runtime code, but it triggers dependency scanners. The
163
+ Stackline artifact ships only runtime entries, configs, types, documentation,
164
+ licenses, and generated browser bundles. No redeyed runtime CVE is claimed.
165
+
166
+ The maintained suite includes all 187 upstream assertions, more than 1,000
167
+ differential executions, immutable and hostile-key configs, modern parser
168
+ adapters, hashbang edges, browser/modules/types, package audits, and a direct
169
+ `cardinal` adoption check.
170
+
171
+ ## Security
172
+
173
+ Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
174
+ Please do not publish an unpatched report in a public issue.
175
+
176
+ ## Provenance
177
+
178
+ The source history, decisions, and preserved boundary are recorded in
179
+ [UPSTREAM_AUDIT.md](UPSTREAM_AUDIT.md),
180
+ [COMPATIBILITY_CONTRACT.md](COMPATIBILITY_CONTRACT.md), and [NOTICE](NOTICE).
181
+ Stackline is not affiliated with or endorsed by the upstream author.
182
+
183
+ ## License
184
+
185
+ MIT. The original copyright and permission notice remain in
186
+ [LICENSE](LICENSE). Browser bundles also retain Esprima's BSD-2-Clause legal
187
+ terms in [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md).
package/SECURITY.md ADDED
@@ -0,0 +1,26 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | --- | --- |
7
+ | 1.x | Yes |
8
+ | Upstream 2.x | Maintained by its upstream owner |
9
+
10
+ ## Reporting A Vulnerability
11
+
12
+ Use GitHub private vulnerability reporting for this repository. If that channel
13
+ is unavailable, contact the security address on the Stackline organization
14
+ profile.
15
+
16
+ Include the affected version, runtime and parser, a minimal reproduction,
17
+ impact, and known workarounds. Do not open a public issue before a coordinated
18
+ fix is available. A complete report will be acknowledged within five business
19
+ days.
20
+
21
+ ## Historical Artifact Note
22
+
23
+ Upstream issue #22 concerns an old jQuery URL in an example shipped with
24
+ `redeyed@2.1.1`. The example is not executed by the library. Stackline excludes
25
+ that example from npm artifacts, but does not misrepresent the scanner finding
26
+ as a CVE in redeyed's runtime.
@@ -0,0 +1,25 @@
1
+ # Third-Party Licenses
2
+
3
+ ## Esprima 4.0.1 (BSD-2-Clause)
4
+
5
+ Copyright JS Foundation and other contributors, https://js.foundation/
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright
11
+ notice, this list of conditions and the following disclaimer.
12
+ * Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in the
14
+ documentation and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+ import redeyed = require("./index")
2
+
3
+ declare const config: redeyed.Config
4
+
5
+ export = config
package/config-es5.js ADDED
@@ -0,0 +1,140 @@
1
+ /*
2
+ * This config only contains ES5 tokens while the default config.js contains
3
+ * ES6 tokens as well.
4
+ *
5
+ * Copy this file and use it as a starting point for your redeyed config.
6
+ * Just fill in the tokens you want to surround/replace.
7
+ * Keep in mind that more specific configurations override less specific ones.
8
+ */
9
+
10
+ module.exports = {
11
+
12
+ 'Boolean': {
13
+ 'true' : undefined
14
+ , 'false' : undefined
15
+ , _default : undefined
16
+ }
17
+
18
+ , 'Identifier': {
19
+ _default: undefined
20
+ }
21
+
22
+ , 'Null': {
23
+ _default: undefined
24
+ }
25
+
26
+ , 'Numeric': {
27
+ _default: undefined
28
+ }
29
+
30
+ , 'String': {
31
+ _default: undefined
32
+ }
33
+
34
+ , 'Keyword': {
35
+ 'break' : undefined
36
+
37
+ , 'case' : undefined
38
+ , 'catch' : undefined
39
+ , 'continue' : undefined
40
+
41
+ , 'debugger' : undefined
42
+ , 'default' : undefined
43
+ , 'delete' : undefined
44
+ , 'do' : undefined
45
+
46
+ , 'else' : undefined
47
+
48
+ , 'finally' : undefined
49
+ , 'for' : undefined
50
+ , 'function' : undefined
51
+
52
+ , 'if' : undefined
53
+ , 'in' : undefined
54
+ , 'instanceof' : undefined
55
+
56
+ , 'new' : undefined
57
+ , 'return' : undefined
58
+ , 'switch' : undefined
59
+
60
+ , 'this' : undefined
61
+ , 'throw' : undefined
62
+ , 'try' : undefined
63
+ , 'typeof' : undefined
64
+
65
+ , 'var' : undefined
66
+ , 'void' : undefined
67
+
68
+ , 'while' : undefined
69
+ , 'with' : undefined
70
+ , _default : undefined
71
+ }
72
+ , 'Punctuator': {
73
+ ';': undefined
74
+ , '.': undefined
75
+ , ',': undefined
76
+
77
+ , '{': undefined
78
+ , '}': undefined
79
+ , '(': undefined
80
+ , ')': undefined
81
+ , '[': undefined
82
+ , ']': undefined
83
+
84
+ , '<': undefined
85
+ , '>': undefined
86
+ , '+': undefined
87
+ , '-': undefined
88
+ , '*': undefined
89
+ , '%': undefined
90
+ , '&': undefined
91
+ , '|': undefined
92
+ , '^': undefined
93
+ , '!': undefined
94
+ , '~': undefined
95
+ , '?': undefined
96
+ , ':': undefined
97
+ , '=': undefined
98
+
99
+ , '<=': undefined
100
+ , '>=': undefined
101
+ , '==': undefined
102
+ , '!=': undefined
103
+ , '++': undefined
104
+ , '--': undefined
105
+ , '<<': undefined
106
+ , '>>': undefined
107
+ , '&&': undefined
108
+ , '||': undefined
109
+ , '+=': undefined
110
+ , '-=': undefined
111
+ , '*=': undefined
112
+ , '%=': undefined
113
+ , '&=': undefined
114
+ , '|=': undefined
115
+ , '^=': undefined
116
+ , '/=': undefined
117
+
118
+ , '===': undefined
119
+ , '!==': undefined
120
+ , '>>>': undefined
121
+ , '<<=': undefined
122
+ , '>>=': undefined
123
+
124
+ , '>>>=': undefined
125
+
126
+ , _default: undefined
127
+ }
128
+
129
+ // line comment
130
+ , Line: {
131
+ _default: undefined
132
+ }
133
+
134
+ /* block comment */
135
+ , Block: {
136
+ _default: undefined
137
+ }
138
+
139
+ , _default: undefined
140
+ }
package/config.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import redeyed = require("./index")
2
+
3
+ declare const config: redeyed.Config
4
+
5
+ export = config
package/config.js ADDED
@@ -0,0 +1,195 @@
1
+ /*
2
+ * Copy this file and use it as a starting point for your redeyed config.
3
+ * Just fill in the tokens you want to surround/replace.
4
+ * Keep in mind that more specific configurations override less specific ones.
5
+ */
6
+
7
+ module.exports = {
8
+
9
+ 'Boolean': {
10
+ 'true' : undefined
11
+ , 'false' : undefined
12
+ , _default : undefined
13
+ }
14
+
15
+ , 'Identifier': {
16
+ _default: undefined
17
+ }
18
+
19
+ , 'Null': {
20
+ _default: undefined
21
+ }
22
+
23
+ , 'Numeric': {
24
+ _default: undefined
25
+ }
26
+
27
+ , 'String': {
28
+ _default: undefined
29
+ }
30
+
31
+ , 'Keyword': {
32
+ 'break' : undefined
33
+
34
+ , 'case' : undefined
35
+ , 'catch' : undefined
36
+ , 'class' : undefined
37
+ , 'const' : undefined
38
+ , 'continue' : undefined
39
+
40
+ , 'debugger' : undefined
41
+ , 'default' : undefined
42
+ , 'delete' : undefined
43
+ , 'do' : undefined
44
+
45
+ , 'else' : undefined
46
+ , 'enum' : undefined
47
+ , 'export' : undefined
48
+ , 'extends' : undefined
49
+
50
+ , 'finally' : undefined
51
+ , 'for' : undefined
52
+ , 'function' : undefined
53
+
54
+ , 'if' : undefined
55
+ , 'implements' : undefined
56
+ , 'import' : undefined
57
+ , 'in' : undefined
58
+ , 'instanceof' : undefined
59
+ , 'interface' : undefined
60
+ , 'let' : undefined
61
+ , 'new' : undefined
62
+
63
+ , 'package' : undefined
64
+ , 'private' : undefined
65
+ , 'protected' : undefined
66
+ , 'public' : undefined
67
+
68
+ , 'return' : undefined
69
+ , 'static' : undefined
70
+ , 'super' : undefined
71
+ , 'switch' : undefined
72
+
73
+ , 'this' : undefined
74
+ , 'throw' : undefined
75
+ , 'try' : undefined
76
+ , 'typeof' : undefined
77
+
78
+ , 'var' : undefined
79
+ , 'void' : undefined
80
+
81
+ , 'while' : undefined
82
+ , 'with' : undefined
83
+ , 'yield' : undefined
84
+ , _default : undefined
85
+ }
86
+ , 'Punctuator': {
87
+ ';': undefined
88
+ , '.': undefined
89
+ , ',': undefined
90
+
91
+ , '{': undefined
92
+ , '}': undefined
93
+ , '(': undefined
94
+ , ')': undefined
95
+ , '[': undefined
96
+ , ']': undefined
97
+
98
+ , '<': undefined
99
+ , '>': undefined
100
+ , '+': undefined
101
+ , '-': undefined
102
+ , '*': undefined
103
+ , '%': undefined
104
+ , '&': undefined
105
+ , '|': undefined
106
+ , '^': undefined
107
+ , '!': undefined
108
+ , '~': undefined
109
+ , '?': undefined
110
+ , ':': undefined
111
+ , '=': undefined
112
+
113
+ , '<=': undefined
114
+ , '>=': undefined
115
+ , '==': undefined
116
+ , '!=': undefined
117
+ , '++': undefined
118
+ , '--': undefined
119
+ , '<<': undefined
120
+ , '>>': undefined
121
+ , '&&': undefined
122
+ , '||': undefined
123
+ , '+=': undefined
124
+ , '-=': undefined
125
+ , '*=': undefined
126
+ , '%=': undefined
127
+ , '&=': undefined
128
+ , '|=': undefined
129
+ , '^=': undefined
130
+ , '/=': undefined
131
+ , '=>': undefined
132
+ , '**': undefined
133
+
134
+ , '===': undefined
135
+ , '!==': undefined
136
+ , '>>>': undefined
137
+ , '<<=': undefined
138
+ , '>>=': undefined
139
+ , '...': undefined
140
+ , '**=': undefined
141
+
142
+ , '>>>=': undefined
143
+
144
+ , _default: undefined
145
+ }
146
+
147
+ // line comment
148
+ , Line: {
149
+ _default: undefined
150
+ }
151
+
152
+ /* block comment */
153
+ , Block: {
154
+ _default: undefined
155
+ }
156
+
157
+ // JSX
158
+ , JSXAttribute: {
159
+ _default: undefined
160
+ }
161
+ , JSXClosingElement: {
162
+ _default: undefined
163
+ }
164
+ , JSXElement: {
165
+ _default: undefined
166
+ }
167
+ , JSXEmptyExpression: {
168
+ _default: undefined
169
+ }
170
+ , JSXExpressionContainer: {
171
+ _default: undefined
172
+ }
173
+ , JSXIdentifier: {
174
+ // many more identifies are possible, div, table, etc.
175
+ className: undefined
176
+ , _default: undefined
177
+ }
178
+ , JSXMemberExpression: {
179
+ _default: undefined
180
+ }
181
+ , JSXNamespacedName: {
182
+ _default: undefined
183
+ }
184
+ , JSXOpeningElement: {
185
+ _default: undefined
186
+ }
187
+ , JSXSpreadAttribute: {
188
+ _default: undefined
189
+ }
190
+ , JSXText: {
191
+ _default: undefined
192
+ }
193
+
194
+ , _default: undefined
195
+ }