@amamo/mdx 0.2.0 → 0.4.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/README.md +102 -39
- package/dist/compiler.d.ts +5 -1
- package/dist/compiler.js +113 -22
- package/dist/config.d.ts +9 -7
- package/dist/config.js +26 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/native.d.ts +10 -6
- package/dist/native.js +13 -1
- package/dist/next-loader.cjs +31 -13
- package/dist/next-runtime.d.ts +3 -0
- package/dist/next-runtime.js +20 -0
- package/dist/next.js +10 -4
- package/dist/shiki.js +20 -3
- package/dist/vite.js +2 -2
- package/native.d.ts +1 -0
- package/package.json +26 -23
package/README.md
CHANGED
|
@@ -1,50 +1,75 @@
|
|
|
1
1
|
# @amamo/mdx
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
highlighted HAST back into the same compile pipeline.
|
|
3
|
+
Build MDX collections for Vite 8, Next 16, or a custom Node.js build. Define each collection with
|
|
4
|
+
the package's `z` schema builder, then import MDX as application modules or consume the generated
|
|
5
|
+
collection registry and JSON manifests.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
`@amamo/mdx` provides:
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
- frontmatter validation and defaults;
|
|
10
|
+
- JavaScript modules for a configurable JSX runtime, with React as the default;
|
|
11
|
+
- fenced-code highlighting and Markdown media imports;
|
|
12
|
+
- collection metadata with companion TypeScript declarations;
|
|
13
|
+
- configurable JSON manifests and a persistent build cache.
|
|
15
14
|
|
|
16
|
-
##
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Node.js 20.19 or newer.
|
|
18
|
+
- A [supported native target](https://jikkai.github.io/mdx/native-targets/). There is no JavaScript
|
|
19
|
+
or WASI fallback for MDX compilation.
|
|
20
|
+
- React 19 when using the default JSX runtime.
|
|
21
|
+
|
|
22
|
+
MDX can contain imports, expressions, and JSX. Compile content from authors who are allowed to add
|
|
23
|
+
application code.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
17
26
|
|
|
18
27
|
```sh
|
|
19
28
|
pnpm add @amamo/mdx
|
|
20
29
|
```
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
The package manager installs the platform package for the current operating system and CPU. Install
|
|
32
|
+
dependencies again after moving the project to a different platform instead of copying
|
|
33
|
+
`node_modules`.
|
|
34
|
+
|
|
35
|
+
## Define a collection
|
|
24
36
|
|
|
25
|
-
Create
|
|
37
|
+
Create `amamo.config.mjs`:
|
|
26
38
|
|
|
27
39
|
```js
|
|
28
|
-
|
|
29
|
-
import { defineConfig } from '@amamo/mdx'
|
|
40
|
+
import { defineConfig, z } from '@amamo/mdx'
|
|
30
41
|
|
|
31
42
|
export default defineConfig({
|
|
32
43
|
root: import.meta.dirname,
|
|
33
44
|
collections: {
|
|
34
45
|
posts: {
|
|
35
46
|
directory: 'content/posts',
|
|
36
|
-
schema: {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
required: ['title'],
|
|
41
|
-
},
|
|
47
|
+
schema: z.object({
|
|
48
|
+
title: z.string(),
|
|
49
|
+
publishedAt: z.string().optional(),
|
|
50
|
+
}),
|
|
42
51
|
},
|
|
43
52
|
},
|
|
44
53
|
})
|
|
45
54
|
```
|
|
46
55
|
|
|
47
|
-
Then
|
|
56
|
+
Then add `content/posts/hello.mdx`:
|
|
57
|
+
|
|
58
|
+
```mdx
|
|
59
|
+
---
|
|
60
|
+
title: Hello
|
|
61
|
+
publishedAt: 2026-08-15
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
# Hello
|
|
65
|
+
|
|
66
|
+
This document is compiled by @amamo/mdx.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The collection directory must exist before the first full build. Relative collection, cache,
|
|
70
|
+
generated, and manifest paths are resolved from `root`.
|
|
71
|
+
|
|
72
|
+
## Choose an integration
|
|
48
73
|
|
|
49
74
|
### Vite
|
|
50
75
|
|
|
@@ -55,7 +80,9 @@ import { defineConfig } from 'vite'
|
|
|
55
80
|
|
|
56
81
|
import amamo from './amamo.config.mjs'
|
|
57
82
|
|
|
58
|
-
export default defineConfig({
|
|
83
|
+
export default defineConfig({
|
|
84
|
+
plugins: [amamoMdx(amamo)],
|
|
85
|
+
})
|
|
59
86
|
```
|
|
60
87
|
|
|
61
88
|
### Next
|
|
@@ -66,17 +93,21 @@ import { withAmamoMdx } from '@amamo/mdx/next'
|
|
|
66
93
|
|
|
67
94
|
import amamo from './amamo.config.mjs'
|
|
68
95
|
|
|
69
|
-
export default withAmamoMdx(amamo)({
|
|
96
|
+
export default withAmamoMdx(amamo)({
|
|
97
|
+
reactStrictMode: true,
|
|
98
|
+
})
|
|
70
99
|
```
|
|
71
100
|
|
|
72
101
|
### Direct compiler API
|
|
73
102
|
|
|
74
|
-
```
|
|
103
|
+
```js
|
|
104
|
+
// build-content.mjs
|
|
75
105
|
import { createCompiler } from '@amamo/mdx'
|
|
76
106
|
|
|
77
107
|
import amamo from './amamo.config.mjs'
|
|
78
108
|
|
|
79
109
|
const compiler = await createCompiler(amamo)
|
|
110
|
+
|
|
80
111
|
try {
|
|
81
112
|
const result = await compiler.build()
|
|
82
113
|
console.log(result)
|
|
@@ -85,25 +116,57 @@ try {
|
|
|
85
116
|
}
|
|
86
117
|
```
|
|
87
118
|
|
|
88
|
-
|
|
89
|
-
`.amamo-mdx`):
|
|
119
|
+
Run the script with `node build-content.mjs`.
|
|
90
120
|
|
|
91
|
-
|
|
92
|
-
- `collections.d.ts` — a companion declaration output for the collection registry.
|
|
93
|
-
- `index.json` — the private index used by the Next loader.
|
|
121
|
+
## Use compiled content
|
|
94
122
|
|
|
95
|
-
|
|
123
|
+
With the Vite plugin or Next wrapper configured, import an MDX file like an application module:
|
|
96
124
|
|
|
97
|
-
|
|
125
|
+
```tsx
|
|
126
|
+
import Post, { frontmatter } from './content/posts/hello.mdx'
|
|
98
127
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
128
|
+
export function Page() {
|
|
129
|
+
return (
|
|
130
|
+
<main>
|
|
131
|
+
<h1>{frontmatter.title}</h1>
|
|
132
|
+
<Post />
|
|
133
|
+
</main>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
```
|
|
103
137
|
|
|
104
|
-
|
|
138
|
+
Or load a document from the generated registry:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { collections } from './.amamo-mdx/collections.mjs'
|
|
142
|
+
|
|
143
|
+
const hello = collections.posts.find((document) => document.slug === 'hello')
|
|
144
|
+
const module = await hello?.load()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Registry `load()` functions import the source MDX file, so they must run through the configured Vite
|
|
148
|
+
plugin or Next loader.
|
|
105
149
|
|
|
106
|
-
|
|
150
|
+
## Generated files
|
|
151
|
+
|
|
152
|
+
The first build writes these files under `generatedDirectory`, which defaults to `.amamo-mdx`:
|
|
153
|
+
|
|
154
|
+
- `collections.mjs` — sorted collection metadata and lazy source imports;
|
|
155
|
+
- `collections.d.ts` — TypeScript declarations for the registry;
|
|
156
|
+
- `index.json` — the source-to-cache index used by the Next loader.
|
|
157
|
+
|
|
158
|
+
Cache and manifest paths are configured separately from `generatedDirectory`. Add `.amamo-mdx/` to
|
|
159
|
+
the host repository's ignore file unless the application deliberately tracks generated output.
|
|
160
|
+
|
|
161
|
+
## Package entry points
|
|
162
|
+
|
|
163
|
+
| Import | Use it for |
|
|
164
|
+
| ----------------- | ------------------------------------------ |
|
|
165
|
+
| `@amamo/mdx` | Configuration and the direct compiler API. |
|
|
166
|
+
| `@amamo/mdx/vite` | Vite 8 development and production builds. |
|
|
167
|
+
| `@amamo/mdx/next` | Next 16 development and production builds. |
|
|
168
|
+
|
|
169
|
+
## Documentation
|
|
107
170
|
|
|
108
171
|
- [Getting started](https://jikkai.github.io/mdx/getting-started/)
|
|
109
172
|
- [Configuration reference](https://jikkai.github.io/mdx/configuration/)
|
package/dist/compiler.d.ts
CHANGED
|
@@ -22,7 +22,11 @@ export interface ICompiler {
|
|
|
22
22
|
export interface IAdapterCompiler extends ICompiler {
|
|
23
23
|
readonly generatedCollectionModule: string;
|
|
24
24
|
isContentFile(file: string): boolean;
|
|
25
|
+
scan(): Promise<IBuildResult>;
|
|
25
26
|
startWatch(onGeneratedChange?: (paths: string[]) => Promise<void> | void): () => void;
|
|
27
|
+
transformSource(file: string, source: string): Promise<ITransformResult>;
|
|
26
28
|
}
|
|
27
29
|
export declare function createCompiler(config: IAmamoMdxConfig): Promise<ICompiler>;
|
|
28
|
-
export declare function createAdapterCompiler(config: IAmamoMdxConfig
|
|
30
|
+
export declare function createAdapterCompiler(config: IAmamoMdxConfig, options?: {
|
|
31
|
+
retainModules?: boolean;
|
|
32
|
+
}): Promise<IAdapterCompiler>;
|
package/dist/compiler.js
CHANGED
|
@@ -10,19 +10,22 @@ let temporaryFileId = 0;
|
|
|
10
10
|
const execFileAsync = promisify(execFile);
|
|
11
11
|
class Compiler {
|
|
12
12
|
config;
|
|
13
|
-
|
|
13
|
+
retainModules;
|
|
14
14
|
generatedCollectionModule;
|
|
15
15
|
buildInFlight;
|
|
16
16
|
disposed = false;
|
|
17
17
|
generatedListener;
|
|
18
18
|
gitModifiedTimes = new Map();
|
|
19
|
+
modules = new Map();
|
|
19
20
|
records = new Map();
|
|
21
|
+
sources = new Map();
|
|
22
|
+
shikiPromise;
|
|
20
23
|
tail = Promise.resolve();
|
|
21
24
|
watcher;
|
|
22
25
|
watcherError;
|
|
23
|
-
constructor(config,
|
|
26
|
+
constructor(config, retainModules) {
|
|
24
27
|
this.config = config;
|
|
25
|
-
this.
|
|
28
|
+
this.retainModules = retainModules;
|
|
26
29
|
this.generatedCollectionModule = path.join(config.generatedDirectory, 'collections.mjs');
|
|
27
30
|
}
|
|
28
31
|
build() {
|
|
@@ -42,11 +45,19 @@ class Compiler {
|
|
|
42
45
|
transform(file) {
|
|
43
46
|
return this.enqueue(() => this.transformNow(cleanFileId(file)));
|
|
44
47
|
}
|
|
48
|
+
transformSource(file, source) {
|
|
49
|
+
return this.enqueue(() => this.transformNow(cleanFileId(file), source));
|
|
50
|
+
}
|
|
51
|
+
scan() {
|
|
52
|
+
return this.enqueue(() => this.scanNow());
|
|
53
|
+
}
|
|
45
54
|
remove(file) {
|
|
46
55
|
return this.enqueue(async () => {
|
|
47
56
|
const absolute = cleanFileId(file);
|
|
48
57
|
if (!this.records.delete(absolute))
|
|
49
58
|
return 0;
|
|
59
|
+
this.modules.delete(absolute);
|
|
60
|
+
this.sources.delete(absolute);
|
|
50
61
|
const changed = await this.writeOutputs();
|
|
51
62
|
if (this.config.cache.enabled) {
|
|
52
63
|
pruneNativeCache(this.config.cache.directory, [...this.records.values()].map((record) => record.cacheKey));
|
|
@@ -61,7 +72,8 @@ class Compiler {
|
|
|
61
72
|
await this.enqueue(async () => {
|
|
62
73
|
this.watcher?.close();
|
|
63
74
|
this.watcher = undefined;
|
|
64
|
-
this.
|
|
75
|
+
const shiki = this.shikiPromise ? await this.shikiPromise : undefined;
|
|
76
|
+
shiki?.dispose();
|
|
65
77
|
this.disposed = true;
|
|
66
78
|
}, false);
|
|
67
79
|
}
|
|
@@ -123,9 +135,12 @@ class Compiler {
|
|
|
123
135
|
async buildNow() {
|
|
124
136
|
const discovered = await this.discover();
|
|
125
137
|
const records = await this.compile(discovered.map((document) => document.input));
|
|
126
|
-
this.records.
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
this.replaceRecords(records.map(documentMetadata), discovered.map((document) => document.input));
|
|
139
|
+
this.modules.clear();
|
|
140
|
+
if (this.retainModules) {
|
|
141
|
+
for (const record of records)
|
|
142
|
+
this.modules.set(path.resolve(record.file), record.module);
|
|
143
|
+
}
|
|
129
144
|
const changed = await this.writeOutputs();
|
|
130
145
|
if (this.config.cache.enabled) {
|
|
131
146
|
pruneNativeCache(this.config.cache.directory, records.map((record) => record.cacheKey));
|
|
@@ -138,7 +153,39 @@ class Compiler {
|
|
|
138
153
|
outputsWritten: changed.length,
|
|
139
154
|
};
|
|
140
155
|
}
|
|
141
|
-
async
|
|
156
|
+
async scanNow() {
|
|
157
|
+
const discovered = await this.discover();
|
|
158
|
+
const inputs = discovered.map((document) => document.input);
|
|
159
|
+
const records = prepareNativeBatch(this.config, inputs).takeMetadata();
|
|
160
|
+
this.replaceRecords(records, inputs);
|
|
161
|
+
this.modules.clear();
|
|
162
|
+
const changed = await this.writeOutputs();
|
|
163
|
+
if (this.config.cache.enabled) {
|
|
164
|
+
pruneNativeCache(this.config.cache.directory, records.map((record) => record.cacheKey));
|
|
165
|
+
}
|
|
166
|
+
await this.notifyGeneratedChange(changed);
|
|
167
|
+
return {
|
|
168
|
+
cached: records.filter((record) => record.cached).length,
|
|
169
|
+
compiled: 0,
|
|
170
|
+
discovered: discovered.length,
|
|
171
|
+
outputsWritten: changed.length,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
async transformNow(file, source) {
|
|
175
|
+
const current = this.records.get(file);
|
|
176
|
+
const currentModule = this.modules.get(file);
|
|
177
|
+
if (source !== undefined &&
|
|
178
|
+
source === this.sources.get(file) &&
|
|
179
|
+
current &&
|
|
180
|
+
currentModule !== undefined) {
|
|
181
|
+
return {
|
|
182
|
+
cached: true,
|
|
183
|
+
code: currentModule,
|
|
184
|
+
map: null,
|
|
185
|
+
outputsWritten: 0,
|
|
186
|
+
record: { ...current, cached: true, module: currentModule },
|
|
187
|
+
};
|
|
188
|
+
}
|
|
142
189
|
const metadata = this.metadataForFile(file);
|
|
143
190
|
if (!metadata) {
|
|
144
191
|
throw new Error(`AMAMO_FILE_OUTSIDE_COLLECTION: ${file}`);
|
|
@@ -150,12 +197,16 @@ class Compiler {
|
|
|
150
197
|
throw new Error(`AMAMO_DOCUMENT_DUPLICATE_KEY: ${metadata.collection}/${metadata.key}`);
|
|
151
198
|
}
|
|
152
199
|
}
|
|
153
|
-
const document = await this.readDocument(metadata);
|
|
200
|
+
const document = await this.readDocument(metadata, source);
|
|
154
201
|
const records = await this.compile([document.input]);
|
|
155
202
|
const record = records[0];
|
|
156
203
|
if (!record)
|
|
157
204
|
throw new Error(`AMAMO_NATIVE_RESULT_MISSING: ${file}`);
|
|
158
|
-
this.records.set(file, record);
|
|
205
|
+
this.records.set(file, documentMetadata(record));
|
|
206
|
+
if (this.retainModules) {
|
|
207
|
+
this.modules.set(file, record.module);
|
|
208
|
+
this.sources.set(file, document.input.source);
|
|
209
|
+
}
|
|
159
210
|
const changed = await this.writeOutputs();
|
|
160
211
|
if (this.config.cache.enabled) {
|
|
161
212
|
pruneNativeCache(this.config.cache.directory, [...this.records.values()].map((value) => value.cacheKey));
|
|
@@ -171,7 +222,11 @@ class Compiler {
|
|
|
171
222
|
}
|
|
172
223
|
async compile(inputs) {
|
|
173
224
|
const batch = prepareNativeBatch(this.config, inputs);
|
|
174
|
-
|
|
225
|
+
let highlights = [];
|
|
226
|
+
if (this.config.highlight.enabled && batch.codeBlocks.length > 0) {
|
|
227
|
+
this.shikiPromise ??= createShikiRenderer(this.config.highlight);
|
|
228
|
+
highlights = await (await this.shikiPromise).highlight(batch.codeBlocks);
|
|
229
|
+
}
|
|
175
230
|
return batch.finish(highlights);
|
|
176
231
|
}
|
|
177
232
|
async discover() {
|
|
@@ -200,10 +255,10 @@ class Compiler {
|
|
|
200
255
|
const documents = await Promise.all(documentsMetadata.map((value) => this.readDocument(value)));
|
|
201
256
|
return documents.toSorted((left, right) => left.input.file.localeCompare(right.input.file));
|
|
202
257
|
}
|
|
203
|
-
async readDocument(metadata) {
|
|
258
|
+
async readDocument(metadata, providedSource) {
|
|
204
259
|
const [source, stats] = await Promise.all([
|
|
205
|
-
readFile(metadata.file, 'utf8'),
|
|
206
|
-
stat(metadata.file),
|
|
260
|
+
providedSource ?? readFile(metadata.file, 'utf8'),
|
|
261
|
+
this.config.derived.lastModified ? stat(metadata.file) : undefined,
|
|
207
262
|
]);
|
|
208
263
|
return {
|
|
209
264
|
input: {
|
|
@@ -212,7 +267,7 @@ class Compiler {
|
|
|
212
267
|
key: metadata.key,
|
|
213
268
|
locale: metadata.locale,
|
|
214
269
|
modifiedAt: this.config.derived.lastModified
|
|
215
|
-
? (this.gitModifiedTimes.get(metadata.file) ?? stats
|
|
270
|
+
? (this.gitModifiedTimes.get(metadata.file) ?? stats?.mtime.toISOString())
|
|
216
271
|
: undefined,
|
|
217
272
|
slug: metadata.slug,
|
|
218
273
|
source,
|
|
@@ -246,9 +301,20 @@ class Compiler {
|
|
|
246
301
|
}, {
|
|
247
302
|
contents: `${JSON.stringify({
|
|
248
303
|
cacheDirectory: this.config.cache.directory,
|
|
304
|
+
config: this.config,
|
|
249
305
|
configFingerprint: configurationFingerprint(this.config),
|
|
250
|
-
documents: Object.fromEntries(records.map((record) => [
|
|
251
|
-
|
|
306
|
+
documents: Object.fromEntries(records.map((record) => [
|
|
307
|
+
record.file,
|
|
308
|
+
{
|
|
309
|
+
cacheKey: record.cacheKey,
|
|
310
|
+
collection: record.collection,
|
|
311
|
+
key: record.key,
|
|
312
|
+
locale: record.locale,
|
|
313
|
+
modifiedAt: record.modifiedAt,
|
|
314
|
+
slug: record.slug,
|
|
315
|
+
},
|
|
316
|
+
])),
|
|
317
|
+
version: 2,
|
|
252
318
|
}, null, 2)}\n`,
|
|
253
319
|
path: path.join(this.config.generatedDirectory, 'index.json'),
|
|
254
320
|
});
|
|
@@ -259,6 +325,16 @@ class Compiler {
|
|
|
259
325
|
}
|
|
260
326
|
return changed;
|
|
261
327
|
}
|
|
328
|
+
replaceRecords(records, inputs) {
|
|
329
|
+
this.records.clear();
|
|
330
|
+
for (const record of records)
|
|
331
|
+
this.records.set(path.resolve(record.file), record);
|
|
332
|
+
this.sources.clear();
|
|
333
|
+
if (this.retainModules) {
|
|
334
|
+
for (const input of inputs)
|
|
335
|
+
this.sources.set(path.resolve(input.file), input.source);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
262
338
|
async notifyGeneratedChange(paths) {
|
|
263
339
|
if (paths.length === 0 || !this.generatedListener)
|
|
264
340
|
return;
|
|
@@ -268,12 +344,9 @@ class Compiler {
|
|
|
268
344
|
export async function createCompiler(config) {
|
|
269
345
|
return createAdapterCompiler(config);
|
|
270
346
|
}
|
|
271
|
-
export async function createAdapterCompiler(config) {
|
|
347
|
+
export async function createAdapterCompiler(config, options = {}) {
|
|
272
348
|
const normalized = normalizeConfig(config);
|
|
273
|
-
|
|
274
|
-
? await createShikiRenderer(normalized.highlight)
|
|
275
|
-
: undefined;
|
|
276
|
-
return new Compiler(normalized, shiki);
|
|
349
|
+
return new Compiler(normalized, options.retainModules ?? true);
|
|
277
350
|
}
|
|
278
351
|
function deriveMetadata(collection, config, file, extensionless) {
|
|
279
352
|
const segments = extensionless.split(path.sep);
|
|
@@ -382,6 +455,24 @@ async function writeIfChanged(file, contents) {
|
|
|
382
455
|
function compareRecords(left, right) {
|
|
383
456
|
return left.collection.localeCompare(right.collection) || left.key.localeCompare(right.key);
|
|
384
457
|
}
|
|
458
|
+
function documentMetadata(record) {
|
|
459
|
+
return {
|
|
460
|
+
cacheKey: record.cacheKey,
|
|
461
|
+
cached: record.cached,
|
|
462
|
+
collection: record.collection,
|
|
463
|
+
dependencies: record.dependencies,
|
|
464
|
+
derived: record.derived,
|
|
465
|
+
diagnostics: record.diagnostics,
|
|
466
|
+
file: record.file,
|
|
467
|
+
frontmatter: record.frontmatter,
|
|
468
|
+
hash: record.hash,
|
|
469
|
+
key: record.key,
|
|
470
|
+
locale: record.locale,
|
|
471
|
+
modifiedAt: record.modifiedAt,
|
|
472
|
+
projections: record.projections,
|
|
473
|
+
slug: record.slug,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
385
476
|
function cleanFileId(file) {
|
|
386
477
|
const absolute = path.resolve(file.split('?')[0] ?? file);
|
|
387
478
|
const missing = [];
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
export { z };
|
|
1
3
|
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
2
4
|
[key: string]: JsonValue;
|
|
3
5
|
};
|
|
@@ -13,14 +15,15 @@ export interface ILocaleConfig {
|
|
|
13
15
|
export interface ISlugConfig {
|
|
14
16
|
indexNames?: string[];
|
|
15
17
|
}
|
|
18
|
+
export interface IFrontmatterSchema {
|
|
19
|
+
readonly shape: Readonly<Record<string, unknown>>;
|
|
20
|
+
toJSONSchema(): unknown;
|
|
21
|
+
}
|
|
16
22
|
export interface ICollectionConfig {
|
|
17
23
|
directory: string;
|
|
18
24
|
extensions?: string[];
|
|
19
25
|
locales?: ILocaleConfig;
|
|
20
|
-
schema:
|
|
21
|
-
[key: string]: JsonValue;
|
|
22
|
-
};
|
|
23
|
-
sensitive?: string[];
|
|
26
|
+
schema: IFrontmatterSchema;
|
|
24
27
|
slug?: ISlugConfig;
|
|
25
28
|
}
|
|
26
29
|
export interface IMathConfig {
|
|
@@ -90,7 +93,6 @@ export interface INormalizedCollectionConfig {
|
|
|
90
93
|
schema: {
|
|
91
94
|
[key: string]: JsonValue;
|
|
92
95
|
};
|
|
93
|
-
sensitive: string[];
|
|
94
96
|
slug: {
|
|
95
97
|
indexNames: string[];
|
|
96
98
|
};
|
|
@@ -116,7 +118,7 @@ export interface INormalizedManifestConfig extends Omit<IManifestConfig, 'collec
|
|
|
116
118
|
collections: string[];
|
|
117
119
|
output: string;
|
|
118
120
|
}
|
|
119
|
-
export interface
|
|
121
|
+
export interface IAmamoMDXConfig {
|
|
120
122
|
cache: {
|
|
121
123
|
directory: string;
|
|
122
124
|
enabled: boolean;
|
|
@@ -142,4 +144,4 @@ export interface INormalizedConfig {
|
|
|
142
144
|
root: string;
|
|
143
145
|
}
|
|
144
146
|
export declare function defineConfig<T extends IAmamoMdxConfig>(config: T): T;
|
|
145
|
-
export declare function normalizeConfig(config: IAmamoMdxConfig):
|
|
147
|
+
export declare function normalizeConfig(config: IAmamoMdxConfig): IAmamoMDXConfig;
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
2
|
import { existsSync, realpathSync } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import * as z from 'zod';
|
|
5
|
+
export { z };
|
|
4
6
|
const DEFAULT_MEDIA_ATTRIBUTES = {
|
|
5
7
|
audio: ['src'],
|
|
6
8
|
embed: ['src'],
|
|
@@ -16,7 +18,9 @@ const MAX_MATH_MACROS_BYTES = 16 * 1024;
|
|
|
16
18
|
function notSerializable(location, reason) {
|
|
17
19
|
throw new TypeError(`AMAMO_CONFIG_NOT_SERIALIZABLE: ${location} ${reason}`);
|
|
18
20
|
}
|
|
19
|
-
function assertPlainData(value, location, active) {
|
|
21
|
+
function assertPlainData(value, location, active, segments = []) {
|
|
22
|
+
if (segments.length === 3 && segments[0] === 'collections' && segments[2] === 'schema')
|
|
23
|
+
return;
|
|
20
24
|
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
21
25
|
return;
|
|
22
26
|
if (typeof value === 'number') {
|
|
@@ -39,7 +43,7 @@ function assertPlainData(value, location, active) {
|
|
|
39
43
|
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
40
44
|
if (!descriptor || !('value' in descriptor))
|
|
41
45
|
notSerializable(`${location}.${key}`, 'contains an accessor');
|
|
42
|
-
assertPlainData(descriptor.value, `${location}.${key}`, active);
|
|
46
|
+
assertPlainData(descriptor.value, `${location}.${key}`, active, [...segments, key]);
|
|
43
47
|
}
|
|
44
48
|
active.delete(value);
|
|
45
49
|
}
|
|
@@ -57,14 +61,32 @@ function normalizeCollection(root, name, config) {
|
|
|
57
61
|
throw new TypeError(`AMAMO_CONFIG_INVALID: collections.${name}.locales.default must be listed in names`);
|
|
58
62
|
}
|
|
59
63
|
const directory = path.resolve(root, requireNonEmpty(config.directory, `collections.${name}.directory`));
|
|
64
|
+
if (typeof config.schema?.shape !== 'object' ||
|
|
65
|
+
config.schema.shape === null ||
|
|
66
|
+
typeof config.schema.toJSONSchema !== 'function') {
|
|
67
|
+
throw new TypeError(`AMAMO_CONFIG_INVALID: collections.${name}.schema must be a compatible object schema`);
|
|
68
|
+
}
|
|
69
|
+
let schema;
|
|
70
|
+
try {
|
|
71
|
+
schema = JSON.parse(JSON.stringify(config.schema.toJSONSchema()));
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const reason = error instanceof Error ? error.message : 'could not be converted to JSON Schema';
|
|
75
|
+
throw new TypeError(`AMAMO_CONFIG_INVALID: collections.${name}.schema ${reason}`, {
|
|
76
|
+
cause: error,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (schema.type !== 'object') {
|
|
80
|
+
throw new TypeError(`AMAMO_CONFIG_INVALID: collections.${name}.schema must convert to an object schema`);
|
|
81
|
+
}
|
|
82
|
+
assertPlainData(schema, `collections.${name}.schema`, new WeakSet());
|
|
60
83
|
return {
|
|
61
84
|
directory: existsSync(directory) ? realpathSync.native(directory) : directory,
|
|
62
85
|
extensions: [...extensions],
|
|
63
86
|
locales: config.locales
|
|
64
87
|
? { default: config.locales.default, names: [...config.locales.names] }
|
|
65
88
|
: undefined,
|
|
66
|
-
schema
|
|
67
|
-
sensitive: [...(config.sensitive ?? [])],
|
|
89
|
+
schema,
|
|
68
90
|
slug: { indexNames: [...(config.slug?.indexNames ?? ['index', 'page'])] },
|
|
69
91
|
};
|
|
70
92
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { IAmamoMdxConfig, ICacheConfig, ICollectionConfig, IDerivedConfig, IHighlightConfig, ILocaleConfig, IManifestConfig, IMathConfig, IMdxConfig, IMdxExtensionsConfig, IMediaConfig,
|
|
2
|
-
export { defineConfig, normalizeConfig } from './config.js';
|
|
1
|
+
export type { IAmamoMDXConfig, IAmamoMdxConfig, ICacheConfig, ICollectionConfig, IDerivedConfig, IFrontmatterSchema, IHighlightConfig, ILocaleConfig, IManifestConfig, IMathConfig, IMdxConfig, IMdxExtensionsConfig, IMediaConfig, JsonValue, ManifestField, } from './config.js';
|
|
2
|
+
export { defineConfig, normalizeConfig, z } from './config.js';
|
|
3
3
|
export type { IBuildResult, ICompiler, ITransformResult } from './compiler.js';
|
|
4
4
|
export { createCompiler } from './compiler.js';
|
|
5
5
|
export type { IDiagnostic } from './native.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { defineConfig, normalizeConfig } from './config.js';
|
|
1
|
+
export { defineConfig, normalizeConfig, z } from './config.js';
|
|
2
2
|
export { createCompiler } from './compiler.js';
|
package/dist/native.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IAmamoMDXConfig, JsonValue } from './config.js';
|
|
2
2
|
export interface ISourcePoint {
|
|
3
3
|
column: number;
|
|
4
4
|
line: number;
|
|
@@ -37,7 +37,7 @@ export interface IHighlightedCodeBlock {
|
|
|
37
37
|
documentId: string;
|
|
38
38
|
hast: JsonValue;
|
|
39
39
|
}
|
|
40
|
-
export interface
|
|
40
|
+
export interface IDocumentMetadata {
|
|
41
41
|
cacheKey: string;
|
|
42
42
|
cached: boolean;
|
|
43
43
|
collection: string;
|
|
@@ -49,10 +49,13 @@ export interface IDocumentRecord {
|
|
|
49
49
|
hash: string;
|
|
50
50
|
key: string;
|
|
51
51
|
locale?: string;
|
|
52
|
-
|
|
52
|
+
modifiedAt?: string;
|
|
53
53
|
projections: Record<string, JsonValue>;
|
|
54
54
|
slug?: string;
|
|
55
55
|
}
|
|
56
|
+
export interface IDocumentRecord extends IDocumentMetadata {
|
|
57
|
+
module: string;
|
|
58
|
+
}
|
|
56
59
|
export interface IRenderedManifest {
|
|
57
60
|
contents: string;
|
|
58
61
|
path: string;
|
|
@@ -60,12 +63,13 @@ export interface IRenderedManifest {
|
|
|
60
63
|
export interface IPreparedNativeBatch {
|
|
61
64
|
codeBlocks: ICodeBlock[];
|
|
62
65
|
finish(highlights: IHighlightedCodeBlock[]): IDocumentRecord[];
|
|
66
|
+
takeMetadata(): IDocumentMetadata[];
|
|
63
67
|
}
|
|
64
68
|
export declare class AmamoMdxError extends Error {
|
|
65
69
|
readonly diagnostics: IDiagnostic[];
|
|
66
70
|
constructor(diagnostics: IDiagnostic[]);
|
|
67
71
|
}
|
|
68
|
-
export declare function configurationFingerprint(config:
|
|
69
|
-
export declare function prepareNativeBatch(config:
|
|
72
|
+
export declare function configurationFingerprint(config: IAmamoMDXConfig): string;
|
|
73
|
+
export declare function prepareNativeBatch(config: IAmamoMDXConfig, inputs: INativeDocumentInput[]): IPreparedNativeBatch;
|
|
70
74
|
export declare function pruneNativeCache(cacheDirectory: string, keepKeys: string[]): number;
|
|
71
|
-
export declare function renderNativeManifests(config:
|
|
75
|
+
export declare function renderNativeManifests(config: IAmamoMDXConfig, records: IDocumentMetadata[]): IRenderedManifest[];
|
package/dist/native.js
CHANGED
|
@@ -44,6 +44,14 @@ export function prepareNativeBatch(config, inputs) {
|
|
|
44
44
|
return mapNativeError(error);
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
+
takeMetadata() {
|
|
48
|
+
try {
|
|
49
|
+
return JSON.parse(batch.takeMetadataJson());
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return mapNativeError(error);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
47
55
|
};
|
|
48
56
|
}
|
|
49
57
|
catch (error) {
|
|
@@ -60,7 +68,11 @@ export function pruneNativeCache(cacheDirectory, keepKeys) {
|
|
|
60
68
|
}
|
|
61
69
|
export function renderNativeManifests(config, records) {
|
|
62
70
|
try {
|
|
63
|
-
|
|
71
|
+
const manifestRecords = records.map(({ key, projections }) => ({
|
|
72
|
+
key,
|
|
73
|
+
projections,
|
|
74
|
+
}));
|
|
75
|
+
return JSON.parse(loadBinding().renderManifests(nativeConfigJson(config), JSON.stringify(manifestRecords)));
|
|
64
76
|
}
|
|
65
77
|
catch (error) {
|
|
66
78
|
return mapNativeError(error);
|
package/dist/next-loader.cjs
CHANGED
|
@@ -4,30 +4,48 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
const promises_1 = require("node:fs/promises");
|
|
6
6
|
const node_path_1 = __importDefault(require("node:path"));
|
|
7
|
-
function nextLoader(
|
|
8
|
-
return
|
|
7
|
+
function nextLoader(source) {
|
|
8
|
+
return compileModule(this, source);
|
|
9
9
|
}
|
|
10
|
-
async function
|
|
10
|
+
async function compileModule(context, source) {
|
|
11
11
|
const options = context.getOptions();
|
|
12
|
+
context.addDependency(options.indexFile);
|
|
13
|
+
let config;
|
|
14
|
+
let input;
|
|
12
15
|
try {
|
|
13
16
|
const index = JSON.parse(await (0, promises_1.readFile)(options.indexFile, 'utf8'));
|
|
14
17
|
const resource = await (0, promises_1.realpath)(node_path_1.default.resolve(context.resourcePath));
|
|
15
|
-
const
|
|
16
|
-
if (index.
|
|
18
|
+
const document = index.documents?.[resource];
|
|
19
|
+
if (index.version !== 2 ||
|
|
20
|
+
index.configFingerprint !== options.configFingerprint ||
|
|
17
21
|
typeof index.cacheDirectory !== 'string' ||
|
|
18
|
-
typeof
|
|
19
|
-
|
|
22
|
+
typeof index.config !== 'object' ||
|
|
23
|
+
index.config === null ||
|
|
24
|
+
index.config.cache.directory !== index.cacheDirectory ||
|
|
25
|
+
typeof document?.cacheKey !== 'string' ||
|
|
26
|
+
!/^[a-f0-9]{64}$/.test(document.cacheKey) ||
|
|
27
|
+
typeof document.collection !== 'string' ||
|
|
28
|
+
typeof document.key !== 'string') {
|
|
20
29
|
throw new Error('index entry does not match this build');
|
|
21
30
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
config = index.config;
|
|
32
|
+
input = {
|
|
33
|
+
collection: document.collection,
|
|
34
|
+
file: resource,
|
|
35
|
+
key: document.key,
|
|
36
|
+
locale: document.locale,
|
|
37
|
+
modifiedAt: document.modifiedAt,
|
|
38
|
+
slug: document.slug,
|
|
39
|
+
source,
|
|
40
|
+
};
|
|
28
41
|
}
|
|
29
42
|
catch (error) {
|
|
30
43
|
throw new Error(`AMAMO_NEXT_CACHE_MISS: ${context.resourcePath}; rerun the coordinated amamo-mdx build`, { cause: error });
|
|
31
44
|
}
|
|
45
|
+
const { compileNextDocument } = await import('./next-runtime.js');
|
|
46
|
+
const record = await compileNextDocument(config, input);
|
|
47
|
+
for (const dependency of record.dependencies)
|
|
48
|
+
context.addDependency(dependency);
|
|
49
|
+
return record.module;
|
|
32
50
|
}
|
|
33
51
|
module.exports = nextLoader;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { configurationFingerprint, prepareNativeBatch } from './native.js';
|
|
2
|
+
import { createShikiRenderer } from './shiki.js';
|
|
3
|
+
const renderers = new Map();
|
|
4
|
+
export async function compileNextDocument(config, input) {
|
|
5
|
+
const batch = prepareNativeBatch(config, [input]);
|
|
6
|
+
let highlights = [];
|
|
7
|
+
if (config.highlight.enabled && batch.codeBlocks.length > 0) {
|
|
8
|
+
const fingerprint = configurationFingerprint(config);
|
|
9
|
+
let renderer = renderers.get(fingerprint);
|
|
10
|
+
if (!renderer) {
|
|
11
|
+
renderer = createShikiRenderer(config.highlight);
|
|
12
|
+
renderers.set(fingerprint, renderer);
|
|
13
|
+
}
|
|
14
|
+
highlights = await (await renderer).highlight(batch.codeBlocks);
|
|
15
|
+
}
|
|
16
|
+
const record = batch.finish(highlights)[0];
|
|
17
|
+
if (!record)
|
|
18
|
+
throw new Error(`AMAMO_NATIVE_RESULT_MISSING: ${input.file}`);
|
|
19
|
+
return record;
|
|
20
|
+
}
|
package/dist/next.js
CHANGED
|
@@ -13,17 +13,23 @@ export function withAmamoMdx(config) {
|
|
|
13
13
|
};
|
|
14
14
|
let compilerPromise;
|
|
15
15
|
let buildPromise;
|
|
16
|
+
let scanPromise;
|
|
16
17
|
let watching = false;
|
|
17
18
|
function compiler() {
|
|
18
|
-
compilerPromise ??= createAdapterCompiler(config);
|
|
19
|
+
compilerPromise ??= createAdapterCompiler(config, { retainModules: false });
|
|
19
20
|
return compilerPromise;
|
|
20
21
|
}
|
|
21
22
|
async function prepare(phase) {
|
|
22
23
|
if (phase !== PHASE_DEVELOPMENT_SERVER && phase !== PHASE_PRODUCTION_BUILD)
|
|
23
24
|
return;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (phase === PHASE_PRODUCTION_BUILD) {
|
|
26
|
+
buildPromise ??= compiler().then((instance) => instance.build());
|
|
27
|
+
await buildPromise;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
scanPromise ??= compiler().then((instance) => instance.scan());
|
|
31
|
+
await scanPromise;
|
|
32
|
+
if (!watching) {
|
|
27
33
|
const instance = await compiler();
|
|
28
34
|
instance.startWatch();
|
|
29
35
|
watching = true;
|
package/dist/shiki.js
CHANGED
|
@@ -59,8 +59,17 @@ export async function createShikiRenderer(config) {
|
|
|
59
59
|
async highlight(blocks) {
|
|
60
60
|
if (disposed)
|
|
61
61
|
throw new Error('AMAMO_SHIKI_DISPOSED: Shiki renderer is disposed');
|
|
62
|
-
const
|
|
63
|
-
|
|
62
|
+
const keys = blocks.map((block) => JSON.stringify([block.lang, block.meta, block.code]));
|
|
63
|
+
const uniqueBlocks = new Map();
|
|
64
|
+
for (const [index, block] of blocks.entries()) {
|
|
65
|
+
const key = keys[index];
|
|
66
|
+
if (key !== undefined && !uniqueBlocks.has(key))
|
|
67
|
+
uniqueBlocks.set(key, block);
|
|
68
|
+
}
|
|
69
|
+
const entries = [...uniqueBlocks.entries()];
|
|
70
|
+
const languages = await Promise.all(entries.map(([, block]) => loadLanguage(block.lang)));
|
|
71
|
+
const highlighted = new Map();
|
|
72
|
+
for (const [index, [key, block]] of entries.entries()) {
|
|
64
73
|
const language = block.lang;
|
|
65
74
|
const hast = highlighter.codeToHast(block.code, {
|
|
66
75
|
colorReplacements: config.colorReplacements,
|
|
@@ -82,10 +91,18 @@ export async function createShikiRenderer(config) {
|
|
|
82
91
|
]
|
|
83
92
|
: undefined,
|
|
84
93
|
});
|
|
94
|
+
highlighted.set(key, JSON.parse(JSON.stringify(hast)));
|
|
95
|
+
}
|
|
96
|
+
return blocks.map((block, index) => {
|
|
97
|
+
const key = keys[index];
|
|
98
|
+
const hast = key === undefined ? undefined : highlighted.get(key);
|
|
99
|
+
if (hast === undefined) {
|
|
100
|
+
throw new Error('AMAMO_SHIKI_RESULT_MISSING: Highlighted code block is missing');
|
|
101
|
+
}
|
|
85
102
|
return {
|
|
86
103
|
blockId: block.blockId,
|
|
87
104
|
documentId: block.documentId,
|
|
88
|
-
hast
|
|
105
|
+
hast,
|
|
89
106
|
};
|
|
90
107
|
});
|
|
91
108
|
},
|
package/dist/vite.js
CHANGED
|
@@ -25,11 +25,11 @@ export function amamoMdx(config) {
|
|
|
25
25
|
async buildStart() {
|
|
26
26
|
await ensureBuild();
|
|
27
27
|
},
|
|
28
|
-
async transform(
|
|
28
|
+
async transform(source, id) {
|
|
29
29
|
const instance = await compiler();
|
|
30
30
|
if (!instance.isContentFile(id))
|
|
31
31
|
return null;
|
|
32
|
-
const result = await instance.
|
|
32
|
+
const result = await instance.transformSource(id, source);
|
|
33
33
|
return { code: result.code, map: result.map };
|
|
34
34
|
},
|
|
35
35
|
async configureServer(server) {
|
package/native.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amamo/mdx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A native MDX content compiler with Vite and Next adapters",
|
|
5
5
|
"homepage": "https://jikkai.github.io/mdx/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,30 +48,33 @@
|
|
|
48
48
|
"test": "pnpm run build && vitest run src/__tests__",
|
|
49
49
|
"test:rust": "cargo test",
|
|
50
50
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
51
|
-
"check": "pnpm run format:check && pnpm run lint &&
|
|
51
|
+
"check": "pnpm run format:check && pnpm run lint && pnpm run check:rust && pnpm run check:npm && pnpm run check:docs",
|
|
52
52
|
"check:docs": "pnpm --filter @amamo/mdx-docs types:check && pnpm --filter @amamo/mdx-docs build",
|
|
53
|
+
"check:npm": "pnpm run typecheck && pnpm run test",
|
|
54
|
+
"check:rust": "cargo clippy --all-targets -- -D warnings && pnpm run test:rust",
|
|
53
55
|
"release": "verso"
|
|
54
56
|
},
|
|
55
57
|
"dependencies": {
|
|
56
|
-
"shiki": "4.4.
|
|
58
|
+
"shiki": "4.4.3",
|
|
59
|
+
"zod": "4.5.4"
|
|
57
60
|
},
|
|
58
61
|
"devDependencies": {
|
|
59
|
-
"@amamo/oxlint-config": "1.
|
|
60
|
-
"@amamo/verso": "1.0
|
|
61
|
-
"@napi-rs/cli": "3.8.
|
|
62
|
-
"@types/node": "26.
|
|
62
|
+
"@amamo/oxlint-config": "1.1.0",
|
|
63
|
+
"@amamo/verso": "1.2.0",
|
|
64
|
+
"@napi-rs/cli": "3.8.6",
|
|
65
|
+
"@types/node": "26.4.0",
|
|
63
66
|
"@types/react": "19.2.18",
|
|
64
|
-
"@types/react-dom": "19.2.
|
|
65
|
-
"lint-staged": "17.
|
|
66
|
-
"next": "16.3.
|
|
67
|
-
"oxfmt": "0.
|
|
68
|
-
"oxlint": "1.
|
|
67
|
+
"@types/react-dom": "19.2.5",
|
|
68
|
+
"lint-staged": "17.4.1",
|
|
69
|
+
"next": "16.3.3",
|
|
70
|
+
"oxfmt": "0.65.0",
|
|
71
|
+
"oxlint": "1.80.0",
|
|
69
72
|
"react": "19.2.8",
|
|
70
73
|
"react-dom": "19.2.8",
|
|
71
|
-
"simple-git-hooks": "2.
|
|
74
|
+
"simple-git-hooks": "2.14.0",
|
|
72
75
|
"typescript": "7.0.2",
|
|
73
|
-
"vite": "8.2.
|
|
74
|
-
"vitest": "4.1.
|
|
76
|
+
"vite": "8.2.2",
|
|
77
|
+
"vitest": "4.1.11"
|
|
75
78
|
},
|
|
76
79
|
"peerDependencies": {
|
|
77
80
|
"next": "^16.0.0",
|
|
@@ -114,14 +117,14 @@
|
|
|
114
117
|
"engines": {
|
|
115
118
|
"node": ">=20.19"
|
|
116
119
|
},
|
|
117
|
-
"packageManager": "pnpm@
|
|
120
|
+
"packageManager": "pnpm@12.1.0",
|
|
118
121
|
"optionalDependencies": {
|
|
119
|
-
"@amamo/mdx-darwin-arm64": "0.
|
|
120
|
-
"@amamo/mdx-darwin-x64": "0.
|
|
121
|
-
"@amamo/mdx-linux-arm64-gnu": "0.
|
|
122
|
-
"@amamo/mdx-linux-x64-gnu": "0.
|
|
123
|
-
"@amamo/mdx-linux-arm64-musl": "0.
|
|
124
|
-
"@amamo/mdx-linux-x64-musl": "0.
|
|
125
|
-
"@amamo/mdx-win32-x64-msvc": "0.
|
|
122
|
+
"@amamo/mdx-darwin-arm64": "0.4.0",
|
|
123
|
+
"@amamo/mdx-darwin-x64": "0.4.0",
|
|
124
|
+
"@amamo/mdx-linux-arm64-gnu": "0.4.0",
|
|
125
|
+
"@amamo/mdx-linux-x64-gnu": "0.4.0",
|
|
126
|
+
"@amamo/mdx-linux-arm64-musl": "0.4.0",
|
|
127
|
+
"@amamo/mdx-linux-x64-musl": "0.4.0",
|
|
128
|
+
"@amamo/mdx-win32-x64-msvc": "0.4.0"
|
|
126
129
|
}
|
|
127
130
|
}
|