aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/tr46/index.js
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-14 14:46:37 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-14 14:46:37 -0800
commitafa87af01c79a9baa539f2992d32154d2a4739bd (patch)
tree92c7416db734270a2fee1d72ee9cc119379ff8e1 /vanilla/node_modules/tr46/index.js
parent3b927e84d200402281f68181cd4253bc77e5528d (diff)
downloadneko-afa87af01c79a9baa539f2992d32154d2a4739bd.tar.gz
neko-afa87af01c79a9baa539f2992d32154d2a4739bd.tar.bz2
neko-afa87af01c79a9baa539f2992d32154d2a4739bd.zip
task: delete vanilla js prototype\n\n- Removed vanilla/ directory and web/dist/vanilla directory\n- Updated Makefile, Dockerfile, and CI workflow to remove vanilla references\n- Cleaned up web/web.go to remove vanilla embed and routes\n- Verified build and tests pass\n\nCloses NK-2tcnmq
Diffstat (limited to 'vanilla/node_modules/tr46/index.js')
-rw-r--r--vanilla/node_modules/tr46/index.js344
1 files changed, 0 insertions, 344 deletions
diff --git a/vanilla/node_modules/tr46/index.js b/vanilla/node_modules/tr46/index.js
deleted file mode 100644
index 9e53f05..0000000
--- a/vanilla/node_modules/tr46/index.js
+++ /dev/null
@@ -1,344 +0,0 @@
-"use strict";
-
-const punycode = require("punycode/");
-const regexes = require("./lib/regexes.js");
-const mappingTable = require("./lib/mappingTable.json");
-const { STATUS_MAPPING } = require("./lib/statusMapping.js");
-
-function containsNonASCII(str) {
- return /[^\x00-\x7F]/u.test(str);
-}
-
-function findStatus(val) {
- let start = 0;
- let end = mappingTable.length - 1;
-
- while (start <= end) {
- const mid = Math.floor((start + end) / 2);
-
- const target = mappingTable[mid];
- const min = Array.isArray(target[0]) ? target[0][0] : target[0];
- const max = Array.isArray(target[0]) ? target[0][1] : target[0];
-
- if (min <= val && max >= val) {
- return target.slice(1);
- } else if (min > val) {
- end = mid - 1;
- } else {
- start = mid + 1;
- }
- }
-
- return null;
-}
-
-function mapChars(domainName, { transitionalProcessing }) {
- let processed = "";
-
- for (const ch of domainName) {
- const [status, mapping] = findStatus(ch.codePointAt(0));
-
- switch (status) {
- case STATUS_MAPPING.disallowed:
- processed += ch;
- break;
- case STATUS_MAPPING.ignored:
- break;
- case STATUS_MAPPING.mapped:
- if (transitionalProcessing && ch === "ẞ") {
- processed += "ss";
- } else {
- processed += mapping;
- }
- break;
- case STATUS_MAPPING.deviation:
- if (transitionalProcessing) {
- processed += mapping;
- } else {
- processed += ch;
- }
- break;
- case STATUS_MAPPING.valid:
- processed += ch;
- break;
- }
- }
-
- return processed;
-}
-
-function validateLabel(label, {
- checkHyphens,
- checkBidi,
- checkJoiners,
- transitionalProcessing,
- useSTD3ASCIIRules,
- isBidi
-}) {
- // "must be satisfied for a non-empty label"
- if (label.length === 0) {
- return true;
- }
-
- // "1. The label must be in Unicode Normalization Form NFC."
- if (label.normalize("NFC") !== label) {
- return false;
- }
-
- const codePoints = Array.from(label);
-
- // "2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character in both the
- // third and fourth positions."
- //
- // "3. If CheckHyphens, the label must neither begin nor end with a U+002D HYPHEN-MINUS character."
- if (checkHyphens) {
- if ((codePoints[2] === "-" && codePoints[3] === "-") ||
- (label.startsWith("-") || label.endsWith("-"))) {
- return false;
- }
- }
-
- // "4. If not CheckHyphens, the label must not begin with “xn--”."
- if (!checkHyphens) {
- if (label.startsWith("xn--")) {
- return false;
- }
- }
-
- // "5. The label must not contain a U+002E ( . ) FULL STOP."
- if (label.includes(".")) {
- return false;
- }
-
- // "6. The label must not begin with a combining mark, that is: General_Category=Mark."
- if (regexes.combiningMarks.test(codePoints[0])) {
- return false;
- }
-
- // "7. Each code point in the label must only have certain Status values according to Section 5"
- for (const ch of codePoints) {
- const codePoint = ch.codePointAt(0);
- const [status] = findStatus(codePoint);
- if (transitionalProcessing) {
- // "For Transitional Processing (deprecated), each value must be valid."
- if (status !== STATUS_MAPPING.valid) {
- return false;
- }
- } else if (status !== STATUS_MAPPING.valid && status !== STATUS_MAPPING.deviation) {
- // "For Nontransitional Processing, each value must be either valid or deviation."
- return false;
- }
- // "In addition, if UseSTD3ASCIIRules=true and the code point is an ASCII code point (U+0000..U+007F), then it must
- // be a lowercase letter (a-z), a digit (0-9), or a hyphen-minus (U+002D). (Note: This excludes uppercase ASCII
- // A-Z which are mapped in UTS #46 and disallowed in IDNA2008.)"
- if (useSTD3ASCIIRules && codePoint <= 0x7F) {
- if (!/^(?:[a-z]|[0-9]|-)$/u.test(ch)) {
- return false;
- }
- }
- }
-
- // "8. If CheckJoiners, the label must satisify the ContextJ rules"
- // https://tools.ietf.org/html/rfc5892#appendix-A
- if (checkJoiners) {
- let last = 0;
- for (const [i, ch] of codePoints.entries()) {
- if (ch === "\u200C" || ch === "\u200D") {
- if (i > 0) {
- if (regexes.combiningClassVirama.test(codePoints[i - 1])) {
- continue;
- }
- if (ch === "\u200C") {
- // TODO: make this more efficient
- const next = codePoints.indexOf("\u200C", i + 1);
- const test = next < 0 ? codePoints.slice(last) : codePoints.slice(last, next);
- if (regexes.validZWNJ.test(test.join(""))) {
- last = i + 1;
- continue;
- }
- }
- }
- return false;
- }
- }
- }
-
- // "9. If CheckBidi, and if the domain name is a Bidi domain name, then the label must satisfy..."
- // https://tools.ietf.org/html/rfc5893#section-2
- if (checkBidi && isBidi) {
- let rtl;
-
- // 1
- if (regexes.bidiS1LTR.test(codePoints[0])) {
- rtl = false;
- } else if (regexes.bidiS1RTL.test(codePoints[0])) {
- rtl = true;
- } else {
- return false;
- }
-
- if (rtl) {
- // 2-4
- if (!regexes.bidiS2.test(label) ||
- !regexes.bidiS3.test(label) ||
- (regexes.bidiS4EN.test(label) && regexes.bidiS4AN.test(label))) {
- return false;
- }
- } else if (!regexes.bidiS5.test(label) ||
- !regexes.bidiS6.test(label)) { // 5-6
- return false;
- }
- }
-
- return true;
-}
-
-function isBidiDomain(labels) {
- const domain = labels.map(label => {
- if (label.startsWith("xn--")) {
- try {
- return punycode.decode(label.substring(4));
- } catch {
- return "";
- }
- }
- return label;
- }).join(".");
- return regexes.bidiDomain.test(domain);
-}
-
-function processing(domainName, options) {
- // 1. Map.
- let string = mapChars(domainName, options);
-
- // 2. Normalize.
- string = string.normalize("NFC");
-
- // 3. Break.
- const labels = string.split(".");
- const isBidi = isBidiDomain(labels);
-
- // 4. Convert/Validate.
- let error = false;
- for (const [i, origLabel] of labels.entries()) {
- let label = origLabel;
- let transitionalProcessingForThisLabel = options.transitionalProcessing;
- if (label.startsWith("xn--")) {
- if (containsNonASCII(label)) {
- error = true;
- continue;
- }
-
- try {
- label = punycode.decode(label.substring(4));
- } catch {
- if (!options.ignoreInvalidPunycode) {
- error = true;
- continue;
- }
- }
- labels[i] = label;
-
- if (label === "" || !containsNonASCII(label)) {
- error = true;
- }
-
- transitionalProcessingForThisLabel = false;
- }
-
- // No need to validate if we already know there is an error.
- if (error) {
- continue;
- }
- const validation = validateLabel(label, {
- ...options,
- transitionalProcessing: transitionalProcessingForThisLabel,
- isBidi
- });
- if (!validation) {
- error = true;
- }
- }
-
- return {
- string: labels.join("."),
- error
- };
-}
-
-function toASCII(domainName, {
- checkHyphens = false,
- checkBidi = false,
- checkJoiners = false,
- useSTD3ASCIIRules = false,
- verifyDNSLength = false,
- transitionalProcessing = false,
- ignoreInvalidPunycode = false
-} = {}) {
- const result = processing(domainName, {
- checkHyphens,
- checkBidi,
- checkJoiners,
- useSTD3ASCIIRules,
- transitionalProcessing,
- ignoreInvalidPunycode
- });
- let labels = result.string.split(".");
- labels = labels.map(l => {
- if (containsNonASCII(l)) {
- try {
- return `xn--${punycode.encode(l)}`;
- } catch {
- result.error = true;
- }
- }
- return l;
- });
-
- if (verifyDNSLength) {
- const total = labels.join(".").length;
- if (total > 253 || total === 0) {
- result.error = true;
- }
-
- for (let i = 0; i < labels.length; ++i) {
- if (labels[i].length > 63 || labels[i].length === 0) {
- result.error = true;
- break;
- }
- }
- }
-
- if (result.error) {
- return null;
- }
- return labels.join(".");
-}
-
-function toUnicode(domainName, {
- checkHyphens = false,
- checkBidi = false,
- checkJoiners = false,
- useSTD3ASCIIRules = false,
- transitionalProcessing = false,
- ignoreInvalidPunycode = false
-} = {}) {
- const result = processing(domainName, {
- checkHyphens,
- checkBidi,
- checkJoiners,
- useSTD3ASCIIRules,
- transitionalProcessing,
- ignoreInvalidPunycode
- });
-
- return {
- domain: result.string,
- error: result.error
- };
-}
-
-module.exports = {
- toASCII,
- toUnicode
-};