@utilix-tech/sdk 0.9.0 → 0.11.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 +7 -0
- package/README.md +19 -3
- package/dist/{chunk-QJE743LY.js → chunk-GGDDCTFM.js} +224 -1
- package/dist/{chunk-LI5AME5R.js → chunk-OB56VNKJ.js} +85 -1
- package/dist/index.cjs +311 -4
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{network-Cy02-FIO.d.cts → network-DaNoZ5ER.d.cts} +39 -2
- package/dist/{network-Cy02-FIO.d.ts → network-DaNoZ5ER.d.ts} +39 -2
- package/dist/tools/network.cjs +84 -0
- package/dist/tools/network.d.cts +1 -1
- package/dist/tools/network.d.ts +1 -1
- package/dist/tools/network.js +1 -1
- package/dist/tools/units.cjs +223 -0
- package/dist/tools/units.d.cts +1 -1
- package/dist/tools/units.d.ts +1 -1
- package/dist/tools/units.js +1 -1
- package/dist/{units-6lwDYBvX.d.cts → units-BG387sch.d.cts} +67 -2
- package/dist/{units-6lwDYBvX.d.ts → units-BG387sch.d.ts} +67 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6621,6 +6621,7 @@ __export(units_exports, {
|
|
|
6621
6621
|
bumpVersion: () => bumpVersion,
|
|
6622
6622
|
calcAspectRatio: () => calcAspectRatio,
|
|
6623
6623
|
calcSubnet: () => calcSubnet,
|
|
6624
|
+
calculateLoan: () => calculateLoan,
|
|
6624
6625
|
compareSemver: () => compareSemver,
|
|
6625
6626
|
convert: () => convert,
|
|
6626
6627
|
convertBytes: () => convertBytes,
|
|
@@ -6665,6 +6666,8 @@ __export(units_exports, {
|
|
|
6665
6666
|
sortVersions: () => sortVersions,
|
|
6666
6667
|
splitSubnet: () => splitSubnet,
|
|
6667
6668
|
symbolicToPermissions: () => symbolicToPermissions,
|
|
6669
|
+
validateCardNumber: () => validateCardNumber,
|
|
6670
|
+
validateIban: () => validateIban,
|
|
6668
6671
|
viewportToPx: () => viewportToPx
|
|
6669
6672
|
});
|
|
6670
6673
|
function pxToAll(px, baseFontSize = 16, viewportWidth = 1440, viewportHeight = 900) {
|
|
@@ -7497,6 +7500,226 @@ function sortVersions(versions, order = "asc") {
|
|
|
7497
7500
|
return order === "asc" ? cmp : -cmp;
|
|
7498
7501
|
});
|
|
7499
7502
|
}
|
|
7503
|
+
var CARD_NETWORK_RULES = [
|
|
7504
|
+
{ name: "American Express", lengths: [15], test: (d) => /^3[47]/.test(d) },
|
|
7505
|
+
{ name: "Diners Club", lengths: [14], test: (d) => /^3(?:0[0-5]|[68])/.test(d) },
|
|
7506
|
+
{
|
|
7507
|
+
name: "Discover",
|
|
7508
|
+
lengths: [16, 19],
|
|
7509
|
+
test: (d) => /^(?:6011|65|64[4-9])/.test(d) || /^622(?:12[6-9]|1[3-9]\d|[2-8]\d{2}|9[01]\d|92[0-5])/.test(d)
|
|
7510
|
+
},
|
|
7511
|
+
{ name: "JCB", lengths: [16], test: (d) => /^35(?:2[89]|[3-8]\d)/.test(d) },
|
|
7512
|
+
{
|
|
7513
|
+
name: "Mastercard",
|
|
7514
|
+
lengths: [16],
|
|
7515
|
+
test: (d) => {
|
|
7516
|
+
const two = parseInt(d.slice(0, 2), 10);
|
|
7517
|
+
const four = parseInt(d.slice(0, 4), 10);
|
|
7518
|
+
return two >= 51 && two <= 55 || four >= 2221 && four <= 2720;
|
|
7519
|
+
}
|
|
7520
|
+
},
|
|
7521
|
+
{ name: "Maestro", lengths: [12, 13, 14, 15, 16, 17, 18, 19], test: (d) => /^(?:50|5[6-8]|6304|6390|67)/.test(d) },
|
|
7522
|
+
{ name: "UnionPay", lengths: [16, 17, 18, 19], test: (d) => /^62/.test(d) },
|
|
7523
|
+
{ name: "Visa", lengths: [13, 16, 19], test: (d) => /^4/.test(d) }
|
|
7524
|
+
];
|
|
7525
|
+
function luhnCheck(digits) {
|
|
7526
|
+
let sum = 0;
|
|
7527
|
+
let shouldDouble = false;
|
|
7528
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
7529
|
+
let d = parseInt(digits[i], 10);
|
|
7530
|
+
if (shouldDouble) {
|
|
7531
|
+
d *= 2;
|
|
7532
|
+
if (d > 9) d -= 9;
|
|
7533
|
+
}
|
|
7534
|
+
sum += d;
|
|
7535
|
+
shouldDouble = !shouldDouble;
|
|
7536
|
+
}
|
|
7537
|
+
return sum % 10 === 0;
|
|
7538
|
+
}
|
|
7539
|
+
function detectCardNetwork(digits) {
|
|
7540
|
+
for (const rule of CARD_NETWORK_RULES) {
|
|
7541
|
+
if (rule.lengths.includes(digits.length) && rule.test(digits)) return rule.name;
|
|
7542
|
+
}
|
|
7543
|
+
return null;
|
|
7544
|
+
}
|
|
7545
|
+
function formatCardNumber(digits, network) {
|
|
7546
|
+
if (network === "American Express") {
|
|
7547
|
+
return `${digits.slice(0, 4)} ${digits.slice(4, 10)} ${digits.slice(10)}`.trim();
|
|
7548
|
+
}
|
|
7549
|
+
return digits.match(/.{1,4}/g)?.join(" ") ?? digits;
|
|
7550
|
+
}
|
|
7551
|
+
function validateCardNumber(input) {
|
|
7552
|
+
if (!input || !input.trim()) return { error: "Input is empty" };
|
|
7553
|
+
const digits = input.replace(/[\s-]/g, "");
|
|
7554
|
+
if (!/^\d+$/.test(digits)) return { error: "Card number must contain only digits, spaces, or hyphens" };
|
|
7555
|
+
if (digits.length < 12 || digits.length > 19) {
|
|
7556
|
+
return { error: `Card number length (${digits.length}) is outside the valid range of 12-19 digits` };
|
|
7557
|
+
}
|
|
7558
|
+
const valid = luhnCheck(digits);
|
|
7559
|
+
const network = detectCardNetwork(digits);
|
|
7560
|
+
const formatted = formatCardNumber(digits, network);
|
|
7561
|
+
return { valid, network, length: digits.length, formatted };
|
|
7562
|
+
}
|
|
7563
|
+
var IBAN_COUNTRY_LENGTHS = {
|
|
7564
|
+
AD: 24,
|
|
7565
|
+
AE: 23,
|
|
7566
|
+
AL: 28,
|
|
7567
|
+
AT: 20,
|
|
7568
|
+
AZ: 28,
|
|
7569
|
+
BA: 20,
|
|
7570
|
+
BE: 16,
|
|
7571
|
+
BG: 22,
|
|
7572
|
+
BH: 22,
|
|
7573
|
+
BR: 29,
|
|
7574
|
+
BY: 28,
|
|
7575
|
+
CH: 21,
|
|
7576
|
+
CR: 22,
|
|
7577
|
+
CY: 28,
|
|
7578
|
+
CZ: 24,
|
|
7579
|
+
DE: 22,
|
|
7580
|
+
DK: 18,
|
|
7581
|
+
DO: 28,
|
|
7582
|
+
EE: 20,
|
|
7583
|
+
EG: 29,
|
|
7584
|
+
ES: 24,
|
|
7585
|
+
FI: 18,
|
|
7586
|
+
FO: 18,
|
|
7587
|
+
FR: 27,
|
|
7588
|
+
GB: 22,
|
|
7589
|
+
GE: 22,
|
|
7590
|
+
GI: 23,
|
|
7591
|
+
GL: 18,
|
|
7592
|
+
GR: 27,
|
|
7593
|
+
GT: 28,
|
|
7594
|
+
HR: 21,
|
|
7595
|
+
HU: 28,
|
|
7596
|
+
IE: 22,
|
|
7597
|
+
IL: 23,
|
|
7598
|
+
IQ: 23,
|
|
7599
|
+
IS: 26,
|
|
7600
|
+
IT: 27,
|
|
7601
|
+
JO: 30,
|
|
7602
|
+
KW: 30,
|
|
7603
|
+
KZ: 20,
|
|
7604
|
+
LB: 28,
|
|
7605
|
+
LC: 32,
|
|
7606
|
+
LI: 21,
|
|
7607
|
+
LT: 20,
|
|
7608
|
+
LU: 20,
|
|
7609
|
+
LV: 21,
|
|
7610
|
+
LY: 25,
|
|
7611
|
+
MC: 27,
|
|
7612
|
+
MD: 24,
|
|
7613
|
+
ME: 22,
|
|
7614
|
+
MK: 19,
|
|
7615
|
+
MR: 27,
|
|
7616
|
+
MT: 31,
|
|
7617
|
+
MU: 30,
|
|
7618
|
+
NL: 18,
|
|
7619
|
+
NO: 15,
|
|
7620
|
+
PK: 24,
|
|
7621
|
+
PL: 28,
|
|
7622
|
+
PS: 29,
|
|
7623
|
+
PT: 25,
|
|
7624
|
+
QA: 29,
|
|
7625
|
+
RO: 24,
|
|
7626
|
+
RS: 22,
|
|
7627
|
+
SA: 24,
|
|
7628
|
+
SC: 31,
|
|
7629
|
+
SE: 24,
|
|
7630
|
+
SI: 19,
|
|
7631
|
+
SK: 24,
|
|
7632
|
+
SM: 27,
|
|
7633
|
+
ST: 25,
|
|
7634
|
+
SV: 28,
|
|
7635
|
+
TL: 23,
|
|
7636
|
+
TN: 24,
|
|
7637
|
+
TR: 26,
|
|
7638
|
+
UA: 29,
|
|
7639
|
+
VA: 22,
|
|
7640
|
+
VG: 24,
|
|
7641
|
+
XK: 20
|
|
7642
|
+
};
|
|
7643
|
+
function ibanMod97(numeric) {
|
|
7644
|
+
let remainder = 0;
|
|
7645
|
+
for (let i = 0; i < numeric.length; i += 7) {
|
|
7646
|
+
remainder = parseInt(String(remainder) + numeric.substr(i, 7), 10) % 97;
|
|
7647
|
+
}
|
|
7648
|
+
return remainder;
|
|
7649
|
+
}
|
|
7650
|
+
function formatIban(cleaned) {
|
|
7651
|
+
return cleaned.match(/.{1,4}/g)?.join(" ") ?? cleaned;
|
|
7652
|
+
}
|
|
7653
|
+
function validateIban(input) {
|
|
7654
|
+
if (!input || !input.trim()) return { error: "Input is empty" };
|
|
7655
|
+
const cleaned = input.replace(/\s/g, "").toUpperCase();
|
|
7656
|
+
if (!/^[A-Z0-9]+$/.test(cleaned)) return { error: "IBAN must contain only letters and digits" };
|
|
7657
|
+
if (cleaned.length < 4 || cleaned.length > 34) {
|
|
7658
|
+
return { error: `IBAN length (${cleaned.length}) is outside the valid range of 4-34 characters` };
|
|
7659
|
+
}
|
|
7660
|
+
if (!/^[A-Z]{2}\d{2}/.test(cleaned)) {
|
|
7661
|
+
return { error: "IBAN must start with a 2-letter country code followed by 2 check digits" };
|
|
7662
|
+
}
|
|
7663
|
+
const countryCode = cleaned.slice(0, 2);
|
|
7664
|
+
const checkDigits = cleaned.slice(2, 4);
|
|
7665
|
+
const bban = cleaned.slice(4);
|
|
7666
|
+
const rearranged = cleaned.slice(4) + cleaned.slice(0, 4);
|
|
7667
|
+
const numeric = rearranged.split("").map((ch) => /[A-Z]/.test(ch) ? String(ch.charCodeAt(0) - 55) : ch).join("");
|
|
7668
|
+
const checksumValid = ibanMod97(numeric) === 1;
|
|
7669
|
+
const expectedLength = IBAN_COUNTRY_LENGTHS[countryCode] ?? null;
|
|
7670
|
+
const lengthValid = expectedLength === null ? null : cleaned.length === expectedLength;
|
|
7671
|
+
const valid = checksumValid && lengthValid !== false;
|
|
7672
|
+
return {
|
|
7673
|
+
valid,
|
|
7674
|
+
formatted: formatIban(cleaned),
|
|
7675
|
+
countryCode,
|
|
7676
|
+
checkDigits,
|
|
7677
|
+
bban,
|
|
7678
|
+
length: cleaned.length,
|
|
7679
|
+
expectedLength,
|
|
7680
|
+
checksumValid,
|
|
7681
|
+
lengthValid
|
|
7682
|
+
};
|
|
7683
|
+
}
|
|
7684
|
+
function round2(n) {
|
|
7685
|
+
return Math.round(n * 100) / 100;
|
|
7686
|
+
}
|
|
7687
|
+
function calculateLoan(principal, annualRatePercent, termMonths) {
|
|
7688
|
+
if (!Number.isFinite(principal) || principal <= 0) return { error: "Principal must be a positive number" };
|
|
7689
|
+
if (!Number.isFinite(annualRatePercent) || annualRatePercent < 0) {
|
|
7690
|
+
return { error: "Annual interest rate must be zero or a positive number" };
|
|
7691
|
+
}
|
|
7692
|
+
if (!Number.isInteger(termMonths) || termMonths <= 0) {
|
|
7693
|
+
return { error: "Term must be a positive whole number of months" };
|
|
7694
|
+
}
|
|
7695
|
+
const monthlyRate = annualRatePercent / 100 / 12;
|
|
7696
|
+
let monthlyPayment;
|
|
7697
|
+
if (monthlyRate === 0) {
|
|
7698
|
+
monthlyPayment = principal / termMonths;
|
|
7699
|
+
} else {
|
|
7700
|
+
const factor = Math.pow(1 + monthlyRate, termMonths);
|
|
7701
|
+
monthlyPayment = principal * monthlyRate * factor / (factor - 1);
|
|
7702
|
+
}
|
|
7703
|
+
const schedule = [];
|
|
7704
|
+
let balance = round2(principal);
|
|
7705
|
+
let totalPayment = 0;
|
|
7706
|
+
for (let month = 1; month <= termMonths; month++) {
|
|
7707
|
+
const interest = monthlyRate === 0 ? 0 : round2(balance * monthlyRate);
|
|
7708
|
+
let principalPortion = round2(monthlyPayment) - interest;
|
|
7709
|
+
if (month === termMonths || principalPortion > balance) principalPortion = balance;
|
|
7710
|
+
const payment = round2(principalPortion + interest);
|
|
7711
|
+
balance = round2(balance - principalPortion);
|
|
7712
|
+
totalPayment += payment;
|
|
7713
|
+
schedule.push({ month, payment, principal: round2(principalPortion), interest, balance: Math.max(balance, 0) });
|
|
7714
|
+
}
|
|
7715
|
+
return {
|
|
7716
|
+
monthlyPayment: round2(monthlyPayment),
|
|
7717
|
+
totalPayment: round2(totalPayment),
|
|
7718
|
+
totalInterest: round2(totalPayment - principal),
|
|
7719
|
+
termMonths,
|
|
7720
|
+
schedule
|
|
7721
|
+
};
|
|
7722
|
+
}
|
|
7500
7723
|
|
|
7501
7724
|
// src/tools/network.ts
|
|
7502
7725
|
var network_exports = {};
|
|
@@ -7531,6 +7754,7 @@ __export(network_exports, {
|
|
|
7531
7754
|
validateDomain: () => validateDomain,
|
|
7532
7755
|
validateHeaderName: () => validateHeaderName,
|
|
7533
7756
|
validateHeaderValue: () => validateHeaderValue,
|
|
7757
|
+
validateRobotsTxt: () => validateRobotsTxt,
|
|
7534
7758
|
validateSitemap: () => validateSitemap
|
|
7535
7759
|
});
|
|
7536
7760
|
var DNS_RECORD_TYPES = ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
|
|
@@ -9029,6 +9253,89 @@ function validateSitemap(xml) {
|
|
|
9029
9253
|
const valid = !issues.some((i) => i.severity === "error");
|
|
9030
9254
|
return { type, urlCount: entries.length, entries, issues, valid };
|
|
9031
9255
|
}
|
|
9256
|
+
var KNOWN_ROBOTS_DIRECTIVES = /* @__PURE__ */ new Set(["user-agent", "disallow", "allow", "sitemap", "crawl-delay", "host"]);
|
|
9257
|
+
function validateRobotsTxt(text) {
|
|
9258
|
+
if (!text || !text.trim()) return { error: "Input is empty" };
|
|
9259
|
+
const lines = text.split("\n");
|
|
9260
|
+
const issues = [];
|
|
9261
|
+
const groups = [];
|
|
9262
|
+
const sitemaps = [];
|
|
9263
|
+
let currentGroup = null;
|
|
9264
|
+
for (let i = 0; i < lines.length; i++) {
|
|
9265
|
+
const rawLine = lines[i];
|
|
9266
|
+
const lineNum = i + 1;
|
|
9267
|
+
const commentIdx = rawLine.indexOf("#");
|
|
9268
|
+
const line = (commentIdx >= 0 ? rawLine.slice(0, commentIdx) : rawLine).trim();
|
|
9269
|
+
if (!line) continue;
|
|
9270
|
+
const colonIdx = line.indexOf(":");
|
|
9271
|
+
if (colonIdx === -1) {
|
|
9272
|
+
issues.push({ severity: "error", line: lineNum, message: `Malformed line (missing ':'): "${line}"` });
|
|
9273
|
+
continue;
|
|
9274
|
+
}
|
|
9275
|
+
const directive = line.slice(0, colonIdx).trim().toLowerCase();
|
|
9276
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
9277
|
+
if (!KNOWN_ROBOTS_DIRECTIVES.has(directive)) {
|
|
9278
|
+
issues.push({ severity: "warning", line: lineNum, message: `Unknown directive "${directive}"` });
|
|
9279
|
+
continue;
|
|
9280
|
+
}
|
|
9281
|
+
if (directive === "sitemap") {
|
|
9282
|
+
if (!/^https?:\/\//i.test(value)) {
|
|
9283
|
+
issues.push({ severity: "error", line: lineNum, message: `Sitemap URL "${value}" must be absolute (start with http:// or https://)` });
|
|
9284
|
+
}
|
|
9285
|
+
sitemaps.push(value);
|
|
9286
|
+
continue;
|
|
9287
|
+
}
|
|
9288
|
+
if (directive === "user-agent") {
|
|
9289
|
+
if (!value) {
|
|
9290
|
+
issues.push({ severity: "error", line: lineNum, message: "User-agent directive is missing a value" });
|
|
9291
|
+
}
|
|
9292
|
+
if (currentGroup && currentGroup.rules.length === 0 && currentGroup.crawlDelay === void 0) {
|
|
9293
|
+
currentGroup.userAgents.push(value);
|
|
9294
|
+
} else {
|
|
9295
|
+
currentGroup = { userAgents: [value], rules: [], line: lineNum };
|
|
9296
|
+
groups.push(currentGroup);
|
|
9297
|
+
}
|
|
9298
|
+
continue;
|
|
9299
|
+
}
|
|
9300
|
+
if (!currentGroup) {
|
|
9301
|
+
issues.push({ severity: "error", line: lineNum, message: `"${directive}" directive found before any User-agent line` });
|
|
9302
|
+
continue;
|
|
9303
|
+
}
|
|
9304
|
+
if (directive === "disallow" || directive === "allow") {
|
|
9305
|
+
if (value !== "" && !value.startsWith("/") && !value.startsWith("*")) {
|
|
9306
|
+
issues.push({ severity: "warning", line: lineNum, message: `${directive === "disallow" ? "Disallow" : "Allow"} value "${value}" should start with "/" (or be empty)` });
|
|
9307
|
+
}
|
|
9308
|
+
if (currentGroup.rules.some((r) => r.type === directive && r.value === value)) {
|
|
9309
|
+
issues.push({ severity: "warning", line: lineNum, message: `Duplicate ${directive} rule for "${value}" in this group` });
|
|
9310
|
+
}
|
|
9311
|
+
currentGroup.rules.push({ type: directive, value, line: lineNum });
|
|
9312
|
+
} else if (directive === "crawl-delay") {
|
|
9313
|
+
const n = Number(value);
|
|
9314
|
+
if (Number.isNaN(n) || n < 0) {
|
|
9315
|
+
issues.push({ severity: "error", line: lineNum, message: `Crawl-delay "${value}" must be a non-negative number` });
|
|
9316
|
+
} else {
|
|
9317
|
+
currentGroup.crawlDelay = n;
|
|
9318
|
+
}
|
|
9319
|
+
}
|
|
9320
|
+
}
|
|
9321
|
+
if (groups.length === 0) {
|
|
9322
|
+
issues.push({ severity: "error", line: 1, message: "No User-agent groups found" });
|
|
9323
|
+
}
|
|
9324
|
+
const seenUA = /* @__PURE__ */ new Map();
|
|
9325
|
+
for (const g of groups) {
|
|
9326
|
+
for (const ua of g.userAgents) {
|
|
9327
|
+
const key = ua.toLowerCase();
|
|
9328
|
+
const firstLine = seenUA.get(key);
|
|
9329
|
+
if (firstLine !== void 0) {
|
|
9330
|
+
issues.push({ severity: "warning", line: g.line, message: `Duplicate User-agent "${ua}" (first seen on line ${firstLine})` });
|
|
9331
|
+
} else {
|
|
9332
|
+
seenUA.set(key, g.line);
|
|
9333
|
+
}
|
|
9334
|
+
}
|
|
9335
|
+
}
|
|
9336
|
+
const valid = !issues.some((i) => i.severity === "error");
|
|
9337
|
+
return { groups, sitemaps, issues, valid };
|
|
9338
|
+
}
|
|
9032
9339
|
|
|
9033
9340
|
// src/tools/api.ts
|
|
9034
9341
|
var api_exports = {};
|
|
@@ -17307,12 +17614,12 @@ function readGpsCoordinate(r, entries, valueTag, refTag) {
|
|
|
17307
17614
|
function gcd2(a, b) {
|
|
17308
17615
|
return b === 0 ? a : gcd2(b, a % b);
|
|
17309
17616
|
}
|
|
17310
|
-
function
|
|
17617
|
+
function round22(n) {
|
|
17311
17618
|
return Math.round(n * 100) / 100;
|
|
17312
17619
|
}
|
|
17313
17620
|
function formatExposureTime(num, den) {
|
|
17314
17621
|
if (num === 0) return "0s";
|
|
17315
|
-
if (num >= den) return `${
|
|
17622
|
+
if (num >= den) return `${round22(num / den)}s`;
|
|
17316
17623
|
const divisor = gcd2(num, den) || 1;
|
|
17317
17624
|
const n = num / divisor;
|
|
17318
17625
|
const d = den / divisor;
|
|
@@ -17401,14 +17708,14 @@ function readExifData(bytes) {
|
|
|
17401
17708
|
const fEntry = findEntry(sub.entries, 33437);
|
|
17402
17709
|
if (fEntry) {
|
|
17403
17710
|
const rat = readRational(r, fEntry);
|
|
17404
|
-
if (rat && rat.den !== 0) result.fNumber =
|
|
17711
|
+
if (rat && rat.den !== 0) result.fNumber = round22(rat.num / rat.den);
|
|
17405
17712
|
}
|
|
17406
17713
|
const isoEntry = findEntry(sub.entries, 34855);
|
|
17407
17714
|
if (isoEntry) result.isoSpeed = tu16(r, isoEntry.valueOffsetField);
|
|
17408
17715
|
const focalEntry = findEntry(sub.entries, 37386);
|
|
17409
17716
|
if (focalEntry) {
|
|
17410
17717
|
const rat = readRational(r, focalEntry);
|
|
17411
|
-
if (rat && rat.den !== 0) result.focalLength =
|
|
17718
|
+
if (rat && rat.den !== 0) result.focalLength = round22(rat.num / rat.den);
|
|
17412
17719
|
}
|
|
17413
17720
|
}
|
|
17414
17721
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,8 +5,8 @@ export { t as text } from './text-Bbx-tZ43.cjs';
|
|
|
5
5
|
export { d as data } from './data-D8XTI7Du.cjs';
|
|
6
6
|
export { g as generators } from './generators-BGtRGpJZ.cjs';
|
|
7
7
|
export { t as time } from './time-DbT8fjaF.cjs';
|
|
8
|
-
export { u as units } from './units-
|
|
9
|
-
export { n as network } from './network-
|
|
8
|
+
export { u as units } from './units-BG387sch.cjs';
|
|
9
|
+
export { n as network } from './network-DaNoZ5ER.cjs';
|
|
10
10
|
export { a as api } from './api-Xl7OzIgq.cjs';
|
|
11
11
|
export { c as code } from './code-BUqyaofO.cjs';
|
|
12
12
|
export { c as color } from './color-tPwZCr9H.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ export { t as text } from './text-Bbx-tZ43.js';
|
|
|
5
5
|
export { d as data } from './data-D8XTI7Du.js';
|
|
6
6
|
export { g as generators } from './generators-BGtRGpJZ.js';
|
|
7
7
|
export { t as time } from './time-DbT8fjaF.js';
|
|
8
|
-
export { u as units } from './units-
|
|
9
|
-
export { n as network } from './network-
|
|
8
|
+
export { u as units } from './units-BG387sch.js';
|
|
9
|
+
export { n as network } from './network-DaNoZ5ER.js';
|
|
10
10
|
export { a as api } from './api-Xl7OzIgq.js';
|
|
11
11
|
export { c as code } from './code-BUqyaofO.js';
|
|
12
12
|
export { c as color } from './color-tPwZCr9H.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { media_exports as media } from './chunk-GUUYEIU6.js';
|
|
2
|
-
export { units_exports as units } from './chunk-
|
|
3
|
-
export { network_exports as network } from './chunk-
|
|
2
|
+
export { units_exports as units } from './chunk-GGDDCTFM.js';
|
|
3
|
+
export { network_exports as network } from './chunk-OB56VNKJ.js';
|
|
4
4
|
export { api_exports as api } from './chunk-Q3B3YWOA.js';
|
|
5
5
|
export { code_exports as code } from './chunk-V5S6OJ4A.js';
|
|
6
6
|
export { color_exports as color } from './chunk-BPVAB4P2.js';
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - http-headers : HTTP header reference lookup and validation
|
|
10
10
|
* - har-viewer : parseHar
|
|
11
11
|
* - sitemap-validator: validateSitemap
|
|
12
|
+
* - robots-txt-validator: validateRobotsTxt
|
|
12
13
|
*/
|
|
13
14
|
declare const DNS_RECORD_TYPES: readonly ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
|
|
14
15
|
type DnsRecordType = typeof DNS_RECORD_TYPES[number];
|
|
@@ -190,6 +191,37 @@ interface SitemapValidationResult {
|
|
|
190
191
|
declare function validateSitemap(xml: string): SitemapValidationResult | {
|
|
191
192
|
error: string;
|
|
192
193
|
};
|
|
194
|
+
interface RobotsRule {
|
|
195
|
+
type: 'allow' | 'disallow';
|
|
196
|
+
value: string;
|
|
197
|
+
line: number;
|
|
198
|
+
}
|
|
199
|
+
interface RobotsGroup {
|
|
200
|
+
userAgents: string[];
|
|
201
|
+
rules: RobotsRule[];
|
|
202
|
+
crawlDelay?: number;
|
|
203
|
+
line: number;
|
|
204
|
+
}
|
|
205
|
+
interface RobotsIssue {
|
|
206
|
+
severity: 'error' | 'warning';
|
|
207
|
+
line: number;
|
|
208
|
+
message: string;
|
|
209
|
+
}
|
|
210
|
+
interface RobotsValidationResult {
|
|
211
|
+
groups: RobotsGroup[];
|
|
212
|
+
sitemaps: string[];
|
|
213
|
+
issues: RobotsIssue[];
|
|
214
|
+
valid: boolean;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate a robots.txt file: parse it into User-agent groups and flag
|
|
218
|
+
* structural mistakes against the de facto robots.txt convention — directives
|
|
219
|
+
* before any User-agent, unknown directives, non-absolute Sitemap URLs,
|
|
220
|
+
* malformed Crawl-delay values, missing leading slashes, and duplicate rules.
|
|
221
|
+
*/
|
|
222
|
+
declare function validateRobotsTxt(text: string): RobotsValidationResult | {
|
|
223
|
+
error: string;
|
|
224
|
+
};
|
|
193
225
|
|
|
194
226
|
declare const network_DNS_RECORD_TYPES: typeof DNS_RECORD_TYPES;
|
|
195
227
|
type network_DnsRecord = DnsRecord;
|
|
@@ -204,6 +236,10 @@ type network_HeaderCategory = HeaderCategory;
|
|
|
204
236
|
type network_HttpHeader = HttpHeader;
|
|
205
237
|
type network_ParsedDnsResult = ParsedDnsResult;
|
|
206
238
|
type network_ParsedGeoResult = ParsedGeoResult;
|
|
239
|
+
type network_RobotsGroup = RobotsGroup;
|
|
240
|
+
type network_RobotsIssue = RobotsIssue;
|
|
241
|
+
type network_RobotsRule = RobotsRule;
|
|
242
|
+
type network_RobotsValidationResult = RobotsValidationResult;
|
|
207
243
|
declare const network_STATUS_CODES: typeof STATUS_CODES;
|
|
208
244
|
type network_SitemapIndexEntry = SitemapIndexEntry;
|
|
209
245
|
type network_SitemapIssue = SitemapIssue;
|
|
@@ -237,9 +273,10 @@ declare const network_typeNumberToLabel: typeof typeNumberToLabel;
|
|
|
237
273
|
declare const network_validateDomain: typeof validateDomain;
|
|
238
274
|
declare const network_validateHeaderName: typeof validateHeaderName;
|
|
239
275
|
declare const network_validateHeaderValue: typeof validateHeaderValue;
|
|
276
|
+
declare const network_validateRobotsTxt: typeof validateRobotsTxt;
|
|
240
277
|
declare const network_validateSitemap: typeof validateSitemap;
|
|
241
278
|
declare namespace network {
|
|
242
|
-
export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateSitemap as validateSitemap };
|
|
279
|
+
export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, type network_RobotsGroup as RobotsGroup, type network_RobotsIssue as RobotsIssue, type network_RobotsRule as RobotsRule, type network_RobotsValidationResult as RobotsValidationResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateRobotsTxt as validateRobotsTxt, network_validateSitemap as validateSitemap };
|
|
243
280
|
}
|
|
244
281
|
|
|
245
|
-
export {
|
|
282
|
+
export { getHeadersByCategory as A, getStatusByCategory as B, getStatusCode as C, DNS_RECORD_TYPES as D, isClientError as E, isServerError as F, type GeoResult as G, HTTP_HEADERS as H, isSuccess as I, isValidIp as J, isValidIpv4 as K, isValidIpv6 as L, parseDnsResponse as M, parseGeoResponse as N, parseHar as O, type ParsedDnsResult as P, searchHeaders as Q, type RobotsGroup as R, STATUS_CODES as S, searchStatusCodes as T, statusCodeToText as U, typeNumberToLabel as V, validateDomain as W, validateHeaderName as X, validateHeaderValue as Y, validateRobotsTxt as Z, validateSitemap as _, type DnsRecord as a, type DnsRecordType as b, type DnsResponse as c, type HarEntry as d, type HarParseResult as e, type HarSummary as f, type HeaderCategory as g, type HttpHeader as h, type ParsedGeoResult as i, type RobotsIssue as j, type RobotsRule as k, type RobotsValidationResult as l, type SitemapIndexEntry as m, network as n, type SitemapIssue as o, type SitemapUrlEntry as p, type SitemapValidationResult as q, type StatusCode as r, buildDnsQueryUrl as s, buildGeoUrl as t, buildMapUrl as u, countryCodeToFlag as v, formatCoordinates as w, formatTtl as x, getByCategory as y, getHeader as z };
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - http-headers : HTTP header reference lookup and validation
|
|
10
10
|
* - har-viewer : parseHar
|
|
11
11
|
* - sitemap-validator: validateSitemap
|
|
12
|
+
* - robots-txt-validator: validateRobotsTxt
|
|
12
13
|
*/
|
|
13
14
|
declare const DNS_RECORD_TYPES: readonly ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
|
|
14
15
|
type DnsRecordType = typeof DNS_RECORD_TYPES[number];
|
|
@@ -190,6 +191,37 @@ interface SitemapValidationResult {
|
|
|
190
191
|
declare function validateSitemap(xml: string): SitemapValidationResult | {
|
|
191
192
|
error: string;
|
|
192
193
|
};
|
|
194
|
+
interface RobotsRule {
|
|
195
|
+
type: 'allow' | 'disallow';
|
|
196
|
+
value: string;
|
|
197
|
+
line: number;
|
|
198
|
+
}
|
|
199
|
+
interface RobotsGroup {
|
|
200
|
+
userAgents: string[];
|
|
201
|
+
rules: RobotsRule[];
|
|
202
|
+
crawlDelay?: number;
|
|
203
|
+
line: number;
|
|
204
|
+
}
|
|
205
|
+
interface RobotsIssue {
|
|
206
|
+
severity: 'error' | 'warning';
|
|
207
|
+
line: number;
|
|
208
|
+
message: string;
|
|
209
|
+
}
|
|
210
|
+
interface RobotsValidationResult {
|
|
211
|
+
groups: RobotsGroup[];
|
|
212
|
+
sitemaps: string[];
|
|
213
|
+
issues: RobotsIssue[];
|
|
214
|
+
valid: boolean;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate a robots.txt file: parse it into User-agent groups and flag
|
|
218
|
+
* structural mistakes against the de facto robots.txt convention — directives
|
|
219
|
+
* before any User-agent, unknown directives, non-absolute Sitemap URLs,
|
|
220
|
+
* malformed Crawl-delay values, missing leading slashes, and duplicate rules.
|
|
221
|
+
*/
|
|
222
|
+
declare function validateRobotsTxt(text: string): RobotsValidationResult | {
|
|
223
|
+
error: string;
|
|
224
|
+
};
|
|
193
225
|
|
|
194
226
|
declare const network_DNS_RECORD_TYPES: typeof DNS_RECORD_TYPES;
|
|
195
227
|
type network_DnsRecord = DnsRecord;
|
|
@@ -204,6 +236,10 @@ type network_HeaderCategory = HeaderCategory;
|
|
|
204
236
|
type network_HttpHeader = HttpHeader;
|
|
205
237
|
type network_ParsedDnsResult = ParsedDnsResult;
|
|
206
238
|
type network_ParsedGeoResult = ParsedGeoResult;
|
|
239
|
+
type network_RobotsGroup = RobotsGroup;
|
|
240
|
+
type network_RobotsIssue = RobotsIssue;
|
|
241
|
+
type network_RobotsRule = RobotsRule;
|
|
242
|
+
type network_RobotsValidationResult = RobotsValidationResult;
|
|
207
243
|
declare const network_STATUS_CODES: typeof STATUS_CODES;
|
|
208
244
|
type network_SitemapIndexEntry = SitemapIndexEntry;
|
|
209
245
|
type network_SitemapIssue = SitemapIssue;
|
|
@@ -237,9 +273,10 @@ declare const network_typeNumberToLabel: typeof typeNumberToLabel;
|
|
|
237
273
|
declare const network_validateDomain: typeof validateDomain;
|
|
238
274
|
declare const network_validateHeaderName: typeof validateHeaderName;
|
|
239
275
|
declare const network_validateHeaderValue: typeof validateHeaderValue;
|
|
276
|
+
declare const network_validateRobotsTxt: typeof validateRobotsTxt;
|
|
240
277
|
declare const network_validateSitemap: typeof validateSitemap;
|
|
241
278
|
declare namespace network {
|
|
242
|
-
export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateSitemap as validateSitemap };
|
|
279
|
+
export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, type network_RobotsGroup as RobotsGroup, type network_RobotsIssue as RobotsIssue, type network_RobotsRule as RobotsRule, type network_RobotsValidationResult as RobotsValidationResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateRobotsTxt as validateRobotsTxt, network_validateSitemap as validateSitemap };
|
|
243
280
|
}
|
|
244
281
|
|
|
245
|
-
export {
|
|
282
|
+
export { getHeadersByCategory as A, getStatusByCategory as B, getStatusCode as C, DNS_RECORD_TYPES as D, isClientError as E, isServerError as F, type GeoResult as G, HTTP_HEADERS as H, isSuccess as I, isValidIp as J, isValidIpv4 as K, isValidIpv6 as L, parseDnsResponse as M, parseGeoResponse as N, parseHar as O, type ParsedDnsResult as P, searchHeaders as Q, type RobotsGroup as R, STATUS_CODES as S, searchStatusCodes as T, statusCodeToText as U, typeNumberToLabel as V, validateDomain as W, validateHeaderName as X, validateHeaderValue as Y, validateRobotsTxt as Z, validateSitemap as _, type DnsRecord as a, type DnsRecordType as b, type DnsResponse as c, type HarEntry as d, type HarParseResult as e, type HarSummary as f, type HeaderCategory as g, type HttpHeader as h, type ParsedGeoResult as i, type RobotsIssue as j, type RobotsRule as k, type RobotsValidationResult as l, type SitemapIndexEntry as m, network as n, type SitemapIssue as o, type SitemapUrlEntry as p, type SitemapValidationResult as q, type StatusCode as r, buildDnsQueryUrl as s, buildGeoUrl as t, buildMapUrl as u, countryCodeToFlag as v, formatCoordinates as w, formatTtl as x, getByCategory as y, getHeader as z };
|
package/dist/tools/network.cjs
CHANGED
|
@@ -1497,6 +1497,89 @@ function validateSitemap(xml) {
|
|
|
1497
1497
|
const valid = !issues.some((i) => i.severity === "error");
|
|
1498
1498
|
return { type, urlCount: entries.length, entries, issues, valid };
|
|
1499
1499
|
}
|
|
1500
|
+
var KNOWN_ROBOTS_DIRECTIVES = /* @__PURE__ */ new Set(["user-agent", "disallow", "allow", "sitemap", "crawl-delay", "host"]);
|
|
1501
|
+
function validateRobotsTxt(text) {
|
|
1502
|
+
if (!text || !text.trim()) return { error: "Input is empty" };
|
|
1503
|
+
const lines = text.split("\n");
|
|
1504
|
+
const issues = [];
|
|
1505
|
+
const groups = [];
|
|
1506
|
+
const sitemaps = [];
|
|
1507
|
+
let currentGroup = null;
|
|
1508
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1509
|
+
const rawLine = lines[i];
|
|
1510
|
+
const lineNum = i + 1;
|
|
1511
|
+
const commentIdx = rawLine.indexOf("#");
|
|
1512
|
+
const line = (commentIdx >= 0 ? rawLine.slice(0, commentIdx) : rawLine).trim();
|
|
1513
|
+
if (!line) continue;
|
|
1514
|
+
const colonIdx = line.indexOf(":");
|
|
1515
|
+
if (colonIdx === -1) {
|
|
1516
|
+
issues.push({ severity: "error", line: lineNum, message: `Malformed line (missing ':'): "${line}"` });
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
const directive = line.slice(0, colonIdx).trim().toLowerCase();
|
|
1520
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
1521
|
+
if (!KNOWN_ROBOTS_DIRECTIVES.has(directive)) {
|
|
1522
|
+
issues.push({ severity: "warning", line: lineNum, message: `Unknown directive "${directive}"` });
|
|
1523
|
+
continue;
|
|
1524
|
+
}
|
|
1525
|
+
if (directive === "sitemap") {
|
|
1526
|
+
if (!/^https?:\/\//i.test(value)) {
|
|
1527
|
+
issues.push({ severity: "error", line: lineNum, message: `Sitemap URL "${value}" must be absolute (start with http:// or https://)` });
|
|
1528
|
+
}
|
|
1529
|
+
sitemaps.push(value);
|
|
1530
|
+
continue;
|
|
1531
|
+
}
|
|
1532
|
+
if (directive === "user-agent") {
|
|
1533
|
+
if (!value) {
|
|
1534
|
+
issues.push({ severity: "error", line: lineNum, message: "User-agent directive is missing a value" });
|
|
1535
|
+
}
|
|
1536
|
+
if (currentGroup && currentGroup.rules.length === 0 && currentGroup.crawlDelay === void 0) {
|
|
1537
|
+
currentGroup.userAgents.push(value);
|
|
1538
|
+
} else {
|
|
1539
|
+
currentGroup = { userAgents: [value], rules: [], line: lineNum };
|
|
1540
|
+
groups.push(currentGroup);
|
|
1541
|
+
}
|
|
1542
|
+
continue;
|
|
1543
|
+
}
|
|
1544
|
+
if (!currentGroup) {
|
|
1545
|
+
issues.push({ severity: "error", line: lineNum, message: `"${directive}" directive found before any User-agent line` });
|
|
1546
|
+
continue;
|
|
1547
|
+
}
|
|
1548
|
+
if (directive === "disallow" || directive === "allow") {
|
|
1549
|
+
if (value !== "" && !value.startsWith("/") && !value.startsWith("*")) {
|
|
1550
|
+
issues.push({ severity: "warning", line: lineNum, message: `${directive === "disallow" ? "Disallow" : "Allow"} value "${value}" should start with "/" (or be empty)` });
|
|
1551
|
+
}
|
|
1552
|
+
if (currentGroup.rules.some((r) => r.type === directive && r.value === value)) {
|
|
1553
|
+
issues.push({ severity: "warning", line: lineNum, message: `Duplicate ${directive} rule for "${value}" in this group` });
|
|
1554
|
+
}
|
|
1555
|
+
currentGroup.rules.push({ type: directive, value, line: lineNum });
|
|
1556
|
+
} else if (directive === "crawl-delay") {
|
|
1557
|
+
const n = Number(value);
|
|
1558
|
+
if (Number.isNaN(n) || n < 0) {
|
|
1559
|
+
issues.push({ severity: "error", line: lineNum, message: `Crawl-delay "${value}" must be a non-negative number` });
|
|
1560
|
+
} else {
|
|
1561
|
+
currentGroup.crawlDelay = n;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
if (groups.length === 0) {
|
|
1566
|
+
issues.push({ severity: "error", line: 1, message: "No User-agent groups found" });
|
|
1567
|
+
}
|
|
1568
|
+
const seenUA = /* @__PURE__ */ new Map();
|
|
1569
|
+
for (const g of groups) {
|
|
1570
|
+
for (const ua of g.userAgents) {
|
|
1571
|
+
const key = ua.toLowerCase();
|
|
1572
|
+
const firstLine = seenUA.get(key);
|
|
1573
|
+
if (firstLine !== void 0) {
|
|
1574
|
+
issues.push({ severity: "warning", line: g.line, message: `Duplicate User-agent "${ua}" (first seen on line ${firstLine})` });
|
|
1575
|
+
} else {
|
|
1576
|
+
seenUA.set(key, g.line);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
const valid = !issues.some((i) => i.severity === "error");
|
|
1581
|
+
return { groups, sitemaps, issues, valid };
|
|
1582
|
+
}
|
|
1500
1583
|
|
|
1501
1584
|
exports.DNS_RECORD_TYPES = DNS_RECORD_TYPES;
|
|
1502
1585
|
exports.HTTP_HEADERS = HTTP_HEADERS;
|
|
@@ -1528,4 +1611,5 @@ exports.typeNumberToLabel = typeNumberToLabel;
|
|
|
1528
1611
|
exports.validateDomain = validateDomain;
|
|
1529
1612
|
exports.validateHeaderName = validateHeaderName;
|
|
1530
1613
|
exports.validateHeaderValue = validateHeaderValue;
|
|
1614
|
+
exports.validateRobotsTxt = validateRobotsTxt;
|
|
1531
1615
|
exports.validateSitemap = validateSitemap;
|
package/dist/tools/network.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { D as DNS_RECORD_TYPES, a as DnsRecord, b as DnsRecordType, c as DnsResponse, G as GeoResult, H as HTTP_HEADERS, d as HarEntry, e as HarParseResult, f as HarSummary, g as HeaderCategory, h as HttpHeader, P as ParsedDnsResult, i as ParsedGeoResult, S as STATUS_CODES,
|
|
1
|
+
export { D as DNS_RECORD_TYPES, a as DnsRecord, b as DnsRecordType, c as DnsResponse, G as GeoResult, H as HTTP_HEADERS, d as HarEntry, e as HarParseResult, f as HarSummary, g as HeaderCategory, h as HttpHeader, P as ParsedDnsResult, i as ParsedGeoResult, R as RobotsGroup, j as RobotsIssue, k as RobotsRule, l as RobotsValidationResult, S as STATUS_CODES, m as SitemapIndexEntry, o as SitemapIssue, p as SitemapUrlEntry, q as SitemapValidationResult, r as StatusCode, s as buildDnsQueryUrl, t as buildGeoUrl, u as buildMapUrl, v as countryCodeToFlag, w as formatCoordinates, x as formatTtl, y as getByCategory, z as getHeader, A as getHeadersByCategory, B as getStatusByCategory, C as getStatusCode, E as isClientError, F as isServerError, I as isSuccess, J as isValidIp, K as isValidIpv4, L as isValidIpv6, M as parseDnsResponse, N as parseGeoResponse, O as parseHar, Q as searchHeaders, T as searchStatusCodes, U as statusCodeToText, V as typeNumberToLabel, W as validateDomain, X as validateHeaderName, Y as validateHeaderValue, Z as validateRobotsTxt, _ as validateSitemap } from '../network-DaNoZ5ER.cjs';
|