@jk2908/mdsrc 0.4.1 → 0.6.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 +19 -0
- package/README.md +54 -4
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +47 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +524 -193
- package/dist/index.js.map +8 -6
- package/dist/types.d.ts +41 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +6 -0
- package/dist/utils.js.map +1 -1
- package/dist/validate.d.ts +18 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +366 -0
- package/dist/validate.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.0 - 2026-07-01
|
|
4
|
+
|
|
5
|
+
- For Markdown files, non-frontmatter content is now available on the `html` field, replacing `body`.
|
|
6
|
+
- Added support for `.mdx` files. MDX entries now generate a `Component` field instead of `html`.
|
|
7
|
+
- Added cleanup to remove stale generated files and empty directories when source files are removed or renamed.
|
|
8
|
+
- Improved pluralisation for generated collection names and types.
|
|
9
|
+
|
|
10
|
+
## 0.5.0 - 2026-06-25
|
|
11
|
+
|
|
12
|
+
- Added multi-type support using pipe syntax: `'string|number'`. The first matching type wins.
|
|
13
|
+
- Added validation modifiers via pipe syntax: `'string|min=3|max=6'`, `'number|min=18'`, `'date|max=1735689600000'`, `'array|min=2'`.
|
|
14
|
+
- Added `array` as a supported primitive type with `min`/`max` length modifiers.
|
|
15
|
+
- Added `BAD_MODIFIER` issue code for unparseable modifier values.
|
|
16
|
+
- Added `INVALID_LENGTH` issue code for string and array length constraint failures.
|
|
17
|
+
- Added `INVALID_SIZE` issue code for number value constraint failures.
|
|
18
|
+
- Single-type fields now return specific issue codes (e.g. `INVALID_DATE` for invalid dates, `INVALID_TYPE` for wrong type) instead of a generic message.
|
|
19
|
+
- Multi-type fields return a single `INVALID_TYPE` issue listing all attempted types when no type matches.
|
|
20
|
+
- Moved validation logic into `src/validate.ts`.
|
|
21
|
+
|
|
3
22
|
## 0.4.1 - 2026-06-23
|
|
4
23
|
|
|
5
24
|
- Updated README to reflect the new schema API and removed outdated markdown-it references.
|
package/README.md
CHANGED
|
@@ -32,14 +32,45 @@ export default defineConfig({
|
|
|
32
32
|
})
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
The plugin reads markdown content, validates frontmatter against your schema, and generates typed modules during build and watch. Root config uses `collections`, optional `compileOptions`, and `logger`. Collection config uses `name`, `dir`, and `schema`.
|
|
35
|
+
The plugin reads markdown and MDX content, validates frontmatter against your schema, and generates typed modules during build and watch. Root config uses `collections`, optional `compileOptions`, and `logger`. Collection config uses `name`, `dir`, and `schema`.
|
|
36
36
|
|
|
37
37
|
### Schema
|
|
38
38
|
|
|
39
|
-
Fields are declared as `fieldName: 'type'`. Supported types: `string`, `number`, `boolean`, `date`, `
|
|
39
|
+
Fields are declared as `fieldName: 'type'`. Supported types: `string`, `number`, `boolean`, `date`, `array`.
|
|
40
40
|
|
|
41
41
|
Optional fields use a `?` suffix: `'metadata?': { author: 'string' }`.
|
|
42
42
|
|
|
43
|
+
Multiple types can be combined with `|`:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
schema: {
|
|
47
|
+
val: 'string|number',
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Validation modifiers are supported:
|
|
52
|
+
|
|
53
|
+
- `min`:
|
|
54
|
+
- strings: minimum string length
|
|
55
|
+
- numbers: minimum value
|
|
56
|
+
- dates: earliest allowed date
|
|
57
|
+
- arrays: minimum array length
|
|
58
|
+
|
|
59
|
+
- `max`:
|
|
60
|
+
- strings: maximum string length
|
|
61
|
+
- numbers: maximum value
|
|
62
|
+
- dates: latest allowed date
|
|
63
|
+
- arrays: maximum array length
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
schema: {
|
|
67
|
+
title: 'string|min=3|max=6',
|
|
68
|
+
age: 'number|min=18',
|
|
69
|
+
date: 'date|max=1735689600000',
|
|
70
|
+
tags: 'array|min=2',
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
43
74
|
Nested objects are declared inline:
|
|
44
75
|
|
|
45
76
|
```ts
|
|
@@ -76,7 +107,7 @@ See [satteri](https://satteri.bruits.org/) for the full list of compile options
|
|
|
76
107
|
|
|
77
108
|
### Output
|
|
78
109
|
|
|
79
|
-
Each entry exports a `
|
|
110
|
+
Each entry exports a `html` field containing the rendered HTML for markdown files, or a `Component` field for MDX files.
|
|
80
111
|
|
|
81
112
|
If you configure a collection with `name: 'post'`, `mdsrc` exposes `allPosts` from the package root.
|
|
82
113
|
|
|
@@ -86,10 +117,29 @@ import { allPosts } from '@jk2908/mdsrc'
|
|
|
86
117
|
export const summaries = allPosts.map(post => ({
|
|
87
118
|
title: post.title,
|
|
88
119
|
slug: post.__mdsrc.slug,
|
|
89
|
-
|
|
120
|
+
html: post.html,
|
|
90
121
|
}))
|
|
91
122
|
```
|
|
92
123
|
|
|
124
|
+
#### Using MDX Components
|
|
125
|
+
|
|
126
|
+
For `.mdx` files, the generated entry includes a `Component` that you can render in your application. You can also pass custom components to it.
|
|
127
|
+
|
|
128
|
+
For example, to render a post and provide a custom `h1` component:
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
import { allPosts } from '@jk2908/mdsrc'
|
|
132
|
+
|
|
133
|
+
const post = allPosts.find(p => p.__mdsrc.slug === 'my-first-post')
|
|
134
|
+
const H1 = ({ children }) => <h1 style={{ color: 'red' }}>{children}</h1>
|
|
135
|
+
|
|
136
|
+
export function Post() {
|
|
137
|
+
if (!post || !post.Component) return <div>Not found</div>
|
|
138
|
+
|
|
139
|
+
return <post.Component components={{ h1: H1 }} />
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
93
143
|
If you want the generated collection module directly, you can also import the collection subpath.
|
|
94
144
|
|
|
95
145
|
```ts
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,UAAU,CAAA;AAC3B,eAAO,MAAM,QAAQ,kBAAoB,CAAA;AACzC,eAAO,MAAM,aAAa,WAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,UAAU,CAAA;AAC3B,eAAO,MAAM,QAAQ,kBAAoB,CAAA;AACzC,eAAO,MAAM,aAAa,WAAa,CAAA;AACvC,eAAO,MAAM,WAAW,+BAAiC,CAAA"}
|
package/dist/config.js
CHANGED
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAA;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,IAAI,EAAE,CAAA;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,IAAI,EAAE,CAAA"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAA;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,IAAI,EAAE,CAAA;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,IAAI,EAAE,CAAA;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,IAAI,EAAE,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,61 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import { type MarkdownToHtmlResult } from 'satteri';
|
|
3
|
+
import type { BuildContext, Manifest, PluginConfig, Schema } from './types.js';
|
|
4
|
+
export declare const DEFAULT_COMPILE_OPTIONS: {
|
|
5
|
+
features: {
|
|
6
|
+
frontmatter: true;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export type { Collection, CompileOptions } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Parse YAML or TOML frontmatter
|
|
12
|
+
*/
|
|
13
|
+
export declare function parse(frontmatter: MarkdownToHtmlResult['frontmatter']): Promise<any>;
|
|
4
14
|
/**
|
|
5
15
|
* Read every markdown file in a collection and turn it into the raw entry shape
|
|
6
16
|
* add mdsrc metadata like slug and filename alongside the trimmed body
|
|
7
17
|
* return an empty list if the directory read fails
|
|
8
18
|
*/
|
|
9
19
|
export declare function create(dir: string, buildContext: BuildContext): Promise<any[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Returns whether the error was caused by a missing file or directory
|
|
22
|
+
*/
|
|
23
|
+
export declare function isENOENT(err: unknown): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* LRU cache for file content. Stores the last written content per file path
|
|
26
|
+
* so `maybeWrite` can skip disk I/O when nothing has changed.
|
|
27
|
+
*
|
|
28
|
+
* Uses Map insertion order to track recency: the front of the map holds the
|
|
29
|
+
* least recently used entries, which are evicted first when the cache is full.
|
|
30
|
+
*/
|
|
31
|
+
export declare const fileCache: Map<string, string>;
|
|
32
|
+
export declare const FILE_CACHE_MAX_SIZE = 100;
|
|
33
|
+
/**
|
|
34
|
+
* Promote an existing cache entry to most-recently-used by deleting and
|
|
35
|
+
* re-inserting it, which moves it to the end of the Map's iteration
|
|
36
|
+
* order. If the cache is at capacity, evict the least recently used
|
|
37
|
+
* entry (front) before inserting
|
|
38
|
+
*/
|
|
39
|
+
export declare function setFileCache(filePath: string, content: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve a cached value and promote it to most-recently-used so it won't
|
|
42
|
+
* be evicted while still actively referenced
|
|
43
|
+
*/
|
|
44
|
+
export declare function getFileCache(filePath: string): string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Write a file only if the content has changed since the last build
|
|
47
|
+
*/
|
|
48
|
+
export declare function maybeWrite(filePath: string, content: string): Promise<boolean>;
|
|
49
|
+
export declare function schemaToType(schema: Schema): string;
|
|
50
|
+
export declare function getManifest(outDir: string): Promise<{
|
|
51
|
+
[k: string]: string[];
|
|
52
|
+
} | null>;
|
|
53
|
+
export declare function cleanup(outDir: string, manifest: Manifest, prevManifest: Manifest | null): Promise<boolean>;
|
|
10
54
|
/**
|
|
11
55
|
* Build the Vite plugin that validates collections and writes the generated modules
|
|
12
56
|
* keep the runtime data and declaration files in the same pass
|
|
13
57
|
* resolve package imports from the generated directory
|
|
14
58
|
*/
|
|
15
59
|
export default function mdsrc(config: PluginConfig): Plugin;
|
|
60
|
+
export declare function toModuleName(name: string): string;
|
|
16
61
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAEjD,OAAO,EAIN,KAAK,oBAAoB,EACzB,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EAEX,YAAY,EAEZ,QAAQ,EAER,YAAY,EAEZ,MAAM,EACN,MAAM,YAAY,CAAA;AAanB,eAAO,MAAM,uBAAuB;;;;CAIV,CAAA;AAI1B,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5D;;GAEG;AACH,wBAAsB,KAAK,CAAC,WAAW,EAAE,oBAAoB,CAAC,aAAa,CAAC,gBAa3E;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,kBA+DnE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,WAEpC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,qBAA4B,CAAA;AAElD,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAY7D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,sBAQ5C;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAyBjE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,UAoB1C;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM;;UAiB/C;AAED,wBAAsB,OAAO,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,QAAQ,GAAG,IAAI,oBAsC7B;AAiND;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAgJ1D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,UAExC"}
|