@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 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, { type MarkdownItConfig } from '@jk2908/mdsrc'
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: { type: 'string' },
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 `markdown`, and `logger`. Collection config uses `name`, `dir`, and `schema`.
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
- Each entry exports both `html` and `markdown`.
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
- - `html` is rendered with `markdown-it-ts`, with hard line breaks preserved by default.
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
- Use `markdown.plugins` for `markdown-it-ts` compatible plugins, and `markdown.config` to pass renderer options.
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
- See `examples/basic` for the default HTML output flow and `examples/components` for the shared `@comark/markdown-it` plugin used with React.
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
- html: post.html,
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 type { BuildContext, PluginConfig } from './types.js';
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
@@ -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;AAIjD,OAAO,KAAK,EACX,YAAY,EAIZ,YAAY,EAIZ,MAAM,YAAY,CAAA;AAanB,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAoBhD;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,kBAgDnE;AA4VD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAoJ1D"}
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"}