lintmax 0.1.15

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.

Potentially problematic release.


This version of lintmax might be problematic. Click here for more details.

@@ -0,0 +1,168 @@
1
+ //#region src/normalize.ts
2
+ const normalizeIgnorePattern = ({ pattern }) => {
3
+ const trimmed = pattern.trim();
4
+ if (trimmed.length === 0) return "";
5
+ return trimmed.startsWith("./") ? trimmed.slice(2) : trimmed;
6
+ };
7
+ const normalizePathListInput = ({ allowUndefined = false, label, value }) => {
8
+ if (value === void 0 && allowUndefined) return [];
9
+ if (!Array.isArray(value)) throw new Error(`${label} must be an array of strings`);
10
+ const out = [];
11
+ const arr = value;
12
+ for (let i = 0; i < arr.length; i += 1) {
13
+ const item = arr[i];
14
+ if (typeof item !== "string") throw new Error(`${label}[${i}] must be a string`);
15
+ const normalized = normalizeIgnorePattern({ pattern: item });
16
+ if (normalized.length === 0) throw new Error(`${label}[${i}] must not be empty`);
17
+ if (!out.includes(normalized)) out.push(normalized);
18
+ }
19
+ return out;
20
+ };
21
+ const hasPlainObjectPrototype = ({ value }) => {
22
+ const prototype = Object.getPrototypeOf(value);
23
+ return prototype === null || prototype === Object.prototype;
24
+ };
25
+ const isObjectLike = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26
+ const isRecord = (value) => isObjectLike(value) && hasPlainObjectPrototype({ value });
27
+ const assertObject = ({ label, value }) => {
28
+ if (!isRecord(value)) throw new Error(`${label} must be an object`);
29
+ return value;
30
+ };
31
+ const assertOptionalString = ({ label, value }) => {
32
+ if (value !== void 0 && typeof value !== "string") throw new Error(`${label} must be a string`);
33
+ };
34
+ const stripPluginNamespace = ({ rule }) => rule.includes("/") ? rule.slice(rule.indexOf("/") + 1) : rule;
35
+ const findUnknownRules = ({ knownRules, normalizeRule, rules }) => {
36
+ const unknown = [];
37
+ for (const rule of Object.keys(rules)) {
38
+ const normalized = normalizeRule ? normalizeRule(rule) : rule;
39
+ if (!knownRules.has(normalized)) unknown.push(rule);
40
+ }
41
+ return unknown;
42
+ };
43
+ const assertJsonSerializable = ({ label, seen, value }) => {
44
+ if (value === null) return;
45
+ if (typeof value === "string" || typeof value === "boolean") return;
46
+ if (typeof value === "number") {
47
+ if (!Number.isFinite(value)) throw new Error(`${label} must be JSON-serializable`);
48
+ return;
49
+ }
50
+ if (typeof value !== "object") throw new Error(`${label} must be JSON-serializable`);
51
+ const objectValue = value;
52
+ const objectSeen = seen ?? /* @__PURE__ */ new WeakSet();
53
+ if (objectSeen.has(objectValue)) throw new Error(`${label} must be JSON-serializable`);
54
+ objectSeen.add(objectValue);
55
+ try {
56
+ if (Array.isArray(value)) {
57
+ for (let i = 0; i < value.length; i += 1) assertJsonSerializable({
58
+ label: `${label}[${i}]`,
59
+ seen: objectSeen,
60
+ value: value[i]
61
+ });
62
+ return;
63
+ }
64
+ if (!isRecord(value)) throw new Error(`${label} must be JSON-serializable`);
65
+ for (const [key, nested] of Object.entries(value)) assertJsonSerializable({
66
+ label: `${label}.${key}`,
67
+ seen: objectSeen,
68
+ value: nested
69
+ });
70
+ } finally {
71
+ objectSeen.delete(objectValue);
72
+ }
73
+ };
74
+ const normalizeObjectListInput = ({ allowNonPlain = false, label, value }) => {
75
+ if (value === void 0) return [];
76
+ if (!Array.isArray(value)) throw new Error(`${label} must be an array of objects`);
77
+ const out = [];
78
+ const arr = value;
79
+ for (let i = 0; i < arr.length; i += 1) {
80
+ const item = arr[i];
81
+ let normalizedItem;
82
+ if (allowNonPlain) {
83
+ if (isObjectLike(item)) normalizedItem = item;
84
+ } else if (isRecord(item)) normalizedItem = item;
85
+ if (!normalizedItem) throw new Error(`${label}[${i}] must be an object`);
86
+ out.push(normalizedItem);
87
+ }
88
+ return out;
89
+ };
90
+ const normalizeRulesOffInput = ({ label, value }) => {
91
+ if (value === void 0) return;
92
+ if (!Array.isArray(value)) throw new Error(`${label} must be an array of rule names`);
93
+ const out = {};
94
+ const arr = value;
95
+ for (let i = 0; i < arr.length; i += 1) {
96
+ const item = arr[i];
97
+ if (typeof item !== "string") throw new Error(`${label}[${i}] must be a string rule name`);
98
+ const ruleName = item.trim();
99
+ if (ruleName.length === 0) throw new Error(`${label}[${i}] must not be empty`);
100
+ out[ruleName] = "off";
101
+ }
102
+ const sorted = {};
103
+ for (const key of Object.keys(out).toSorted((a, b) => a.localeCompare(b))) sorted[key] = "off";
104
+ return sorted;
105
+ };
106
+ const normalizeTailwindOption = ({ label, value }) => {
107
+ if (value === void 0) return;
108
+ if (typeof value === "boolean" || typeof value === "string") return value;
109
+ throw new Error(`${label} must be a string, true, or false`);
110
+ };
111
+ const warnToError = (rules) => {
112
+ const result = {};
113
+ for (const [key, value] of Object.entries(rules)) if (value === void 0) result[key] = "error";
114
+ else if (value === "warn" || value === 1) result[key] = "error";
115
+ else if (Array.isArray(value) && (value[0] === "warn" || value[0] === 1)) result[key] = ["error", ...value.slice(1)];
116
+ else result[key] = value;
117
+ return result;
118
+ };
119
+ //#endregion
120
+ //#region src/path.ts
121
+ const DRIVE_PATH_REGEX = /^[A-Za-z]:\//u;
122
+ const MULTI_SLASH_REGEX = /\/+/gu;
123
+ const normalizeSlashes = (value) => value.replaceAll("\\", "/");
124
+ const trimLeadingSlash = (value) => {
125
+ let result = value;
126
+ while (result.startsWith("/")) result = result.slice(1);
127
+ return result;
128
+ };
129
+ const trimTrailingSlash = (value) => {
130
+ let result = value;
131
+ while (result.endsWith("/") && result.length > 1) result = result.slice(0, -1);
132
+ return result;
133
+ };
134
+ const fromFileUrl = (value) => {
135
+ if (!value.startsWith("file://")) return normalizeSlashes(value);
136
+ const normalized = normalizeSlashes(decodeURIComponent(new URL(value).pathname));
137
+ if (DRIVE_PATH_REGEX.test(normalized.slice(1))) return normalized.slice(1);
138
+ return normalized;
139
+ };
140
+ const joinPath = (...parts) => {
141
+ if (parts.length === 0) return "";
142
+ const normalizedParts = [];
143
+ for (const part of parts) {
144
+ const normalized = normalizeSlashes(part);
145
+ if (normalized.length > 0) normalizedParts.push(normalized);
146
+ }
147
+ if (normalizedParts.length === 0) return "";
148
+ const first = normalizedParts[0] ?? "";
149
+ const isAbsolute = first.startsWith("/") || DRIVE_PATH_REGEX.test(first);
150
+ const [head, ...tail] = normalizedParts;
151
+ const segments = [trimTrailingSlash(head ?? "")];
152
+ for (const segment of tail) segments.push(trimLeadingSlash(trimTrailingSlash(segment)));
153
+ const joined = segments.join("/").replace(MULTI_SLASH_REGEX, "/");
154
+ return isAbsolute && !joined.startsWith("/") && !DRIVE_PATH_REGEX.test(joined) ? `/${joined}` : joined;
155
+ };
156
+ const dirnamePath = (value) => {
157
+ const normalized = trimTrailingSlash(normalizeSlashes(value));
158
+ const lastSlash = normalized.lastIndexOf("/");
159
+ if (lastSlash === -1) return ".";
160
+ if (lastSlash === 0) return "/";
161
+ return normalized.slice(0, lastSlash);
162
+ };
163
+ const isAbsolutePath = (value) => {
164
+ const normalized = normalizeSlashes(value);
165
+ return normalized.startsWith("/") || DRIVE_PATH_REGEX.test(normalized);
166
+ };
167
+ //#endregion
168
+ export { assertJsonSerializable as a, findUnknownRules as c, normalizeObjectListInput as d, normalizePathListInput as f, warnToError as g, stripPluginNamespace as h, joinPath as i, isRecord as l, normalizeTailwindOption as m, fromFileUrl as n, assertObject as o, normalizeRulesOffInput as p, isAbsolutePath as r, assertOptionalString as s, dirnamePath as t, normalizeIgnorePattern as u };