@useavalon/avalon 0.1.11 → 0.1.13
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 +54 -54
- package/mod.ts +302 -302
- package/package.json +49 -26
- package/src/build/integration-bundler-plugin.ts +116 -116
- package/src/build/integration-config.ts +168 -168
- package/src/build/integration-detection-plugin.ts +117 -117
- package/src/build/integration-resolver-plugin.ts +90 -90
- package/src/build/island-manifest.ts +269 -269
- package/src/build/island-types-generator.ts +476 -476
- package/src/build/mdx-island-transform.ts +464 -464
- package/src/build/mdx-plugin.ts +98 -98
- package/src/build/page-island-transform.ts +598 -598
- package/src/build/prop-extractors/index.ts +21 -21
- package/src/build/prop-extractors/lit.ts +140 -140
- package/src/build/prop-extractors/qwik.ts +16 -16
- package/src/build/prop-extractors/solid.ts +125 -125
- package/src/build/prop-extractors/svelte.ts +194 -194
- package/src/build/prop-extractors/vue.ts +111 -111
- package/src/build/sidecar-file-manager.ts +104 -104
- package/src/build/sidecar-renderer.ts +30 -30
- package/src/client/adapters/index.ts +21 -13
- package/src/client/components.ts +35 -35
- package/src/client/css-hmr-handler.ts +344 -344
- package/src/client/framework-adapter.ts +462 -462
- package/src/client/hmr-coordinator.ts +396 -396
- package/src/client/hmr-error-overlay.js +533 -533
- package/src/client/main.js +824 -816
- package/src/client/types/framework-runtime.d.ts +68 -68
- package/src/client/types/vite-hmr.d.ts +46 -46
- package/src/client/types/vite-virtual-modules.d.ts +70 -60
- package/src/components/Image.tsx +123 -123
- package/src/components/IslandErrorBoundary.tsx +145 -145
- package/src/components/LayoutDataErrorBoundary.tsx +141 -141
- package/src/components/LayoutErrorBoundary.tsx +127 -127
- package/src/components/PersistentIsland.tsx +52 -52
- package/src/components/StreamingErrorBoundary.tsx +233 -233
- package/src/components/StreamingLayout.tsx +538 -538
- package/src/core/components/component-analyzer.ts +192 -192
- package/src/core/components/component-detection.ts +508 -508
- package/src/core/components/enhanced-framework-detector.ts +500 -500
- package/src/core/components/framework-registry.ts +563 -563
- package/src/core/content/mdx-processor.ts +46 -46
- package/src/core/integrations/index.ts +19 -19
- package/src/core/integrations/loader.ts +125 -125
- package/src/core/integrations/registry.ts +175 -175
- package/src/core/islands/island-persistence.ts +325 -325
- package/src/core/islands/island-state-serializer.ts +258 -258
- package/src/core/islands/persistent-island-context.tsx +80 -80
- package/src/core/islands/use-persistent-state.ts +68 -68
- package/src/core/layout/enhanced-layout-resolver.ts +322 -322
- package/src/core/layout/layout-cache-manager.ts +485 -485
- package/src/core/layout/layout-composer.ts +357 -357
- package/src/core/layout/layout-data-loader.ts +516 -516
- package/src/core/layout/layout-discovery.ts +243 -243
- package/src/core/layout/layout-matcher.ts +299 -299
- package/src/core/layout/layout-types.ts +110 -110
- package/src/core/modules/framework-module-resolver.ts +273 -273
- package/src/islands/component-analysis.ts +213 -213
- package/src/islands/css-utils.ts +565 -565
- package/src/islands/discovery/index.ts +80 -80
- package/src/islands/discovery/registry.ts +340 -340
- package/src/islands/discovery/resolver.ts +477 -477
- package/src/islands/discovery/scanner.ts +386 -386
- package/src/islands/discovery/types.ts +117 -117
- package/src/islands/discovery/validator.ts +544 -544
- package/src/islands/discovery/watcher.ts +368 -368
- package/src/islands/framework-detection.ts +428 -428
- package/src/islands/integration-loader.ts +490 -490
- package/src/islands/island.tsx +565 -565
- package/src/islands/render-cache.ts +550 -550
- package/src/islands/types.ts +80 -80
- package/src/islands/universal-css-collector.ts +157 -157
- package/src/islands/universal-head-collector.ts +137 -137
- package/src/layout-system.d.ts +592 -592
- package/src/layout-system.ts +218 -218
- package/src/middleware/discovery.ts +268 -268
- package/src/middleware/executor.ts +315 -315
- package/src/middleware/index.ts +76 -76
- package/src/middleware/types.ts +99 -99
- package/src/nitro/build-config.ts +575 -575
- package/src/nitro/config.ts +483 -483
- package/src/nitro/error-handler.ts +636 -636
- package/src/nitro/index.ts +173 -173
- package/src/nitro/island-manifest.ts +584 -584
- package/src/nitro/middleware-adapter.ts +260 -260
- package/src/nitro/renderer.ts +1471 -1471
- package/src/nitro/route-discovery.ts +439 -439
- package/src/nitro/types.ts +321 -321
- package/src/render/collect-css.ts +198 -198
- package/src/render/error-pages.ts +79 -79
- package/src/render/isolated-ssr-renderer.ts +654 -654
- package/src/render/ssr.ts +1030 -1030
- package/src/schemas/api.ts +30 -30
- package/src/schemas/core.ts +64 -64
- package/src/schemas/index.ts +212 -212
- package/src/schemas/layout.ts +279 -279
- package/src/schemas/routing/index.ts +38 -38
- package/src/schemas/routing.ts +376 -376
- package/src/types/as-island.ts +20 -20
- package/src/types/image.d.ts +106 -106
- package/src/types/index.d.ts +22 -22
- package/src/types/island-jsx.d.ts +33 -33
- package/src/types/island-prop.d.ts +20 -20
- package/src/types/layout.ts +285 -285
- package/src/types/mdx.d.ts +6 -6
- package/src/types/routing.ts +555 -555
- package/src/types/types.ts +5 -5
- package/src/types/urlpattern.d.ts +49 -49
- package/src/types/vite-env.d.ts +11 -11
- package/src/utils/dev-logger.ts +299 -299
- package/src/utils/fs.ts +151 -151
- package/src/vite-plugin/auto-discover.ts +551 -551
- package/src/vite-plugin/config.ts +266 -266
- package/src/vite-plugin/errors.ts +127 -127
- package/src/vite-plugin/image-optimization.ts +156 -156
- package/src/vite-plugin/integration-activator.ts +126 -126
- package/src/vite-plugin/island-sidecar-plugin.ts +176 -176
- package/src/vite-plugin/module-discovery.ts +189 -189
- package/src/vite-plugin/nitro-integration.ts +1354 -1354
- package/src/vite-plugin/plugin.ts +403 -409
- package/src/vite-plugin/types.ts +327 -327
- package/src/vite-plugin/validation.ts +228 -228
- package/src/client/adapters/index.js +0 -12
- package/src/client/adapters/lit-adapter.js +0 -467
- package/src/client/adapters/lit-adapter.ts +0 -654
- package/src/client/adapters/preact-adapter.js +0 -223
- package/src/client/adapters/preact-adapter.ts +0 -331
- package/src/client/adapters/qwik-adapter.js +0 -259
- package/src/client/adapters/qwik-adapter.ts +0 -345
- package/src/client/adapters/react-adapter.js +0 -220
- package/src/client/adapters/react-adapter.ts +0 -353
- package/src/client/adapters/solid-adapter.js +0 -295
- package/src/client/adapters/solid-adapter.ts +0 -451
- package/src/client/adapters/svelte-adapter.js +0 -368
- package/src/client/adapters/svelte-adapter.ts +0 -524
- package/src/client/adapters/vue-adapter.js +0 -278
- package/src/client/adapters/vue-adapter.ts +0 -467
- package/src/client/components.js +0 -23
- package/src/client/css-hmr-handler.js +0 -263
- package/src/client/framework-adapter.js +0 -283
- package/src/client/hmr-coordinator.js +0 -274
|
@@ -1,266 +1,266 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configuration Resolution for Avalon Vite Plugin
|
|
3
|
-
*
|
|
4
|
-
* This module provides default configuration values and the resolution
|
|
5
|
-
* function that merges user configuration with defaults.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
AvalonPluginConfig,
|
|
10
|
-
ResolvedAvalonConfig,
|
|
11
|
-
ResolvedMDXConfig,
|
|
12
|
-
ResolvedModulesConfig,
|
|
13
|
-
ResolvedImageConfig,
|
|
14
|
-
ModulesConfig,
|
|
15
|
-
ImageConfig,
|
|
16
|
-
} from "./types.ts";
|
|
17
|
-
import { existsSync } from "node:fs";
|
|
18
|
-
import { resolve } from "node:path";
|
|
19
|
-
import process from "node:process";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Default MDX configuration values
|
|
23
|
-
*/
|
|
24
|
-
export const DEFAULT_MDX_CONFIG: ResolvedMDXConfig = {
|
|
25
|
-
jsxImportSource: "preact",
|
|
26
|
-
syntaxHighlighting: true,
|
|
27
|
-
remarkPlugins: [],
|
|
28
|
-
rehypePlugins: [],
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Default image optimization configuration values
|
|
33
|
-
*/
|
|
34
|
-
export const DEFAULT_IMAGE_CONFIG: ResolvedImageConfig = {
|
|
35
|
-
enabled: true,
|
|
36
|
-
defaultFormat: "webp",
|
|
37
|
-
quality: 80,
|
|
38
|
-
widths: [200, 400, 600, 800, 1200],
|
|
39
|
-
removeMetadata: true,
|
|
40
|
-
include: /^[^?]+\.(heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/,
|
|
41
|
-
exclude: "public/**/*",
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Default configuration values for the Avalon plugin
|
|
46
|
-
* These are used when the user doesn't provide specific values
|
|
47
|
-
*/
|
|
48
|
-
export const DEFAULT_CONFIG: Omit<ResolvedAvalonConfig, "isDev"> = {
|
|
49
|
-
pagesDir: "src/pages",
|
|
50
|
-
layoutsDir: "src/layouts",
|
|
51
|
-
modules: null,
|
|
52
|
-
integrations: [],
|
|
53
|
-
mdx: DEFAULT_MDX_CONFIG,
|
|
54
|
-
image: DEFAULT_IMAGE_CONFIG,
|
|
55
|
-
verbose: false,
|
|
56
|
-
autoDiscoverIntegrations: true,
|
|
57
|
-
validateIntegrations: true,
|
|
58
|
-
showWarnings: true,
|
|
59
|
-
lazyIntegrations: true,
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Default modules configuration values
|
|
64
|
-
*/
|
|
65
|
-
export const DEFAULT_MODULES_CONFIG = {
|
|
66
|
-
pagesDirName: "pages",
|
|
67
|
-
layoutsDirName: "layouts",
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Resolves the modules configuration
|
|
72
|
-
*/
|
|
73
|
-
function resolveModulesConfig(
|
|
74
|
-
modules: string | ModulesConfig | undefined
|
|
75
|
-
): ResolvedModulesConfig | null {
|
|
76
|
-
if (!modules) return null;
|
|
77
|
-
|
|
78
|
-
if (typeof modules === "string") {
|
|
79
|
-
return {
|
|
80
|
-
dir: modules,
|
|
81
|
-
pagesDirName: DEFAULT_MODULES_CONFIG.pagesDirName,
|
|
82
|
-
layoutsDirName: DEFAULT_MODULES_CONFIG.layoutsDirName,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
dir: modules.dir,
|
|
88
|
-
pagesDirName: modules.pagesDirName ?? DEFAULT_MODULES_CONFIG.pagesDirName,
|
|
89
|
-
layoutsDirName: modules.layoutsDirName ?? DEFAULT_MODULES_CONFIG.layoutsDirName,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Resolves the image optimization configuration
|
|
95
|
-
*/
|
|
96
|
-
function resolveImageConfig(
|
|
97
|
-
image: boolean | ImageConfig | undefined
|
|
98
|
-
): ResolvedImageConfig {
|
|
99
|
-
// Explicitly disabled
|
|
100
|
-
if (image === false) {
|
|
101
|
-
return { ...DEFAULT_IMAGE_CONFIG, enabled: false };
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Default or explicitly enabled with no options
|
|
105
|
-
if (image === undefined || image === true) {
|
|
106
|
-
return DEFAULT_IMAGE_CONFIG;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Custom config object
|
|
110
|
-
return {
|
|
111
|
-
enabled: image.enabled ?? DEFAULT_IMAGE_CONFIG.enabled,
|
|
112
|
-
defaultFormat: image.defaultFormat ?? DEFAULT_IMAGE_CONFIG.defaultFormat,
|
|
113
|
-
quality: image.quality ?? DEFAULT_IMAGE_CONFIG.quality,
|
|
114
|
-
widths: image.widths ?? DEFAULT_IMAGE_CONFIG.widths,
|
|
115
|
-
removeMetadata: image.removeMetadata ?? DEFAULT_IMAGE_CONFIG.removeMetadata,
|
|
116
|
-
include: image.include ?? DEFAULT_IMAGE_CONFIG.include,
|
|
117
|
-
exclude: image.exclude ?? DEFAULT_IMAGE_CONFIG.exclude,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Resolves user configuration by merging with defaults
|
|
123
|
-
*
|
|
124
|
-
* @param userConfig - Partial configuration provided by the user
|
|
125
|
-
* @param isDev - Whether the application is running in development mode
|
|
126
|
-
* @returns Fully resolved configuration with all defaults applied
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
129
|
-
* ```ts
|
|
130
|
-
* const resolved = resolveConfig({ integrations: ["react"] }, true);
|
|
131
|
-
* // resolved.pagesDir === "src/pages" (default)
|
|
132
|
-
* // resolved.integrations === ["react"] (user provided)
|
|
133
|
-
* // resolved.isDev === true
|
|
134
|
-
* ```
|
|
135
|
-
*/
|
|
136
|
-
export function resolveConfig(
|
|
137
|
-
userConfig: AvalonPluginConfig | undefined,
|
|
138
|
-
isDev: boolean
|
|
139
|
-
): ResolvedAvalonConfig {
|
|
140
|
-
const config = userConfig ?? {};
|
|
141
|
-
const modules = resolveModulesConfig(config.modules);
|
|
142
|
-
const image = resolveImageConfig(config.image);
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
pagesDir: config.pagesDir ?? DEFAULT_CONFIG.pagesDir,
|
|
146
|
-
layoutsDir: config.layoutsDir ?? DEFAULT_CONFIG.layoutsDir,
|
|
147
|
-
modules,
|
|
148
|
-
integrations: config.integrations ?? DEFAULT_CONFIG.integrations,
|
|
149
|
-
mdx: {
|
|
150
|
-
jsxImportSource:
|
|
151
|
-
config.mdx?.jsxImportSource ?? DEFAULT_MDX_CONFIG.jsxImportSource,
|
|
152
|
-
syntaxHighlighting:
|
|
153
|
-
config.mdx?.syntaxHighlighting ?? DEFAULT_MDX_CONFIG.syntaxHighlighting,
|
|
154
|
-
remarkPlugins:
|
|
155
|
-
config.mdx?.remarkPlugins ?? DEFAULT_MDX_CONFIG.remarkPlugins,
|
|
156
|
-
rehypePlugins:
|
|
157
|
-
config.mdx?.rehypePlugins ?? DEFAULT_MDX_CONFIG.rehypePlugins,
|
|
158
|
-
},
|
|
159
|
-
image,
|
|
160
|
-
verbose: config.verbose ?? DEFAULT_CONFIG.verbose,
|
|
161
|
-
autoDiscoverIntegrations:
|
|
162
|
-
config.autoDiscoverIntegrations ?? DEFAULT_CONFIG.autoDiscoverIntegrations,
|
|
163
|
-
validateIntegrations:
|
|
164
|
-
config.validateIntegrations ?? DEFAULT_CONFIG.validateIntegrations,
|
|
165
|
-
showWarnings: config.showWarnings ?? DEFAULT_CONFIG.showWarnings,
|
|
166
|
-
lazyIntegrations: config.lazyIntegrations ?? DEFAULT_CONFIG.lazyIntegrations,
|
|
167
|
-
isDev,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Result of directory existence check
|
|
174
|
-
*/
|
|
175
|
-
export interface DirectoryCheckResult {
|
|
176
|
-
/** The directory path that was checked */
|
|
177
|
-
path: string;
|
|
178
|
-
/** The resolved absolute path */
|
|
179
|
-
absolutePath: string;
|
|
180
|
-
/** Whether the directory exists */
|
|
181
|
-
exists: boolean;
|
|
182
|
-
/** The type of directory (pages, layouts) */
|
|
183
|
-
type: "pages" | "layouts";
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Check if configured directories exist and log warnings for missing ones
|
|
188
|
-
*
|
|
189
|
-
* This function checks if the configured directories (pagesDir, layoutsDir)
|
|
190
|
-
* exist on the filesystem. If a directory doesn't exist, it logs a warning but
|
|
191
|
-
* does NOT throw an error, allowing the application to continue.
|
|
192
|
-
*
|
|
193
|
-
* @param config - The resolved Avalon configuration
|
|
194
|
-
* @param projectRoot - The root directory of the project (defaults to process.cwd())
|
|
195
|
-
* @returns Array of directory check results
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* ```ts
|
|
199
|
-
* const results = checkDirectoriesExist(resolvedConfig, '/path/to/project');
|
|
200
|
-
* // Logs warnings for any missing directories
|
|
201
|
-
* // Returns results for programmatic access
|
|
202
|
-
* ```
|
|
203
|
-
*/
|
|
204
|
-
export function checkDirectoriesExist(
|
|
205
|
-
config: ResolvedAvalonConfig,
|
|
206
|
-
projectRoot: string = process.cwd()
|
|
207
|
-
): DirectoryCheckResult[] {
|
|
208
|
-
const directories: Array<{ path: string; type: DirectoryCheckResult["type"] }> = [];
|
|
209
|
-
|
|
210
|
-
// Only check pagesDir if modules is not configured (traditional architecture)
|
|
211
|
-
// When using modular architecture, pages are discovered from modules
|
|
212
|
-
if (!config.modules && config.pagesDir) {
|
|
213
|
-
directories.push({ path: config.pagesDir, type: "pages" });
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Always check layoutsDir if it's set
|
|
217
|
-
if (config.layoutsDir) {
|
|
218
|
-
directories.push({ path: config.layoutsDir, type: "layouts" });
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const results: DirectoryCheckResult[] = [];
|
|
222
|
-
|
|
223
|
-
for (const { path, type } of directories) {
|
|
224
|
-
const absolutePath = resolve(projectRoot, path);
|
|
225
|
-
const exists = existsSync(absolutePath);
|
|
226
|
-
|
|
227
|
-
results.push({
|
|
228
|
-
path,
|
|
229
|
-
absolutePath,
|
|
230
|
-
exists,
|
|
231
|
-
type,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
if (!exists && config.showWarnings) {
|
|
235
|
-
console.warn(
|
|
236
|
-
`⚠️ Avalon: ${type} directory '${path}' does not exist (resolved to: ${absolutePath}). ` +
|
|
237
|
-
`This directory will be skipped.`
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return results;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Log a summary of directory check results
|
|
247
|
-
*
|
|
248
|
-
* @param results - The directory check results
|
|
249
|
-
* @param verbose - Whether to log verbose output
|
|
250
|
-
*/
|
|
251
|
-
export function logDirectoryCheckSummary(
|
|
252
|
-
results: DirectoryCheckResult[],
|
|
253
|
-
verbose: boolean
|
|
254
|
-
): void {
|
|
255
|
-
const missing = results.filter((r) => !r.exists);
|
|
256
|
-
const existing = results.filter((r) => r.exists);
|
|
257
|
-
|
|
258
|
-
if (verbose) {
|
|
259
|
-
if (existing.length > 0) {
|
|
260
|
-
console.log(` ✅ Found directories: ${existing.map((r) => r.path).join(", ")}`);
|
|
261
|
-
}
|
|
262
|
-
if (missing.length > 0) {
|
|
263
|
-
console.log(` ⚠️ Missing directories: ${missing.map((r) => r.path).join(", ")}`);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Resolution for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module provides default configuration values and the resolution
|
|
5
|
+
* function that merges user configuration with defaults.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
AvalonPluginConfig,
|
|
10
|
+
ResolvedAvalonConfig,
|
|
11
|
+
ResolvedMDXConfig,
|
|
12
|
+
ResolvedModulesConfig,
|
|
13
|
+
ResolvedImageConfig,
|
|
14
|
+
ModulesConfig,
|
|
15
|
+
ImageConfig,
|
|
16
|
+
} from "./types.ts";
|
|
17
|
+
import { existsSync } from "node:fs";
|
|
18
|
+
import { resolve } from "node:path";
|
|
19
|
+
import process from "node:process";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Default MDX configuration values
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_MDX_CONFIG: ResolvedMDXConfig = {
|
|
25
|
+
jsxImportSource: "preact",
|
|
26
|
+
syntaxHighlighting: true,
|
|
27
|
+
remarkPlugins: [],
|
|
28
|
+
rehypePlugins: [],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Default image optimization configuration values
|
|
33
|
+
*/
|
|
34
|
+
export const DEFAULT_IMAGE_CONFIG: ResolvedImageConfig = {
|
|
35
|
+
enabled: true,
|
|
36
|
+
defaultFormat: "webp",
|
|
37
|
+
quality: 80,
|
|
38
|
+
widths: [200, 400, 600, 800, 1200],
|
|
39
|
+
removeMetadata: true,
|
|
40
|
+
include: /^[^?]+\.(heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/,
|
|
41
|
+
exclude: "public/**/*",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Default configuration values for the Avalon plugin
|
|
46
|
+
* These are used when the user doesn't provide specific values
|
|
47
|
+
*/
|
|
48
|
+
export const DEFAULT_CONFIG: Omit<ResolvedAvalonConfig, "isDev"> = {
|
|
49
|
+
pagesDir: "src/pages",
|
|
50
|
+
layoutsDir: "src/layouts",
|
|
51
|
+
modules: null,
|
|
52
|
+
integrations: [],
|
|
53
|
+
mdx: DEFAULT_MDX_CONFIG,
|
|
54
|
+
image: DEFAULT_IMAGE_CONFIG,
|
|
55
|
+
verbose: false,
|
|
56
|
+
autoDiscoverIntegrations: true,
|
|
57
|
+
validateIntegrations: true,
|
|
58
|
+
showWarnings: true,
|
|
59
|
+
lazyIntegrations: true,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Default modules configuration values
|
|
64
|
+
*/
|
|
65
|
+
export const DEFAULT_MODULES_CONFIG = {
|
|
66
|
+
pagesDirName: "pages",
|
|
67
|
+
layoutsDirName: "layouts",
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Resolves the modules configuration
|
|
72
|
+
*/
|
|
73
|
+
function resolveModulesConfig(
|
|
74
|
+
modules: string | ModulesConfig | undefined
|
|
75
|
+
): ResolvedModulesConfig | null {
|
|
76
|
+
if (!modules) return null;
|
|
77
|
+
|
|
78
|
+
if (typeof modules === "string") {
|
|
79
|
+
return {
|
|
80
|
+
dir: modules,
|
|
81
|
+
pagesDirName: DEFAULT_MODULES_CONFIG.pagesDirName,
|
|
82
|
+
layoutsDirName: DEFAULT_MODULES_CONFIG.layoutsDirName,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
dir: modules.dir,
|
|
88
|
+
pagesDirName: modules.pagesDirName ?? DEFAULT_MODULES_CONFIG.pagesDirName,
|
|
89
|
+
layoutsDirName: modules.layoutsDirName ?? DEFAULT_MODULES_CONFIG.layoutsDirName,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Resolves the image optimization configuration
|
|
95
|
+
*/
|
|
96
|
+
function resolveImageConfig(
|
|
97
|
+
image: boolean | ImageConfig | undefined
|
|
98
|
+
): ResolvedImageConfig {
|
|
99
|
+
// Explicitly disabled
|
|
100
|
+
if (image === false) {
|
|
101
|
+
return { ...DEFAULT_IMAGE_CONFIG, enabled: false };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Default or explicitly enabled with no options
|
|
105
|
+
if (image === undefined || image === true) {
|
|
106
|
+
return DEFAULT_IMAGE_CONFIG;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Custom config object
|
|
110
|
+
return {
|
|
111
|
+
enabled: image.enabled ?? DEFAULT_IMAGE_CONFIG.enabled,
|
|
112
|
+
defaultFormat: image.defaultFormat ?? DEFAULT_IMAGE_CONFIG.defaultFormat,
|
|
113
|
+
quality: image.quality ?? DEFAULT_IMAGE_CONFIG.quality,
|
|
114
|
+
widths: image.widths ?? DEFAULT_IMAGE_CONFIG.widths,
|
|
115
|
+
removeMetadata: image.removeMetadata ?? DEFAULT_IMAGE_CONFIG.removeMetadata,
|
|
116
|
+
include: image.include ?? DEFAULT_IMAGE_CONFIG.include,
|
|
117
|
+
exclude: image.exclude ?? DEFAULT_IMAGE_CONFIG.exclude,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Resolves user configuration by merging with defaults
|
|
123
|
+
*
|
|
124
|
+
* @param userConfig - Partial configuration provided by the user
|
|
125
|
+
* @param isDev - Whether the application is running in development mode
|
|
126
|
+
* @returns Fully resolved configuration with all defaults applied
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const resolved = resolveConfig({ integrations: ["react"] }, true);
|
|
131
|
+
* // resolved.pagesDir === "src/pages" (default)
|
|
132
|
+
* // resolved.integrations === ["react"] (user provided)
|
|
133
|
+
* // resolved.isDev === true
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export function resolveConfig(
|
|
137
|
+
userConfig: AvalonPluginConfig | undefined,
|
|
138
|
+
isDev: boolean
|
|
139
|
+
): ResolvedAvalonConfig {
|
|
140
|
+
const config = userConfig ?? {};
|
|
141
|
+
const modules = resolveModulesConfig(config.modules);
|
|
142
|
+
const image = resolveImageConfig(config.image);
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
pagesDir: config.pagesDir ?? DEFAULT_CONFIG.pagesDir,
|
|
146
|
+
layoutsDir: config.layoutsDir ?? DEFAULT_CONFIG.layoutsDir,
|
|
147
|
+
modules,
|
|
148
|
+
integrations: config.integrations ?? DEFAULT_CONFIG.integrations,
|
|
149
|
+
mdx: {
|
|
150
|
+
jsxImportSource:
|
|
151
|
+
config.mdx?.jsxImportSource ?? DEFAULT_MDX_CONFIG.jsxImportSource,
|
|
152
|
+
syntaxHighlighting:
|
|
153
|
+
config.mdx?.syntaxHighlighting ?? DEFAULT_MDX_CONFIG.syntaxHighlighting,
|
|
154
|
+
remarkPlugins:
|
|
155
|
+
config.mdx?.remarkPlugins ?? DEFAULT_MDX_CONFIG.remarkPlugins,
|
|
156
|
+
rehypePlugins:
|
|
157
|
+
config.mdx?.rehypePlugins ?? DEFAULT_MDX_CONFIG.rehypePlugins,
|
|
158
|
+
},
|
|
159
|
+
image,
|
|
160
|
+
verbose: config.verbose ?? DEFAULT_CONFIG.verbose,
|
|
161
|
+
autoDiscoverIntegrations:
|
|
162
|
+
config.autoDiscoverIntegrations ?? DEFAULT_CONFIG.autoDiscoverIntegrations,
|
|
163
|
+
validateIntegrations:
|
|
164
|
+
config.validateIntegrations ?? DEFAULT_CONFIG.validateIntegrations,
|
|
165
|
+
showWarnings: config.showWarnings ?? DEFAULT_CONFIG.showWarnings,
|
|
166
|
+
lazyIntegrations: config.lazyIntegrations ?? DEFAULT_CONFIG.lazyIntegrations,
|
|
167
|
+
isDev,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Result of directory existence check
|
|
174
|
+
*/
|
|
175
|
+
export interface DirectoryCheckResult {
|
|
176
|
+
/** The directory path that was checked */
|
|
177
|
+
path: string;
|
|
178
|
+
/** The resolved absolute path */
|
|
179
|
+
absolutePath: string;
|
|
180
|
+
/** Whether the directory exists */
|
|
181
|
+
exists: boolean;
|
|
182
|
+
/** The type of directory (pages, layouts) */
|
|
183
|
+
type: "pages" | "layouts";
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Check if configured directories exist and log warnings for missing ones
|
|
188
|
+
*
|
|
189
|
+
* This function checks if the configured directories (pagesDir, layoutsDir)
|
|
190
|
+
* exist on the filesystem. If a directory doesn't exist, it logs a warning but
|
|
191
|
+
* does NOT throw an error, allowing the application to continue.
|
|
192
|
+
*
|
|
193
|
+
* @param config - The resolved Avalon configuration
|
|
194
|
+
* @param projectRoot - The root directory of the project (defaults to process.cwd())
|
|
195
|
+
* @returns Array of directory check results
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* const results = checkDirectoriesExist(resolvedConfig, '/path/to/project');
|
|
200
|
+
* // Logs warnings for any missing directories
|
|
201
|
+
* // Returns results for programmatic access
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export function checkDirectoriesExist(
|
|
205
|
+
config: ResolvedAvalonConfig,
|
|
206
|
+
projectRoot: string = process.cwd()
|
|
207
|
+
): DirectoryCheckResult[] {
|
|
208
|
+
const directories: Array<{ path: string; type: DirectoryCheckResult["type"] }> = [];
|
|
209
|
+
|
|
210
|
+
// Only check pagesDir if modules is not configured (traditional architecture)
|
|
211
|
+
// When using modular architecture, pages are discovered from modules
|
|
212
|
+
if (!config.modules && config.pagesDir) {
|
|
213
|
+
directories.push({ path: config.pagesDir, type: "pages" });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Always check layoutsDir if it's set
|
|
217
|
+
if (config.layoutsDir) {
|
|
218
|
+
directories.push({ path: config.layoutsDir, type: "layouts" });
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const results: DirectoryCheckResult[] = [];
|
|
222
|
+
|
|
223
|
+
for (const { path, type } of directories) {
|
|
224
|
+
const absolutePath = resolve(projectRoot, path);
|
|
225
|
+
const exists = existsSync(absolutePath);
|
|
226
|
+
|
|
227
|
+
results.push({
|
|
228
|
+
path,
|
|
229
|
+
absolutePath,
|
|
230
|
+
exists,
|
|
231
|
+
type,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
if (!exists && config.showWarnings) {
|
|
235
|
+
console.warn(
|
|
236
|
+
`⚠️ Avalon: ${type} directory '${path}' does not exist (resolved to: ${absolutePath}). ` +
|
|
237
|
+
`This directory will be skipped.`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return results;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Log a summary of directory check results
|
|
247
|
+
*
|
|
248
|
+
* @param results - The directory check results
|
|
249
|
+
* @param verbose - Whether to log verbose output
|
|
250
|
+
*/
|
|
251
|
+
export function logDirectoryCheckSummary(
|
|
252
|
+
results: DirectoryCheckResult[],
|
|
253
|
+
verbose: boolean
|
|
254
|
+
): void {
|
|
255
|
+
const missing = results.filter((r) => !r.exists);
|
|
256
|
+
const existing = results.filter((r) => r.exists);
|
|
257
|
+
|
|
258
|
+
if (verbose) {
|
|
259
|
+
if (existing.length > 0) {
|
|
260
|
+
console.log(` ✅ Found directories: ${existing.map((r) => r.path).join(", ")}`);
|
|
261
|
+
}
|
|
262
|
+
if (missing.length > 0) {
|
|
263
|
+
console.log(` ⚠️ Missing directories: ${missing.map((r) => r.path).join(", ")}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|