@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,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Core utilities barrel file for @writenex/astro
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports shared utilities including error classes,
|
|
5
|
+
* error codes, and constants used across the integration.
|
|
6
|
+
*
|
|
7
|
+
* @module @writenex/astro/core
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from "./errors";
|
|
11
|
+
export * from "./constants";
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Collection discovery for Astro content collections
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to auto-discover content collections
|
|
5
|
+
* from an Astro project's src/content directory.
|
|
6
|
+
*
|
|
7
|
+
* ## Discovery Process:
|
|
8
|
+
* 1. Scan src/content/ for subdirectories
|
|
9
|
+
* 2. Each subdirectory is treated as a collection
|
|
10
|
+
* 3. Count content files in each collection
|
|
11
|
+
* 4. Detect file patterns from existing files
|
|
12
|
+
* 5. Auto-detect frontmatter schema from sample files
|
|
13
|
+
*
|
|
14
|
+
* @module @writenex/astro/discovery/collections
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { readdir, stat } from "node:fs/promises";
|
|
18
|
+
import { existsSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import type { DiscoveredCollection, CollectionConfig } from "@/types";
|
|
21
|
+
import { getCollectionCount } from "@/filesystem/reader";
|
|
22
|
+
import { DEFAULT_FILE_PATTERN } from "@/config/defaults";
|
|
23
|
+
import { detectFilePattern as detectPattern } from "./patterns";
|
|
24
|
+
import { detectSchema } from "./schema";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Default content directory path relative to project root
|
|
28
|
+
*/
|
|
29
|
+
const DEFAULT_CONTENT_DIR = "src/content";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Directories to ignore during discovery
|
|
33
|
+
*/
|
|
34
|
+
const IGNORED_DIRECTORIES = new Set(["node_modules", ".git", "_", "."]);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if a directory should be ignored
|
|
38
|
+
*
|
|
39
|
+
* @param name - Directory name
|
|
40
|
+
* @returns True if should be ignored
|
|
41
|
+
*/
|
|
42
|
+
function shouldIgnore(name: string): boolean {
|
|
43
|
+
return (
|
|
44
|
+
IGNORED_DIRECTORIES.has(name) ||
|
|
45
|
+
name.startsWith("_") ||
|
|
46
|
+
name.startsWith(".")
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Discover all content collections in a project
|
|
52
|
+
*
|
|
53
|
+
* Scans the src/content directory for subdirectories and treats
|
|
54
|
+
* each as a content collection.
|
|
55
|
+
*
|
|
56
|
+
* @param projectRoot - Absolute path to the project root
|
|
57
|
+
* @param contentDir - Relative path to content directory (default: src/content)
|
|
58
|
+
* @returns Array of discovered collections
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const collections = await discoverCollections('/path/to/project');
|
|
63
|
+
* // Returns: [
|
|
64
|
+
* // { name: 'blog', path: 'src/content/blog', count: 10, ... },
|
|
65
|
+
* // { name: 'docs', path: 'src/content/docs', count: 5, ... },
|
|
66
|
+
* // ]
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export async function discoverCollections(
|
|
70
|
+
projectRoot: string,
|
|
71
|
+
contentDir: string = DEFAULT_CONTENT_DIR
|
|
72
|
+
): Promise<DiscoveredCollection[]> {
|
|
73
|
+
const contentPath = join(projectRoot, contentDir);
|
|
74
|
+
|
|
75
|
+
// Check if content directory exists
|
|
76
|
+
if (!existsSync(contentPath)) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const collections: DiscoveredCollection[] = [];
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const entries = await readdir(contentPath, { withFileTypes: true });
|
|
84
|
+
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
// Skip non-directories and ignored directories
|
|
87
|
+
if (!entry.isDirectory() || shouldIgnore(entry.name)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const collectionPath = join(contentPath, entry.name);
|
|
92
|
+
const relativePath = join(contentDir, entry.name);
|
|
93
|
+
|
|
94
|
+
// Count content files in this collection
|
|
95
|
+
const count = await getCollectionCount(collectionPath);
|
|
96
|
+
|
|
97
|
+
// Detect file pattern using pattern detection module
|
|
98
|
+
const patternResult = await detectPattern(collectionPath);
|
|
99
|
+
const filePattern = patternResult.pattern;
|
|
100
|
+
|
|
101
|
+
// Auto-detect schema from sample files
|
|
102
|
+
const schemaResult = await detectSchema(collectionPath);
|
|
103
|
+
const schema =
|
|
104
|
+
Object.keys(schemaResult.schema).length > 0
|
|
105
|
+
? schemaResult.schema
|
|
106
|
+
: undefined;
|
|
107
|
+
|
|
108
|
+
// Generate default preview URL pattern
|
|
109
|
+
const previewUrl = `/${entry.name}/{slug}`;
|
|
110
|
+
|
|
111
|
+
collections.push({
|
|
112
|
+
name: entry.name,
|
|
113
|
+
path: relativePath,
|
|
114
|
+
filePattern,
|
|
115
|
+
count,
|
|
116
|
+
schema,
|
|
117
|
+
previewUrl,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error(`[writenex] Failed to discover collections: ${error}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return collections;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Merge discovered collections with configured collections
|
|
129
|
+
*
|
|
130
|
+
* Configured collections take precedence over discovered ones.
|
|
131
|
+
* This allows users to override auto-discovered settings.
|
|
132
|
+
*
|
|
133
|
+
* @param discovered - Auto-discovered collections
|
|
134
|
+
* @param configured - User-configured collections
|
|
135
|
+
* @returns Merged collection list
|
|
136
|
+
*/
|
|
137
|
+
export function mergeCollections(
|
|
138
|
+
discovered: DiscoveredCollection[],
|
|
139
|
+
configured: CollectionConfig[]
|
|
140
|
+
): DiscoveredCollection[] {
|
|
141
|
+
const configuredNames = new Set(configured.map((c) => c.name));
|
|
142
|
+
const result: DiscoveredCollection[] = [];
|
|
143
|
+
|
|
144
|
+
// Add configured collections first (they take precedence)
|
|
145
|
+
for (const config of configured) {
|
|
146
|
+
const discoveredMatch = discovered.find((d) => d.name === config.name);
|
|
147
|
+
|
|
148
|
+
result.push({
|
|
149
|
+
name: config.name,
|
|
150
|
+
path: config.path,
|
|
151
|
+
filePattern:
|
|
152
|
+
config.filePattern ??
|
|
153
|
+
discoveredMatch?.filePattern ??
|
|
154
|
+
DEFAULT_FILE_PATTERN,
|
|
155
|
+
count: discoveredMatch?.count ?? 0,
|
|
156
|
+
schema: config.schema ?? discoveredMatch?.schema,
|
|
157
|
+
previewUrl:
|
|
158
|
+
config.previewUrl ??
|
|
159
|
+
discoveredMatch?.previewUrl ??
|
|
160
|
+
`/${config.name}/{slug}`,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Add discovered collections that weren't configured
|
|
165
|
+
for (const disc of discovered) {
|
|
166
|
+
if (!configuredNames.has(disc.name)) {
|
|
167
|
+
result.push(disc);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get a single collection by name
|
|
176
|
+
*
|
|
177
|
+
* @param projectRoot - Absolute path to the project root
|
|
178
|
+
* @param collectionName - Name of the collection
|
|
179
|
+
* @param contentDir - Relative path to content directory
|
|
180
|
+
* @returns The collection if found, undefined otherwise
|
|
181
|
+
*/
|
|
182
|
+
export async function getCollection(
|
|
183
|
+
projectRoot: string,
|
|
184
|
+
collectionName: string,
|
|
185
|
+
contentDir: string = DEFAULT_CONTENT_DIR
|
|
186
|
+
): Promise<DiscoveredCollection | undefined> {
|
|
187
|
+
const collections = await discoverCollections(projectRoot, contentDir);
|
|
188
|
+
return collections.find((c) => c.name === collectionName);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Check if a collection exists
|
|
193
|
+
*
|
|
194
|
+
* @param projectRoot - Absolute path to the project root
|
|
195
|
+
* @param collectionName - Name of the collection
|
|
196
|
+
* @param contentDir - Relative path to content directory
|
|
197
|
+
* @returns True if the collection exists
|
|
198
|
+
*/
|
|
199
|
+
export async function collectionExists(
|
|
200
|
+
projectRoot: string,
|
|
201
|
+
collectionName: string,
|
|
202
|
+
contentDir: string = DEFAULT_CONTENT_DIR
|
|
203
|
+
): Promise<boolean> {
|
|
204
|
+
const collectionPath = join(projectRoot, contentDir, collectionName);
|
|
205
|
+
|
|
206
|
+
if (!existsSync(collectionPath)) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
const stats = await stat(collectionPath);
|
|
212
|
+
return stats.isDirectory();
|
|
213
|
+
} catch {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Discovery module exports for @writenex/astro
|
|
3
|
+
*
|
|
4
|
+
* This module provides the public API for collection discovery,
|
|
5
|
+
* file pattern detection, and schema auto-detection.
|
|
6
|
+
*
|
|
7
|
+
* @module @writenex/astro/discovery
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Collection discovery
|
|
11
|
+
export {
|
|
12
|
+
discoverCollections,
|
|
13
|
+
mergeCollections,
|
|
14
|
+
getCollection,
|
|
15
|
+
collectionExists,
|
|
16
|
+
} from "./collections";
|
|
17
|
+
|
|
18
|
+
// Pattern detection
|
|
19
|
+
export {
|
|
20
|
+
detectFilePattern,
|
|
21
|
+
generatePathFromPattern,
|
|
22
|
+
parsePatternTokens,
|
|
23
|
+
validatePattern,
|
|
24
|
+
getPatternExtension,
|
|
25
|
+
resolvePatternTokens,
|
|
26
|
+
isValidPattern,
|
|
27
|
+
getSupportedTokens,
|
|
28
|
+
} from "./patterns";
|
|
29
|
+
export type { PatternDetectionResult, ResolveTokensOptions } from "./patterns";
|
|
30
|
+
|
|
31
|
+
// Schema detection
|
|
32
|
+
export { detectSchema, mergeSchema, describeSchema } from "./schema";
|
|
33
|
+
export type { SchemaDetectionResult } from "./schema";
|