Remove dependency from uslug, shrink uslug built size

pull/12118/head
Henry Heino 2025-04-14 16:42:03 -07:00
parent 7c9fc4e9c2
commit 5802e17ee9
17 changed files with 170 additions and 205 deletions

View File

@ -1002,6 +1002,8 @@ packages/fork-htmlparser2/src/__tests__/events.js
packages/fork-htmlparser2/src/__tests__/stream.js
packages/fork-htmlparser2/src/index.spec.js
packages/fork-htmlparser2/src/index.js
packages/fork-uslug/lib/uslug.test.js
packages/fork-uslug/lib/uslug.js
packages/generator-joplin/generators/app/templates/api/index.js
packages/generator-joplin/generators/app/templates/api/noteListType.js
packages/generator-joplin/generators/app/templates/api/types.js

2
.gitignore vendored
View File

@ -977,6 +977,8 @@ packages/fork-htmlparser2/src/__tests__/events.js
packages/fork-htmlparser2/src/__tests__/stream.js
packages/fork-htmlparser2/src/index.spec.js
packages/fork-htmlparser2/src/index.js
packages/fork-uslug/lib/uslug.test.js
packages/fork-uslug/lib/uslug.js
packages/generator-joplin/generators/app/templates/api/index.js
packages/generator-joplin/generators/app/templates/api/noteListType.js
packages/generator-joplin/generators/app/templates/api/types.js

View File

@ -5,6 +5,7 @@
Modified for Joplin:
- Added support for emojis - "🐶🐶🐶🐱" => "dogdogdogcat"
- Migrated to TypeScript and removed dependencies on functionality now built-in to JavaScript (Unicode normalization, Unicode character class regular expressions).
* * *

View File

@ -1 +1 @@
module.exports = require('./lib/uslug');
module.exports = require('./lib/uslug').default;

View File

@ -0,0 +1,5 @@
module.exports = {
testMatch: [
'**/*.test.js',
]
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
/*
* List of Unicode code that are flagged as separator.
*
* Contains Unicode code of:
* - Zs = Separator, space
* - Zl = Separator, line
* - Zp = Separator, paragraph
*
* This list has been computed from http://unicode.org/Public/UNIDATA/UnicodeData.txt
* curl -s http://unicode.org/Public/UNIDATA/UnicodeData.txt | grep -E ';Zs;|;Zl;|;Zp;' | cut -d \; -f 1 | xargs -I{} printf '%d, ' 0x{}
*
*/
exports.Z = [32, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288];

View File

@ -1,61 +0,0 @@
(function() {
var L = require('./L').L,
N = require('./N').N,
Z = require('./Z').Z,
M = require('./M').M,
unorm = require('unorm');
var nodeEmoji = require('node-emoji')
var _unicodeCategory = function(code) {
if (~L.indexOf(code)) return 'L';
if (~N.indexOf(code)) return 'N';
if (~Z.indexOf(code)) return 'Z';
if (~M.indexOf(code)) return 'M';
return undefined;
};
module.exports = function(string, options) {
string = string || '';
options = options || {};
var allowedChars = options.allowedChars || '-_~';
var lower = typeof options.lower === 'boolean' ? options.lower : true;
var spaces = typeof options.spaces === 'boolean' ? options.spaces : false;
var rv = [];
var noEmojiString = nodeEmoji.unemojify(string);
var chars = unorm.nfkc(noEmojiString);
for(var i = 0; i < chars.length; i++) {
var c = chars[i];
var code = c.charCodeAt(0);
// Allow Common CJK Unified Ideographs
// See: http://www.unicode.org/versions/Unicode6.0.0/ch12.pdf - Table 12-2
if (0x4E00 <= code && code <= 0x9FFF) {
rv.push(c);
continue;
}
// Allow Hangul
if (0xAC00 <= code && code <= 0xD7A3) {
rv.push(c);
continue;
}
// Japanese ideographic punctuation
if ((0x3000 <= code && code <= 0x3002) || (0xFF01 <= code && code <= 0xFF02)) {
rv.push(' ');
}
if (allowedChars.indexOf(c) != -1) {
rv.push(c);
continue;
}
var val = _unicodeCategory(code);
if (val && ~'LNM'.indexOf(val)) rv.push(c);
if (val && ~'Z'.indexOf(val)) rv.push(' ');
}
var slug = rv.join('').replace(/^\s+|\s+$/g, '').replace(/\s+/g,' ');
if (!spaces) slug = slug.replace(/[\s\-]+/g,'-');
if (lower) slug = slug.toLowerCase();
return slug;
};
}());

View File

@ -1,12 +1,20 @@
var should = require('should'),
uslug = require('../lib/uslug');
/**
* Based on @joplin/fork-uslug
*
* The original is Copyright (c) 2012 Jeremy Selier
*
* MIT Licensed
*
* You may find a copy of this license in the LICENSE file that should have been provided
* to you with a copy of this software.
*/
import uslug from "./uslug";
const word0 = 'Ελληνικά';
const word1 = [word0, word0].join('-');
const word2 = [word0, word0].join(' - ');
var word0 = 'Ελληνικά';
var word1 = [word0, word0].join('-');
var word2 = [word0, word0].join(' - ');
var tests = [
const tests: Array<[string, string]> = [
['', ''],
['The \u212B symbol invented by A. J. \u00C5ngstr\u00F6m (1814, L\u00F6gd\u00F6, \u2013 1874) denotes the length 10\u207B\u00B9\u2070 m.', 'the-å-symbol-invented-by-a-j-ångström-1814-lögdö-1874-denotes-the-length-1010-m'],
['Быстрее и лучше!', 'быстрее-и-лучше'],
@ -35,10 +43,11 @@ var tests = [
['😁a', 'grina'],
['🐶🐶🐶🐱', 'dogdogdogcat'],
];
for (var t in tests) {
var test = tests[t];
uslug(test[0]).should.equal(test[1]);
}
uslug('qbc,fe', { allowedChars: 'q' }).should.equal('qbcfe');
describe('uslug', () => {
it.each(tests)('should convert %s to %s', (input, expected) => {
expect(uslug(input)).toBe(expected);
});
it('should support "allowedChars"', () => {
expect(uslug('qbc,fe', { allowedChars: 'q' })).toBe('qbcfe');
});
});

View File

@ -0,0 +1,99 @@
/**
* Based on @joplin/fork-uslug
*
* The original is Copyright (c) 2012 Jeremy Selier
*
* MIT Licensed
*
* You may find a copy of this license in the LICENSE file that should have been provided
* to you with a copy of this software.
*/
const nodeEmoji = require('node-emoji');
// Very old browsers (e.g. Chrome < 64, which is from 2018) may not support
// \p{} regexes.
let regexes_;
try {
regexes_ = {
L: new RegExp('\\p{L}', 'u'),
N: new RegExp('\\p{N}', 'u'),
Z: new RegExp('\\p{Z}', 'u'),
M: new RegExp('\\p{M}', 'u'),
};
} catch (error) {
console.error(error);
regexes_ = undefined;
}
const _unicodeCategory = function (c: string) {
if (!regexes_) {
console.warn('Unicode RegExps not loaded. Skipping category check.');
return undefined;
}
for (const [key, val] of Object.entries(regexes_)) {
if (c.match(val)) return key;
}
return undefined;
};
interface Options {
lower?: boolean;
spaces?: boolean;
allowedChars?: string;
}
export default function (string: string, options: Options = {}) {
string = string || '';
options = options || {};
const allowedChars = options.allowedChars || '-_~';
const lower = typeof options.lower === 'boolean' ? options.lower : true;
const spaces = typeof options.spaces === 'boolean' ? options.spaces : false;
const rv = [];
const noEmojiString: string = nodeEmoji.unemojify(string);
const chars = noEmojiString.normalize('NFKC').split('');
for (let i = 0; i < chars.length; i++) {
let c = chars[i];
let code = c.charCodeAt(0);
// Allow Common CJK Unified Ideographs
// See: http://www.unicode.org/versions/Unicode6.0.0/ch12.pdf - Table 12-2
if (0x4E00 <= code && code <= 0x9FFF) {
rv.push(c);
continue;
}
// Allow Hangul
if (0xAC00 <= code && code <= 0xD7A3) {
rv.push(c);
continue;
}
// Japanese ideographic punctuation
if ((0x3000 <= code && code <= 0x3002) || (0xFF01 <= code && code <= 0xFF02)) {
rv.push(' ');
}
if (allowedChars.indexOf(c) != -1) {
rv.push(c);
continue;
}
const val = _unicodeCategory(c);
if (val && ~'LNM'.indexOf(val)) rv.push(c);
if (val && ~'Z'.indexOf(val)) rv.push(' ');
}
let slug = rv.join('').replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ');
if (!spaces) slug = slug.replace(/[\s\-]+/g, '-');
if (lower) slug = slug.toLowerCase();
return slug;
};

View File

@ -1,25 +1,39 @@
{
"name": "@joplin/fork-uslug",
"version": "1.0.22",
"version": "2.0.0",
"description": "A permissive slug generator that works with unicode.",
"author": "Jeremy Selier <jerem.selier@gmail.com>",
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "jest",
"tsc": "tsc --project tsconfig.json",
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json"
},
"dependencies": {
"node-emoji": "1.11.0",
"unorm": "1.6.0"
"node-emoji": "1.11.0"
},
"devDependencies": {
"should": "13.2.3"
"@types/jest": "29.5.12",
"@types/node": "18.19.67",
"jest": "29.7.0",
"typescript": "5.4.5"
},
"repository": {
"type": "git",
"url": "http://github.com/jeremys/uslug.git"
},
"main": "./index",
"exports": {
"default": "./index.js",
"uslug": {
"default": "./lib/uslug.js",
"types": "./lib/uslug.ts"
}
},
"engines": {
"node": ">= 0.4.0"
"node": ">= 10.0.0"
},
"bugs": {
"url": "http://github.com/jeremys/uslug/issues"

View File

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"include": [
"**/*.ts"
],
"compilerOptions": {
"types": ["jest", "node"]
}
}

View File

@ -45,7 +45,7 @@
"@aws-sdk/s3-request-presigner": "3.296.0",
"@joplin/fork-htmlparser2": "^4.1.57",
"@joplin/fork-sax": "^1.2.61",
"@joplin/fork-uslug": "^1.0.22",
"@joplin/fork-uslug": "^2.0.0",
"@joplin/htmlpack": "~3.3",
"@joplin/onenote-converter": "~3.3",
"@joplin/renderer": "~3.3",

View File

@ -31,7 +31,7 @@
},
"dependencies": {
"@joplin/fork-htmlparser2": "^4.1.57",
"@joplin/fork-uslug": "^1.0.22",
"@joplin/fork-uslug": "^2.0.0",
"@joplin/utils": "~3.3",
"font-awesome-filetypes": "2.1.0",
"fs-extra": "11.2.0",

View File

@ -8563,13 +8563,15 @@ __metadata:
languageName: unknown
linkType: soft
"@joplin/fork-uslug@^1.0.22, @joplin/fork-uslug@workspace:packages/fork-uslug":
"@joplin/fork-uslug@^2.0.0, @joplin/fork-uslug@workspace:packages/fork-uslug":
version: 0.0.0-use.local
resolution: "@joplin/fork-uslug@workspace:packages/fork-uslug"
dependencies:
"@types/jest": 29.5.12
"@types/node": 18.19.67
jest: 29.7.0
node-emoji: 1.11.0
should: 13.2.3
unorm: 1.6.0
typescript: 5.4.5
languageName: unknown
linkType: soft
@ -8595,7 +8597,7 @@ __metadata:
"@aws-sdk/s3-request-presigner": 3.296.0
"@joplin/fork-htmlparser2": ^4.1.57
"@joplin/fork-sax": ^1.2.61
"@joplin/fork-uslug": ^1.0.22
"@joplin/fork-uslug": ^2.0.0
"@joplin/htmlpack": ~3.3
"@joplin/onenote-converter": ~3.3
"@joplin/renderer": ~3.3
@ -8778,7 +8780,7 @@ __metadata:
resolution: "@joplin/renderer@workspace:packages/renderer"
dependencies:
"@joplin/fork-htmlparser2": ^4.1.57
"@joplin/fork-uslug": ^1.0.22
"@joplin/fork-uslug": ^2.0.0
"@joplin/utils": ~3.3
"@types/jest": 29.5.12
"@types/markdown-it": 13.0.9
@ -43071,62 +43073,6 @@ __metadata:
languageName: node
linkType: hard
"should-equal@npm:^2.0.0":
version: 2.0.0
resolution: "should-equal@npm:2.0.0"
dependencies:
should-type: ^1.4.0
checksum: 3f3580a223bf76f9309a4d957d2dcbd6059bda816f2e6656e822b7518218ef653c25e9271b2f5765ca6f5a72a217105ad343a8ceea831d15aff44dd691cc1dcd
languageName: node
linkType: hard
"should-format@npm:^3.0.3":
version: 3.0.3
resolution: "should-format@npm:3.0.3"
dependencies:
should-type: ^1.3.0
should-type-adaptors: ^1.0.1
checksum: 5304e89b4d4c42078c7f66232d13cca1d6a1c00c173f500f64160f57d4ecd7522a25106b313fe8f8694547e8a1ce4d975f1f09a3d1618f1dc054db48c0683d87
languageName: node
linkType: hard
"should-type-adaptors@npm:^1.0.1":
version: 1.1.0
resolution: "should-type-adaptors@npm:1.1.0"
dependencies:
should-type: ^1.3.0
should-util: ^1.0.0
checksum: 94dd1d225c8f2590278f46689258a1df684ca1f26262459c4e2d64a09d06935ec1410a24fe7b5f98b9429093e48afef2ed1b370634e0444b930547df4943f70d
languageName: node
linkType: hard
"should-type@npm:^1.3.0, should-type@npm:^1.4.0":
version: 1.4.0
resolution: "should-type@npm:1.4.0"
checksum: 88d9324c6c0c2f94e71d2f8b11c84e44de81f16eeb6fafcba47f4af430c65e46bad18eb472827526cad22b4fe693aba8b022739d1c453672faf28860df223491
languageName: node
linkType: hard
"should-util@npm:^1.0.0":
version: 1.0.1
resolution: "should-util@npm:1.0.1"
checksum: c3be15e0fdc851f8338676b3f8b590d330bbea94ec41c1343cc9983dea295915073f69a215795454b6adda6579ec8927c7c0ab178b83f9f11a0247ccdba53381
languageName: node
linkType: hard
"should@npm:13.2.3":
version: 13.2.3
resolution: "should@npm:13.2.3"
dependencies:
should-equal: ^2.0.0
should-format: ^3.0.3
should-type: ^1.4.0
should-type-adaptors: ^1.0.1
should-util: ^1.0.0
checksum: 74bcc0eb85e0a63a88e501ff9ca3b53dbc6d1ee47823c029a18a4b14b3ef4e2561733e161033df720599d2153283470e9647fdcb1bbc78903960ffb0363239c4
languageName: node
linkType: hard
"side-channel@npm:^1.0.4":
version: 1.0.4
resolution: "side-channel@npm:1.0.4"
@ -47493,13 +47439,6 @@ __metadata:
languageName: node
linkType: hard
"unorm@npm:1.6.0":
version: 1.6.0
resolution: "unorm@npm:1.6.0"
checksum: 9a86546256a45f855b6cfe719086785d6aada94f63778cecdecece8d814ac26af76cb6da70130da0a08b8803bbf0986e56c7ec4249038198f3de02607fffd811
languageName: node
linkType: hard
"unpack-string@npm:0.0.2":
version: 0.0.2
resolution: "unpack-string@npm:0.0.2"