@stackline/wcwidth 1.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 +16 -0
- package/COMPATIBILITY.md +5 -0
- package/COMPATIBILITY_CONTRACT.md +75 -0
- package/CONTRIBUTING.md +18 -0
- package/LICENSE +21 -0
- package/MIGRATION.md +39 -0
- package/NOTICE +15 -0
- package/PUBLISHING.md +103 -0
- package/README.md +112 -0
- package/SECURITY.md +21 -0
- package/THIRD_PARTY_LICENSES.md +90 -0
- package/VERIFICATION.md +29 -0
- package/combining.d.ts +3 -0
- package/combining.js +5 -0
- package/dist/index.mjs +1 -0
- package/examples/commonjs.cjs +6 -0
- package/examples/esm.mjs +4 -0
- package/examples/install.sh +1 -0
- package/examples/legacy-alias.json +5 -0
- package/index.d.cts +17 -0
- package/index.d.mts +19 -0
- package/index.d.ts +17 -0
- package/index.js +28 -0
- package/index.mjs +7 -0
- package/lib/defaults.js +12 -0
- package/lib/graphemes.js +147 -0
- package/lib/ranges.js +22 -0
- package/lib/unicode-tables.js +653 -0
- package/lib/width.js +91 -0
- package/package.json +149 -0
- package/scripts/test-package.mjs +38 -0
- package/tools/generate-unicode-tables.mjs +234 -0
- package/unicode-sources.json +33 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this package are documented here.
|
|
4
|
+
|
|
5
|
+
## 1.0.0 - 2026-09-06
|
|
6
|
+
|
|
7
|
+
- Continue the callable `wcwidth@1.0.1` CommonJS API and `.config()` behavior.
|
|
8
|
+
- Remove the `defaults` and `clone` production dependency chain.
|
|
9
|
+
- Use checksum-pinned Unicode 17.0.0 width and grapheme properties.
|
|
10
|
+
- Count fully-qualified emoji, flags, keycaps, presentation sequences, and
|
|
11
|
+
emoji ZWJ sequences by grapheme cluster.
|
|
12
|
+
- Add native ESM, first-party TypeScript declarations, browser bundler support,
|
|
13
|
+
reproducible Unicode generation, and a root-only production closure.
|
|
14
|
+
- Add exact-artifact GitHub Actions publishing with a first-package token
|
|
15
|
+
bootstrap, npm provenance, registry verification, and Trusted Publisher OIDC
|
|
16
|
+
for later versions.
|
package/COMPATIBILITY.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Compatibility contract
|
|
2
|
+
|
|
3
|
+
Baseline: `wcwidth@1.0.1`.
|
|
4
|
+
|
|
5
|
+
## Public surface
|
|
6
|
+
|
|
7
|
+
`require('@stackline/wcwidth')` returns one callable function named `wcwidth`
|
|
8
|
+
with arity one and no nested `default` property. Its enumerable own-property
|
|
9
|
+
shape matches the baseline: `Object.keys(wcwidth)` is exactly `['config']`.
|
|
10
|
+
The read-only, non-enumerable `unicodeVersion` property is an additive reference
|
|
11
|
+
and is currently `17.0.0`.
|
|
12
|
+
|
|
13
|
+
`import wcwidth from '@stackline/wcwidth'` returns an equivalent standalone ESM
|
|
14
|
+
function and also exports `config` and `unicodeVersion`. `./package.json` is
|
|
15
|
+
exported for tooling. The historical CommonJS subpaths `./index.js`,
|
|
16
|
+
`./combining`, and `./combining.js` remain resolvable. The combining subpaths
|
|
17
|
+
preserve the baseline array shape while exposing the maintained Unicode 17
|
|
18
|
+
zero-width ranges.
|
|
19
|
+
|
|
20
|
+
## Configuration
|
|
21
|
+
|
|
22
|
+
The default options are `{ nul: 0, control: 0 }`.
|
|
23
|
+
|
|
24
|
+
As in `wcwidth@1.0.1`, `config(options)` uses the supplied object directly. It
|
|
25
|
+
adds missing `nul` and `control` properties, accepts inherited values, and the
|
|
26
|
+
returned function observes later mutations. Falsy options select a new default
|
|
27
|
+
object. Truthy primitives and non-extensible objects retain the historical
|
|
28
|
+
coercive results. A negative configured control width causes a containing
|
|
29
|
+
string to return `-1` at the first control character.
|
|
30
|
+
|
|
31
|
+
The runtime preserves the historical handling of non-string inputs exercised
|
|
32
|
+
by the upstream suite. First-party declarations describe this observable
|
|
33
|
+
surface without adding implicit string conversion.
|
|
34
|
+
|
|
35
|
+
## Unicode width model
|
|
36
|
+
|
|
37
|
+
Strings are decoded as Unicode scalar values and split using the extended
|
|
38
|
+
grapheme-cluster rules in Unicode Standard Annex #29. Generated data is pinned
|
|
39
|
+
to Unicode 17.0.0 and does not depend on the ICU version of the executing Node
|
|
40
|
+
runtime.
|
|
41
|
+
|
|
42
|
+
- NUL uses the configured `nul` width.
|
|
43
|
+
- C0, DEL, and C1 control characters use the configured `control` width.
|
|
44
|
+
- zero-width, combining, and enclosing characters occupy zero columns.
|
|
45
|
+
- East Asian Wide and Fullwidth characters occupy two columns.
|
|
46
|
+
- East Asian Ambiguous characters occupy one column.
|
|
47
|
+
- fully-qualified emoji, regional-indicator flags, keycaps, emoji-presentation
|
|
48
|
+
sequences, and qualifying emoji ZWJ sequences occupy two columns for the
|
|
49
|
+
complete grapheme cluster.
|
|
50
|
+
- ordinary remaining scalar values occupy one column.
|
|
51
|
+
- ANSI terminal escape sequences are ordinary input and are not stripped.
|
|
52
|
+
|
|
53
|
+
## Intentional differences from 1.0.1
|
|
54
|
+
|
|
55
|
+
The historical implementation iterated UTF-16 code units and used a table
|
|
56
|
+
described as Unicode 5.0. This continuation intentionally corrects widths where
|
|
57
|
+
that behavior disagrees with its pinned Unicode 17.0.0 model. Examples include:
|
|
58
|
+
|
|
59
|
+
| Input | `wcwidth@1.0.1` | `@stackline/wcwidth@1.0.0` | Reason |
|
|
60
|
+
| --- | ---: | ---: | --- |
|
|
61
|
+
| `🤦🏼♂️` | 5 | 2 | one emoji grapheme cluster |
|
|
62
|
+
| `U+D7B0..U+D7C6` | 1 | 0 | Hangul Jamo medial vowels |
|
|
63
|
+
| `U+D7CB..U+D7FB` | 1 | 0 | Hangul Jamo final consonants |
|
|
64
|
+
| `U+10330` | 2 | 1 | one supplementary narrow scalar value |
|
|
65
|
+
|
|
66
|
+
The complete reviewed BMP difference set is a test fixture. Unicode and emoji
|
|
67
|
+
conformance fixtures establish the maintained behavior rather than silently
|
|
68
|
+
inheriting the host runtime's Unicode data.
|
|
69
|
+
|
|
70
|
+
## Distribution contract
|
|
71
|
+
|
|
72
|
+
The package supports Node.js 18 and newer plus current browser bundlers. It
|
|
73
|
+
ships CommonJS, native ESM, TypeScript 3.9-compatible CommonJS declarations,
|
|
74
|
+
modern conditional declarations, Unicode source metadata, and zero runtime,
|
|
75
|
+
optional, peer, or bundled dependencies.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use Node.js 18 or newer and install the exact development graph with:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm ci --ignore-scripts
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Run `npm run verify` before opening a pull request. Changes to width behavior
|
|
10
|
+
must include focused regression tests, the relevant upstream or Unicode source,
|
|
11
|
+
and an update to `COMPATIBILITY_CONTRACT.md` when observable output changes.
|
|
12
|
+
|
|
13
|
+
Do not edit `lib/unicode-tables.js` by hand. Update checksum-pinned sources,
|
|
14
|
+
regenerate the table, run `npm run unicode:check`, and include the applicable
|
|
15
|
+
license or attribution change. Build output, coverage, tarballs, and release
|
|
16
|
+
candidate evidence are not committed.
|
|
17
|
+
|
|
18
|
+
Security reports should follow `SECURITY.md`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stackline maintainers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
10
|
+
so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/MIGRATION.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Migration
|
|
2
|
+
|
|
3
|
+
## Preserve existing imports
|
|
4
|
+
|
|
5
|
+
Replace the historical dependency value with an exact npm alias:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"wcwidth": "npm:@stackline/wcwidth@1.0.0"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Existing `require('wcwidth')` calls stay unchanged. Regenerate the lockfile with
|
|
16
|
+
the downstream project's normal package manager. The installed manifest will
|
|
17
|
+
identify `@stackline/wcwidth@1.0.0` while Node resolves the historical key.
|
|
18
|
+
|
|
19
|
+
Alternatively, install the scoped package directly and update imports to
|
|
20
|
+
`@stackline/wcwidth`.
|
|
21
|
+
|
|
22
|
+
## Expected behavior
|
|
23
|
+
|
|
24
|
+
The callable CommonJS API, `.config({ nul, control })`, default option values,
|
|
25
|
+
configuration-object mutation, and historical non-string behavior remain.
|
|
26
|
+
Native ESM and first-party TypeScript declarations are additive.
|
|
27
|
+
|
|
28
|
+
Width results change where Unicode 17.0.0 grapheme and property data correct
|
|
29
|
+
the Unicode 5-era, UTF-16-unit baseline. In particular, emoji ZWJ sequences,
|
|
30
|
+
flags, keycaps, presentation sequences, modern combining characters, Hangul
|
|
31
|
+
Jamo extensions, and supplementary scalar values may use different widths.
|
|
32
|
+
|
|
33
|
+
## Downstream verification
|
|
34
|
+
|
|
35
|
+
Run a clean install plus the downstream project's normal tests, lint, types,
|
|
36
|
+
and build. Add representative assertions for ASCII, combining text, CJK,
|
|
37
|
+
controls, a flag, a keycap, and an emoji ZWJ sequence. Applications with
|
|
38
|
+
snapshot-aligned tables should review output containing emoji or post-Unicode-5
|
|
39
|
+
characters before merging.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@stackline/wcwidth is an independently maintained compatibility continuation
|
|
2
|
+
of wcwidth@1.0.1. It is not affiliated with or endorsed by Tim Oxley, Jun Woong,
|
|
3
|
+
Markus Kuhn, the original project, or the Unicode Consortium.
|
|
4
|
+
|
|
5
|
+
The historical JavaScript API and behavior derive from wcwidth, a JavaScript
|
|
6
|
+
port by Jun Woong of Markus Kuhn's wcwidth implementation. The complete notice
|
|
7
|
+
distributed with wcwidth 1.0.1 is preserved in THIRD_PARTY_LICENSES.md.
|
|
8
|
+
|
|
9
|
+
Generated width, emoji, and grapheme tables use Unicode Character Database and
|
|
10
|
+
emoji data version 17.0.0. Exact source URLs and SHA-256 digests are recorded in
|
|
11
|
+
unicode-sources.json. The Unicode License V3 is reproduced in
|
|
12
|
+
THIRD_PARTY_LICENSES.md.
|
|
13
|
+
|
|
14
|
+
The maintained Unicode model, grapheme handling, module distribution, types,
|
|
15
|
+
and dependency-free configuration implementation are Stackline work.
|
package/PUBLISHING.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Publishing
|
|
2
|
+
|
|
3
|
+
## First-package bootstrap
|
|
4
|
+
|
|
5
|
+
npm cannot configure a Trusted Publisher or staged publishing for a package
|
|
6
|
+
that does not exist yet. Therefore `@stackline/wcwidth@1.0.0` cannot rely on
|
|
7
|
+
OIDC for its first publication.
|
|
8
|
+
|
|
9
|
+
To publish 1.0.0 from the reviewed GitHub artifact, create a temporary npm
|
|
10
|
+
access token that is permitted to create and publish this public package. Store
|
|
11
|
+
it only as the `NPM_BOOTSTRAP_TOKEN` secret in the GitHub `Prod` environment.
|
|
12
|
+
Dispatch `publish.yml` from `main` with the successful CI run ID and
|
|
13
|
+
`bootstrap: true`. The workflow still checks the exact commit, successful CI
|
|
14
|
+
and CodeQL runs, downloads the CI tarball without rebuilding it, publishes that
|
|
15
|
+
exact tarball with provenance, and performs registry verification.
|
|
16
|
+
|
|
17
|
+
After 1.0.0 exists and verification succeeds, delete `NPM_BOOTSTRAP_TOKEN` from
|
|
18
|
+
GitHub and revoke the temporary token at npm. Then configure the package's
|
|
19
|
+
Trusted Publisher using the values below. All later versions must run with
|
|
20
|
+
`bootstrap: false` and use OIDC.
|
|
21
|
+
|
|
22
|
+
The workflow permits bootstrap only when the package itself is absent and the
|
|
23
|
+
reviewed version is exactly 1.0.0. Once any package version exists, it rejects
|
|
24
|
+
bootstrap mode. Do not claim or test OIDC publication before the npm package
|
|
25
|
+
exists and the publisher is configured.
|
|
26
|
+
|
|
27
|
+
## GitHub trusted publishing after bootstrap
|
|
28
|
+
|
|
29
|
+
For a release, update the package, lockfile, changelog, compatibility contract,
|
|
30
|
+
Unicode metadata, and versioned documentation. Run the complete local gate and
|
|
31
|
+
push the reviewed commit to `main`. Wait for both CI and CodeQL to pass for that
|
|
32
|
+
exact commit.
|
|
33
|
+
|
|
34
|
+
Configure npm's Trusted Publisher as:
|
|
35
|
+
|
|
36
|
+
- Owner: `alexandroit`
|
|
37
|
+
- Repository: `stackline-wcwidth`
|
|
38
|
+
- Workflow: `publish.yml`
|
|
39
|
+
- Environment: `Prod`
|
|
40
|
+
- Allowed action: `npm publish`
|
|
41
|
+
|
|
42
|
+
Before dispatch, confirm repository release immutability is enabled using an
|
|
43
|
+
administrator account:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
gh api repos/alexandroit/stackline-wcwidth/immutable-releases
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Dispatch `publish.yml` on `main` with the successful CI run ID as `ci_run_id`
|
|
50
|
+
and `bootstrap: false`.
|
|
51
|
+
The workflow checks the CI run identity, source commit, result, and CodeQL
|
|
52
|
+
result. It downloads the reviewed `npm-package` artifact from that CI run and
|
|
53
|
+
publishes that tarball using OIDC and provenance. It does not rebuild the
|
|
54
|
+
package or use an npm token.
|
|
55
|
+
|
|
56
|
+
After publication, `scripts/verify-registry.mjs` compares official npm bytes,
|
|
57
|
+
validates the registry signature and provenance, and audits fresh normal scoped
|
|
58
|
+
and legacy-key alias installations. The workflow retains the archive and
|
|
59
|
+
verification record as `published-package-evidence`.
|
|
60
|
+
|
|
61
|
+
If npm succeeds but verification fails, do not republish the version. The
|
|
62
|
+
workflow can resume verification: it skips publication only when registry
|
|
63
|
+
metadata and downloaded bytes exactly match the CI artifact. Different bytes
|
|
64
|
+
or registry errors stop the workflow. Verification waits for new attestations
|
|
65
|
+
to propagate and retries only attestation HTTP 404 responses, never invalid
|
|
66
|
+
signatures.
|
|
67
|
+
|
|
68
|
+
A recovery dispatch must also provide `expected_source_commit` and
|
|
69
|
+
`expected_publication_run` from the original npm provenance. The verifier binds
|
|
70
|
+
the subject name and digest, main-branch source commit, GitHub-hosted builder,
|
|
71
|
+
workflow path, and invocation URL to those reviewed values. A fresh publication
|
|
72
|
+
binds them directly to the current commit and workflow attempt.
|
|
73
|
+
|
|
74
|
+
The publication workflow builds every checksum and metadata asset from the
|
|
75
|
+
exact downloaded CI tarball after registry verification. It then requires one
|
|
76
|
+
tarball plus exactly 11 linked evidence files. Download that single
|
|
77
|
+
`published-package-evidence` artifact and preserve it without combining files
|
|
78
|
+
from a local build. Create the annotated `stackline-v<version>` tag at the
|
|
79
|
+
attested source commit and wait for its CI and CodeQL checks. Upload the exact
|
|
80
|
+
12-file evidence set to a draft GitHub release, run
|
|
81
|
+
`node scripts/check-release-assets.mjs <directory>`, and only then publish the
|
|
82
|
+
release as immutable. Finally deploy the matching Alexandro.Net documentation
|
|
83
|
+
and localized catalog entry.
|
|
84
|
+
|
|
85
|
+
Never reuse a published npm version or replace a published tag or release
|
|
86
|
+
asset.
|
|
87
|
+
|
|
88
|
+
## Local artifact preparation
|
|
89
|
+
|
|
90
|
+
A release may be prepared only from a clean, reviewed Git commit after
|
|
91
|
+
`npm ci --ignore-scripts` and `npm run verify` pass on the pinned toolchain and
|
|
92
|
+
required CI/CodeQL checks are green.
|
|
93
|
+
|
|
94
|
+
Set `STACKLINE_GREEN_COMMIT` to the exact reviewed `HEAD`, then run:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
npm run artifact:prepare
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The command refuses a dirty worktree or existing `release-candidate`, reruns
|
|
101
|
+
verification, and prepares a local review candidate. Those preliminary files
|
|
102
|
+
must not be mixed into the GitHub release. Final release evidence is assembled
|
|
103
|
+
only by `publish.yml` from the exact CI tarball that npm accepted.
|
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# @stackline/wcwidth
|
|
2
|
+
|
|
3
|
+
A dependency-free compatibility continuation of `wcwidth@1.0.1` with
|
|
4
|
+
deterministic Unicode 17.0.0 tables and grapheme-aware terminal widths.
|
|
5
|
+
|
|
6
|
+
Stackline maintains this package independently. It is not affiliated with or
|
|
7
|
+
endorsed by Tim Oxley, Jun Woong, Markus Kuhn, or the Unicode Consortium.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @stackline/wcwidth
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
An npm alias preserves an existing dependency key and every root import:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"wcwidth": "npm:@stackline/wcwidth@^1.0.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Historical CommonJS imports through `wcwidth/index.js`, `wcwidth/combining`,
|
|
26
|
+
and `wcwidth/combining.js` also remain available under the alias. The combining
|
|
27
|
+
table contains the maintained Unicode 17 zero-width ranges.
|
|
28
|
+
|
|
29
|
+
CommonJS returns the callable function directly:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const wcwidth = require('@stackline/wcwidth')
|
|
33
|
+
|
|
34
|
+
wcwidth('한글') // 4
|
|
35
|
+
wcwidth('e\u0301') // 1
|
|
36
|
+
wcwidth('🤦🏼♂️') // 2
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Native ESM exposes an equivalent standalone default function plus named
|
|
40
|
+
configuration and Unicode-version references:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import wcwidth, { config, unicodeVersion } from '@stackline/wcwidth'
|
|
44
|
+
|
|
45
|
+
const strictWidth = config({ nul: 0, control: -1 })
|
|
46
|
+
strictWidth('hello\nworld') // -1
|
|
47
|
+
console.log(unicodeVersion) // 17.0.0
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Compatibility contract
|
|
51
|
+
|
|
52
|
+
The root CommonJS export remains a function named `wcwidth` with arity one.
|
|
53
|
+
Its enumerable `.config(options)` method returns another function named
|
|
54
|
+
`wcwidth` with arity one. Default NUL and control widths remain zero.
|
|
55
|
+
|
|
56
|
+
For compatibility with `defaults@1.x`, `.config()` fills missing `nul` and
|
|
57
|
+
`control` properties on the supplied object, observes inherited properties,
|
|
58
|
+
and retains the object so later changes affect the configured function.
|
|
59
|
+
|
|
60
|
+
Unicode results intentionally differ from the 2016 package where UTF-16 code
|
|
61
|
+
units or Unicode 5-era tables produced incorrect terminal widths. The package
|
|
62
|
+
uses pinned Unicode 17.0.0 data, extended grapheme segmentation, and these
|
|
63
|
+
terminal rules:
|
|
64
|
+
|
|
65
|
+
- combining marks and zero-width format characters occupy zero columns;
|
|
66
|
+
- East Asian Wide and Fullwidth characters occupy two columns;
|
|
67
|
+
- East Asian Ambiguous characters occupy one column;
|
|
68
|
+
- fully-qualified emoji, flags, keycaps, emoji presentation sequences, and
|
|
69
|
+
emoji ZWJ sequences occupy two columns per grapheme cluster;
|
|
70
|
+
- unpaired UTF-16 surrogates remain one column;
|
|
71
|
+
- ANSI escape sequences are not stripped.
|
|
72
|
+
|
|
73
|
+
See `COMPATIBILITY_CONTRACT.md` for the precise preserved API and intentional
|
|
74
|
+
Unicode boundary.
|
|
75
|
+
|
|
76
|
+
## Reproducible Unicode data
|
|
77
|
+
|
|
78
|
+
`lib/unicode-tables.js` is generated from checksum-pinned Unicode 17.0.0
|
|
79
|
+
sources recorded in `unicode-sources.json`.
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
npm run unicode:generate
|
|
83
|
+
npm run unicode:check
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The generator uses Node.js built-ins. Unicode source URLs, accepted hashes,
|
|
87
|
+
license terms, generated-table invariants, and conformance fixtures are kept
|
|
88
|
+
with the repository.
|
|
89
|
+
|
|
90
|
+
## Runtimes and types
|
|
91
|
+
|
|
92
|
+
- Node.js 18 or newer;
|
|
93
|
+
- modern browsers through standard CommonJS or ESM bundlers;
|
|
94
|
+
- callable CommonJS and native ESM default entries;
|
|
95
|
+
- named ESM `config` and `unicodeVersion` exports;
|
|
96
|
+
- TypeScript 3.9-compatible CommonJS declarations and modern conditional
|
|
97
|
+
ESM/CJS declarations;
|
|
98
|
+
- zero runtime, optional, peer, and bundled dependencies.
|
|
99
|
+
|
|
100
|
+
## Verification
|
|
101
|
+
|
|
102
|
+
The release gate includes upstream characterization, full-BMP differential
|
|
103
|
+
review, Unicode and emoji conformance corpora, table invariants, CJS/ESM/browser
|
|
104
|
+
checks, TypeScript 3.9/current declarations, coverage, packed direct and legacy
|
|
105
|
+
alias consumers, recursive closure, package/type linting, licenses, CycloneDX
|
|
106
|
+
SBOM, audits, exact artifact identity, registry signatures, and provenance.
|
|
107
|
+
|
|
108
|
+
## License
|
|
109
|
+
|
|
110
|
+
The Stackline implementation is MIT licensed in `LICENSE`. The complete notice
|
|
111
|
+
distributed with `wcwidth@1.0.1` and the Unicode License V3 are preserved in
|
|
112
|
+
`THIRD_PARTY_LICENSES.md`.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
The latest published `@stackline/wcwidth` version receives correctness,
|
|
6
|
+
dependency, packaging, and release-integrity fixes.
|
|
7
|
+
|
|
8
|
+
## Reporting
|
|
9
|
+
|
|
10
|
+
Use GitHub private vulnerability reporting for
|
|
11
|
+
`alexandroit/stackline-wcwidth`. Include the affected version, a minimal
|
|
12
|
+
reproduction, expected and actual behavior, and any practical impact.
|
|
13
|
+
|
|
14
|
+
Do not open a public issue containing exploit details or sensitive downstream
|
|
15
|
+
information. Ordinary width discrepancies without a security impact may use a
|
|
16
|
+
public issue with the exact input, expected width, terminal context, and Unicode
|
|
17
|
+
reference.
|
|
18
|
+
|
|
19
|
+
No vulnerability claim is made about `wcwidth@1.0.1`. This continuation focuses
|
|
20
|
+
on maintained Unicode correctness, dependency removal, reproducible packaging,
|
|
21
|
+
and release integrity.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Third-party licenses
|
|
2
|
+
|
|
3
|
+
The production package has zero runtime, optional, peer, and bundled dependencies.
|
|
4
|
+
Its installed production closure is one MIT-licensed Stackline root node.
|
|
5
|
+
|
|
6
|
+
## wcwidth 1.0.1
|
|
7
|
+
|
|
8
|
+
The compatibility API, selected historical behavior, and differential tests
|
|
9
|
+
derive from `wcwidth@1.0.1`. Its package manifest declares `MIT`; the complete
|
|
10
|
+
notice distributed in its `LICENSE` file is reproduced verbatim below.
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
wcwidth.js: JavaScript Portng of Markus Kuhn's wcwidth() Implementation
|
|
14
|
+
=======================================================================
|
|
15
|
+
|
|
16
|
+
Copyright (C) 2012 by Jun Woong.
|
|
17
|
+
|
|
18
|
+
This package is a JavaScript porting of `wcwidth()` implementation
|
|
19
|
+
[by Markus Kuhn](http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c).
|
|
20
|
+
|
|
21
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
22
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
23
|
+
the Software without restriction, including without limitation the rights to
|
|
24
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
25
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
26
|
+
so, subject to the following conditions:
|
|
27
|
+
|
|
28
|
+
The above copyright notice and this permission notice shall be included in all
|
|
29
|
+
copies or substantial portions of the Software.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
33
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
34
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
|
|
35
|
+
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
36
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
37
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
38
|
+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
39
|
+
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
40
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
41
|
+
POSSIBILITY OF SUCH DAMAGE.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The exact upstream package and its `defaults` and `clone` dependency chain are
|
|
45
|
+
development-only differential fixtures. They are absent from the production
|
|
46
|
+
graph.
|
|
47
|
+
|
|
48
|
+
## Unicode Character Database 17.0.0
|
|
49
|
+
|
|
50
|
+
Generated width, emoji, and grapheme tables and conformance fixtures derive
|
|
51
|
+
from the Unicode data files listed with exact URLs and SHA-256 digests in
|
|
52
|
+
`unicode-sources.json`.
|
|
53
|
+
|
|
54
|
+
### Unicode License V3
|
|
55
|
+
|
|
56
|
+
COPYRIGHT AND PERMISSION NOTICE
|
|
57
|
+
|
|
58
|
+
Copyright © 1991-2026 Unicode, Inc.
|
|
59
|
+
|
|
60
|
+
NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
|
|
61
|
+
INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR SOFTWARE, YOU
|
|
62
|
+
UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS
|
|
63
|
+
OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY,
|
|
64
|
+
DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
65
|
+
|
|
66
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
67
|
+
data files and any associated documentation (the "Data Files") or software and
|
|
68
|
+
any associated documentation (the "Software") to deal in the Data Files or
|
|
69
|
+
Software without restriction, including without limitation the rights to use,
|
|
70
|
+
copy, modify, merge, publish, distribute, and/or sell copies of the Data Files
|
|
71
|
+
or Software, and to permit persons to whom the Data Files or Software are
|
|
72
|
+
furnished to do so, provided that either (a) this copyright and permission
|
|
73
|
+
notice appear with all copies of the Data Files or Software, or (b) this
|
|
74
|
+
copyright and permission notice appear in associated Documentation.
|
|
75
|
+
|
|
76
|
+
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
77
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
78
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
|
|
79
|
+
PARTY RIGHTS.
|
|
80
|
+
|
|
81
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
|
|
82
|
+
LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
|
|
83
|
+
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
84
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
85
|
+
CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
|
86
|
+
|
|
87
|
+
Except as contained in this notice, the name of a copyright holder shall not be
|
|
88
|
+
used in advertising or otherwise to promote the sale, use or other dealings in
|
|
89
|
+
these Data Files or Software without prior written authorization of the
|
|
90
|
+
copyright holder.
|
package/VERIFICATION.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Verification
|
|
2
|
+
|
|
3
|
+
Install pinned development tools without lifecycle scripts and run the complete
|
|
4
|
+
gate:
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm ci --ignore-scripts
|
|
8
|
+
npm run verify
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The behavioral suite covers the historical upstream cases; CommonJS export
|
|
12
|
+
shape; `.config()` defaults, mutation, inheritance, and coercive edges; the
|
|
13
|
+
reviewed full-BMP differential; Unicode 17.0.0 width rules; UAX #29 grapheme
|
|
14
|
+
conformance; fully-qualified emoji conformance; table invariants; native ESM;
|
|
15
|
+
browser bundling; TypeScript 3.9/current declarations; and bounded stress cases.
|
|
16
|
+
|
|
17
|
+
Packed scoped and historical-key npm-alias consumers verify package contents,
|
|
18
|
+
callability, root and historical subpath exports, Unicode version, CommonJS,
|
|
19
|
+
standalone ESM, esbuild and Rollup browser conditions, npm
|
|
20
|
+
tree health, and the production audit. Separate checks prove the one-node
|
|
21
|
+
production closure, upstream and Unicode attribution, CycloneDX SBOM, release
|
|
22
|
+
metadata, strict publint, and strict Are the Types Wrong results. Production,
|
|
23
|
+
full-development, and registry-signature audits complete the local gate.
|
|
24
|
+
|
|
25
|
+
CI repeats the packed consumer across Node.js 18, 20, 22, 24, and 26 and on
|
|
26
|
+
Linux, macOS, and Windows. CodeQL analyzes JavaScript and TypeScript. Official
|
|
27
|
+
publication additionally requires byte identity with the CI artifact, npm
|
|
28
|
+
signature and provenance validation, and fresh direct and alias registry
|
|
29
|
+
consumers.
|
package/combining.d.ts
ADDED