@imjp/writenex-astro 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/README.md +539 -0
- package/dist/chunk-5PM6EQE5.js +151 -0
- package/dist/chunk-5PM6EQE5.js.map +1 -0
- package/dist/chunk-7XU5X6CW.js +1331 -0
- package/dist/chunk-7XU5X6CW.js.map +1 -0
- package/dist/chunk-AAOQHQPU.js +574 -0
- package/dist/chunk-AAOQHQPU.js.map +1 -0
- package/dist/chunk-CF2XXJFF.js +1410 -0
- package/dist/chunk-CF2XXJFF.js.map +1 -0
- package/dist/chunk-CRPZUUDU.js +52 -0
- package/dist/chunk-CRPZUUDU.js.map +1 -0
- package/dist/chunk-CYLDJ3HZ.js +310 -0
- package/dist/chunk-CYLDJ3HZ.js.map +1 -0
- package/dist/chunk-KIKIPIFA.js +1 -0
- package/dist/chunk-KIKIPIFA.js.map +1 -0
- package/dist/chunk-XNTQTTJU.js +145 -0
- package/dist/chunk-XNTQTTJU.js.map +1 -0
- package/dist/client/index.css +2 -0
- package/dist/client/index.css.map +1 -0
- package/dist/client/index.js +375 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/styles.css +584 -0
- package/dist/client/variables.css +304 -0
- package/dist/config/index.d.ts +54 -0
- package/dist/config/index.js +38 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config-BmEdBDo_.d.ts +220 -0
- package/dist/content-BWR52vD-.d.ts +64 -0
- package/dist/discovery/index.d.ts +310 -0
- package/dist/discovery/index.js +38 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/errors-C0iYiDTv.d.ts +107 -0
- package/dist/filesystem/index.d.ts +1292 -0
- package/dist/filesystem/index.js +203 -0
- package/dist/filesystem/index.js.map +1 -0
- package/dist/image-FP7w5ZIs.d.ts +47 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +151 -0
- package/dist/index.js.map +1 -0
- package/dist/loader-55LWCXHA.js +12 -0
- package/dist/loader-55LWCXHA.js.map +1 -0
- package/dist/loader-CrdnaAWR.d.ts +327 -0
- package/dist/server/index.d.ts +357 -0
- package/dist/server/index.js +37 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +94 -0
- package/src/client/App.tsx +900 -0
- package/src/client/components/ConfigPanel/ConfigPanel.css +553 -0
- package/src/client/components/ConfigPanel/ConfigPanel.tsx +396 -0
- package/src/client/components/ConfigPanel/index.ts +6 -0
- package/src/client/components/CreateContentModal/CreateContentModal.css +327 -0
- package/src/client/components/CreateContentModal/CreateContentModal.tsx +216 -0
- package/src/client/components/CreateContentModal/index.ts +7 -0
- package/src/client/components/Editor/Editor.css +885 -0
- package/src/client/components/Editor/Editor.tsx +484 -0
- package/src/client/components/Editor/ImageDialog.css +344 -0
- package/src/client/components/Editor/ImageDialog.tsx +367 -0
- package/src/client/components/Editor/LinkDialog.css +326 -0
- package/src/client/components/Editor/LinkDialog.tsx +332 -0
- package/src/client/components/Editor/index.ts +6 -0
- package/src/client/components/FrontmatterForm/FrontmatterForm.css +468 -0
- package/src/client/components/FrontmatterForm/FrontmatterForm.tsx +914 -0
- package/src/client/components/FrontmatterForm/index.ts +7 -0
- package/src/client/components/Header/Header.css +300 -0
- package/src/client/components/Header/Header.tsx +300 -0
- package/src/client/components/Header/index.ts +7 -0
- package/src/client/components/KeyboardShortcuts/KeyboardShortcuts.css +239 -0
- package/src/client/components/KeyboardShortcuts/KeyboardShortcuts.tsx +151 -0
- package/src/client/components/KeyboardShortcuts/index.ts +6 -0
- package/src/client/components/LazyEditor.tsx +75 -0
- package/src/client/components/LiveRegion/LiveRegion.css +19 -0
- package/src/client/components/LiveRegion/LiveRegion.tsx +60 -0
- package/src/client/components/LiveRegion/index.ts +7 -0
- package/src/client/components/SearchReplace/SearchReplacePanel.css +300 -0
- package/src/client/components/SearchReplace/SearchReplacePanel.tsx +332 -0
- package/src/client/components/SearchReplace/index.ts +7 -0
- package/src/client/components/SelectCollectionModal/SelectCollectionModal.css +308 -0
- package/src/client/components/SelectCollectionModal/SelectCollectionModal.tsx +223 -0
- package/src/client/components/SelectCollectionModal/index.ts +7 -0
- package/src/client/components/Sidebar/Sidebar.css +570 -0
- package/src/client/components/Sidebar/Sidebar.tsx +617 -0
- package/src/client/components/Sidebar/index.ts +7 -0
- package/src/client/components/SkipLink/SkipLink.css +51 -0
- package/src/client/components/SkipLink/SkipLink.tsx +67 -0
- package/src/client/components/SkipLink/index.ts +7 -0
- package/src/client/components/UnsavedChangesModal/UnsavedChangesModal.css +233 -0
- package/src/client/components/UnsavedChangesModal/UnsavedChangesModal.tsx +160 -0
- package/src/client/components/UnsavedChangesModal/index.ts +1 -0
- package/src/client/components/VersionHistory/DiffViewer.css +430 -0
- package/src/client/components/VersionHistory/DiffViewer.tsx +383 -0
- package/src/client/components/VersionHistory/VersionActions.css +318 -0
- package/src/client/components/VersionHistory/VersionActions.tsx +277 -0
- package/src/client/components/VersionHistory/VersionHistoryPanel.css +369 -0
- package/src/client/components/VersionHistory/VersionHistoryPanel.tsx +469 -0
- package/src/client/components/VersionHistory/index.ts +9 -0
- package/src/client/context/ApiContext.tsx +154 -0
- package/src/client/context/ThemeContext.tsx +172 -0
- package/src/client/hooks/useAnnounce.ts +201 -0
- package/src/client/hooks/useApi.ts +374 -0
- package/src/client/hooks/useArrowNavigation.ts +286 -0
- package/src/client/hooks/useAutosave.ts +241 -0
- package/src/client/hooks/useFocusTrap.ts +178 -0
- package/src/client/hooks/useKeyboardShortcuts.ts +203 -0
- package/src/client/hooks/useSearch.ts +206 -0
- package/src/client/hooks/useVersionHistory.ts +451 -0
- package/src/client/index.tsx +70 -0
- package/src/client/styles.css +584 -0
- package/src/client/utils/focus.ts +57 -0
- package/src/client/utils/openInEditor.ts +130 -0
- package/src/client/variables.css +304 -0
- package/src/config/defaults.ts +109 -0
- package/src/config/index.ts +32 -0
- package/src/config/loader.ts +174 -0
- package/src/config/schema.ts +161 -0
- package/src/core/constants.ts +39 -0
- package/src/core/errors.ts +739 -0
- package/src/core/index.ts +11 -0
- package/src/discovery/collections.ts +216 -0
- package/src/discovery/index.ts +33 -0
- package/src/discovery/patterns.ts +702 -0
- package/src/discovery/schema.ts +453 -0
- package/src/filesystem/images.ts +798 -0
- package/src/filesystem/index.ts +107 -0
- package/src/filesystem/reader.ts +452 -0
- package/src/filesystem/version-config.ts +390 -0
- package/src/filesystem/versions.ts +1339 -0
- package/src/filesystem/watcher.ts +226 -0
- package/src/filesystem/writer.ts +540 -0
- package/src/index.ts +61 -0
- package/src/integration.ts +228 -0
- package/src/server/assets.ts +254 -0
- package/src/server/cache.ts +355 -0
- package/src/server/index.ts +33 -0
- package/src/server/middleware.ts +209 -0
- package/src/server/routes.ts +1428 -0
- package/src/types/api.ts +61 -0
- package/src/types/config.ts +134 -0
- package/src/types/content.ts +64 -0
- package/src/types/image.ts +48 -0
- package/src/types/index.ts +58 -0
- package/src/types/version.ts +117 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { a as WritenexConfig } from './config-BmEdBDo_.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @fileoverview Configuration schema and validation for @writenex/astro
|
|
6
|
+
*
|
|
7
|
+
* This module provides Zod schemas for validating Writenex configuration
|
|
8
|
+
* and a helper function for defining type-safe configurations.
|
|
9
|
+
*
|
|
10
|
+
* @module @writenex/astro/config/schema
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Main Writenex configuration schema
|
|
15
|
+
*/
|
|
16
|
+
declare const writenexConfigSchema: z.ZodObject<{
|
|
17
|
+
collections: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
18
|
+
name: z.ZodString;
|
|
19
|
+
path: z.ZodString;
|
|
20
|
+
filePattern: z.ZodOptional<z.ZodString>;
|
|
21
|
+
previewUrl: z.ZodOptional<z.ZodString>;
|
|
22
|
+
schema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
23
|
+
type: z.ZodEnum<["string", "number", "boolean", "date", "array", "image", "object"]>;
|
|
24
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
26
|
+
items: z.ZodOptional<z.ZodString>;
|
|
27
|
+
description: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
type: "string" | "number" | "boolean" | "object" | "date" | "array" | "image";
|
|
30
|
+
required?: boolean | undefined;
|
|
31
|
+
default?: unknown;
|
|
32
|
+
items?: string | undefined;
|
|
33
|
+
description?: string | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
type: "string" | "number" | "boolean" | "object" | "date" | "array" | "image";
|
|
36
|
+
required?: boolean | undefined;
|
|
37
|
+
default?: unknown;
|
|
38
|
+
items?: string | undefined;
|
|
39
|
+
description?: string | undefined;
|
|
40
|
+
}>>>;
|
|
41
|
+
images: z.ZodOptional<z.ZodObject<{
|
|
42
|
+
strategy: z.ZodEnum<["colocated", "public", "custom"]>;
|
|
43
|
+
publicPath: z.ZodOptional<z.ZodString>;
|
|
44
|
+
storagePath: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
strategy: "colocated" | "public" | "custom";
|
|
47
|
+
publicPath?: string | undefined;
|
|
48
|
+
storagePath?: string | undefined;
|
|
49
|
+
}, {
|
|
50
|
+
strategy: "colocated" | "public" | "custom";
|
|
51
|
+
publicPath?: string | undefined;
|
|
52
|
+
storagePath?: string | undefined;
|
|
53
|
+
}>>;
|
|
54
|
+
}, "strip", z.ZodTypeAny, {
|
|
55
|
+
name: string;
|
|
56
|
+
path: string;
|
|
57
|
+
images?: {
|
|
58
|
+
strategy: "colocated" | "public" | "custom";
|
|
59
|
+
publicPath?: string | undefined;
|
|
60
|
+
storagePath?: string | undefined;
|
|
61
|
+
} | undefined;
|
|
62
|
+
filePattern?: string | undefined;
|
|
63
|
+
previewUrl?: string | undefined;
|
|
64
|
+
schema?: Record<string, {
|
|
65
|
+
type: "string" | "number" | "boolean" | "object" | "date" | "array" | "image";
|
|
66
|
+
required?: boolean | undefined;
|
|
67
|
+
default?: unknown;
|
|
68
|
+
items?: string | undefined;
|
|
69
|
+
description?: string | undefined;
|
|
70
|
+
}> | undefined;
|
|
71
|
+
}, {
|
|
72
|
+
name: string;
|
|
73
|
+
path: string;
|
|
74
|
+
images?: {
|
|
75
|
+
strategy: "colocated" | "public" | "custom";
|
|
76
|
+
publicPath?: string | undefined;
|
|
77
|
+
storagePath?: string | undefined;
|
|
78
|
+
} | undefined;
|
|
79
|
+
filePattern?: string | undefined;
|
|
80
|
+
previewUrl?: string | undefined;
|
|
81
|
+
schema?: Record<string, {
|
|
82
|
+
type: "string" | "number" | "boolean" | "object" | "date" | "array" | "image";
|
|
83
|
+
required?: boolean | undefined;
|
|
84
|
+
default?: unknown;
|
|
85
|
+
items?: string | undefined;
|
|
86
|
+
description?: string | undefined;
|
|
87
|
+
}> | undefined;
|
|
88
|
+
}>, "many">>;
|
|
89
|
+
images: z.ZodOptional<z.ZodObject<{
|
|
90
|
+
strategy: z.ZodEnum<["colocated", "public", "custom"]>;
|
|
91
|
+
publicPath: z.ZodOptional<z.ZodString>;
|
|
92
|
+
storagePath: z.ZodOptional<z.ZodString>;
|
|
93
|
+
}, "strip", z.ZodTypeAny, {
|
|
94
|
+
strategy: "colocated" | "public" | "custom";
|
|
95
|
+
publicPath?: string | undefined;
|
|
96
|
+
storagePath?: string | undefined;
|
|
97
|
+
}, {
|
|
98
|
+
strategy: "colocated" | "public" | "custom";
|
|
99
|
+
publicPath?: string | undefined;
|
|
100
|
+
storagePath?: string | undefined;
|
|
101
|
+
}>>;
|
|
102
|
+
editor: z.ZodOptional<z.ZodObject<{
|
|
103
|
+
autosave: z.ZodOptional<z.ZodBoolean>;
|
|
104
|
+
autosaveInterval: z.ZodOptional<z.ZodNumber>;
|
|
105
|
+
}, "strip", z.ZodTypeAny, {
|
|
106
|
+
autosave?: boolean | undefined;
|
|
107
|
+
autosaveInterval?: number | undefined;
|
|
108
|
+
}, {
|
|
109
|
+
autosave?: boolean | undefined;
|
|
110
|
+
autosaveInterval?: number | undefined;
|
|
111
|
+
}>>;
|
|
112
|
+
discovery: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
enabled: z.ZodBoolean;
|
|
114
|
+
ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
enabled: boolean;
|
|
117
|
+
ignore?: string[] | undefined;
|
|
118
|
+
}, {
|
|
119
|
+
enabled: boolean;
|
|
120
|
+
ignore?: string[] | undefined;
|
|
121
|
+
}>>;
|
|
122
|
+
versionHistory: z.ZodOptional<z.ZodObject<{
|
|
123
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
124
|
+
maxVersions: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
storagePath: z.ZodOptional<z.ZodString>;
|
|
126
|
+
}, "strip", z.ZodTypeAny, {
|
|
127
|
+
storagePath?: string | undefined;
|
|
128
|
+
enabled?: boolean | undefined;
|
|
129
|
+
maxVersions?: number | undefined;
|
|
130
|
+
}, {
|
|
131
|
+
storagePath?: string | undefined;
|
|
132
|
+
enabled?: boolean | undefined;
|
|
133
|
+
maxVersions?: number | undefined;
|
|
134
|
+
}>>;
|
|
135
|
+
}, "strip", z.ZodTypeAny, {
|
|
136
|
+
collections?: {
|
|
137
|
+
name: string;
|
|
138
|
+
path: string;
|
|
139
|
+
images?: {
|
|
140
|
+
strategy: "colocated" | "public" | "custom";
|
|
141
|
+
publicPath?: string | undefined;
|
|
142
|
+
storagePath?: string | undefined;
|
|
143
|
+
} | undefined;
|
|
144
|
+
filePattern?: string | undefined;
|
|
145
|
+
previewUrl?: string | undefined;
|
|
146
|
+
schema?: Record<string, {
|
|
147
|
+
type: "string" | "number" | "boolean" | "object" | "date" | "array" | "image";
|
|
148
|
+
required?: boolean | undefined;
|
|
149
|
+
default?: unknown;
|
|
150
|
+
items?: string | undefined;
|
|
151
|
+
description?: string | undefined;
|
|
152
|
+
}> | undefined;
|
|
153
|
+
}[] | undefined;
|
|
154
|
+
images?: {
|
|
155
|
+
strategy: "colocated" | "public" | "custom";
|
|
156
|
+
publicPath?: string | undefined;
|
|
157
|
+
storagePath?: string | undefined;
|
|
158
|
+
} | undefined;
|
|
159
|
+
editor?: {
|
|
160
|
+
autosave?: boolean | undefined;
|
|
161
|
+
autosaveInterval?: number | undefined;
|
|
162
|
+
} | undefined;
|
|
163
|
+
discovery?: {
|
|
164
|
+
enabled: boolean;
|
|
165
|
+
ignore?: string[] | undefined;
|
|
166
|
+
} | undefined;
|
|
167
|
+
versionHistory?: {
|
|
168
|
+
storagePath?: string | undefined;
|
|
169
|
+
enabled?: boolean | undefined;
|
|
170
|
+
maxVersions?: number | undefined;
|
|
171
|
+
} | undefined;
|
|
172
|
+
}, {
|
|
173
|
+
collections?: {
|
|
174
|
+
name: string;
|
|
175
|
+
path: string;
|
|
176
|
+
images?: {
|
|
177
|
+
strategy: "colocated" | "public" | "custom";
|
|
178
|
+
publicPath?: string | undefined;
|
|
179
|
+
storagePath?: string | undefined;
|
|
180
|
+
} | undefined;
|
|
181
|
+
filePattern?: string | undefined;
|
|
182
|
+
previewUrl?: string | undefined;
|
|
183
|
+
schema?: Record<string, {
|
|
184
|
+
type: "string" | "number" | "boolean" | "object" | "date" | "array" | "image";
|
|
185
|
+
required?: boolean | undefined;
|
|
186
|
+
default?: unknown;
|
|
187
|
+
items?: string | undefined;
|
|
188
|
+
description?: string | undefined;
|
|
189
|
+
}> | undefined;
|
|
190
|
+
}[] | undefined;
|
|
191
|
+
images?: {
|
|
192
|
+
strategy: "colocated" | "public" | "custom";
|
|
193
|
+
publicPath?: string | undefined;
|
|
194
|
+
storagePath?: string | undefined;
|
|
195
|
+
} | undefined;
|
|
196
|
+
editor?: {
|
|
197
|
+
autosave?: boolean | undefined;
|
|
198
|
+
autosaveInterval?: number | undefined;
|
|
199
|
+
} | undefined;
|
|
200
|
+
discovery?: {
|
|
201
|
+
enabled: boolean;
|
|
202
|
+
ignore?: string[] | undefined;
|
|
203
|
+
} | undefined;
|
|
204
|
+
versionHistory?: {
|
|
205
|
+
storagePath?: string | undefined;
|
|
206
|
+
enabled?: boolean | undefined;
|
|
207
|
+
maxVersions?: number | undefined;
|
|
208
|
+
} | undefined;
|
|
209
|
+
}>;
|
|
210
|
+
/**
|
|
211
|
+
* Schema for integration options
|
|
212
|
+
*/
|
|
213
|
+
declare const writenexOptionsSchema: z.ZodObject<{
|
|
214
|
+
allowProduction: z.ZodOptional<z.ZodBoolean>;
|
|
215
|
+
}, "strip", z.ZodTypeAny, {
|
|
216
|
+
allowProduction?: boolean | undefined;
|
|
217
|
+
}, {
|
|
218
|
+
allowProduction?: boolean | undefined;
|
|
219
|
+
}>;
|
|
220
|
+
/**
|
|
221
|
+
* Helper function for defining type-safe Writenex configuration.
|
|
222
|
+
*
|
|
223
|
+
* This function provides IDE autocompletion and type checking for
|
|
224
|
+
* the configuration object. It's the recommended way to create
|
|
225
|
+
* a writenex.config.ts file.
|
|
226
|
+
*
|
|
227
|
+
* @param config - The Writenex configuration object
|
|
228
|
+
* @returns The same configuration object (identity function for type safety)
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* // writenex.config.ts
|
|
233
|
+
* import { defineConfig } from '@writenex/astro';
|
|
234
|
+
*
|
|
235
|
+
* export default defineConfig({
|
|
236
|
+
* collections: [
|
|
237
|
+
* {
|
|
238
|
+
* name: 'blog',
|
|
239
|
+
* path: 'src/content/blog',
|
|
240
|
+
* filePattern: '{slug}.md',
|
|
241
|
+
* },
|
|
242
|
+
* ],
|
|
243
|
+
* });
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
declare function defineConfig(config: WritenexConfig): WritenexConfig;
|
|
247
|
+
/**
|
|
248
|
+
* Validate a Writenex configuration object
|
|
249
|
+
*
|
|
250
|
+
* @param config - The configuration to validate
|
|
251
|
+
* @returns Validation result with success status and parsed data or errors
|
|
252
|
+
*/
|
|
253
|
+
declare function validateConfig(config: unknown): z.SafeParseReturnType<unknown, WritenexConfig>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @fileoverview Configuration loader for @writenex/astro
|
|
257
|
+
*
|
|
258
|
+
* This module handles loading Writenex configuration from various sources:
|
|
259
|
+
* - writenex.config.ts (TypeScript)
|
|
260
|
+
* - writenex.config.js (JavaScript)
|
|
261
|
+
* - writenex.config.mjs (ES Module)
|
|
262
|
+
*
|
|
263
|
+
* The loader searches for configuration files in the project root and
|
|
264
|
+
* applies default values for any missing options.
|
|
265
|
+
*
|
|
266
|
+
* @module @writenex/astro/config/loader
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Result of loading configuration
|
|
271
|
+
*/
|
|
272
|
+
interface LoadConfigResult {
|
|
273
|
+
/** The loaded and validated configuration with defaults applied */
|
|
274
|
+
config: Required<WritenexConfig>;
|
|
275
|
+
/** Path to the configuration file (if found) */
|
|
276
|
+
configPath: string | null;
|
|
277
|
+
/** Whether a configuration file was found */
|
|
278
|
+
hasConfigFile: boolean;
|
|
279
|
+
/** Any warnings generated during loading */
|
|
280
|
+
warnings: string[];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Find the configuration file in the project root
|
|
284
|
+
*
|
|
285
|
+
* @param projectRoot - The root directory of the Astro project
|
|
286
|
+
* @returns Path to the configuration file, or null if not found
|
|
287
|
+
*/
|
|
288
|
+
declare function findConfigFile(projectRoot: string): string | null;
|
|
289
|
+
/**
|
|
290
|
+
* Load Writenex configuration from the project root
|
|
291
|
+
*
|
|
292
|
+
* This function:
|
|
293
|
+
* 1. Searches for a configuration file in the project root
|
|
294
|
+
* 2. Loads and validates the configuration if found
|
|
295
|
+
* 3. Applies default values for any missing options
|
|
296
|
+
* 4. Returns the resolved configuration
|
|
297
|
+
*
|
|
298
|
+
* If no configuration file is found, default configuration is returned
|
|
299
|
+
* with auto-discovery enabled.
|
|
300
|
+
*
|
|
301
|
+
* @param projectRoot - The root directory of the Astro project
|
|
302
|
+
* @returns LoadConfigResult with the resolved configuration
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```typescript
|
|
306
|
+
* const { config, hasConfigFile, warnings } = await loadConfig('/path/to/project');
|
|
307
|
+
*
|
|
308
|
+
* if (!hasConfigFile) {
|
|
309
|
+
* console.log('Using auto-discovery mode');
|
|
310
|
+
* }
|
|
311
|
+
*
|
|
312
|
+
* if (warnings.length > 0) {
|
|
313
|
+
* warnings.forEach(w => console.warn(w));
|
|
314
|
+
* }
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
declare function loadConfig(projectRoot: string): Promise<LoadConfigResult>;
|
|
318
|
+
/**
|
|
319
|
+
* Check if a content directory exists in the project
|
|
320
|
+
*
|
|
321
|
+
* @param projectRoot - The root directory of the Astro project
|
|
322
|
+
* @param contentPath - Relative path to the content directory
|
|
323
|
+
* @returns True if the content directory exists
|
|
324
|
+
*/
|
|
325
|
+
declare function contentDirectoryExists(projectRoot: string, contentPath?: string): boolean;
|
|
326
|
+
|
|
327
|
+
export { type LoadConfigResult as L, writenexOptionsSchema as a, contentDirectoryExists as c, defineConfig as d, findConfigFile as f, loadConfig as l, validateConfig as v, writenexConfigSchema as w };
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { Connect } from 'vite';
|
|
3
|
+
import { a as WritenexConfig } from '../config-BmEdBDo_.js';
|
|
4
|
+
import { W as WritenexError } from '../errors-C0iYiDTv.js';
|
|
5
|
+
import { D as DiscoveredCollection, a as ContentSummary } from '../content-BWR52vD-.js';
|
|
6
|
+
import { D as DiscoveredImage } from '../image-FP7w5ZIs.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @fileoverview Vite middleware for Writenex routes
|
|
10
|
+
*
|
|
11
|
+
* This module provides the main middleware handler that intercepts requests
|
|
12
|
+
* to Writenex routes (/_writenex/*) and delegates to appropriate handlers.
|
|
13
|
+
*
|
|
14
|
+
* ## Route Structure:
|
|
15
|
+
* - `/_writenex` - Editor UI (HTML page with React app)
|
|
16
|
+
* - `/_writenex/api/*` - API endpoints for CRUD operations
|
|
17
|
+
* - `/_writenex/assets/*` - Static assets (JS, CSS)
|
|
18
|
+
*
|
|
19
|
+
* @module @writenex/astro/server/middleware
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Middleware context passed to handlers
|
|
24
|
+
*/
|
|
25
|
+
interface MiddlewareContext {
|
|
26
|
+
/** Base path for Writenex routes */
|
|
27
|
+
basePath: string;
|
|
28
|
+
/** Project root directory */
|
|
29
|
+
projectRoot: string;
|
|
30
|
+
/** Resolved Writenex configuration */
|
|
31
|
+
config: Required<WritenexConfig>;
|
|
32
|
+
/** Astro trailingSlash setting for preview URLs */
|
|
33
|
+
trailingSlash: "always" | "never" | "ignore";
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create the Writenex middleware handler
|
|
37
|
+
*
|
|
38
|
+
* @param context - Middleware context with configuration
|
|
39
|
+
* @returns Connect middleware function
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const middleware = createMiddleware({
|
|
44
|
+
* basePath: '/_writenex',
|
|
45
|
+
* projectRoot: '/path/to/project',
|
|
46
|
+
* config: resolvedConfig,
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* server.middlewares.use(middleware);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare function createMiddleware(context: MiddlewareContext): Connect.NextHandleFunction;
|
|
53
|
+
/**
|
|
54
|
+
* Parse URL query parameters
|
|
55
|
+
*
|
|
56
|
+
* @param url - The URL string to parse
|
|
57
|
+
* @returns Object with query parameters
|
|
58
|
+
*/
|
|
59
|
+
declare function parseQueryParams(url: string): Record<string, string>;
|
|
60
|
+
/**
|
|
61
|
+
* Parse request body as JSON
|
|
62
|
+
*
|
|
63
|
+
* @param req - The incoming request
|
|
64
|
+
* @returns Parsed JSON body or null
|
|
65
|
+
*/
|
|
66
|
+
declare function parseJsonBody(req: IncomingMessage): Promise<unknown | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Send JSON response
|
|
69
|
+
*
|
|
70
|
+
* @param res - The server response
|
|
71
|
+
* @param data - Data to send as JSON
|
|
72
|
+
* @param statusCode - HTTP status code (default: 200)
|
|
73
|
+
*/
|
|
74
|
+
declare function sendJson(res: ServerResponse, data: unknown, statusCode?: number): void;
|
|
75
|
+
/**
|
|
76
|
+
* Send error response
|
|
77
|
+
*
|
|
78
|
+
* @param res - The server response
|
|
79
|
+
* @param message - Error message
|
|
80
|
+
* @param statusCode - HTTP status code (default: 400)
|
|
81
|
+
*/
|
|
82
|
+
declare function sendError(res: ServerResponse, message: string, statusCode?: number): void;
|
|
83
|
+
/**
|
|
84
|
+
* Send WritenexError response
|
|
85
|
+
*
|
|
86
|
+
* Automatically uses the error's HTTP status code and formats
|
|
87
|
+
* the response using the error's toJSON method.
|
|
88
|
+
*
|
|
89
|
+
* @param res - The server response
|
|
90
|
+
* @param error - WritenexError instance
|
|
91
|
+
*/
|
|
92
|
+
declare function sendWritenexError(res: ServerResponse, error: WritenexError): void;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @fileoverview API route handlers for Writenex
|
|
96
|
+
*
|
|
97
|
+
* This module provides the API router that handles CRUD operations
|
|
98
|
+
* for content collections.
|
|
99
|
+
*
|
|
100
|
+
* ## API Endpoints:
|
|
101
|
+
* - GET /api/collections - List all collections
|
|
102
|
+
* - GET /api/content/:collection - List content in collection
|
|
103
|
+
* - GET /api/content/:collection/:id - Get single content item
|
|
104
|
+
* - POST /api/content/:collection - Create new content
|
|
105
|
+
* - PUT /api/content/:collection/:id - Update content
|
|
106
|
+
* - DELETE /api/content/:collection/:id - Delete content
|
|
107
|
+
* - GET /api/images/:collection/:contentId - Discover images for content
|
|
108
|
+
* - GET /api/images/:collection/:contentId/* - Serve image file
|
|
109
|
+
* - POST /api/images - Upload image
|
|
110
|
+
* - GET /api/versions/:collection/:id - List versions
|
|
111
|
+
* - GET /api/versions/:collection/:id/:versionId - Get version
|
|
112
|
+
* - POST /api/versions/:collection/:id - Create manual version
|
|
113
|
+
* - POST /api/versions/:collection/:id/:versionId/restore - Restore version
|
|
114
|
+
* - GET /api/versions/:collection/:id/:versionId/diff - Get diff data
|
|
115
|
+
* - DELETE /api/versions/:collection/:id/:versionId - Delete version
|
|
116
|
+
* - DELETE /api/versions/:collection/:id - Clear all versions
|
|
117
|
+
*
|
|
118
|
+
* @module @writenex/astro/server/routes
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Create the API router
|
|
123
|
+
*
|
|
124
|
+
* @param context - Middleware context
|
|
125
|
+
* @returns Router function that handles API requests
|
|
126
|
+
*/
|
|
127
|
+
declare function createApiRouter(context: MiddlewareContext): (req: IncomingMessage, res: ServerResponse, path: string) => Promise<void>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @fileoverview Static asset serving for Writenex editor
|
|
131
|
+
*
|
|
132
|
+
* This module handles serving the editor UI HTML and static assets
|
|
133
|
+
* (JavaScript, CSS) for the Writenex editor interface.
|
|
134
|
+
*
|
|
135
|
+
* ## Asset Strategy:
|
|
136
|
+
* - In development: Serve from source with Vite transform
|
|
137
|
+
* - In production: Serve pre-bundled assets from dist/client
|
|
138
|
+
*
|
|
139
|
+
* @module @writenex/astro/server/assets
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Serve the editor HTML page
|
|
144
|
+
*
|
|
145
|
+
* This generates the HTML shell that loads the React editor application.
|
|
146
|
+
* The actual React components will be loaded via the bundled client assets.
|
|
147
|
+
*
|
|
148
|
+
* @param _req - The incoming request
|
|
149
|
+
* @param res - The server response
|
|
150
|
+
* @param context - Middleware context
|
|
151
|
+
*/
|
|
152
|
+
declare function serveEditorHtml(_req: IncomingMessage, res: ServerResponse, context: MiddlewareContext): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Serve static assets (JS, CSS, etc.)
|
|
155
|
+
*
|
|
156
|
+
* @param _req - The incoming request
|
|
157
|
+
* @param res - The server response
|
|
158
|
+
* @param assetPath - Path to the asset (relative to assets directory)
|
|
159
|
+
* @param _context - Middleware context
|
|
160
|
+
*/
|
|
161
|
+
declare function serveAsset(_req: IncomingMessage, res: ServerResponse, assetPath: string, _context: MiddlewareContext): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Get the path to bundled client assets
|
|
164
|
+
*
|
|
165
|
+
* @returns Path to the client dist directory
|
|
166
|
+
*/
|
|
167
|
+
declare function getClientDistPath(): string;
|
|
168
|
+
/**
|
|
169
|
+
* Check if client assets are bundled
|
|
170
|
+
*
|
|
171
|
+
* @returns True if bundled assets exist
|
|
172
|
+
*/
|
|
173
|
+
declare function hasClientBundle(): boolean;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @fileoverview Server-side caching for Writenex
|
|
177
|
+
*
|
|
178
|
+
* Provides in-memory caching for collection discovery and content summaries
|
|
179
|
+
* to improve performance by avoiding repeated filesystem operations.
|
|
180
|
+
*
|
|
181
|
+
* ## Features:
|
|
182
|
+
* - TTL-based cache expiration
|
|
183
|
+
* - Per-collection content caching
|
|
184
|
+
* - Image discovery caching
|
|
185
|
+
* - Manual cache invalidation
|
|
186
|
+
* - Integration with file watcher for automatic invalidation
|
|
187
|
+
*
|
|
188
|
+
* @module @writenex/astro/server/cache
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Server-side cache for collection and content data
|
|
193
|
+
*
|
|
194
|
+
* This cache stores:
|
|
195
|
+
* - Collection discovery results (list of collections with metadata)
|
|
196
|
+
* - Content summaries per collection (list of content items)
|
|
197
|
+
* - Discovered images per content item
|
|
198
|
+
*
|
|
199
|
+
* Cache invalidation happens:
|
|
200
|
+
* - Automatically when TTL expires
|
|
201
|
+
* - Manually via invalidate methods
|
|
202
|
+
* - Via file watcher integration
|
|
203
|
+
*/
|
|
204
|
+
declare class ServerCache {
|
|
205
|
+
/** Cache for collection discovery results */
|
|
206
|
+
private collectionsCache;
|
|
207
|
+
/** Cache for content summaries, keyed by collection name */
|
|
208
|
+
private contentCache;
|
|
209
|
+
/** Cache for discovered images, keyed by "collection:contentId" */
|
|
210
|
+
private imagesCache;
|
|
211
|
+
/** Time-to-live for cache entries in milliseconds */
|
|
212
|
+
private ttl;
|
|
213
|
+
/** Whether file watcher is integrated (allows longer TTL) */
|
|
214
|
+
private hasWatcher;
|
|
215
|
+
constructor(options?: {
|
|
216
|
+
ttl?: number;
|
|
217
|
+
hasWatcher?: boolean;
|
|
218
|
+
});
|
|
219
|
+
/**
|
|
220
|
+
* Enable file watcher integration
|
|
221
|
+
*
|
|
222
|
+
* When watcher is enabled, cache can use longer TTL since
|
|
223
|
+
* invalidation happens via watcher events.
|
|
224
|
+
*/
|
|
225
|
+
enableWatcher(): void;
|
|
226
|
+
/**
|
|
227
|
+
* Check if a cache entry is still valid
|
|
228
|
+
*/
|
|
229
|
+
private isValid;
|
|
230
|
+
/**
|
|
231
|
+
* Get cached collections if valid
|
|
232
|
+
*
|
|
233
|
+
* @returns Cached collections or null if expired/not cached
|
|
234
|
+
*/
|
|
235
|
+
getCollections(): DiscoveredCollection[] | null;
|
|
236
|
+
/**
|
|
237
|
+
* Set collections cache
|
|
238
|
+
*
|
|
239
|
+
* @param collections - Collections to cache
|
|
240
|
+
*/
|
|
241
|
+
setCollections(collections: DiscoveredCollection[]): void;
|
|
242
|
+
/**
|
|
243
|
+
* Invalidate collections cache
|
|
244
|
+
*/
|
|
245
|
+
invalidateCollections(): void;
|
|
246
|
+
/**
|
|
247
|
+
* Get cached content summaries for a collection if valid
|
|
248
|
+
*
|
|
249
|
+
* @param collection - Collection name
|
|
250
|
+
* @returns Cached content summaries or null if expired/not cached
|
|
251
|
+
*/
|
|
252
|
+
getContent(collection: string): ContentSummary[] | null;
|
|
253
|
+
/**
|
|
254
|
+
* Set content cache for a collection
|
|
255
|
+
*
|
|
256
|
+
* @param collection - Collection name
|
|
257
|
+
* @param items - Content summaries to cache
|
|
258
|
+
*/
|
|
259
|
+
setContent(collection: string, items: ContentSummary[]): void;
|
|
260
|
+
/**
|
|
261
|
+
* Invalidate content cache for a specific collection
|
|
262
|
+
*
|
|
263
|
+
* @param collection - Collection name to invalidate
|
|
264
|
+
*/
|
|
265
|
+
invalidateContent(collection: string): void;
|
|
266
|
+
/**
|
|
267
|
+
* Invalidate all content caches
|
|
268
|
+
*/
|
|
269
|
+
invalidateAllContent(): void;
|
|
270
|
+
/**
|
|
271
|
+
* Generate cache key for image cache
|
|
272
|
+
*
|
|
273
|
+
* @param collection - Collection name
|
|
274
|
+
* @param contentId - Content ID
|
|
275
|
+
* @returns Cache key string
|
|
276
|
+
*/
|
|
277
|
+
private getImagesCacheKey;
|
|
278
|
+
/**
|
|
279
|
+
* Get cached images for a content item if valid
|
|
280
|
+
*
|
|
281
|
+
* @param collection - Collection name
|
|
282
|
+
* @param contentId - Content ID
|
|
283
|
+
* @returns Cached images or null if expired/not cached
|
|
284
|
+
*/
|
|
285
|
+
getImages(collection: string, contentId: string): DiscoveredImage[] | null;
|
|
286
|
+
/**
|
|
287
|
+
* Set images cache for a content item
|
|
288
|
+
*
|
|
289
|
+
* @param collection - Collection name
|
|
290
|
+
* @param contentId - Content ID
|
|
291
|
+
* @param images - Discovered images to cache
|
|
292
|
+
*/
|
|
293
|
+
setImages(collection: string, contentId: string, images: DiscoveredImage[]): void;
|
|
294
|
+
/**
|
|
295
|
+
* Invalidate image cache for a specific content item
|
|
296
|
+
*
|
|
297
|
+
* @param collection - Collection name
|
|
298
|
+
* @param contentId - Content ID
|
|
299
|
+
*/
|
|
300
|
+
invalidateImages(collection: string, contentId: string): void;
|
|
301
|
+
/**
|
|
302
|
+
* Invalidate all image caches for a collection
|
|
303
|
+
*
|
|
304
|
+
* @param collection - Collection name
|
|
305
|
+
*/
|
|
306
|
+
invalidateCollectionImages(collection: string): void;
|
|
307
|
+
/**
|
|
308
|
+
* Invalidate all image caches
|
|
309
|
+
*/
|
|
310
|
+
invalidateAllImages(): void;
|
|
311
|
+
/**
|
|
312
|
+
* Invalidate all caches
|
|
313
|
+
*
|
|
314
|
+
* Called when a major change occurs that affects everything.
|
|
315
|
+
*/
|
|
316
|
+
invalidateAll(): void;
|
|
317
|
+
/**
|
|
318
|
+
* Handle file change event from watcher
|
|
319
|
+
*
|
|
320
|
+
* Intelligently invalidates only the affected caches.
|
|
321
|
+
*
|
|
322
|
+
* @param type - Type of file change (add, change, unlink)
|
|
323
|
+
* @param collection - Collection that was affected
|
|
324
|
+
* @param contentId - Optional content ID for targeted image cache invalidation
|
|
325
|
+
*/
|
|
326
|
+
handleFileChange(type: "add" | "change" | "unlink", collection: string, contentId?: string): void;
|
|
327
|
+
/**
|
|
328
|
+
* Get cache statistics for debugging
|
|
329
|
+
*
|
|
330
|
+
* @returns Object with cache stats
|
|
331
|
+
*/
|
|
332
|
+
getStats(): {
|
|
333
|
+
collectionsValid: boolean;
|
|
334
|
+
contentCollections: string[];
|
|
335
|
+
cachedImages: string[];
|
|
336
|
+
ttl: number;
|
|
337
|
+
hasWatcher: boolean;
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Get or create the global cache instance
|
|
342
|
+
*
|
|
343
|
+
* @param options - Cache options (only used on first call)
|
|
344
|
+
* @returns The global cache instance
|
|
345
|
+
*/
|
|
346
|
+
declare function getCache(options?: {
|
|
347
|
+
ttl?: number;
|
|
348
|
+
hasWatcher?: boolean;
|
|
349
|
+
}): ServerCache;
|
|
350
|
+
/**
|
|
351
|
+
* Reset the global cache instance
|
|
352
|
+
*
|
|
353
|
+
* Useful for testing or when configuration changes.
|
|
354
|
+
*/
|
|
355
|
+
declare function resetCache(): void;
|
|
356
|
+
|
|
357
|
+
export { type MiddlewareContext, ServerCache, createApiRouter, createMiddleware, getCache, getClientDistPath, hasClientBundle, parseJsonBody, parseQueryParams, resetCache, sendError, sendJson, sendWritenexError, serveAsset, serveEditorHtml };
|