Skip to content

Add TypeScript support #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ const generateData = function(version) {
path.resolve(__dirname, `output/unicode-${version}/index.js`),
compileIndex({ 'version': version, 'data': jsesc(dirMap) })
);
fs.writeFileSync(
path.resolve(__dirname, `output/unicode-${version}/index.d.ts`),
Object.keys(dirMap)
.map(key => `export const ${key}: string[];`)
.join('\n')
);
fs.writeFileSync(
path.resolve(__dirname, `output/unicode-${version}/package.json`),
compilePackage({ 'version': version })
Expand All @@ -203,7 +209,9 @@ const generateData = function(version) {
'.gitignore',
'.npmignore',
'decode-property-map.js',
'decode-property-map.d.ts',
'decode-ranges.js',
'decode-ranges.d.ts',
].forEach(function(file) {
fs.copyFileSync(
path.resolve(staticPath, file),
Expand Down
38 changes: 34 additions & 4 deletions scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ const writeFiles = function(options) {
return;
}
const dirMap = {};

const rootDir = path.resolve(
__dirname, '..',
'output', 'unicode-' + version
);

/**
* A list of flatten (x, y) pairs,
* where x is a codepoint, y := codepoint(z) - x,
Expand All @@ -101,10 +107,7 @@ const writeFiles = function(options) {
const isNamesCanon = type == 'Names' && !subType;
const isNameAliases = type == 'Names' && subType == 'name-aliases';
const subdir = isNameAliases ? item.charAt(0).toUpperCase() + item.slice(1) : item;
const dir = path.resolve(
__dirname, '..',
'output', 'unicode-' + version, type, subdir
);
const dir = path.resolve(rootDir, type, subdir);
if (
type == 'Bidi_Class' ||
type == 'Bidi_Mirroring_Glyph' ||
Expand Down Expand Up @@ -147,6 +150,12 @@ const writeFiles = function(options) {
path.resolve(dir, 'index.js'),
output
);
fs.writeFileSync(
path.resolve(dir, 'index.d.ts'),
type === 'Sequence_Property'
? `const data: string[];\nexport default data;`
: `const aliasMap: Record<number, string[]>;\nexport default aliasMap;`
);
return;
}

Expand All @@ -159,10 +168,18 @@ const writeFiles = function(options) {
path.resolve(dir, 'ranges.js'),
`module.exports=require('../../decode-ranges.js')('${encodedRanges}')`
);
fs.writeFileSync(
path.resolve(dir, 'ranges.d.ts'),
'import type { UnicodeRange } from "../../decode-ranges.js";\n\nconst ranges: UnicodeRange[];\nexport default ranges;\n'
);
fs.writeFileSync(
path.resolve(dir, 'regex.js'),
'module.exports=/' + regenerate(codePoints).toString() + '/'
);
fs.writeFileSync(
path.resolve(dir, 'regex.d.ts'),
'declare const regex: RegExp;\nexport default regex;'
);
if (codePointsSizeLt(codePoints, 10)) {
const codePointsAsArray = codePoints instanceof regenerate ? codePoints.toArray() : codePoints;
codePointsExports = jsesc(codePointsAsArray);
Expand All @@ -186,10 +203,18 @@ const writeFiles = function(options) {
path.resolve(dir, 'code-points.js'),
`module.exports=${ codePointsExports }`
);
fs.writeFileSync(
path.resolve(dir, 'code-points.d.ts'),
`declare const codePoints: number[];\nexport default codePoints;`
);
fs.writeFileSync(
path.resolve(dir, 'symbols.js'),
`module.exports=${ symbolsExports }`
);
fs.writeFileSync(
path.resolve(dir, 'symbols.d.ts'),
`declare const symbols: string[];\nexport default symbols;`
);
});
if (options.type == 'Bidi_Mirroring_Glyph') {
const type = options.type;
Expand All @@ -214,6 +239,10 @@ const writeFiles = function(options) {
path.resolve(dir, 'index.js'),
output
);
fs.writeFileSync(
path.resolve(dir, 'index.d.ts'),
`const data: Map<number, string>;\nexport default data;`
);
} else {
Object.keys(auxMap).forEach(function(type) {
const dir = path.resolve(
Expand All @@ -233,6 +262,7 @@ const writeFiles = function(options) {
flatRuns
)})`;
fs.writeFileSync(path.resolve(dir, "index.js"), output);
fs.writeFileSync(path.resolve(dir, "index.d.ts"), `declare const map: Map<number, string>;\nexport default map;`);
});
}
return dirMap;
Expand Down
1 change: 1 addition & 0 deletions static/decode-property-map.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function decodePropertyMap(runs: Array<number | string>): Map<number, string>;
17 changes: 17 additions & 0 deletions static/decode-ranges.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class UnicodeRange {
readonly begin: number;
readonly end: number;
readonly length: number;

private constructor(begin: number, end: number);

keys(): Generator<number, void, unknown>;
values(): Generator<string, void, unknown>;
}

/**
* RLE + base64 decode code point ranges.
*/
export default function decodeRanges(input: string): UnicodeRange[];

export type { UnicodeRange };
7 changes: 7 additions & 0 deletions static/decode-ranges.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const base64dec = Object.freeze(Object.fromEntries(
));

class UnicodeRange {
/**
* @param {number} begin
* @param {number} end
*/
constructor(begin, end) {
this.begin = begin;
this.end = end;
Expand All @@ -32,8 +36,10 @@ class UnicodeRange {

/**
* Base64 decode variable-length deltas (5/10/15/21-bit).
* @param {string} input
*/
function decodeDeltas(input) {
/** @type {number[]} */
const output = [];
for (let i = 0; i < input.length; ) {
let x = base64dec[input[i++]];
Expand Down Expand Up @@ -63,6 +69,7 @@ function decodeDeltas(input) {

/**
* RLE + base64 decode code point ranges.
* @param {string} input
*/
function decodeRanges(input) {
const deltas = decodeDeltas(input);
Expand Down