This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# eslint-config-airbnb-base@15 deklariert nur ESLint 7/8, das Setup läuft auf ESLint 9.
|
||||
legacy-peer-deps=true
|
||||
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
assets
|
||||
dev/js/libs
|
||||
package-lock.json
|
||||
dev/js/modules/airbnbLintExample.js
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "always",
|
||||
"printWidth": 100
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["dbaeumer.vscode-eslint"]
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"eslint.enable": true,
|
||||
"eslint.useFlatConfig": true,
|
||||
"eslint.validate": ["javascript"],
|
||||
"eslint.workingDirectories": [{ "mode": "auto" }]
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
(() => {
|
||||
// node_modules/uuid/dist/stringify.js
|
||||
var byteToHex = [];
|
||||
for (let i = 0; i < 256; ++i) {
|
||||
byteToHex.push((i + 256).toString(16).slice(1));
|
||||
}
|
||||
function unsafeStringify(arr, offset = 0) {
|
||||
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
||||
}
|
||||
|
||||
// node_modules/uuid/dist/rng.js
|
||||
var rnds8 = new Uint8Array(16);
|
||||
function rng() {
|
||||
return crypto.getRandomValues(rnds8);
|
||||
}
|
||||
|
||||
// node_modules/uuid/dist/v4.js
|
||||
function v4(options, buf, offset) {
|
||||
if (!buf && !options && crypto.randomUUID) {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
return _v4(options, buf, offset);
|
||||
}
|
||||
function _v4(options, buf, offset) {
|
||||
options = options || {};
|
||||
const rnds = options.random ?? options.rng?.() ?? rng();
|
||||
if (rnds.length < 16) {
|
||||
throw new Error("Random bytes length must be >= 16");
|
||||
}
|
||||
rnds[6] = rnds[6] & 15 | 64;
|
||||
rnds[8] = rnds[8] & 63 | 128;
|
||||
if (buf) {
|
||||
offset = offset || 0;
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
buf[offset + i] = rnds[i];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
return unsafeStringify(rnds);
|
||||
}
|
||||
var v4_default = v4;
|
||||
|
||||
// dev/js/modules/Counter.js
|
||||
var Counter = (elOrSelector = null) => {
|
||||
const module = elOrSelector || document.querySelector(elOrSelector);
|
||||
const countEl = module.querySelector('input[id^="count"]');
|
||||
const btnEl = module.querySelector('button[id^="incrementButton"]');
|
||||
const id = v4_default();
|
||||
countEl.id = `count-${id}`;
|
||||
btnEl.id = `incrementButton-${id}`;
|
||||
const counter = { count: 0 };
|
||||
const init = () => {
|
||||
btnEl.addEventListener("click", onClickIncrement);
|
||||
};
|
||||
const onClickIncrement = () => {
|
||||
const count = counter.count + 1;
|
||||
countEl.value = count;
|
||||
};
|
||||
init();
|
||||
};
|
||||
var Counter_default = Counter;
|
||||
|
||||
// dev/js/main.js
|
||||
(() => {
|
||||
const DOM = {
|
||||
counters: Array.from(document.querySelectorAll(".counter"))
|
||||
};
|
||||
const init = () => {
|
||||
DOM.counters.forEach((el) => {
|
||||
Counter_default(el);
|
||||
});
|
||||
};
|
||||
init();
|
||||
})();
|
||||
})();
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
(() => {
|
||||
const findings = [{"file":"dev/js/modules/Counter.js","line":22,"column":37,"rule":"no-use-before-define","message":"'onClickIncrement' was used before it was defined."},{"file":"dev/js/modules/ternaryLintExample.js","line":39,"column":12,"rule":"@stylistic/no-extra-parens","message":"Unnecessary parentheses around expression."}];
|
||||
if (findings.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const box = document.createElement('div');
|
||||
box.className = 'alert alert-danger m-3';
|
||||
box.setAttribute('role', 'alert');
|
||||
|
||||
const title = document.createElement('strong');
|
||||
title.textContent = 'ESLint: ' + findings.length + ' Fehler';
|
||||
box.append(title);
|
||||
|
||||
const list = document.createElement('ul');
|
||||
list.className = 'mb-0 mt-2';
|
||||
|
||||
for (const finding of findings) {
|
||||
const text = finding.file + ':' + finding.line + ':' + finding.column + ' ' + finding.message + ' (' + finding.rule + ')';
|
||||
console.error('[ESLint] ' + text);
|
||||
const item = document.createElement('li');
|
||||
item.textContent = text;
|
||||
list.append(item);
|
||||
}
|
||||
|
||||
box.append(list);
|
||||
document.body.prepend(box);
|
||||
})();
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
export { default as MAX } from './max.js';
|
||||
export { default as NIL } from './nil.js';
|
||||
export { default as parse } from './parse.js';
|
||||
export { default as stringify } from './stringify.js';
|
||||
export type * from './types.js';
|
||||
export { default as v1 } from './v1.js';
|
||||
export { default as v1ToV6 } from './v1ToV6.js';
|
||||
export { default as v3 } from './v3.js';
|
||||
export { default as v4 } from './v4.js';
|
||||
export { default as v5 } from './v5.js';
|
||||
export { default as v6 } from './v6.js';
|
||||
export { default as v6ToV1 } from './v6ToV1.js';
|
||||
export { default as v7 } from './v7.js';
|
||||
export { default as validate } from './validate.js';
|
||||
export { default as version } from './version.js';
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
export { default as MAX } from './max.js';
|
||||
export { default as NIL } from './nil.js';
|
||||
export { default as parse } from './parse.js';
|
||||
export { default as stringify } from './stringify.js';
|
||||
export { default as v1 } from './v1.js';
|
||||
export { default as v1ToV6 } from './v1ToV6.js';
|
||||
export { default as v3 } from './v3.js';
|
||||
export { default as v4 } from './v4.js';
|
||||
export { default as v5 } from './v5.js';
|
||||
export { default as v6 } from './v6.js';
|
||||
export { default as v6ToV1 } from './v6ToV1.js';
|
||||
export { default as v7 } from './v7.js';
|
||||
export { default as validate } from './validate.js';
|
||||
export { default as version } from './version.js';
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
declare const _default: "ffffffff-ffff-ffff-ffff-ffffffffffff";
|
||||
export default _default;
|
||||
@@ -0,0 +1 @@
|
||||
export default 'ffffffff-ffff-ffff-ffff-ffffffffffff';
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
declare function md5(bytes: Uint8Array): Uint8Array;
|
||||
export default md5;
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
function md5(bytes) {
|
||||
const words = uint8ToUint32(bytes);
|
||||
const md5Bytes = wordsToMd5(words, bytes.length * 8);
|
||||
return uint32ToUint8(md5Bytes);
|
||||
}
|
||||
function uint32ToUint8(input) {
|
||||
const bytes = new Uint8Array(input.length * 4);
|
||||
for (let i = 0; i < input.length * 4; i++) {
|
||||
bytes[i] = (input[i >> 2] >>> ((i % 4) * 8)) & 0xff;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
function getOutputLength(inputLength8) {
|
||||
return (((inputLength8 + 64) >>> 9) << 4) + 14 + 1;
|
||||
}
|
||||
function wordsToMd5(x, len) {
|
||||
const xpad = new Uint32Array(getOutputLength(len)).fill(0);
|
||||
xpad.set(x);
|
||||
xpad[len >> 5] |= 0x80 << (len % 32);
|
||||
xpad[xpad.length - 1] = len;
|
||||
x = xpad;
|
||||
let a = 1732584193;
|
||||
let b = -271733879;
|
||||
let c = -1732584194;
|
||||
let d = 271733878;
|
||||
for (let i = 0; i < x.length; i += 16) {
|
||||
const olda = a;
|
||||
const oldb = b;
|
||||
const oldc = c;
|
||||
const oldd = d;
|
||||
a = md5ff(a, b, c, d, x[i], 7, -680876936);
|
||||
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
|
||||
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
|
||||
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
|
||||
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
|
||||
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
|
||||
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
|
||||
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
|
||||
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
|
||||
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
|
||||
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
|
||||
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
|
||||
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
|
||||
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
|
||||
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
|
||||
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
|
||||
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
|
||||
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
|
||||
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
|
||||
b = md5gg(b, c, d, a, x[i], 20, -373897302);
|
||||
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
|
||||
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
|
||||
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
|
||||
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
|
||||
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
|
||||
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
|
||||
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
|
||||
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
|
||||
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
|
||||
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
|
||||
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
|
||||
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
|
||||
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
|
||||
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
|
||||
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
|
||||
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
|
||||
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
|
||||
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
|
||||
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
|
||||
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
|
||||
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
|
||||
d = md5hh(d, a, b, c, x[i], 11, -358537222);
|
||||
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
|
||||
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
|
||||
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
|
||||
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
|
||||
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
|
||||
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
|
||||
a = md5ii(a, b, c, d, x[i], 6, -198630844);
|
||||
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
|
||||
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
|
||||
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
|
||||
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
|
||||
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
|
||||
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
|
||||
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
|
||||
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
|
||||
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
|
||||
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
|
||||
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
|
||||
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
|
||||
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
|
||||
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
|
||||
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
|
||||
a = safeAdd(a, olda);
|
||||
b = safeAdd(b, oldb);
|
||||
c = safeAdd(c, oldc);
|
||||
d = safeAdd(d, oldd);
|
||||
}
|
||||
return Uint32Array.of(a, b, c, d);
|
||||
}
|
||||
function uint8ToUint32(input) {
|
||||
if (input.length === 0) {
|
||||
return new Uint32Array();
|
||||
}
|
||||
const output = new Uint32Array(getOutputLength(input.length * 8)).fill(0);
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
output[i >> 2] |= (input[i] & 0xff) << ((i % 4) * 8);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function safeAdd(x, y) {
|
||||
const lsw = (x & 0xffff) + (y & 0xffff);
|
||||
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return (msw << 16) | (lsw & 0xffff);
|
||||
}
|
||||
function bitRotateLeft(num, cnt) {
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
function md5cmn(q, a, b, x, s, t) {
|
||||
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
|
||||
}
|
||||
function md5ff(a, b, c, d, x, s, t) {
|
||||
return md5cmn((b & c) | (~b & d), a, b, x, s, t);
|
||||
}
|
||||
function md5gg(a, b, c, d, x, s, t) {
|
||||
return md5cmn((b & d) | (c & ~d), a, b, x, s, t);
|
||||
}
|
||||
function md5hh(a, b, c, d, x, s, t) {
|
||||
return md5cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
function md5ii(a, b, c, d, x, s, t) {
|
||||
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
|
||||
}
|
||||
export default md5;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
declare const _default: "00000000-0000-0000-0000-000000000000";
|
||||
export default _default;
|
||||
@@ -0,0 +1 @@
|
||||
export default '00000000-0000-0000-0000-000000000000';
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import type { NonSharedArrayBuffer } from './types.js';
|
||||
declare function parse(uuid: string): NonSharedArrayBuffer;
|
||||
export default parse;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import validate from './validate.js';
|
||||
function parse(uuid) {
|
||||
if (!validate(uuid)) {
|
||||
throw TypeError('Invalid UUID');
|
||||
}
|
||||
let v;
|
||||
return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 0xff, ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff, (v / 0x100000000) & 0xff, (v >>> 24) & 0xff, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff);
|
||||
}
|
||||
export default parse;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
declare const _default: RegExp;
|
||||
export default _default;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export default function rng(): Uint8Array;
|
||||
@@ -0,0 +1,4 @@
|
||||
const rnds8 = new Uint8Array(16);
|
||||
export default function rng() {
|
||||
return crypto.getRandomValues(rnds8);
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
declare function sha1(bytes: Uint8Array): Uint8Array;
|
||||
export default sha1;
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
function f(s, x, y, z) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
return (x & y) ^ (~x & z);
|
||||
case 1:
|
||||
return x ^ y ^ z;
|
||||
case 2:
|
||||
return (x & y) ^ (x & z) ^ (y & z);
|
||||
case 3:
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
}
|
||||
function ROTL(x, n) {
|
||||
return (x << n) | (x >>> (32 - n));
|
||||
}
|
||||
function sha1(bytes) {
|
||||
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
|
||||
const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
|
||||
const newBytes = new Uint8Array(bytes.length + 1);
|
||||
newBytes.set(bytes);
|
||||
newBytes[bytes.length] = 0x80;
|
||||
bytes = newBytes;
|
||||
const l = bytes.length / 4 + 2;
|
||||
const N = Math.ceil(l / 16);
|
||||
const M = new Array(N);
|
||||
for (let i = 0; i < N; ++i) {
|
||||
const arr = new Uint32Array(16);
|
||||
for (let j = 0; j < 16; ++j) {
|
||||
arr[j] =
|
||||
(bytes[i * 64 + j * 4] << 24) |
|
||||
(bytes[i * 64 + j * 4 + 1] << 16) |
|
||||
(bytes[i * 64 + j * 4 + 2] << 8) |
|
||||
bytes[i * 64 + j * 4 + 3];
|
||||
}
|
||||
M[i] = arr;
|
||||
}
|
||||
M[N - 1][14] = ((bytes.length - 1) * 8) / 2 ** 32;
|
||||
M[N - 1][14] = Math.floor(M[N - 1][14]);
|
||||
M[N - 1][15] = ((bytes.length - 1) * 8) & 0xffffffff;
|
||||
for (let i = 0; i < N; ++i) {
|
||||
const W = new Uint32Array(80);
|
||||
for (let t = 0; t < 16; ++t) {
|
||||
W[t] = M[i][t];
|
||||
}
|
||||
for (let t = 16; t < 80; ++t) {
|
||||
W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
|
||||
}
|
||||
let a = H[0];
|
||||
let b = H[1];
|
||||
let c = H[2];
|
||||
let d = H[3];
|
||||
let e = H[4];
|
||||
for (let t = 0; t < 80; ++t) {
|
||||
const s = Math.floor(t / 20);
|
||||
const T = (ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t]) >>> 0;
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROTL(b, 30) >>> 0;
|
||||
b = a;
|
||||
a = T;
|
||||
}
|
||||
H[0] = (H[0] + a) >>> 0;
|
||||
H[1] = (H[1] + b) >>> 0;
|
||||
H[2] = (H[2] + c) >>> 0;
|
||||
H[3] = (H[3] + d) >>> 0;
|
||||
H[4] = (H[4] + e) >>> 0;
|
||||
}
|
||||
return Uint8Array.of(H[0] >> 24, H[0] >> 16, H[0] >> 8, H[0], H[1] >> 24, H[1] >> 16, H[1] >> 8, H[1], H[2] >> 24, H[2] >> 16, H[2] >> 8, H[2], H[3] >> 24, H[3] >> 16, H[3] >> 8, H[3], H[4] >> 24, H[4] >> 16, H[4] >> 8, H[4]);
|
||||
}
|
||||
export default sha1;
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export declare function unsafeStringify(arr: Uint8Array, offset?: number): string;
|
||||
declare function stringify(arr: Uint8Array, offset?: number): string;
|
||||
export default stringify;
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
import validate from './validate.js';
|
||||
const byteToHex = [];
|
||||
for (let i = 0; i < 256; ++i) {
|
||||
byteToHex.push((i + 0x100).toString(16).slice(1));
|
||||
}
|
||||
export function unsafeStringify(arr, offset = 0) {
|
||||
return (byteToHex[arr[offset + 0]] +
|
||||
byteToHex[arr[offset + 1]] +
|
||||
byteToHex[arr[offset + 2]] +
|
||||
byteToHex[arr[offset + 3]] +
|
||||
'-' +
|
||||
byteToHex[arr[offset + 4]] +
|
||||
byteToHex[arr[offset + 5]] +
|
||||
'-' +
|
||||
byteToHex[arr[offset + 6]] +
|
||||
byteToHex[arr[offset + 7]] +
|
||||
'-' +
|
||||
byteToHex[arr[offset + 8]] +
|
||||
byteToHex[arr[offset + 9]] +
|
||||
'-' +
|
||||
byteToHex[arr[offset + 10]] +
|
||||
byteToHex[arr[offset + 11]] +
|
||||
byteToHex[arr[offset + 12]] +
|
||||
byteToHex[arr[offset + 13]] +
|
||||
byteToHex[arr[offset + 14]] +
|
||||
byteToHex[arr[offset + 15]]).toLowerCase();
|
||||
}
|
||||
function stringify(arr, offset = 0) {
|
||||
const uuid = unsafeStringify(arr, offset);
|
||||
if (!validate(uuid)) {
|
||||
throw TypeError('Stringified UUID is invalid');
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
export default stringify;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
export type UUIDTypes<TBuf extends Uint8Array = Uint8Array> = string | TBuf;
|
||||
export type Version1Options = {
|
||||
node?: Uint8Array;
|
||||
clockseq?: number;
|
||||
random?: Uint8Array;
|
||||
rng?: () => Uint8Array;
|
||||
msecs?: number;
|
||||
nsecs?: number;
|
||||
_v6?: boolean;
|
||||
};
|
||||
export type Version4Options = {
|
||||
random?: Uint8Array;
|
||||
rng?: () => Uint8Array;
|
||||
};
|
||||
export type Version6Options = Version1Options;
|
||||
export type Version7Options = {
|
||||
random?: Uint8Array;
|
||||
msecs?: number;
|
||||
seq?: number;
|
||||
rng?: () => Uint8Array;
|
||||
};
|
||||
export type NonSharedArrayBuffer = ReturnType<typeof Uint8Array.of>;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import * as assert from 'node:assert/strict';
|
||||
import v1 from './v1.js';
|
||||
import v3 from './v3.js';
|
||||
import v4 from './v4.js';
|
||||
import v5 from './v5.js';
|
||||
import v6 from './v6.js';
|
||||
import v7 from './v7.js';
|
||||
function usage() {
|
||||
console.log('Usage:');
|
||||
console.log(' uuid');
|
||||
console.log(' uuid v1');
|
||||
console.log(' uuid v3 <name> <namespace uuid>');
|
||||
console.log(' uuid v4');
|
||||
console.log(' uuid v5 <name> <namespace uuid>');
|
||||
console.log(' uuid v6');
|
||||
console.log(' uuid v7');
|
||||
console.log(' uuid --help');
|
||||
console.log('\nNote: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC9562');
|
||||
}
|
||||
const args = process.argv.slice(2);
|
||||
if (args.indexOf('--help') >= 0) {
|
||||
usage();
|
||||
process.exit(0);
|
||||
}
|
||||
const version = args.shift() || 'v4';
|
||||
switch (version) {
|
||||
case 'v1':
|
||||
console.log(v1());
|
||||
break;
|
||||
case 'v3': {
|
||||
const name = args.shift();
|
||||
let namespace = args.shift();
|
||||
assert.ok(name != null, 'v3 name not specified');
|
||||
assert.ok(namespace != null, 'v3 namespace not specified');
|
||||
if (namespace === 'URL') {
|
||||
namespace = v3.URL;
|
||||
}
|
||||
if (namespace === 'DNS') {
|
||||
namespace = v3.DNS;
|
||||
}
|
||||
console.log(v3(name, namespace));
|
||||
break;
|
||||
}
|
||||
case 'v4':
|
||||
console.log(v4());
|
||||
break;
|
||||
case 'v5': {
|
||||
const name = args.shift();
|
||||
let namespace = args.shift();
|
||||
assert.ok(name != null, 'v5 name not specified');
|
||||
assert.ok(namespace != null, 'v5 namespace not specified');
|
||||
if (namespace === 'URL') {
|
||||
namespace = v5.URL;
|
||||
}
|
||||
if (namespace === 'DNS') {
|
||||
namespace = v5.DNS;
|
||||
}
|
||||
console.log(v5(name, namespace));
|
||||
break;
|
||||
}
|
||||
case 'v6':
|
||||
console.log(v6());
|
||||
break;
|
||||
case 'v7':
|
||||
console.log(v7());
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
process.exit(1);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import type { Version1Options } from './types.js';
|
||||
type V1State = {
|
||||
node?: Uint8Array;
|
||||
clockseq?: number;
|
||||
msecs?: number;
|
||||
nsecs?: number;
|
||||
};
|
||||
declare function v1(options?: Version1Options, buf?: undefined, offset?: number): string;
|
||||
declare function v1<Buf extends Uint8Array = Uint8Array>(options: Version1Options | undefined, buf: Buf, offset?: number): Buf;
|
||||
export declare function updateV1State(state: V1State, now: number, rnds: Uint8Array): V1State;
|
||||
export default v1;
|
||||
@@ -0,0 +1,87 @@
|
||||
import rng from './rng.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
const _state = {};
|
||||
function v1(options, buf, offset) {
|
||||
let bytes;
|
||||
const isV6 = options?._v6 ?? false;
|
||||
if (options) {
|
||||
const optionsKeys = Object.keys(options);
|
||||
if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') {
|
||||
options = undefined;
|
||||
}
|
||||
}
|
||||
if (options) {
|
||||
bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset);
|
||||
}
|
||||
else {
|
||||
const now = Date.now();
|
||||
const rnds = rng();
|
||||
updateV1State(_state, now, rnds);
|
||||
bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset);
|
||||
}
|
||||
return buf ?? unsafeStringify(bytes);
|
||||
}
|
||||
export function updateV1State(state, now, rnds) {
|
||||
state.msecs ??= -Infinity;
|
||||
state.nsecs ??= 0;
|
||||
if (now === state.msecs) {
|
||||
state.nsecs++;
|
||||
if (state.nsecs >= 10000) {
|
||||
state.node = undefined;
|
||||
state.nsecs = 0;
|
||||
}
|
||||
}
|
||||
else if (now > state.msecs) {
|
||||
state.nsecs = 0;
|
||||
}
|
||||
else if (now < state.msecs) {
|
||||
state.node = undefined;
|
||||
}
|
||||
if (!state.node) {
|
||||
state.node = rnds.slice(10, 16);
|
||||
state.node[0] |= 0x01;
|
||||
state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;
|
||||
}
|
||||
state.msecs = now;
|
||||
return state;
|
||||
}
|
||||
function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {
|
||||
if (rnds.length < 16) {
|
||||
throw new Error('Random bytes length must be >= 16');
|
||||
}
|
||||
if (!buf) {
|
||||
buf = new Uint8Array(16);
|
||||
offset = 0;
|
||||
}
|
||||
else {
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
}
|
||||
msecs ??= Date.now();
|
||||
nsecs ??= 0;
|
||||
clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;
|
||||
if (node == null) {
|
||||
node = rnds.slice(10, 16);
|
||||
node[0] |= 0x01;
|
||||
}
|
||||
msecs += 12219292800000;
|
||||
const t = (msecs & 0xfffffff) * 10000 + nsecs;
|
||||
const tl = t >>> 0;
|
||||
buf[offset++] = (tl >>> 24) & 0xff;
|
||||
buf[offset++] = (tl >>> 16) & 0xff;
|
||||
buf[offset++] = (tl >>> 8) & 0xff;
|
||||
buf[offset++] = tl & 0xff;
|
||||
const tmh = (((msecs / 0x10000000) | 0) * 625 + ((t / 0x100000000) | 0)) & 0xfffffff;
|
||||
buf[offset++] = (tmh >>> 8) & 0xff;
|
||||
buf[offset++] = tmh & 0xff;
|
||||
buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10;
|
||||
buf[offset++] = (tmh >>> 16) & 0xff;
|
||||
buf[offset++] = (clockseq >>> 8) | 0x80;
|
||||
buf[offset++] = clockseq & 0xff;
|
||||
for (let n = 0; n < 6; ++n) {
|
||||
buf[offset++] = node[n];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
export default v1;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import type { NonSharedArrayBuffer } from './types.js';
|
||||
export default function v1ToV6(uuid: string): string;
|
||||
export default function v1ToV6(uuid: Uint8Array): NonSharedArrayBuffer;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import parse from './parse.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
export default function v1ToV6(uuid) {
|
||||
const v1Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;
|
||||
const v6Bytes = _v1ToV6(v1Bytes);
|
||||
return typeof uuid === 'string' ? unsafeStringify(v6Bytes) : v6Bytes;
|
||||
}
|
||||
function _v1ToV6(v1Bytes) {
|
||||
return Uint8Array.of(((v1Bytes[6] & 0x0f) << 4) | ((v1Bytes[7] >> 4) & 0x0f), ((v1Bytes[7] & 0x0f) << 4) | ((v1Bytes[4] & 0xf0) >> 4), ((v1Bytes[4] & 0x0f) << 4) | ((v1Bytes[5] & 0xf0) >> 4), ((v1Bytes[5] & 0x0f) << 4) | ((v1Bytes[0] & 0xf0) >> 4), ((v1Bytes[0] & 0x0f) << 4) | ((v1Bytes[1] & 0xf0) >> 4), ((v1Bytes[1] & 0x0f) << 4) | ((v1Bytes[2] & 0xf0) >> 4), 0x60 | (v1Bytes[2] & 0x0f), v1Bytes[3], v1Bytes[8], v1Bytes[9], v1Bytes[10], v1Bytes[11], v1Bytes[12], v1Bytes[13], v1Bytes[14], v1Bytes[15]);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { UUIDTypes } from './types.js';
|
||||
export { DNS, URL } from './v35.js';
|
||||
declare function v3(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
|
||||
declare function v3<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
|
||||
declare namespace v3 {
|
||||
var DNS: string;
|
||||
var URL: string;
|
||||
}
|
||||
export default v3;
|
||||
@@ -0,0 +1,9 @@
|
||||
import md5 from './md5.js';
|
||||
import v35, { DNS, URL } from './v35.js';
|
||||
export { DNS, URL } from './v35.js';
|
||||
function v3(value, namespace, buf, offset) {
|
||||
return v35(0x30, md5, value, namespace, buf, offset);
|
||||
}
|
||||
v3.DNS = DNS;
|
||||
v3.URL = URL;
|
||||
export default v3;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { UUIDTypes } from './types.js';
|
||||
export declare function stringToBytes(str: string): Uint8Array;
|
||||
export declare const DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
||||
export declare const URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
||||
type HashFunction = (bytes: Uint8Array) => Uint8Array;
|
||||
export default function v35<TBuf extends Uint8Array = Uint8Array>(version: 0x30 | 0x50, hash: HashFunction, value: string | Uint8Array, namespace: UUIDTypes, buf?: TBuf, offset?: number): UUIDTypes<TBuf>;
|
||||
export {};
|
||||
@@ -0,0 +1,39 @@
|
||||
import parse from './parse.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
export function stringToBytes(str) {
|
||||
str = unescape(encodeURIComponent(str));
|
||||
const bytes = new Uint8Array(str.length);
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
bytes[i] = str.charCodeAt(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
export const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
||||
export const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
|
||||
export default function v35(version, hash, value, namespace, buf, offset) {
|
||||
const valueBytes = typeof value === 'string' ? stringToBytes(value) : value;
|
||||
const namespaceBytes = typeof namespace === 'string' ? parse(namespace) : namespace;
|
||||
if (typeof namespace === 'string') {
|
||||
namespace = parse(namespace);
|
||||
}
|
||||
if (namespace?.length !== 16) {
|
||||
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
|
||||
}
|
||||
let bytes = new Uint8Array(16 + valueBytes.length);
|
||||
bytes.set(namespaceBytes);
|
||||
bytes.set(valueBytes, namespaceBytes.length);
|
||||
bytes = hash(bytes);
|
||||
bytes[6] = (bytes[6] & 0x0f) | version;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
if (buf) {
|
||||
offset ??= 0;
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
buf[offset + i] = bytes[i];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
return unsafeStringify(bytes);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { Version4Options } from './types.js';
|
||||
declare function v4(options?: Version4Options, buf?: undefined, offset?: number): string;
|
||||
declare function v4<TBuf extends Uint8Array = Uint8Array>(options: Version4Options | undefined, buf: TBuf, offset?: number): TBuf;
|
||||
export default v4;
|
||||
@@ -0,0 +1,29 @@
|
||||
import rng from './rng.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
function v4(options, buf, offset) {
|
||||
if (!buf && !options && crypto.randomUUID) {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
return _v4(options, buf, offset);
|
||||
}
|
||||
function _v4(options, buf, offset) {
|
||||
options = options || {};
|
||||
const rnds = options.random ?? options.rng?.() ?? rng();
|
||||
if (rnds.length < 16) {
|
||||
throw new Error('Random bytes length must be >= 16');
|
||||
}
|
||||
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||||
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||||
if (buf) {
|
||||
offset = offset || 0;
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
buf[offset + i] = rnds[i];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
return unsafeStringify(rnds);
|
||||
}
|
||||
export default v4;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { UUIDTypes } from './types.js';
|
||||
export { DNS, URL } from './v35.js';
|
||||
declare function v5(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
|
||||
declare function v5<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
|
||||
declare namespace v5 {
|
||||
var DNS: string;
|
||||
var URL: string;
|
||||
}
|
||||
export default v5;
|
||||
@@ -0,0 +1,9 @@
|
||||
import sha1 from './sha1.js';
|
||||
import v35, { DNS, URL } from './v35.js';
|
||||
export { DNS, URL } from './v35.js';
|
||||
function v5(value, namespace, buf, offset) {
|
||||
return v35(0x50, sha1, value, namespace, buf, offset);
|
||||
}
|
||||
v5.DNS = DNS;
|
||||
v5.URL = URL;
|
||||
export default v5;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { Version6Options } from './types.js';
|
||||
declare function v6(options?: Version6Options, buf?: undefined, offset?: number): string;
|
||||
declare function v6<TBuf extends Uint8Array = Uint8Array>(options: Version6Options | undefined, buf: TBuf, offset?: number): TBuf;
|
||||
export default v6;
|
||||
@@ -0,0 +1,20 @@
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
import v1 from './v1.js';
|
||||
import v1ToV6 from './v1ToV6.js';
|
||||
function v6(options, buf, offset) {
|
||||
options ??= {};
|
||||
offset ??= 0;
|
||||
let bytes = v1({ ...options, _v6: true }, new Uint8Array(16));
|
||||
bytes = v1ToV6(bytes);
|
||||
if (buf) {
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
for (let i = 0; i < 16; i++) {
|
||||
buf[offset + i] = bytes[i];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
return unsafeStringify(bytes);
|
||||
}
|
||||
export default v6;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export default function v6ToV1(uuid: string): string;
|
||||
export default function v6ToV1(uuid: Uint8Array): Uint8Array;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import parse from './parse.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
export default function v6ToV1(uuid) {
|
||||
const v6Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;
|
||||
const v1Bytes = _v6ToV1(v6Bytes);
|
||||
return typeof uuid === 'string' ? unsafeStringify(v1Bytes) : v1Bytes;
|
||||
}
|
||||
function _v6ToV1(v6Bytes) {
|
||||
return Uint8Array.of(((v6Bytes[3] & 0x0f) << 4) | ((v6Bytes[4] >> 4) & 0x0f), ((v6Bytes[4] & 0x0f) << 4) | ((v6Bytes[5] & 0xf0) >> 4), ((v6Bytes[5] & 0x0f) << 4) | (v6Bytes[6] & 0x0f), v6Bytes[7], ((v6Bytes[1] & 0x0f) << 4) | ((v6Bytes[2] & 0xf0) >> 4), ((v6Bytes[2] & 0x0f) << 4) | ((v6Bytes[3] & 0xf0) >> 4), 0x10 | ((v6Bytes[0] & 0xf0) >> 4), ((v6Bytes[0] & 0x0f) << 4) | ((v6Bytes[1] & 0xf0) >> 4), v6Bytes[8], v6Bytes[9], v6Bytes[10], v6Bytes[11], v6Bytes[12], v6Bytes[13], v6Bytes[14], v6Bytes[15]);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import type { Version7Options } from './types.js';
|
||||
type V7State = {
|
||||
msecs?: number;
|
||||
seq?: number;
|
||||
};
|
||||
declare function v7(options?: Version7Options, buf?: undefined, offset?: number): string;
|
||||
declare function v7<TBuf extends Uint8Array = Uint8Array>(options: Version7Options | undefined, buf: TBuf, offset?: number): TBuf;
|
||||
export declare function updateV7State(state: V7State, now: number, rnds: Uint8Array): V7State;
|
||||
export default v7;
|
||||
@@ -0,0 +1,68 @@
|
||||
import rng from './rng.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
const _state = {};
|
||||
function v7(options, buf, offset) {
|
||||
let bytes;
|
||||
if (options) {
|
||||
bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset);
|
||||
}
|
||||
else {
|
||||
const now = Date.now();
|
||||
const rnds = rng();
|
||||
updateV7State(_state, now, rnds);
|
||||
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
|
||||
}
|
||||
return buf ?? unsafeStringify(bytes);
|
||||
}
|
||||
export function updateV7State(state, now, rnds) {
|
||||
state.msecs ??= -Infinity;
|
||||
state.seq ??= 0;
|
||||
if (now > state.msecs) {
|
||||
state.seq = v7Sequence(rnds);
|
||||
state.msecs = now;
|
||||
}
|
||||
else {
|
||||
state.seq = (state.seq + 1) | 0;
|
||||
if (state.seq === 0) {
|
||||
state.msecs++;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
|
||||
if (rnds.length < 16) {
|
||||
throw new Error('Random bytes length must be >= 16');
|
||||
}
|
||||
if (!buf) {
|
||||
buf = new Uint8Array(16);
|
||||
offset = 0;
|
||||
}
|
||||
else {
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
}
|
||||
msecs ??= Date.now();
|
||||
seq ??= v7Sequence(rnds);
|
||||
buf[offset++] = (msecs / 0x10000000000) & 0xff;
|
||||
buf[offset++] = (msecs / 0x100000000) & 0xff;
|
||||
buf[offset++] = (msecs / 0x1000000) & 0xff;
|
||||
buf[offset++] = (msecs / 0x10000) & 0xff;
|
||||
buf[offset++] = (msecs / 0x100) & 0xff;
|
||||
buf[offset++] = msecs & 0xff;
|
||||
buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f);
|
||||
buf[offset++] = (seq >>> 20) & 0xff;
|
||||
buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f);
|
||||
buf[offset++] = (seq >>> 6) & 0xff;
|
||||
buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03);
|
||||
buf[offset++] = rnds[11];
|
||||
buf[offset++] = rnds[12];
|
||||
buf[offset++] = rnds[13];
|
||||
buf[offset++] = rnds[14];
|
||||
buf[offset++] = rnds[15];
|
||||
return buf;
|
||||
}
|
||||
function v7Sequence(rnds) {
|
||||
return ((rnds[6] & 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
|
||||
}
|
||||
export default v7;
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
declare function validate(uuid: unknown): boolean;
|
||||
export default validate;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import REGEX from './regex.js';
|
||||
function validate(uuid) {
|
||||
return typeof uuid === 'string' && REGEX.test(uuid);
|
||||
}
|
||||
export default validate;
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
declare function version(uuid: string): number;
|
||||
export default version;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import validate from './validate.js';
|
||||
function version(uuid) {
|
||||
if (!validate(uuid)) {
|
||||
throw TypeError('Invalid UUID');
|
||||
}
|
||||
return parseInt(uuid.slice(14, 15), 16);
|
||||
}
|
||||
export default version;
|
||||
@@ -0,0 +1,23 @@
|
||||
import Counter from './modules/Counter.js'; // wichtig mit Dateiendung, da kein Bundler
|
||||
|
||||
(() => {
|
||||
// === DOM & VARS =======
|
||||
const DOM = {
|
||||
counters: Array.from(document.querySelectorAll('.counter')),
|
||||
};
|
||||
|
||||
// === INIT =============
|
||||
const init = () => {
|
||||
DOM.counters.forEach((el) => {
|
||||
Counter(el);
|
||||
});
|
||||
};
|
||||
|
||||
// === EVENTHANDLER =====
|
||||
|
||||
// === XHR/FETCH ========
|
||||
|
||||
// === FUNCTIONS ========
|
||||
|
||||
init();
|
||||
})();
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
const Counter = (elOrSelector = null) => {
|
||||
// ===== DOM & VARS =====
|
||||
|
||||
// TODO: forEach for string selector
|
||||
const module = elOrSelector || document.querySelector(elOrSelector);
|
||||
const countEl = module.querySelector('input[id^="count"]');
|
||||
const btnEl = module.querySelector('button[id^="incrementButton"]');
|
||||
|
||||
const id = v4();
|
||||
|
||||
countEl.id = `count-${id}`;
|
||||
btnEl.id = `incrementButton-${id}`;
|
||||
|
||||
// console.log('id:', id);
|
||||
|
||||
const counter = { count: 0 };
|
||||
|
||||
// ===== INIT =====
|
||||
const init = () => {
|
||||
btnEl.addEventListener('click', onClickIncrement);
|
||||
};
|
||||
|
||||
// ===== EVENT HANDLER =====
|
||||
const onClickIncrement = () => {
|
||||
const count = counter.count + 1;
|
||||
// count++;
|
||||
countEl.value = count;
|
||||
};
|
||||
|
||||
// ===== CALL INIT =====
|
||||
init();
|
||||
};
|
||||
|
||||
export default Counter;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
var greeting = 'Hallo';
|
||||
|
||||
let name = 'Welt';
|
||||
|
||||
const airbnbLintExample = {
|
||||
// gültig
|
||||
status(isActive) {
|
||||
return isActive ? 'online' : 'offline';
|
||||
},
|
||||
|
||||
isZero(value) {
|
||||
return value == 0;
|
||||
},
|
||||
|
||||
role(isAdmin, isActive) {
|
||||
return isAdmin ? (isActive ? 'Admin online' : 'Admin offline') : 'Gast';
|
||||
},
|
||||
|
||||
sum(a, b) {
|
||||
const result = a + b;
|
||||
return a + b;
|
||||
},
|
||||
|
||||
next(count) {
|
||||
let value = count;
|
||||
value++;
|
||||
return value;
|
||||
},
|
||||
|
||||
greet() {
|
||||
return `${greeting} ${name}`;
|
||||
},
|
||||
};
|
||||
|
||||
export default airbnbLintExample;
|
||||
@@ -0,0 +1,110 @@
|
||||
import * as esbuild from 'esbuild';
|
||||
import { ESLint } from 'eslint';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const outfile = path.resolve('assets/js/bundle.js');
|
||||
const reportFile = path.resolve('assets/js/lint-report.js');
|
||||
const watch = process.argv.includes('--watch');
|
||||
|
||||
function runtimeReport(results) {
|
||||
const findings = [];
|
||||
|
||||
results.forEach((result) => {
|
||||
const file = path.relative(process.cwd(), result.filePath);
|
||||
|
||||
result.messages.forEach((message) => {
|
||||
if (message.severity !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
findings.push({
|
||||
file,
|
||||
line: message.line ?? 0,
|
||||
column: message.column ?? 0,
|
||||
rule: message.ruleId ?? '',
|
||||
message: message.message,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const script = `(() => {
|
||||
const findings = ${JSON.stringify(findings)};
|
||||
if (findings.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const box = document.createElement('div');
|
||||
box.className = 'alert alert-danger m-3';
|
||||
box.setAttribute('role', 'alert');
|
||||
|
||||
const title = document.createElement('strong');
|
||||
title.textContent = 'ESLint: ' + findings.length + ' Fehler';
|
||||
box.append(title);
|
||||
|
||||
const list = document.createElement('ul');
|
||||
list.className = 'mb-0 mt-2';
|
||||
|
||||
for (const finding of findings) {
|
||||
const text = finding.file + ':' + finding.line + ':' + finding.column + ' ' + finding.message + ' (' + finding.rule + ')';
|
||||
console.error('[ESLint] ' + text);
|
||||
const item = document.createElement('li');
|
||||
item.textContent = text;
|
||||
list.append(item);
|
||||
}
|
||||
|
||||
box.append(list);
|
||||
document.body.prepend(box);
|
||||
})();
|
||||
`;
|
||||
|
||||
return { findings, script };
|
||||
}
|
||||
|
||||
function printFindings(findings) {
|
||||
if (findings.length === 0) {
|
||||
console.log('ESLint: keine Fehler');
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(`ESLint: ${findings.length} Fehler (auch in der geladenen Seite)`);
|
||||
findings.forEach((finding) => {
|
||||
console.error(`${finding.file}:${finding.line}:${finding.column} ${finding.message} (${finding.rule})`);
|
||||
});
|
||||
}
|
||||
|
||||
const eslintRuntime = {
|
||||
name: 'eslint-runtime',
|
||||
setup(build) {
|
||||
build.onEnd(async (result) => {
|
||||
if (result.errors.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const eslint = new ESLint({ cwd: process.cwd() });
|
||||
const results = await eslint.lintFiles(['dev/js/**/*.js']);
|
||||
const report = runtimeReport(results);
|
||||
|
||||
fs.writeFileSync(reportFile, report.script);
|
||||
printFindings(report.findings);
|
||||
} catch (error) {
|
||||
console.error('ESLint-Laufzeitbericht fehlgeschlagen:', error);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const context = await esbuild.context({
|
||||
entryPoints: ['dev/js/main.js'],
|
||||
bundle: true,
|
||||
outfile,
|
||||
plugins: [eslintRuntime],
|
||||
});
|
||||
|
||||
if (watch) {
|
||||
await context.watch();
|
||||
} else {
|
||||
await context.rebuild();
|
||||
await context.dispose();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { FlatCompat } from '@eslint/eslintrc';
|
||||
import js from '@eslint/js';
|
||||
import globals from 'globals';
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: import.meta.dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
});
|
||||
|
||||
export default [
|
||||
{
|
||||
// Geprüft wird nur der eigene Seiten-Code. Build- und Konfigurationsdateien bleiben außen vor.
|
||||
ignores: [
|
||||
'node_modules/**',
|
||||
'assets/**',
|
||||
'dev/js/libs/**',
|
||||
'eslint.config.mjs',
|
||||
'esbuild.config.mjs',
|
||||
],
|
||||
},
|
||||
// Die Airbnb-Regeln, unverändert.
|
||||
...compat.extends('airbnb-base'),
|
||||
{
|
||||
languageOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
globals: {
|
||||
...globals.browser,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
node: {
|
||||
// uuid@14 hat nur ein exports-Feld. Ohne diese Einstellung meldet
|
||||
// import/no-unresolved fälschlich, dass 'uuid' nicht gefunden wird.
|
||||
exportsCategory: 'pattern-trailers-no-dir-slash+json-imports',
|
||||
moduleSystem: 'import',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,89 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Counter Example</title>
|
||||
<link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="assets/js/bundle.js" defer></script>
|
||||
<!-- <script src="assets/js/lint-report.js" defer></script> -->
|
||||
</head>
|
||||
<body>
|
||||
<main id="main">
|
||||
<section class="section-hero">
|
||||
<div class="container py-3">
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<h2>HERO</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section-content">
|
||||
<div class="container">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum animi eaque doloremque
|
||||
error voluptate alias dolorem esse qui voluptatum eius placeat unde consequuntur sequi
|
||||
dolor, repudiandae nobis. Excepturi, dolores tenetur.
|
||||
</p>
|
||||
</div>
|
||||
<div class="counter">
|
||||
<div class="container py-5">
|
||||
<h3>Counter</h3>
|
||||
<div class="row mt-4">
|
||||
<div class="col col-12 col-sm-10 col-lg-6">
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text">Count:</span>
|
||||
<input
|
||||
type="text"
|
||||
id="count"
|
||||
class="form-control input-count"
|
||||
value="0"
|
||||
readonly
|
||||
aria-label="Counter"
|
||||
/>
|
||||
</div>
|
||||
<button id="incrementButton" class="btn btn-primary w-100">Increment</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ▲ /counter ▲ -->
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<div class="container py-3 align-items-center">
|
||||
<div class="col">
|
||||
<p>© copyright 2026 Donkey-Coders</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="counter">
|
||||
<div class="container py-5">
|
||||
<h3>Counter</h3>
|
||||
<div class="row mt-4">
|
||||
<div class="col col-12 col-sm-10 col-lg-6">
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text">Count:</span>
|
||||
<input
|
||||
type="text"
|
||||
id="count-2"
|
||||
class="form-control input-count"
|
||||
value="0"
|
||||
readonly
|
||||
aria-label="Counter"
|
||||
/>
|
||||
</div>
|
||||
<button id="incrementButton-2" class="btn btn-primary w-100">Increment</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ▲ /counter ▲ -->
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
+4546
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "webseite-html-js-bundled",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"bundle": "node esbuild.config.mjs --watch",
|
||||
"dev": "run-p bundle server",
|
||||
"server": "npx http-server -c-1 -p 3000",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"keywords": [],
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.7",
|
||||
"@eslint/js": "^10.0.1",
|
||||
"esbuild": "^0.28.2",
|
||||
"eslint": "^10.14.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"globals": "^17.14.0",
|
||||
"http-server": "^14.1.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.9.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^14.0.3"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user