@yukyu30/fluorite 0.1.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/LICENSE +21 -0
- package/README.md +209 -0
- package/dist/chunk-2QW4LSG5.js +484 -0
- package/dist/chunk-2QW4LSG5.js.map +1 -0
- package/dist/cli.cjs +573 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +93 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +529 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +226 -0
- package/dist/index.d.ts +226 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluent, chainable assertions for a single frontmatter key.
|
|
3
|
+
*
|
|
4
|
+
* Each terminal matcher records one {@link RuleResult} on the parent
|
|
5
|
+
* {@link Recorder} and returns `this`, so matchers can be chained:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* fm.key("title").required().type("string").lengthMin(10);
|
|
9
|
+
* fm.key("tags").not.has("ng");
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* The `.not` modifier negates only the next matcher, then resets.
|
|
13
|
+
*/
|
|
14
|
+
declare class KeyAssertion {
|
|
15
|
+
#private;
|
|
16
|
+
private readonly recorder;
|
|
17
|
+
private readonly key;
|
|
18
|
+
private readonly value;
|
|
19
|
+
private readonly present;
|
|
20
|
+
constructor(recorder: Recorder, key: string, value: unknown, present: boolean);
|
|
21
|
+
/** Negate the next matcher in the chain. */
|
|
22
|
+
get not(): this;
|
|
23
|
+
/** The raw value (resolved against the sentinel) used by matchers. */
|
|
24
|
+
private get resolved();
|
|
25
|
+
/**
|
|
26
|
+
* Record a result, applying the pending `.not` negation, then reset it.
|
|
27
|
+
*/
|
|
28
|
+
private record;
|
|
29
|
+
/** Assert the key exists in the frontmatter. */
|
|
30
|
+
required(): this;
|
|
31
|
+
/** Alias of {@link required}. */
|
|
32
|
+
exists(): this;
|
|
33
|
+
/** Assert the value is of the given type. */
|
|
34
|
+
type(expected: ValueType): this;
|
|
35
|
+
/** Assert the value strictly equals `expected` (deep for arrays/objects). */
|
|
36
|
+
eq(expected: unknown): this;
|
|
37
|
+
/**
|
|
38
|
+
* Assert the value is an array whose every element is in `allowed` (enum).
|
|
39
|
+
*
|
|
40
|
+
* Designed for catching tag notation drift: define the canonical set once
|
|
41
|
+
* and any stray / mistyped value is reported.
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* fm.key("tags").subsetOf(["ok", "release", "blog"]);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
subsetOf(allowed: readonly unknown[]): this;
|
|
48
|
+
/** Alias of {@link subsetOf}. */
|
|
49
|
+
only(allowed: readonly unknown[]): this;
|
|
50
|
+
/**
|
|
51
|
+
* Apply matchers to every element of an array value.
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* fm.key("tags").each.oneOf(["ok", "release"]);
|
|
55
|
+
* fm.key("tags").each.matches(/^[a-z0-9-]+$/);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
get each(): EachAssertion;
|
|
59
|
+
/** Assert the value is one of `allowed` (enum). */
|
|
60
|
+
oneOf(allowed: readonly unknown[]): this;
|
|
61
|
+
/** Assert a string value matches the given regular expression. */
|
|
62
|
+
matches(pattern: RegExp): this;
|
|
63
|
+
/** Assert an array contains `item`, or a string contains the substring. */
|
|
64
|
+
has(item: unknown): this;
|
|
65
|
+
/** Assert an array/string contains all of `items`. */
|
|
66
|
+
hasAll(items: readonly unknown[]): this;
|
|
67
|
+
/** Assert an array/string contains at least one of `items`. */
|
|
68
|
+
hasAny(items: readonly unknown[]): this;
|
|
69
|
+
/** Assert the string/array length equals `n`. */
|
|
70
|
+
length(n: number): this;
|
|
71
|
+
/** Assert the string/array length is at least `n`. */
|
|
72
|
+
lengthMin(n: number): this;
|
|
73
|
+
/** Assert the string/array length is at most `n`. */
|
|
74
|
+
lengthMax(n: number): this;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Applies matchers to every element of an array frontmatter value.
|
|
78
|
+
*
|
|
79
|
+
* Obtained via {@link KeyAssertion.each}. Each terminal matcher records a
|
|
80
|
+
* single {@link RuleResult}: it passes only when the value is an array and
|
|
81
|
+
* every element satisfies the matcher; failures list the offending elements.
|
|
82
|
+
*/
|
|
83
|
+
declare class EachAssertion {
|
|
84
|
+
#private;
|
|
85
|
+
private readonly recorder;
|
|
86
|
+
private readonly key;
|
|
87
|
+
private readonly value;
|
|
88
|
+
constructor(recorder: Recorder, key: string, value: unknown, negated: boolean);
|
|
89
|
+
/** Negate the next matcher in the chain. */
|
|
90
|
+
get not(): this;
|
|
91
|
+
private record;
|
|
92
|
+
/** Every element must be one of `allowed` (enum over array contents). */
|
|
93
|
+
oneOf(allowed: readonly unknown[]): this;
|
|
94
|
+
/** Every element must be of the given type. */
|
|
95
|
+
type(expected: ValueType): this;
|
|
96
|
+
/** Every (string) element must match the pattern. */
|
|
97
|
+
matches(pattern: RegExp): this;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The `fm` object passed to a rule set. Holds the parsed frontmatter data,
|
|
102
|
+
* hands out {@link KeyAssertion} instances via {@link key}, and accumulates
|
|
103
|
+
* every {@link RuleResult} the matchers record.
|
|
104
|
+
*/
|
|
105
|
+
declare class Recorder {
|
|
106
|
+
readonly data: Record<string, unknown>;
|
|
107
|
+
readonly results: RuleResult[];
|
|
108
|
+
constructor(data: Record<string, unknown>);
|
|
109
|
+
/** Begin a chain of assertions against the given frontmatter key. */
|
|
110
|
+
key(name: string): KeyAssertion;
|
|
111
|
+
/** Internal: append a recorded rule result. */
|
|
112
|
+
push(result: RuleResult): void;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The set of value types understood by the `type()` matcher. */
|
|
116
|
+
type ValueType = "string" | "number" | "boolean" | "array" | "object" | "null";
|
|
117
|
+
/** Result of a single matcher invocation against one key. */
|
|
118
|
+
interface RuleResult {
|
|
119
|
+
/** The frontmatter key that was inspected, e.g. `"tags"`. */
|
|
120
|
+
key: string;
|
|
121
|
+
/** The matcher name, e.g. `"has"` or `"lengthMin"`. */
|
|
122
|
+
rule: string;
|
|
123
|
+
/** Whether the check passed. */
|
|
124
|
+
ok: boolean;
|
|
125
|
+
/** Whether the matcher was reached through `.not`. */
|
|
126
|
+
negated: boolean;
|
|
127
|
+
/** Human readable description of the outcome. */
|
|
128
|
+
message: string;
|
|
129
|
+
/** The actual value found at `key`. */
|
|
130
|
+
value: unknown;
|
|
131
|
+
/** The expected value / argument passed to the matcher, if any. */
|
|
132
|
+
expected?: unknown;
|
|
133
|
+
}
|
|
134
|
+
/** Aggregated outcome of running a rule set against one frontmatter object. */
|
|
135
|
+
interface CheckResult {
|
|
136
|
+
/** True when every recorded rule passed. */
|
|
137
|
+
ok: boolean;
|
|
138
|
+
/** Every rule result, in the order they were recorded. */
|
|
139
|
+
results: RuleResult[];
|
|
140
|
+
/** Only the failing rule results. */
|
|
141
|
+
failures: RuleResult[];
|
|
142
|
+
/** The parsed frontmatter data. */
|
|
143
|
+
data: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
/** A rule set: receives the recorder (`fm`) and registers matchers. */
|
|
146
|
+
type RulesFn = (fm: Recorder) => void;
|
|
147
|
+
/** Configuration accepted by `defineConfig` / consumed by the CLI. */
|
|
148
|
+
interface FluoriteConfig {
|
|
149
|
+
/** Glob patterns of Markdown files to check. */
|
|
150
|
+
include?: string[];
|
|
151
|
+
/** Glob patterns to exclude. */
|
|
152
|
+
exclude?: string[];
|
|
153
|
+
/** The rule set applied to every file's frontmatter. */
|
|
154
|
+
rules: RulesFn;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Run a rule set against the frontmatter of a Markdown source string.
|
|
159
|
+
*
|
|
160
|
+
* Never throws: malformed YAML or a missing frontmatter block is surfaced as a
|
|
161
|
+
* failing {@link RuleResult} so results can always be collected and reported.
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* const result = check(markdown, (fm) => {
|
|
165
|
+
* fm.key("title").required().lengthMin(10);
|
|
166
|
+
* fm.key("tags").not.has("ng");
|
|
167
|
+
* });
|
|
168
|
+
* if (!result.ok) console.error(result.failures);
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
declare function check(source: string, rules: RulesFn): CheckResult;
|
|
172
|
+
/** Run a rule set against already-parsed frontmatter data. */
|
|
173
|
+
declare function checkData(data: Record<string, unknown>, rules: RulesFn): CheckResult;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Identity helper for authoring a config file with full type inference:
|
|
177
|
+
*
|
|
178
|
+
* ```ts
|
|
179
|
+
* import { defineConfig } from "fluorite";
|
|
180
|
+
* export default defineConfig({
|
|
181
|
+
* include: ["docs/**\/*.md"],
|
|
182
|
+
* rules: (fm) => fm.key("title").required(),
|
|
183
|
+
* });
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
declare function defineConfig(config: FluoriteConfig): FluoriteConfig;
|
|
187
|
+
/**
|
|
188
|
+
* Locate a config file: an explicit path, or the first conventional name found
|
|
189
|
+
* in `cwd`. Returns `undefined` when none is found.
|
|
190
|
+
*/
|
|
191
|
+
declare function resolveConfigPath(explicit: string | undefined, cwd?: string): Promise<string | undefined>;
|
|
192
|
+
/** Dynamically import a config file and return its default export. */
|
|
193
|
+
declare function loadConfig(path: string): Promise<FluoriteConfig>;
|
|
194
|
+
|
|
195
|
+
/** Outcome of parsing frontmatter out of a Markdown source string. */
|
|
196
|
+
interface ParseResult {
|
|
197
|
+
/** Parsed frontmatter data (empty object when none / on error). */
|
|
198
|
+
data: Record<string, unknown>;
|
|
199
|
+
/** The Markdown body following the frontmatter block. */
|
|
200
|
+
content: string;
|
|
201
|
+
/** Whether a frontmatter block was present at all. */
|
|
202
|
+
hasFrontmatter: boolean;
|
|
203
|
+
/** Parse error message, if the frontmatter (YAML) was malformed. */
|
|
204
|
+
error?: string;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Extract frontmatter from a Markdown source string.
|
|
208
|
+
*
|
|
209
|
+
* Never throws: malformed YAML is reported via the `error` field so callers
|
|
210
|
+
* can record it as a failure rather than crash.
|
|
211
|
+
*/
|
|
212
|
+
declare function parseFrontmatter(source: string): ParseResult;
|
|
213
|
+
|
|
214
|
+
/** A check result paired with the file it came from. */
|
|
215
|
+
interface FileReport {
|
|
216
|
+
file: string;
|
|
217
|
+
result: CheckResult;
|
|
218
|
+
}
|
|
219
|
+
interface FormatOptions {
|
|
220
|
+
/** Suppress per-file lines for passing files. */
|
|
221
|
+
quiet?: boolean;
|
|
222
|
+
}
|
|
223
|
+
/** Format file reports into a human-readable, colorized string. */
|
|
224
|
+
declare function formatReports(reports: FileReport[], options?: FormatOptions): string;
|
|
225
|
+
|
|
226
|
+
export { type CheckResult, EachAssertion, type FileReport, type FluoriteConfig, type FormatOptions, KeyAssertion, type ParseResult, Recorder, type RuleResult, type RulesFn, type ValueType, check, checkData, defineConfig, formatReports, loadConfig, parseFrontmatter, resolveConfigPath };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluent, chainable assertions for a single frontmatter key.
|
|
3
|
+
*
|
|
4
|
+
* Each terminal matcher records one {@link RuleResult} on the parent
|
|
5
|
+
* {@link Recorder} and returns `this`, so matchers can be chained:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* fm.key("title").required().type("string").lengthMin(10);
|
|
9
|
+
* fm.key("tags").not.has("ng");
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* The `.not` modifier negates only the next matcher, then resets.
|
|
13
|
+
*/
|
|
14
|
+
declare class KeyAssertion {
|
|
15
|
+
#private;
|
|
16
|
+
private readonly recorder;
|
|
17
|
+
private readonly key;
|
|
18
|
+
private readonly value;
|
|
19
|
+
private readonly present;
|
|
20
|
+
constructor(recorder: Recorder, key: string, value: unknown, present: boolean);
|
|
21
|
+
/** Negate the next matcher in the chain. */
|
|
22
|
+
get not(): this;
|
|
23
|
+
/** The raw value (resolved against the sentinel) used by matchers. */
|
|
24
|
+
private get resolved();
|
|
25
|
+
/**
|
|
26
|
+
* Record a result, applying the pending `.not` negation, then reset it.
|
|
27
|
+
*/
|
|
28
|
+
private record;
|
|
29
|
+
/** Assert the key exists in the frontmatter. */
|
|
30
|
+
required(): this;
|
|
31
|
+
/** Alias of {@link required}. */
|
|
32
|
+
exists(): this;
|
|
33
|
+
/** Assert the value is of the given type. */
|
|
34
|
+
type(expected: ValueType): this;
|
|
35
|
+
/** Assert the value strictly equals `expected` (deep for arrays/objects). */
|
|
36
|
+
eq(expected: unknown): this;
|
|
37
|
+
/**
|
|
38
|
+
* Assert the value is an array whose every element is in `allowed` (enum).
|
|
39
|
+
*
|
|
40
|
+
* Designed for catching tag notation drift: define the canonical set once
|
|
41
|
+
* and any stray / mistyped value is reported.
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* fm.key("tags").subsetOf(["ok", "release", "blog"]);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
subsetOf(allowed: readonly unknown[]): this;
|
|
48
|
+
/** Alias of {@link subsetOf}. */
|
|
49
|
+
only(allowed: readonly unknown[]): this;
|
|
50
|
+
/**
|
|
51
|
+
* Apply matchers to every element of an array value.
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* fm.key("tags").each.oneOf(["ok", "release"]);
|
|
55
|
+
* fm.key("tags").each.matches(/^[a-z0-9-]+$/);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
get each(): EachAssertion;
|
|
59
|
+
/** Assert the value is one of `allowed` (enum). */
|
|
60
|
+
oneOf(allowed: readonly unknown[]): this;
|
|
61
|
+
/** Assert a string value matches the given regular expression. */
|
|
62
|
+
matches(pattern: RegExp): this;
|
|
63
|
+
/** Assert an array contains `item`, or a string contains the substring. */
|
|
64
|
+
has(item: unknown): this;
|
|
65
|
+
/** Assert an array/string contains all of `items`. */
|
|
66
|
+
hasAll(items: readonly unknown[]): this;
|
|
67
|
+
/** Assert an array/string contains at least one of `items`. */
|
|
68
|
+
hasAny(items: readonly unknown[]): this;
|
|
69
|
+
/** Assert the string/array length equals `n`. */
|
|
70
|
+
length(n: number): this;
|
|
71
|
+
/** Assert the string/array length is at least `n`. */
|
|
72
|
+
lengthMin(n: number): this;
|
|
73
|
+
/** Assert the string/array length is at most `n`. */
|
|
74
|
+
lengthMax(n: number): this;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Applies matchers to every element of an array frontmatter value.
|
|
78
|
+
*
|
|
79
|
+
* Obtained via {@link KeyAssertion.each}. Each terminal matcher records a
|
|
80
|
+
* single {@link RuleResult}: it passes only when the value is an array and
|
|
81
|
+
* every element satisfies the matcher; failures list the offending elements.
|
|
82
|
+
*/
|
|
83
|
+
declare class EachAssertion {
|
|
84
|
+
#private;
|
|
85
|
+
private readonly recorder;
|
|
86
|
+
private readonly key;
|
|
87
|
+
private readonly value;
|
|
88
|
+
constructor(recorder: Recorder, key: string, value: unknown, negated: boolean);
|
|
89
|
+
/** Negate the next matcher in the chain. */
|
|
90
|
+
get not(): this;
|
|
91
|
+
private record;
|
|
92
|
+
/** Every element must be one of `allowed` (enum over array contents). */
|
|
93
|
+
oneOf(allowed: readonly unknown[]): this;
|
|
94
|
+
/** Every element must be of the given type. */
|
|
95
|
+
type(expected: ValueType): this;
|
|
96
|
+
/** Every (string) element must match the pattern. */
|
|
97
|
+
matches(pattern: RegExp): this;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The `fm` object passed to a rule set. Holds the parsed frontmatter data,
|
|
102
|
+
* hands out {@link KeyAssertion} instances via {@link key}, and accumulates
|
|
103
|
+
* every {@link RuleResult} the matchers record.
|
|
104
|
+
*/
|
|
105
|
+
declare class Recorder {
|
|
106
|
+
readonly data: Record<string, unknown>;
|
|
107
|
+
readonly results: RuleResult[];
|
|
108
|
+
constructor(data: Record<string, unknown>);
|
|
109
|
+
/** Begin a chain of assertions against the given frontmatter key. */
|
|
110
|
+
key(name: string): KeyAssertion;
|
|
111
|
+
/** Internal: append a recorded rule result. */
|
|
112
|
+
push(result: RuleResult): void;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The set of value types understood by the `type()` matcher. */
|
|
116
|
+
type ValueType = "string" | "number" | "boolean" | "array" | "object" | "null";
|
|
117
|
+
/** Result of a single matcher invocation against one key. */
|
|
118
|
+
interface RuleResult {
|
|
119
|
+
/** The frontmatter key that was inspected, e.g. `"tags"`. */
|
|
120
|
+
key: string;
|
|
121
|
+
/** The matcher name, e.g. `"has"` or `"lengthMin"`. */
|
|
122
|
+
rule: string;
|
|
123
|
+
/** Whether the check passed. */
|
|
124
|
+
ok: boolean;
|
|
125
|
+
/** Whether the matcher was reached through `.not`. */
|
|
126
|
+
negated: boolean;
|
|
127
|
+
/** Human readable description of the outcome. */
|
|
128
|
+
message: string;
|
|
129
|
+
/** The actual value found at `key`. */
|
|
130
|
+
value: unknown;
|
|
131
|
+
/** The expected value / argument passed to the matcher, if any. */
|
|
132
|
+
expected?: unknown;
|
|
133
|
+
}
|
|
134
|
+
/** Aggregated outcome of running a rule set against one frontmatter object. */
|
|
135
|
+
interface CheckResult {
|
|
136
|
+
/** True when every recorded rule passed. */
|
|
137
|
+
ok: boolean;
|
|
138
|
+
/** Every rule result, in the order they were recorded. */
|
|
139
|
+
results: RuleResult[];
|
|
140
|
+
/** Only the failing rule results. */
|
|
141
|
+
failures: RuleResult[];
|
|
142
|
+
/** The parsed frontmatter data. */
|
|
143
|
+
data: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
/** A rule set: receives the recorder (`fm`) and registers matchers. */
|
|
146
|
+
type RulesFn = (fm: Recorder) => void;
|
|
147
|
+
/** Configuration accepted by `defineConfig` / consumed by the CLI. */
|
|
148
|
+
interface FluoriteConfig {
|
|
149
|
+
/** Glob patterns of Markdown files to check. */
|
|
150
|
+
include?: string[];
|
|
151
|
+
/** Glob patterns to exclude. */
|
|
152
|
+
exclude?: string[];
|
|
153
|
+
/** The rule set applied to every file's frontmatter. */
|
|
154
|
+
rules: RulesFn;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Run a rule set against the frontmatter of a Markdown source string.
|
|
159
|
+
*
|
|
160
|
+
* Never throws: malformed YAML or a missing frontmatter block is surfaced as a
|
|
161
|
+
* failing {@link RuleResult} so results can always be collected and reported.
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* const result = check(markdown, (fm) => {
|
|
165
|
+
* fm.key("title").required().lengthMin(10);
|
|
166
|
+
* fm.key("tags").not.has("ng");
|
|
167
|
+
* });
|
|
168
|
+
* if (!result.ok) console.error(result.failures);
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
declare function check(source: string, rules: RulesFn): CheckResult;
|
|
172
|
+
/** Run a rule set against already-parsed frontmatter data. */
|
|
173
|
+
declare function checkData(data: Record<string, unknown>, rules: RulesFn): CheckResult;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Identity helper for authoring a config file with full type inference:
|
|
177
|
+
*
|
|
178
|
+
* ```ts
|
|
179
|
+
* import { defineConfig } from "fluorite";
|
|
180
|
+
* export default defineConfig({
|
|
181
|
+
* include: ["docs/**\/*.md"],
|
|
182
|
+
* rules: (fm) => fm.key("title").required(),
|
|
183
|
+
* });
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
declare function defineConfig(config: FluoriteConfig): FluoriteConfig;
|
|
187
|
+
/**
|
|
188
|
+
* Locate a config file: an explicit path, or the first conventional name found
|
|
189
|
+
* in `cwd`. Returns `undefined` when none is found.
|
|
190
|
+
*/
|
|
191
|
+
declare function resolveConfigPath(explicit: string | undefined, cwd?: string): Promise<string | undefined>;
|
|
192
|
+
/** Dynamically import a config file and return its default export. */
|
|
193
|
+
declare function loadConfig(path: string): Promise<FluoriteConfig>;
|
|
194
|
+
|
|
195
|
+
/** Outcome of parsing frontmatter out of a Markdown source string. */
|
|
196
|
+
interface ParseResult {
|
|
197
|
+
/** Parsed frontmatter data (empty object when none / on error). */
|
|
198
|
+
data: Record<string, unknown>;
|
|
199
|
+
/** The Markdown body following the frontmatter block. */
|
|
200
|
+
content: string;
|
|
201
|
+
/** Whether a frontmatter block was present at all. */
|
|
202
|
+
hasFrontmatter: boolean;
|
|
203
|
+
/** Parse error message, if the frontmatter (YAML) was malformed. */
|
|
204
|
+
error?: string;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Extract frontmatter from a Markdown source string.
|
|
208
|
+
*
|
|
209
|
+
* Never throws: malformed YAML is reported via the `error` field so callers
|
|
210
|
+
* can record it as a failure rather than crash.
|
|
211
|
+
*/
|
|
212
|
+
declare function parseFrontmatter(source: string): ParseResult;
|
|
213
|
+
|
|
214
|
+
/** A check result paired with the file it came from. */
|
|
215
|
+
interface FileReport {
|
|
216
|
+
file: string;
|
|
217
|
+
result: CheckResult;
|
|
218
|
+
}
|
|
219
|
+
interface FormatOptions {
|
|
220
|
+
/** Suppress per-file lines for passing files. */
|
|
221
|
+
quiet?: boolean;
|
|
222
|
+
}
|
|
223
|
+
/** Format file reports into a human-readable, colorized string. */
|
|
224
|
+
declare function formatReports(reports: FileReport[], options?: FormatOptions): string;
|
|
225
|
+
|
|
226
|
+
export { type CheckResult, EachAssertion, type FileReport, type FluoriteConfig, type FormatOptions, KeyAssertion, type ParseResult, Recorder, type RuleResult, type RulesFn, type ValueType, check, checkData, defineConfig, formatReports, loadConfig, parseFrontmatter, resolveConfigPath };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EachAssertion,
|
|
3
|
+
KeyAssertion,
|
|
4
|
+
Recorder,
|
|
5
|
+
check,
|
|
6
|
+
checkData,
|
|
7
|
+
defineConfig,
|
|
8
|
+
formatReports,
|
|
9
|
+
loadConfig,
|
|
10
|
+
parseFrontmatter,
|
|
11
|
+
resolveConfigPath
|
|
12
|
+
} from "./chunk-2QW4LSG5.js";
|
|
13
|
+
export {
|
|
14
|
+
EachAssertion,
|
|
15
|
+
KeyAssertion,
|
|
16
|
+
Recorder,
|
|
17
|
+
check,
|
|
18
|
+
checkData,
|
|
19
|
+
defineConfig,
|
|
20
|
+
formatReports,
|
|
21
|
+
loadConfig,
|
|
22
|
+
parseFrontmatter,
|
|
23
|
+
resolveConfigPath
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yukyu30/fluorite",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Inspect and validate Markdown frontmatter with a readable, chainable DSL — usable as a library and a CLI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "yukyu30",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/yukyu30/fluorite.git"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"frontmatter",
|
|
14
|
+
"markdown",
|
|
15
|
+
"yaml",
|
|
16
|
+
"validation",
|
|
17
|
+
"linter",
|
|
18
|
+
"cli"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"fluorite": "./dist/cli.js"
|
|
22
|
+
},
|
|
23
|
+
"main": "./dist/index.cjs",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js",
|
|
30
|
+
"require": "./dist/index.cjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"typecheck": "tsc --noEmit",
|
|
47
|
+
"prepublishOnly": "npm run build"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"gray-matter": "^4.0.3",
|
|
51
|
+
"picocolors": "^1.1.1",
|
|
52
|
+
"tinyglobby": "^0.2.10"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^22.10.0",
|
|
56
|
+
"tsup": "^8.3.5",
|
|
57
|
+
"typescript": "^5.7.2",
|
|
58
|
+
"vitest": "^2.1.8"
|
|
59
|
+
}
|
|
60
|
+
}
|