@nuasite/cms-marker 0.0.65 → 0.0.66

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.
Files changed (36) hide show
  1. package/dist/types/build-processor.d.ts +2 -1
  2. package/dist/types/build-processor.d.ts.map +1 -1
  3. package/dist/types/component-registry.d.ts.map +1 -1
  4. package/dist/types/config.d.ts +19 -0
  5. package/dist/types/config.d.ts.map +1 -0
  6. package/dist/types/dev-middleware.d.ts +10 -2
  7. package/dist/types/dev-middleware.d.ts.map +1 -1
  8. package/dist/types/error-collector.d.ts +56 -0
  9. package/dist/types/error-collector.d.ts.map +1 -0
  10. package/dist/types/html-processor.d.ts.map +1 -1
  11. package/dist/types/index.d.ts +2 -1
  12. package/dist/types/index.d.ts.map +1 -1
  13. package/dist/types/manifest-writer.d.ts.map +1 -1
  14. package/dist/types/source-finder.d.ts +18 -3
  15. package/dist/types/source-finder.d.ts.map +1 -1
  16. package/dist/types/tailwind-colors.d.ts.map +1 -1
  17. package/dist/types/tsconfig.tsbuildinfo +1 -1
  18. package/dist/types/types.d.ts +0 -4
  19. package/dist/types/types.d.ts.map +1 -1
  20. package/dist/types/vite-plugin.d.ts.map +1 -1
  21. package/package.json +2 -1
  22. package/src/build-processor.ts +73 -19
  23. package/src/component-registry.ts +2 -0
  24. package/src/config.ts +29 -0
  25. package/src/dev-middleware.ts +12 -4
  26. package/src/error-collector.ts +106 -0
  27. package/src/html-processor.ts +55 -37
  28. package/src/index.ts +20 -4
  29. package/src/manifest-writer.ts +12 -2
  30. package/src/source-finder.ts +1003 -295
  31. package/src/tailwind-colors.ts +248 -48
  32. package/src/types.ts +0 -4
  33. package/src/vite-plugin.ts +4 -12
  34. package/dist/types/astro-transform.d.ts +0 -21
  35. package/dist/types/astro-transform.d.ts.map +0 -1
  36. package/src/astro-transform.ts +0 -205
@@ -139,10 +139,6 @@ export interface ManifestEntry {
139
139
  collectionSlug?: string;
140
140
  /** Path to the markdown content file (e.g., 'src/content/blog/my-post.md') */
141
141
  contentPath?: string;
142
- /** Image source URL (for image entries) - deprecated, use imageMetadata */
143
- imageSrc?: string;
144
- /** Image alt text (for image entries) - deprecated, use imageMetadata */
145
- imageAlt?: string;
146
142
  /** Stable ID derived from content + context hash, survives rebuilds */
147
143
  stableId?: string;
148
144
  /** SHA256 hash of sourceSnippet at generation time for conflict detection */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAEpE,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,cAAc,CAAA;IAC9B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IACzD,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAClC,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5B,OAAO,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;CAC7C;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAoCrE"}
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAEpE,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,cAAc,CAAA;IAC9B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IACzD,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAClC,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5B,OAAO,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;CAC7C;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CA6BrE"}
package/package.json CHANGED
@@ -14,12 +14,13 @@
14
14
  "directory": "packages/cms-marker"
15
15
  },
16
16
  "license": "Apache-2.0",
17
- "version": "0.0.65",
17
+ "version": "0.0.66",
18
18
  "module": "src/index.ts",
19
19
  "types": "src/index.ts",
20
20
  "type": "module",
21
21
  "dependencies": {
22
22
  "@astrojs/compiler": "^2.13.0",
23
+ "@babel/parser": "^7.24.0",
23
24
  "astro": "^5.16.6",
24
25
  "node-html-parser": "^6.1.13"
25
26
  },
@@ -4,7 +4,15 @@ import path from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import { processHtml } from './html-processor'
6
6
  import type { ManifestWriter } from './manifest-writer'
7
- import { findCollectionSource, findImageSourceLocation, findMarkdownSourceLocation, findSourceLocation, parseMarkdownContent } from './source-finder'
7
+ import {
8
+ clearSourceFinderCache,
9
+ findCollectionSource,
10
+ findImageSourceLocation,
11
+ findMarkdownSourceLocation,
12
+ findSourceLocation,
13
+ initializeSearchIndex,
14
+ parseMarkdownContent,
15
+ } from './source-finder'
8
16
  import type { CmsMarkerOptions, CollectionEntry } from './types'
9
17
 
10
18
  // Concurrency limit for parallel processing
@@ -110,22 +118,23 @@ async function processFile(
110
118
  }
111
119
  }
112
120
 
113
- for (const entry of Object.values(result.entries)) {
121
+ // Process entries in parallel for better performance
122
+ const entryLookups = Object.values(result.entries).map(async (entry) => {
114
123
  // Skip entries that already have source info from component detection
115
124
  if (entry.sourcePath && !entry.sourcePath.endsWith('.html')) {
116
- continue
125
+ return
117
126
  }
118
127
 
119
128
  // Handle image entries specially - search by image src
120
- if (entry.sourceType === 'image' && entry.imageSrc) {
121
- const imageSource = await findImageSourceLocation(entry.imageSrc)
129
+ if (entry.sourceType === 'image' && entry.imageMetadata?.src) {
130
+ const imageSource = await findImageSourceLocation(entry.imageMetadata.src)
122
131
  if (imageSource) {
123
132
  entry.sourcePath = imageSource.file
124
133
  entry.sourceLine = imageSource.line
125
134
  entry.sourceSnippet = imageSource.snippet
126
135
  entry.sourceType = 'image'
127
136
  }
128
- continue
137
+ return
129
138
  }
130
139
 
131
140
  // Try to find source in collection markdown frontmatter first
@@ -139,7 +148,7 @@ async function processFile(
139
148
  entry.variableName = mdSource.variableName
140
149
  entry.collectionName = mdSource.collectionName
141
150
  entry.collectionSlug = mdSource.collectionSlug
142
- continue
151
+ return
143
152
  }
144
153
  }
145
154
 
@@ -152,7 +161,9 @@ async function processFile(
152
161
  entry.sourceType = sourceLocation.type
153
162
  entry.variableName = sourceLocation.variableName
154
163
  }
155
- }
164
+ })
165
+
166
+ await Promise.all(entryLookups)
156
167
 
157
168
  // Add to manifest writer (handles per-page manifest writes)
158
169
  manifestWriter.addPage(pagePath, result.entries, result.components, collectionEntry)
@@ -163,8 +174,15 @@ async function processFile(
163
174
  return Object.keys(result.entries).length
164
175
  }
165
176
 
177
+ /** Result of batch processing with error aggregation */
178
+ interface BatchProcessingResult {
179
+ totalEntries: number
180
+ errors: Array<{ file: string; error: Error }>
181
+ }
182
+
166
183
  /**
167
- * Process HTML files in parallel with concurrency limit
184
+ * Process HTML files in parallel with concurrency limit and error aggregation.
185
+ * Unlike Promise.all, this continues processing even if some files fail.
168
186
  */
169
187
  async function processFilesInBatches(
170
188
  files: string[],
@@ -172,23 +190,37 @@ async function processFilesInBatches(
172
190
  config: Required<CmsMarkerOptions>,
173
191
  manifestWriter: ManifestWriter,
174
192
  idCounter: { value: number },
175
- ): Promise<number> {
193
+ ): Promise<BatchProcessingResult> {
176
194
  let totalEntries = 0
195
+ const errors: Array<{ file: string; error: Error }> = []
177
196
 
178
197
  // Process files in batches of MAX_CONCURRENT
179
198
  for (let i = 0; i < files.length; i += MAX_CONCURRENT) {
180
199
  const batch = files.slice(i, i + MAX_CONCURRENT)
181
- const results = await Promise.all(
182
- batch.map(file => processFile(file, outDir, config, manifestWriter, idCounter)),
200
+ const results = await Promise.allSettled(
201
+ batch.map(file =>
202
+ processFile(file, outDir, config, manifestWriter, idCounter)
203
+ .then(count => ({ file, count }))
204
+ .catch(err => Promise.reject({ file, error: err }))
205
+ ),
183
206
  )
184
- totalEntries += results.reduce((sum, count) => sum + count, 0)
207
+
208
+ for (const result of results) {
209
+ if (result.status === 'fulfilled') {
210
+ totalEntries += result.value.count
211
+ } else {
212
+ const { file, error } = result.reason as { file: string; error: Error }
213
+ errors.push({ file, error })
214
+ }
215
+ }
185
216
  }
186
217
 
187
- return totalEntries
218
+ return { totalEntries, errors }
188
219
  }
189
220
 
190
221
  /**
191
- * Process build output - processes all HTML files in parallel
222
+ * Process build output - processes all HTML files in parallel.
223
+ * Uses error aggregation to continue processing even if some files fail.
192
224
  */
193
225
  export async function processBuildOutput(
194
226
  dir: URL,
@@ -200,6 +232,9 @@ export async function processBuildOutput(
200
232
  const outDir = fileURLToPath(dir)
201
233
  manifestWriter.setOutDir(outDir)
202
234
 
235
+ // Clear caches from previous builds and initialize search index
236
+ clearSourceFinderCache()
237
+
203
238
  const htmlFiles = await findHtmlFiles(outDir)
204
239
 
205
240
  if (htmlFiles.length === 0) {
@@ -209,17 +244,36 @@ export async function processBuildOutput(
209
244
 
210
245
  const startTime = Date.now()
211
246
 
212
- // Process all files in parallel batches
213
- await processFilesInBatches(htmlFiles, outDir, config, manifestWriter, idCounter)
247
+ // Pre-build search index for fast source lookups (single pass through all source files)
248
+ await initializeSearchIndex()
249
+
250
+ // Process all files in parallel batches with error aggregation
251
+ const { totalEntries, errors } = await processFilesInBatches(htmlFiles, outDir, config, manifestWriter, idCounter)
252
+
253
+ // Report any errors that occurred during processing
254
+ if (errors.length > 0) {
255
+ const errorLog = logger?.error?.bind(logger) ?? console.error.bind(console)
256
+ errorLog(`[astro-cms-marker] ${errors.length} file(s) failed to process:`)
257
+ for (const { file, error } of errors) {
258
+ const relPath = path.relative(outDir, file)
259
+ errorLog(` - ${relPath}: ${error.message}`)
260
+ }
261
+ }
214
262
 
215
263
  // Finalize manifest (writes global manifest and waits for all per-page writes)
216
264
  const stats = await manifestWriter.finalize()
217
265
 
218
266
  const duration = Date.now() - startTime
219
- const msg = `Processed ${stats.totalPages} pages with ${stats.totalEntries} entries and ${stats.totalComponents} components in ${duration}ms`
267
+ const successCount = htmlFiles.length - errors.length
268
+ const msg =
269
+ `Processed ${successCount}/${htmlFiles.length} pages with ${stats.totalEntries} entries and ${stats.totalComponents} components in ${duration}ms`
220
270
 
221
271
  if (logger) {
222
- logger.info(msg)
272
+ if (errors.length > 0) {
273
+ logger.warn(msg)
274
+ } else {
275
+ logger.info(msg)
276
+ }
223
277
  } else {
224
278
  console.log(`[astro-cms-marker] ${msg}`)
225
279
  }
@@ -1,5 +1,7 @@
1
1
  import fs from 'node:fs/promises'
2
2
  import path from 'node:path'
3
+ import { getProjectRoot } from './config'
4
+ import { getErrorCollector } from './error-collector'
3
5
  import type { ComponentDefinition, ComponentProp } from './types'
4
6
 
5
7
  /**
package/src/config.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Global configuration for cms-marker.
3
+ * This allows overriding the project root for testing.
4
+ */
5
+
6
+ let projectRootOverride: string | null = null
7
+
8
+ /**
9
+ * Get the current project root directory.
10
+ * Returns the override if set, otherwise process.cwd().
11
+ */
12
+ export function getProjectRoot(): string {
13
+ return projectRootOverride ?? process.cwd()
14
+ }
15
+
16
+ /**
17
+ * Set the project root directory override.
18
+ * Call this to use a specific directory instead of process.cwd().
19
+ */
20
+ export function setProjectRoot(root: string): void {
21
+ projectRootOverride = root
22
+ }
23
+
24
+ /**
25
+ * Reset the project root to use process.cwd() again.
26
+ */
27
+ export function resetProjectRoot(): void {
28
+ projectRootOverride = null
29
+ }
@@ -1,9 +1,17 @@
1
- import type { ViteDevServer } from 'vite'
1
+ import type { IncomingMessage, ServerResponse } from 'node:http'
2
2
  import { processHtml } from './html-processor'
3
3
  import type { ManifestWriter } from './manifest-writer'
4
4
  import { findCollectionSource, findImageSourceLocation, parseMarkdownContent } from './source-finder'
5
5
  import type { CmsMarkerOptions, CollectionEntry, ComponentDefinition } from './types'
6
6
 
7
+ /** Minimal ViteDevServer interface to avoid version conflicts between Astro's bundled Vite and root Vite */
8
+ interface ViteDevServerLike {
9
+ middlewares: {
10
+ use: (middleware: (req: IncomingMessage, res: ServerResponse, next: () => void) => void) => void
11
+ }
12
+ transformIndexHtml: (url: string, html: string) => Promise<string>
13
+ }
14
+
7
15
  /**
8
16
  * Get the normalized page path from a URL
9
17
  * For example: /about/ -> /about
@@ -21,7 +29,7 @@ function normalizePagePath(url: string): string {
21
29
  }
22
30
 
23
31
  export function createDevMiddleware(
24
- server: ViteDevServer,
32
+ server: ViteDevServerLike,
25
33
  config: Required<CmsMarkerOptions>,
26
34
  manifestWriter: ManifestWriter,
27
35
  componentDefinitions: Record<string, ComponentDefinition>,
@@ -217,8 +225,8 @@ async function processHtmlForDev(
217
225
  // However, images may not have source info if their ancestors don't have it
218
226
  // In that case, fall back to searching for the image src
219
227
  for (const entry of Object.values(result.entries)) {
220
- if (entry.sourceType === 'image' && entry.imageSrc && !entry.sourcePath) {
221
- const imageSource = await findImageSourceLocation(entry.imageSrc)
228
+ if (entry.sourceType === 'image' && entry.imageMetadata?.src && !entry.sourcePath) {
229
+ const imageSource = await findImageSourceLocation(entry.imageMetadata.src)
222
230
  if (imageSource) {
223
231
  entry.sourcePath = imageSource.file
224
232
  entry.sourceLine = imageSource.line
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Collects errors during processing for aggregated reporting.
3
+ * This allows the build to continue while tracking what failed.
4
+ */
5
+ export class ErrorCollector {
6
+ private errors: Array<{ context: string; error: Error }> = []
7
+ private warnings: Array<{ context: string; message: string }> = []
8
+
9
+ /**
10
+ * Record an error with context about where it occurred.
11
+ */
12
+ addError(context: string, error: Error): void {
13
+ this.errors.push({ context, error })
14
+ }
15
+
16
+ /**
17
+ * Record a warning (non-fatal issue).
18
+ */
19
+ addWarning(context: string, message: string): void {
20
+ this.warnings.push({ context, message })
21
+ }
22
+
23
+ /**
24
+ * Check if any errors were recorded.
25
+ */
26
+ hasErrors(): boolean {
27
+ return this.errors.length > 0
28
+ }
29
+
30
+ /**
31
+ * Check if any warnings were recorded.
32
+ */
33
+ hasWarnings(): boolean {
34
+ return this.warnings.length > 0
35
+ }
36
+
37
+ /**
38
+ * Get all recorded errors.
39
+ */
40
+ getErrors(): ReadonlyArray<{ context: string; error: Error }> {
41
+ return this.errors
42
+ }
43
+
44
+ /**
45
+ * Get all recorded warnings.
46
+ */
47
+ getWarnings(): ReadonlyArray<{ context: string; message: string }> {
48
+ return this.warnings
49
+ }
50
+
51
+ /**
52
+ * Get a summary of all errors and warnings.
53
+ */
54
+ getSummary(): string {
55
+ const lines: string[] = []
56
+
57
+ if (this.errors.length > 0) {
58
+ lines.push(`${this.errors.length} error(s):`)
59
+ for (const { context, error } of this.errors) {
60
+ lines.push(` - ${context}: ${error.message}`)
61
+ }
62
+ }
63
+
64
+ if (this.warnings.length > 0) {
65
+ lines.push(`${this.warnings.length} warning(s):`)
66
+ for (const { context, message } of this.warnings) {
67
+ lines.push(` - ${context}: ${message}`)
68
+ }
69
+ }
70
+
71
+ return lines.join('\n')
72
+ }
73
+
74
+ /**
75
+ * Clear all recorded errors and warnings.
76
+ */
77
+ clear(): void {
78
+ this.errors = []
79
+ this.warnings = []
80
+ }
81
+ }
82
+
83
+ /** Singleton error collector for the build process */
84
+ let globalErrorCollector: ErrorCollector | null = null
85
+
86
+ /**
87
+ * Get the global error collector instance.
88
+ * Creates one if it doesn't exist.
89
+ */
90
+ export function getErrorCollector(): ErrorCollector {
91
+ if (!globalErrorCollector) {
92
+ globalErrorCollector = new ErrorCollector()
93
+ }
94
+ return globalErrorCollector
95
+ }
96
+
97
+ /**
98
+ * Reset the global error collector (call at start of each build).
99
+ */
100
+ export function resetErrorCollector(): void {
101
+ if (globalErrorCollector) {
102
+ globalErrorCollector.clear()
103
+ } else {
104
+ globalErrorCollector = new ErrorCollector()
105
+ }
106
+ }
@@ -1,9 +1,12 @@
1
- import { parse } from 'node-html-parser'
1
+ import { type HTMLElement as ParsedHTMLElement, parse } from 'node-html-parser'
2
2
  import { enhanceManifestWithSourceSnippets } from './source-finder'
3
3
  import { extractColorClasses } from './tailwind-colors'
4
- import type { ComponentInstance, ManifestEntry, SourceContext } from './types'
4
+ import type { ComponentInstance, ImageMetadata, ManifestEntry, SourceContext } from './types'
5
5
  import { generateStableId } from './utils'
6
6
 
7
+ /** Type for parsed HTML element nodes from node-html-parser */
8
+ type HTMLNode = ParsedHTMLElement
9
+
7
10
  /**
8
11
  * Inline text styling elements that should NOT be marked with CMS IDs.
9
12
  * These elements are text formatting and should be part of their parent's content.
@@ -187,7 +190,7 @@ export async function processHtml(
187
190
  const entries: Record<string, ManifestEntry> = {}
188
191
  const components: Record<string, ComponentInstance> = {}
189
192
  const sourceLocationMap = new Map<string, { file: string; line: number }>()
190
- const markedComponentRoots = new Set<any>()
193
+ const markedComponentRoots = new Set<HTMLNode>()
191
194
  let collectionWrapperId: string | undefined
192
195
 
193
196
  // First pass: detect and mark component root elements
@@ -222,15 +225,15 @@ export async function processHtml(
222
225
 
223
226
  // Check if any ancestor is already marked as a component root from the same file
224
227
  // (we only want to mark the outermost element from each component)
225
- let parent = node.parentNode
228
+ let parent = node.parentNode as HTMLNode | null
226
229
  let ancestorFromSameComponent = false
227
230
  while (parent) {
228
- const parentSource = (parent as any).getAttribute?.('data-astro-source-file')
231
+ const parentSource = parent.getAttribute?.('data-astro-source-file')
229
232
  if (parentSource === sourceFile) {
230
233
  ancestorFromSameComponent = true
231
234
  break
232
235
  }
233
- parent = parent.parentNode
236
+ parent = parent.parentNode as HTMLNode | null
234
237
  }
235
238
 
236
239
  if (ancestorFromSameComponent) return
@@ -279,7 +282,12 @@ export async function processHtml(
279
282
 
280
283
  // Image detection pass: mark img elements for CMS image replacement
281
284
  // Store image entries separately to add to manifest later
282
- const imageEntries = new Map<string, { src: string; alt: string; sourceFile?: string; sourceLine?: number }>()
285
+ interface ImageEntry {
286
+ metadata: ImageMetadata
287
+ sourceFile?: string
288
+ sourceLine?: number
289
+ }
290
+ const imageEntries = new Map<string, ImageEntry>()
283
291
  root.querySelectorAll('img').forEach((node) => {
284
292
  // Skip if already marked
285
293
  if (node.getAttribute(attributeName)) return
@@ -294,7 +302,7 @@ export async function processHtml(
294
302
  // Try to get source location from the image itself or ancestors
295
303
  let sourceFile: string | undefined
296
304
  let sourceLine: number | undefined
297
- let current: any = node
305
+ let current: HTMLNode | null = node
298
306
  while (current && !sourceFile) {
299
307
  const file = current.getAttribute?.('data-astro-source-file')
300
308
  const line = current.getAttribute?.('data-astro-source-loc') || current.getAttribute?.('data-astro-source-line')
@@ -307,13 +315,20 @@ export async function processHtml(
307
315
  }
308
316
  }
309
317
  }
310
- current = current.parentNode
318
+ current = current.parentNode as HTMLNode | null
311
319
  }
312
320
 
313
- // Store image info for manifest
314
- imageEntries.set(id, {
321
+ // Build image metadata
322
+ const metadata: ImageMetadata = {
315
323
  src,
316
324
  alt: node.getAttribute('alt') || '',
325
+ srcSet: node.getAttribute('srcset') || undefined,
326
+ sizes: node.getAttribute('sizes') || undefined,
327
+ }
328
+
329
+ // Store image info for manifest
330
+ imageEntries.set(id, {
331
+ metadata,
317
332
  sourceFile,
318
333
  sourceLine,
319
334
  })
@@ -335,23 +350,23 @@ export async function processHtml(
335
350
  // Check if this element has any direct child elements without source file attribute
336
351
  // These would be markdown-rendered elements
337
352
  const childElements = node.childNodes.filter(
338
- (child: any) => child.nodeType === 1 && child.tagName,
353
+ (child): child is HTMLNode => child.nodeType === 1 && 'tagName' in child,
339
354
  )
340
355
  const hasMarkdownChildren = childElements.some(
341
- (child: any) => !child.getAttribute?.('data-astro-source-file'),
356
+ (child) => !child.getAttribute?.('data-astro-source-file'),
342
357
  )
343
358
 
344
359
  if (hasMarkdownChildren) {
345
360
  // Check if any ancestor already has been marked as a collection wrapper
346
361
  // We want the innermost wrapper
347
- let parent = node.parentNode
362
+ let parent = node.parentNode as HTMLNode | null
348
363
  let hasAncestorWrapper = false
349
364
  while (parent) {
350
- if ((parent as any).getAttribute?.(attributeName)?.startsWith('cms-collection-')) {
365
+ if (parent.getAttribute?.(attributeName)?.startsWith('cms-collection-')) {
351
366
  hasAncestorWrapper = true
352
367
  break
353
368
  }
354
- parent = parent.parentNode
369
+ parent = parent.parentNode as HTMLNode | null
355
370
  }
356
371
 
357
372
  if (!hasAncestorWrapper) {
@@ -382,7 +397,7 @@ export async function processHtml(
382
397
 
383
398
  if (bodyStart.length > 10) {
384
399
  // Store all candidates that match the body start
385
- const candidates: Array<{ node: any; blockChildCount: number }> = []
400
+ const candidates: Array<{ node: HTMLNode; blockChildCount: number }> = []
386
401
 
387
402
  for (const node of allElements) {
388
403
  const tag = node.tagName?.toLowerCase?.() ?? ''
@@ -391,8 +406,8 @@ export async function processHtml(
391
406
 
392
407
  // Check if this element's first text content starts with the markdown body
393
408
  const firstChild = node.childNodes.find(
394
- (child: any) => child.nodeType === 1 && child.tagName,
395
- ) as any
409
+ (child): child is HTMLNode => child.nodeType === 1 && 'tagName' in child,
410
+ )
396
411
 
397
412
  if (firstChild) {
398
413
  const firstChildText = (firstChild.innerText || '').trim().substring(0, 80)
@@ -401,7 +416,8 @@ export async function processHtml(
401
416
  // Markdown typically renders to multiple block elements (p, h2, h3, ul, ol, etc.)
402
417
  const blockTags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'blockquote', 'pre', 'table', 'hr']
403
418
  const blockChildCount = node.childNodes.filter(
404
- (child: any) => child.nodeType === 1 && blockTags.includes(child.tagName?.toLowerCase?.()),
419
+ (child): child is HTMLNode =>
420
+ child.nodeType === 1 && 'tagName' in child && blockTags.includes((child as HTMLNode).tagName?.toLowerCase?.() ?? ''),
405
421
  ).length
406
422
 
407
423
  candidates.push({ node, blockChildCount })
@@ -495,11 +511,14 @@ export async function processHtml(
495
511
 
496
512
  // Get child CMS elements
497
513
  const childCmsElements = node.querySelectorAll(`[${attributeName}]`)
498
- const childCmsIds = Array.from(childCmsElements).map((child: any) => child.getAttribute(attributeName))
514
+ const childCmsIds = Array.from(childCmsElements)
515
+ .map((child) => child.getAttribute(attributeName))
516
+ .filter((id): id is string => id !== null)
499
517
 
500
518
  // Build text with placeholders for child CMS elements
501
519
  // Recursively process child nodes to handle nested CMS elements correctly
502
- const buildTextWithPlaceholders = (nodes: any[]): string => {
520
+ type ChildNode = { nodeType: number; text?: string; childNodes?: ChildNode[]; getAttribute?: (name: string) => string | null }
521
+ const buildTextWithPlaceholders = (nodes: ChildNode[]): string => {
503
522
  let text = ''
504
523
  for (const child of nodes) {
505
524
  if (child.nodeType === 3) {
@@ -507,21 +526,21 @@ export async function processHtml(
507
526
  text += child.text || ''
508
527
  } else if (child.nodeType === 1) {
509
528
  // Element node
510
- const directCmsId = (child as any).getAttribute?.(attributeName)
529
+ const directCmsId = child.getAttribute?.(attributeName)
511
530
 
512
531
  if (directCmsId) {
513
532
  // Child has a direct CMS ID - use placeholder
514
533
  text += `{{cms:${directCmsId}}}`
515
534
  } else {
516
535
  // Child doesn't have a CMS ID - recursively process its children
517
- text += buildTextWithPlaceholders(child.childNodes || [])
536
+ text += buildTextWithPlaceholders((child.childNodes || []) as ChildNode[])
518
537
  }
519
538
  }
520
539
  }
521
540
  return text
522
541
  }
523
542
 
524
- const textWithPlaceholders = buildTextWithPlaceholders(node.childNodes || [])
543
+ const textWithPlaceholders = buildTextWithPlaceholders((node.childNodes || []) as ChildNode[])
525
544
 
526
545
  // Get direct text content (without placeholders)
527
546
  const directText = textWithPlaceholders.replace(/\{\{cms:[^}]+\}\}/g, '').trim()
@@ -540,14 +559,14 @@ export async function processHtml(
540
559
 
541
560
  // Find parent component if any
542
561
  let parentComponentId: string | undefined
543
- let parent = node.parentNode
562
+ let parent = node.parentNode as HTMLNode | null
544
563
  while (parent) {
545
- const parentCompId = (parent as any).getAttribute?.('data-cms-component-id')
564
+ const parentCompId = parent.getAttribute?.('data-cms-component-id')
546
565
  if (parentCompId) {
547
566
  parentComponentId = parentCompId
548
567
  break
549
568
  }
550
- parent = parent.parentNode
569
+ parent = parent.parentNode as HTMLNode | null
551
570
  }
552
571
 
553
572
  // Extract source context for resilient matching
@@ -564,7 +583,7 @@ export async function processHtml(
564
583
  const imageInfo = imageEntries.get(id)
565
584
  const isImage = !!imageInfo
566
585
 
567
- const entryText = isImage ? (imageInfo.alt || imageInfo.src) : textWithPlaceholders.trim()
586
+ const entryText = isImage ? (imageInfo.metadata.alt || imageInfo.metadata.src) : textWithPlaceholders.trim()
568
587
  // For images, use the source file we captured from ancestors if not in sourceLocationMap
569
588
  const entrySourcePath = sourceLocation?.file || imageInfo?.sourceFile || sourcePath
570
589
 
@@ -591,12 +610,11 @@ export async function processHtml(
591
610
  collectionName: isCollectionWrapper ? collectionInfo?.name : undefined,
592
611
  collectionSlug: isCollectionWrapper ? collectionInfo?.slug : undefined,
593
612
  contentPath: isCollectionWrapper ? collectionInfo?.contentPath : undefined,
594
- // Add image info for image entries
595
- imageSrc: imageInfo?.src,
596
- imageAlt: imageInfo?.alt,
597
613
  // Robustness fields
598
614
  stableId,
599
615
  sourceContext,
616
+ // Image metadata for image entries
617
+ imageMetadata: imageInfo?.metadata,
600
618
  // Color classes for buttons/styled elements
601
619
  colorClasses,
602
620
  }
@@ -604,7 +622,7 @@ export async function processHtml(
604
622
  }
605
623
 
606
624
  // Clean up any remaining source attributes from component-marked elements
607
- markedComponentRoots.forEach((node: any) => {
625
+ markedComponentRoots.forEach((node) => {
608
626
  node.removeAttribute('data-astro-source-file')
609
627
  node.removeAttribute('data-astro-source-loc')
610
628
  node.removeAttribute('data-astro-source-line')
@@ -645,13 +663,13 @@ export function cleanText(text: string): string {
645
663
  * This captures information about the element's position in the DOM
646
664
  * that can be used as fallback when exact matching fails.
647
665
  */
648
- function extractSourceContext(node: any, attributeName: string): SourceContext | undefined {
649
- const parent = node.parentNode
666
+ function extractSourceContext(node: HTMLNode, attributeName: string): SourceContext | undefined {
667
+ const parent = node.parentNode as HTMLNode | null
650
668
  if (!parent) return undefined
651
669
 
652
- const siblings = parent.childNodes?.filter((child: any) => {
670
+ const siblings = parent.childNodes?.filter((child): child is HTMLNode => {
653
671
  // Only consider element nodes, not text nodes
654
- return child.nodeType === 1 && child.tagName
672
+ return child.nodeType === 1 && 'tagName' in child
655
673
  }) || []
656
674
 
657
675
  const siblingIndex = siblings.indexOf(node)