@jk2908/mdsrc 0.4.0 → 0.5.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 +14 -0
- package/README.md +77 -22
- package/dist/index.d.ts +42 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +409 -177
- package/dist/index.js.map +7 -5
- package/dist/types.d.ts +9 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.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,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0 - 2026-06-25
|
|
4
|
+
|
|
5
|
+
- Added multi-type support using pipe syntax: `'string|number'`. The first matching type wins.
|
|
6
|
+
- Added validation modifiers via pipe syntax: `'string|min=3|max=6'`, `'number|min=18'`, `'date|max=1735689600000'`, `'array|min=2'`.
|
|
7
|
+
- Added `array` as a supported primitive type with `min`/`max` length modifiers.
|
|
8
|
+
- Added `BAD_MODIFIER` issue code for unparseable modifier values.
|
|
9
|
+
- Multi-type fields return a single `INVALID_TYPE` issue listing all attempted types when no type matches.
|
|
10
|
+
- Fixed date modifier parsing — modifier values are now correctly converted to numbers before being passed to `new Date()`.
|
|
11
|
+
- Moved validation logic into `src/validate.ts`.
|
|
12
|
+
|
|
13
|
+
## 0.4.1 - 2026-06-23
|
|
14
|
+
|
|
15
|
+
- Updated README to reflect the new schema API and removed outdated markdown-it references.
|
|
16
|
+
|
|
3
17
|
## 0.4.0 - 2026-06-23
|
|
4
18
|
|
|
5
19
|
- Breaking: replaced the verbose schema API with a simplified string-based syntax. Fields are now declared as `fieldName: 'type'` instead of `fieldName: { type: 'type' }`, optional fields use a `?` suffix (e.g. `'metadata?'`), and nested objects are declared inline without a `schema` wrapper.
|
package/README.md
CHANGED
|
@@ -11,27 +11,19 @@ npm install @jk2908/mdsrc
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import plugin
|
|
15
|
-
import comark from '@comark/markdown-it'
|
|
14
|
+
import plugin from '@jk2908/mdsrc'
|
|
16
15
|
import { defineConfig } from 'vite'
|
|
17
16
|
|
|
18
|
-
const markdownItConfig: MarkdownItConfig = {
|
|
19
|
-
linkify: true,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
17
|
export default defineConfig({
|
|
23
18
|
plugins: [
|
|
24
19
|
plugin({
|
|
25
|
-
markdown: {
|
|
26
|
-
plugins: [comark],
|
|
27
|
-
config: markdownItConfig,
|
|
28
|
-
},
|
|
29
20
|
collections: [
|
|
30
21
|
{
|
|
31
22
|
dir: 'content',
|
|
32
23
|
name: 'post',
|
|
33
24
|
schema: {
|
|
34
|
-
title:
|
|
25
|
+
title: 'string',
|
|
26
|
+
'date?': 'date',
|
|
35
27
|
},
|
|
36
28
|
},
|
|
37
29
|
],
|
|
@@ -40,18 +32,82 @@ export default defineConfig({
|
|
|
40
32
|
})
|
|
41
33
|
```
|
|
42
34
|
|
|
43
|
-
The plugin reads markdown content, validates frontmatter against your schema, and generates typed modules during build and watch. Root config uses `collections`, optional `
|
|
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`.
|
|
36
|
+
|
|
37
|
+
### Schema
|
|
38
|
+
|
|
39
|
+
Fields are declared as `fieldName: 'type'`. Supported types: `string`, `number`, `boolean`, `date`, `array`.
|
|
40
|
+
|
|
41
|
+
Optional fields use a `?` suffix: `'metadata?': { author: 'string' }`.
|
|
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:
|
|
44
52
|
|
|
45
|
-
|
|
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
|
+
|
|
74
|
+
Nested objects are declared inline:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
schema: {
|
|
78
|
+
title: 'string',
|
|
79
|
+
'metadata?': {
|
|
80
|
+
author: 'string',
|
|
81
|
+
publishedAt: 'date',
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Compile Options
|
|
87
|
+
|
|
88
|
+
Pass `compileOptions` to customise markdown parsing via satteri:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
plugin({
|
|
92
|
+
compileOptions: {
|
|
93
|
+
features: {
|
|
94
|
+
gfm: true, // tables, footnotes, strikethrough, task lists
|
|
95
|
+
frontmatter: true, // YAML (---) and TOML (+++)
|
|
96
|
+
math: false, // LaTeX math blocks
|
|
97
|
+
smartPunctuation: true, // curly quotes, em-dashes, ellipses
|
|
98
|
+
},
|
|
99
|
+
mdastPlugins: [/* transform mdast tree */],
|
|
100
|
+
hastPlugins: [/* transform hast tree */],
|
|
101
|
+
},
|
|
102
|
+
collections: [/* ... */],
|
|
103
|
+
})
|
|
104
|
+
```
|
|
46
105
|
|
|
47
|
-
|
|
48
|
-
- Raw HTML is escaped by default because the renderer runs with `html: false`.
|
|
49
|
-
- `markdown` preserves the original body for custom renderers like `@comark/react`.
|
|
106
|
+
See [satteri](https://satteri.bruits.org/) for the full list of compile options and feature toggles.
|
|
50
107
|
|
|
51
|
-
|
|
52
|
-
`MarkdownItConfig` is re-exported from `@jk2908/mdsrc`, and `markdown.config` is merged with the default renderer options `{ html: false, breaks: true }`.
|
|
108
|
+
### Output
|
|
53
109
|
|
|
54
|
-
|
|
110
|
+
Each entry exports a `body` field containing the rendered HTML.
|
|
55
111
|
|
|
56
112
|
If you configure a collection with `name: 'post'`, `mdsrc` exposes `allPosts` from the package root.
|
|
57
113
|
|
|
@@ -61,8 +117,7 @@ import { allPosts } from '@jk2908/mdsrc'
|
|
|
61
117
|
export const summaries = allPosts.map(post => ({
|
|
62
118
|
title: post.title,
|
|
63
119
|
slug: post.__mdsrc.slug,
|
|
64
|
-
|
|
65
|
-
markdown: post.markdown,
|
|
120
|
+
body: post.body,
|
|
66
121
|
}))
|
|
67
122
|
```
|
|
68
123
|
|
|
@@ -76,4 +131,4 @@ The generated files live in `./.mdsrc` on disk, so you can import them directly
|
|
|
76
131
|
|
|
77
132
|
## License
|
|
78
133
|
|
|
79
|
-
MIT
|
|
134
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,57 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
|
-
import
|
|
2
|
+
import { type MarkdownToHtmlResult } from 'satteri';
|
|
3
|
+
import type { BuildContext, PluginConfig, Schema } from './types.js';
|
|
4
|
+
export declare const DEFAULT_COMPILE_OPTIONS: {
|
|
5
|
+
features: {
|
|
6
|
+
frontmatter: true;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
3
9
|
export type { 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;
|
|
10
50
|
/**
|
|
11
51
|
* Build the Vite plugin that validates collections and writes the generated modules
|
|
12
52
|
* keep the runtime data and declaration files in the same pass
|
|
13
53
|
* resolve package imports from the generated directory
|
|
14
54
|
*/
|
|
15
55
|
export default function mdsrc(config: PluginConfig): Plugin;
|
|
56
|
+
export declare function toModuleName(name: string): string;
|
|
16
57
|
//# 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,EAAuC,KAAK,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAExF,OAAO,KAAK,EAAE,YAAY,EAAc,YAAY,EAAO,MAAM,EAAE,MAAM,YAAY,CAAA;AAMrF,eAAO,MAAM,uBAAuB;;;;CAIV,CAAA;AAE1B,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;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,kBAgDnE;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;AAqJD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAgJ1D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,UAExC"}
|