@nuasite/cms 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 +237 -0
- package/dist/src/build-processor.d.ts +20 -0
- package/dist/src/build-processor.d.ts.map +1 -0
- package/dist/src/collection-scanner.d.ts +6 -0
- package/dist/src/collection-scanner.d.ts.map +1 -0
- package/dist/src/component-registry.d.ts +63 -0
- package/dist/src/component-registry.d.ts.map +1 -0
- package/dist/src/config.d.ts +24 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/dev-middleware.d.ts +20 -0
- package/dist/src/dev-middleware.d.ts.map +1 -0
- package/dist/src/editor/ai.d.ts +60 -0
- package/dist/src/editor/ai.d.ts.map +1 -0
- package/dist/src/editor/api.d.ts +140 -0
- package/dist/src/editor/api.d.ts.map +1 -0
- package/dist/src/editor/color-utils.d.ts +106 -0
- package/dist/src/editor/color-utils.d.ts.map +1 -0
- package/dist/src/editor/components/ai-chat.d.ts +11 -0
- package/dist/src/editor/components/ai-chat.d.ts.map +1 -0
- package/dist/src/editor/components/ai-tooltip.d.ts +12 -0
- package/dist/src/editor/components/ai-tooltip.d.ts.map +1 -0
- package/dist/src/editor/components/attribute-editor.d.ts +5 -0
- package/dist/src/editor/components/attribute-editor.d.ts.map +1 -0
- package/dist/src/editor/components/block-editor.d.ts +12 -0
- package/dist/src/editor/components/block-editor.d.ts.map +1 -0
- package/dist/src/editor/components/collections-browser.d.ts +2 -0
- package/dist/src/editor/components/collections-browser.d.ts.map +1 -0
- package/dist/src/editor/components/color-toolbar.d.ts +12 -0
- package/dist/src/editor/components/color-toolbar.d.ts.map +1 -0
- package/dist/src/editor/components/confirm-dialog.d.ts +2 -0
- package/dist/src/editor/components/confirm-dialog.d.ts.map +1 -0
- package/dist/src/editor/components/create-page-modal.d.ts +2 -0
- package/dist/src/editor/components/create-page-modal.d.ts.map +1 -0
- package/dist/src/editor/components/editable-highlights.d.ts +9 -0
- package/dist/src/editor/components/editable-highlights.d.ts.map +1 -0
- package/dist/src/editor/components/error-boundary.d.ts +32 -0
- package/dist/src/editor/components/error-boundary.d.ts.map +1 -0
- package/dist/src/editor/components/fields.d.ts +75 -0
- package/dist/src/editor/components/fields.d.ts.map +1 -0
- package/dist/src/editor/components/frontmatter-fields.d.ts +29 -0
- package/dist/src/editor/components/frontmatter-fields.d.ts.map +1 -0
- package/dist/src/editor/components/highlight-overlay.d.ts +64 -0
- package/dist/src/editor/components/highlight-overlay.d.ts.map +1 -0
- package/dist/src/editor/components/image-overlay.d.ts +12 -0
- package/dist/src/editor/components/image-overlay.d.ts.map +1 -0
- package/dist/src/editor/components/markdown-editor-overlay.d.ts +6 -0
- package/dist/src/editor/components/markdown-editor-overlay.d.ts.map +1 -0
- package/dist/src/editor/components/markdown-inline-editor.d.ts +10 -0
- package/dist/src/editor/components/markdown-inline-editor.d.ts.map +1 -0
- package/dist/src/editor/components/media-library.d.ts +2 -0
- package/dist/src/editor/components/media-library.d.ts.map +1 -0
- package/dist/src/editor/components/outline.d.ts +21 -0
- package/dist/src/editor/components/outline.d.ts.map +1 -0
- package/dist/src/editor/components/redirect-countdown.d.ts +2 -0
- package/dist/src/editor/components/redirect-countdown.d.ts.map +1 -0
- package/dist/src/editor/components/seo-editor.d.ts +2 -0
- package/dist/src/editor/components/seo-editor.d.ts.map +1 -0
- package/dist/src/editor/components/text-style-toolbar.d.ts +8 -0
- package/dist/src/editor/components/text-style-toolbar.d.ts.map +1 -0
- package/dist/src/editor/components/toast/toast-container.d.ts +7 -0
- package/dist/src/editor/components/toast/toast-container.d.ts.map +1 -0
- package/dist/src/editor/components/toast/toast.d.ts +7 -0
- package/dist/src/editor/components/toast/toast.d.ts.map +1 -0
- package/dist/src/editor/components/toast/types.d.ts +7 -0
- package/dist/src/editor/components/toast/types.d.ts.map +1 -0
- package/dist/src/editor/components/toolbar.d.ts +21 -0
- package/dist/src/editor/components/toolbar.d.ts.map +1 -0
- package/dist/src/editor/config.d.ts +4 -0
- package/dist/src/editor/config.d.ts.map +1 -0
- package/dist/src/editor/constants.d.ts +101 -0
- package/dist/src/editor/constants.d.ts.map +1 -0
- package/dist/src/editor/context.d.ts +14 -0
- package/dist/src/editor/context.d.ts.map +1 -0
- package/dist/src/editor/dom.d.ts +77 -0
- package/dist/src/editor/dom.d.ts.map +1 -0
- package/dist/src/editor/editor.d.ts +64 -0
- package/dist/src/editor/editor.d.ts.map +1 -0
- package/dist/src/editor/history.d.ts +20 -0
- package/dist/src/editor/history.d.ts.map +1 -0
- package/dist/src/editor/hooks/index.d.ts +14 -0
- package/dist/src/editor/hooks/index.d.ts.map +1 -0
- package/dist/src/editor/hooks/useAIHandlers.d.ts +22 -0
- package/dist/src/editor/hooks/useAIHandlers.d.ts.map +1 -0
- package/dist/src/editor/hooks/useBlockEditorHandlers.d.ts +18 -0
- package/dist/src/editor/hooks/useBlockEditorHandlers.d.ts.map +1 -0
- package/dist/src/editor/hooks/useElementDetection.d.ts +26 -0
- package/dist/src/editor/hooks/useElementDetection.d.ts.map +1 -0
- package/dist/src/editor/hooks/useImageHoverDetection.d.ts +12 -0
- package/dist/src/editor/hooks/useImageHoverDetection.d.ts.map +1 -0
- package/dist/src/editor/hooks/useTextSelection.d.ts +23 -0
- package/dist/src/editor/hooks/useTextSelection.d.ts.map +1 -0
- package/dist/src/editor/hooks/useTooltipState.d.ts +19 -0
- package/dist/src/editor/hooks/useTooltipState.d.ts.map +1 -0
- package/dist/src/editor/hooks/utils.d.ts +32 -0
- package/dist/src/editor/hooks/utils.d.ts.map +1 -0
- package/dist/src/editor/index.d.ts +12 -0
- package/dist/src/editor/index.d.ts.map +1 -0
- package/dist/src/editor/lib/cn.d.ts +3 -0
- package/dist/src/editor/lib/cn.d.ts.map +1 -0
- package/dist/src/editor/manifest.d.ts +19 -0
- package/dist/src/editor/manifest.d.ts.map +1 -0
- package/dist/src/editor/markdown-api.d.ts +36 -0
- package/dist/src/editor/markdown-api.d.ts.map +1 -0
- package/dist/src/editor/signals.d.ts +242 -0
- package/dist/src/editor/signals.d.ts.map +1 -0
- package/dist/src/editor/storage.d.ts +27 -0
- package/dist/src/editor/storage.d.ts.map +1 -0
- package/dist/src/editor/text-styling.d.ts +350 -0
- package/dist/src/editor/text-styling.d.ts.map +1 -0
- package/dist/src/editor/themes.d.ts +38 -0
- package/dist/src/editor/themes.d.ts.map +1 -0
- package/dist/src/editor/types.d.ts +454 -0
- package/dist/src/editor/types.d.ts.map +1 -0
- package/dist/src/error-collector.d.ts +56 -0
- package/dist/src/error-collector.d.ts.map +1 -0
- package/dist/src/handlers/component-ops.d.ts +34 -0
- package/dist/src/handlers/component-ops.d.ts.map +1 -0
- package/dist/src/handlers/markdown-ops.d.ts +41 -0
- package/dist/src/handlers/markdown-ops.d.ts.map +1 -0
- package/dist/src/handlers/request-utils.d.ts +20 -0
- package/dist/src/handlers/request-utils.d.ts.map +1 -0
- package/dist/src/handlers/source-writer.d.ts +51 -0
- package/dist/src/handlers/source-writer.d.ts.map +1 -0
- package/dist/src/html-processor.d.ts +63 -0
- package/dist/src/html-processor.d.ts.map +1 -0
- package/dist/src/index.d.ts +41 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/manifest-writer.d.ts +111 -0
- package/dist/src/manifest-writer.d.ts.map +1 -0
- package/dist/src/media/contember.d.ts +15 -0
- package/dist/src/media/contember.d.ts.map +1 -0
- package/dist/src/media/local.d.ts +9 -0
- package/dist/src/media/local.d.ts.map +1 -0
- package/dist/src/media/s3.d.ts +12 -0
- package/dist/src/media/s3.d.ts.map +1 -0
- package/dist/src/media/types.d.ts +40 -0
- package/dist/src/media/types.d.ts.map +1 -0
- package/dist/src/preview-generator.d.ts +19 -0
- package/dist/src/preview-generator.d.ts.map +1 -0
- package/dist/src/seo-processor.d.ts +23 -0
- package/dist/src/seo-processor.d.ts.map +1 -0
- package/dist/src/source-finder/ast-extractors.d.ts +35 -0
- package/dist/src/source-finder/ast-extractors.d.ts.map +1 -0
- package/dist/src/source-finder/ast-parser.d.ts +16 -0
- package/dist/src/source-finder/ast-parser.d.ts.map +1 -0
- package/dist/src/source-finder/cache.d.ts +18 -0
- package/dist/src/source-finder/cache.d.ts.map +1 -0
- package/dist/src/source-finder/collection-finder.d.ts +29 -0
- package/dist/src/source-finder/collection-finder.d.ts.map +1 -0
- package/dist/src/source-finder/cross-file-tracker.d.ts +39 -0
- package/dist/src/source-finder/cross-file-tracker.d.ts.map +1 -0
- package/dist/src/source-finder/element-finder.d.ts +42 -0
- package/dist/src/source-finder/element-finder.d.ts.map +1 -0
- package/dist/src/source-finder/image-finder.d.ts +24 -0
- package/dist/src/source-finder/image-finder.d.ts.map +1 -0
- package/dist/src/source-finder/index.d.ts +9 -0
- package/dist/src/source-finder/index.d.ts.map +1 -0
- package/dist/src/source-finder/search-index.d.ts +27 -0
- package/dist/src/source-finder/search-index.d.ts.map +1 -0
- package/dist/src/source-finder/snippet-utils.d.ts +90 -0
- package/dist/src/source-finder/snippet-utils.d.ts.map +1 -0
- package/dist/src/source-finder/source-lookup.d.ts +16 -0
- package/dist/src/source-finder/source-lookup.d.ts.map +1 -0
- package/dist/src/source-finder/types.d.ts +167 -0
- package/dist/src/source-finder/types.d.ts.map +1 -0
- package/dist/src/source-finder/variable-extraction.d.ts +37 -0
- package/dist/src/source-finder/variable-extraction.d.ts.map +1 -0
- package/dist/src/tailwind-colors.d.ts +54 -0
- package/dist/src/tailwind-colors.d.ts.map +1 -0
- package/dist/src/tsconfig.tsbuildinfo +1 -0
- package/dist/src/types.d.ts +367 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +61 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/vite-plugin.d.ts +14 -0
- package/dist/src/vite-plugin.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +80 -0
- package/src/build-processor.ts +784 -0
- package/src/collection-scanner.ts +304 -0
- package/src/component-registry.ts +393 -0
- package/src/config.ts +74 -0
- package/src/dev-middleware.ts +525 -0
- package/src/dist/src/tsconfig.tsbuildinfo +1 -0
- package/src/editor/ai.ts +185 -0
- package/src/editor/api.ts +513 -0
- package/src/editor/color-utils.ts +556 -0
- package/src/editor/components/ai-chat.tsx +632 -0
- package/src/editor/components/ai-tooltip.tsx +179 -0
- package/src/editor/components/attribute-editor.tsx +596 -0
- package/src/editor/components/block-editor.tsx +546 -0
- package/src/editor/components/collections-browser.tsx +248 -0
- package/src/editor/components/color-toolbar.tsx +314 -0
- package/src/editor/components/confirm-dialog.tsx +69 -0
- package/src/editor/components/create-page-modal.tsx +163 -0
- package/src/editor/components/editable-highlights.tsx +260 -0
- package/src/editor/components/error-boundary.tsx +87 -0
- package/src/editor/components/fields.tsx +387 -0
- package/src/editor/components/frontmatter-fields.tsx +469 -0
- package/src/editor/components/highlight-overlay.ts +229 -0
- package/src/editor/components/image-overlay.tsx +230 -0
- package/src/editor/components/markdown-editor-overlay.tsx +505 -0
- package/src/editor/components/markdown-inline-editor.tsx +780 -0
- package/src/editor/components/media-library.tsx +297 -0
- package/src/editor/components/outline.tsx +402 -0
- package/src/editor/components/redirect-countdown.tsx +45 -0
- package/src/editor/components/seo-editor.tsx +498 -0
- package/src/editor/components/text-style-toolbar.tsx +362 -0
- package/src/editor/components/toast/toast-container.tsx +15 -0
- package/src/editor/components/toast/toast.tsx +49 -0
- package/src/editor/components/toast/types.ts +7 -0
- package/src/editor/components/toolbar.tsx +366 -0
- package/src/editor/config.ts +12 -0
- package/src/editor/constants.ts +106 -0
- package/src/editor/context.tsx +38 -0
- package/src/editor/dom.ts +357 -0
- package/src/editor/editor.ts +1510 -0
- package/src/editor/env.d.ts +4 -0
- package/src/editor/history.ts +355 -0
- package/src/editor/hooks/index.ts +19 -0
- package/src/editor/hooks/useAIHandlers.ts +345 -0
- package/src/editor/hooks/useBlockEditorHandlers.ts +206 -0
- package/src/editor/hooks/useElementDetection.ts +284 -0
- package/src/editor/hooks/useImageHoverDetection.ts +102 -0
- package/src/editor/hooks/useTextSelection.ts +187 -0
- package/src/editor/hooks/useTooltipState.ts +126 -0
- package/src/editor/hooks/utils.ts +101 -0
- package/src/editor/index.tsx +481 -0
- package/src/editor/lib/cn.ts +4 -0
- package/src/editor/manifest.ts +25 -0
- package/src/editor/markdown-api.ts +209 -0
- package/src/editor/signals.ts +1351 -0
- package/src/editor/storage.ts +266 -0
- package/src/editor/styles.css +465 -0
- package/src/editor/text-styling.ts +773 -0
- package/src/editor/themes.ts +210 -0
- package/src/editor/types.ts +591 -0
- package/src/error-collector.ts +106 -0
- package/src/handlers/component-ops.ts +463 -0
- package/src/handlers/markdown-ops.ts +202 -0
- package/src/handlers/request-utils.ts +151 -0
- package/src/handlers/source-writer.ts +649 -0
- package/src/html-processor.ts +1108 -0
- package/src/index.ts +284 -0
- package/src/manifest-writer.ts +371 -0
- package/src/media/contember.ts +84 -0
- package/src/media/local.ts +114 -0
- package/src/media/s3.ts +133 -0
- package/src/media/types.ts +33 -0
- package/src/preview-generator.ts +293 -0
- package/src/seo-processor.ts +567 -0
- package/src/source-finder/ast-extractors.ts +185 -0
- package/src/source-finder/ast-parser.ts +150 -0
- package/src/source-finder/cache.ts +76 -0
- package/src/source-finder/collection-finder.ts +335 -0
- package/src/source-finder/cross-file-tracker.ts +741 -0
- package/src/source-finder/element-finder.ts +387 -0
- package/src/source-finder/image-finder.ts +283 -0
- package/src/source-finder/index.ts +37 -0
- package/src/source-finder/search-index.ts +525 -0
- package/src/source-finder/snippet-utils.ts +668 -0
- package/src/source-finder/source-lookup.ts +200 -0
- package/src/source-finder/types.ts +210 -0
- package/src/source-finder/variable-extraction.ts +406 -0
- package/src/tailwind-colors.ts +874 -0
- package/src/tsconfig.json +25 -0
- package/src/types.ts +406 -0
- package/src/utils.ts +186 -0
- package/src/vite-plugin.ts +42 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import { getProjectRoot } from '../config'
|
|
5
|
+
import { getCachedParsedFile } from './ast-parser'
|
|
6
|
+
import { isSearchIndexInitialized } from './cache'
|
|
7
|
+
import { searchForExpressionProp, searchForImportedValue, searchForPropInParents } from './cross-file-tracker'
|
|
8
|
+
import { findElementWithText } from './element-finder'
|
|
9
|
+
import { findInTextIndex } from './search-index'
|
|
10
|
+
import { extractCompleteTagSnippet, extractInnerHtmlFromSnippet, extractOpeningTagSnippet } from './snippet-utils'
|
|
11
|
+
import type { SourceLocation } from './types'
|
|
12
|
+
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Main Source Location Finding
|
|
15
|
+
// ============================================================================
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Find source file and line number for text content.
|
|
19
|
+
* Uses pre-built search index for fast lookups.
|
|
20
|
+
*/
|
|
21
|
+
export async function findSourceLocation(
|
|
22
|
+
textContent: string,
|
|
23
|
+
tag: string,
|
|
24
|
+
): Promise<SourceLocation | undefined> {
|
|
25
|
+
// Use index if available (much faster)
|
|
26
|
+
if (isSearchIndexInitialized()) {
|
|
27
|
+
return findInTextIndex(textContent, tag)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Fallback to slow search if index not initialized
|
|
31
|
+
const srcDir = path.join(getProjectRoot(), 'src')
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const searchDirs = [
|
|
35
|
+
path.join(srcDir, 'components'),
|
|
36
|
+
path.join(srcDir, 'pages'),
|
|
37
|
+
path.join(srcDir, 'layouts'),
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
for (const dir of searchDirs) {
|
|
41
|
+
try {
|
|
42
|
+
const result = await searchDirectory(dir, textContent, tag)
|
|
43
|
+
if (result) {
|
|
44
|
+
return result
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
// Directory doesn't exist, continue
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// If not found directly, try searching for prop values in parent components
|
|
52
|
+
for (const dir of searchDirs) {
|
|
53
|
+
try {
|
|
54
|
+
const result = await searchForPropInParents(dir, textContent)
|
|
55
|
+
if (result) {
|
|
56
|
+
return result
|
|
57
|
+
}
|
|
58
|
+
} catch {
|
|
59
|
+
// Directory doesn't exist, continue
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
// Search failed
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Directory Search
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Recursively search directory for matching content
|
|
75
|
+
*/
|
|
76
|
+
export async function searchDirectory(
|
|
77
|
+
dir: string,
|
|
78
|
+
textContent: string,
|
|
79
|
+
tag: string,
|
|
80
|
+
): Promise<SourceLocation | undefined> {
|
|
81
|
+
try {
|
|
82
|
+
const entries = await fs.readdir(dir, { withFileTypes: true })
|
|
83
|
+
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
const fullPath = path.join(dir, entry.name)
|
|
86
|
+
|
|
87
|
+
if (entry.isDirectory()) {
|
|
88
|
+
const result = await searchDirectory(fullPath, textContent, tag)
|
|
89
|
+
if (result) return result
|
|
90
|
+
} else if (entry.isFile() && entry.name.endsWith('.astro')) {
|
|
91
|
+
const result = await searchAstroFile(fullPath, textContent, tag)
|
|
92
|
+
if (result) return result
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
// Error reading directory
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return undefined
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// Astro File Search
|
|
104
|
+
// ============================================================================
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Search a single Astro file for matching content using AST parsing.
|
|
108
|
+
* Uses caching for better performance.
|
|
109
|
+
*/
|
|
110
|
+
export async function searchAstroFile(
|
|
111
|
+
filePath: string,
|
|
112
|
+
textContent: string,
|
|
113
|
+
tag: string,
|
|
114
|
+
): Promise<SourceLocation | undefined> {
|
|
115
|
+
try {
|
|
116
|
+
// Use cached parsed file
|
|
117
|
+
const cached = await getCachedParsedFile(filePath)
|
|
118
|
+
if (!cached) return undefined
|
|
119
|
+
|
|
120
|
+
const { lines, ast, variableDefinitions, propAliases, imports } = cached
|
|
121
|
+
|
|
122
|
+
// Find matching element in template AST
|
|
123
|
+
const { bestMatch, propCandidates, importCandidates } = findElementWithText(
|
|
124
|
+
ast,
|
|
125
|
+
tag,
|
|
126
|
+
textContent,
|
|
127
|
+
variableDefinitions,
|
|
128
|
+
propAliases,
|
|
129
|
+
imports,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
// First, check if we have a direct match (local variable or static content)
|
|
133
|
+
if (bestMatch && !bestMatch.usesProp && !bestMatch.usesImport) {
|
|
134
|
+
// Determine the editable line (definition for variables, usage for static)
|
|
135
|
+
const editableLine = bestMatch.type === 'variable' && bestMatch.definitionLine
|
|
136
|
+
? bestMatch.definitionLine
|
|
137
|
+
: bestMatch.line
|
|
138
|
+
|
|
139
|
+
// Get the source snippet - complete element for static content, definition line for variables
|
|
140
|
+
let snippet: string
|
|
141
|
+
let openingTagSnippet: string | undefined
|
|
142
|
+
if (bestMatch.type === 'static') {
|
|
143
|
+
// For static content, extract the complete element (including wrapper tags)
|
|
144
|
+
snippet = extractCompleteTagSnippet(lines, editableLine - 1, tag)
|
|
145
|
+
// Also extract just the opening tag for attribute updates
|
|
146
|
+
openingTagSnippet = extractOpeningTagSnippet(lines, editableLine - 1, tag)
|
|
147
|
+
} else {
|
|
148
|
+
// For variables/props, just the definition line with indentation
|
|
149
|
+
snippet = lines[editableLine - 1] || ''
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
file: path.relative(getProjectRoot(), filePath),
|
|
154
|
+
line: editableLine,
|
|
155
|
+
snippet,
|
|
156
|
+
openingTagSnippet,
|
|
157
|
+
type: bestMatch.type,
|
|
158
|
+
variableName: bestMatch.variableName,
|
|
159
|
+
definitionLine: bestMatch.type === 'variable' ? bestMatch.definitionLine : undefined,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Try all prop candidates - verify each one to find the correct match
|
|
164
|
+
// (handles multiple same-tag elements with different prop values)
|
|
165
|
+
for (const propCandidate of propCandidates) {
|
|
166
|
+
if (propCandidate.propName && propCandidate.expressionPath) {
|
|
167
|
+
const componentFileName = path.basename(filePath)
|
|
168
|
+
const exprPropResult = await searchForExpressionProp(
|
|
169
|
+
componentFileName,
|
|
170
|
+
propCandidate.propName,
|
|
171
|
+
propCandidate.expressionPath,
|
|
172
|
+
textContent,
|
|
173
|
+
)
|
|
174
|
+
if (exprPropResult) {
|
|
175
|
+
return exprPropResult
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Try all import candidates - verify each one to find the correct match
|
|
181
|
+
// (handles multiple same-tag elements with different imported values)
|
|
182
|
+
for (const importCandidate of importCandidates) {
|
|
183
|
+
if (importCandidate.importInfo && importCandidate.expressionPath) {
|
|
184
|
+
const importResult = await searchForImportedValue(
|
|
185
|
+
filePath,
|
|
186
|
+
importCandidate.importInfo,
|
|
187
|
+
importCandidate.expressionPath,
|
|
188
|
+
textContent,
|
|
189
|
+
)
|
|
190
|
+
if (importResult) {
|
|
191
|
+
return importResult
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} catch {
|
|
196
|
+
// Error reading/parsing file
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return undefined
|
|
200
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import type { Node as AstroNode } from '@astrojs/compiler/types'
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Import and Variable Information
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
/** Import information from frontmatter */
|
|
8
|
+
export interface ImportInfo {
|
|
9
|
+
/** Local name of the imported binding */
|
|
10
|
+
localName: string
|
|
11
|
+
/** Original exported name (or 'default' for default imports) */
|
|
12
|
+
importedName: string
|
|
13
|
+
/** The import source path (e.g., './config', '../data/nav') */
|
|
14
|
+
source: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface VariableDefinition {
|
|
18
|
+
name: string
|
|
19
|
+
value: string
|
|
20
|
+
line: number
|
|
21
|
+
/** For object properties, the parent variable name */
|
|
22
|
+
parentName?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Cached File Types
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
export interface CachedParsedFile {
|
|
30
|
+
content: string
|
|
31
|
+
lines: string[]
|
|
32
|
+
ast: AstroNode
|
|
33
|
+
frontmatterContent: string | null
|
|
34
|
+
frontmatterStartLine: number
|
|
35
|
+
variableDefinitions: VariableDefinition[]
|
|
36
|
+
/** Mapping of local variable names to prop names from Astro.props destructuring
|
|
37
|
+
* e.g., { navItems: 'items' } for `const { items: navItems } = Astro.props` */
|
|
38
|
+
propAliases: Map<string, string>
|
|
39
|
+
/** Import information from frontmatter */
|
|
40
|
+
imports: ImportInfo[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Search Index Types
|
|
45
|
+
// ============================================================================
|
|
46
|
+
|
|
47
|
+
/** Pre-built search index for fast lookups */
|
|
48
|
+
export interface SearchIndexEntry {
|
|
49
|
+
file: string
|
|
50
|
+
line: number
|
|
51
|
+
snippet: string
|
|
52
|
+
/** Just the opening tag with attributes (for attribute/class updates) */
|
|
53
|
+
openingTagSnippet?: string
|
|
54
|
+
type: 'static' | 'variable' | 'prop' | 'computed'
|
|
55
|
+
variableName?: string
|
|
56
|
+
definitionLine?: number
|
|
57
|
+
normalizedText: string
|
|
58
|
+
tag: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface ImageIndexEntry {
|
|
62
|
+
file: string
|
|
63
|
+
line: number
|
|
64
|
+
snippet: string
|
|
65
|
+
src: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// Source Location Types (Public API)
|
|
70
|
+
// ============================================================================
|
|
71
|
+
|
|
72
|
+
export interface SourceLocation {
|
|
73
|
+
file: string
|
|
74
|
+
line: number
|
|
75
|
+
snippet?: string
|
|
76
|
+
/** Just the opening tag with attributes (for attribute/class updates) */
|
|
77
|
+
openingTagSnippet?: string
|
|
78
|
+
type?: 'static' | 'variable' | 'prop' | 'computed' | 'collection'
|
|
79
|
+
variableName?: string
|
|
80
|
+
definitionLine?: number
|
|
81
|
+
/** Collection name for collection entries */
|
|
82
|
+
collectionName?: string
|
|
83
|
+
/** Entry slug for collection entries */
|
|
84
|
+
collectionSlug?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface VariableReference {
|
|
88
|
+
name: string
|
|
89
|
+
pattern: string
|
|
90
|
+
definitionLine: number
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface CollectionInfo {
|
|
94
|
+
name: string
|
|
95
|
+
slug: string
|
|
96
|
+
file: string
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface MarkdownContent {
|
|
100
|
+
/** Frontmatter fields as key-value pairs with line numbers */
|
|
101
|
+
frontmatter: Record<string, { value: string; line: number }>
|
|
102
|
+
/** The full markdown body content */
|
|
103
|
+
body: string
|
|
104
|
+
/** Line number where body starts */
|
|
105
|
+
bodyStartLine: number
|
|
106
|
+
/** File path relative to cwd */
|
|
107
|
+
file: string
|
|
108
|
+
/** Collection name */
|
|
109
|
+
collectionName: string
|
|
110
|
+
/** Collection slug */
|
|
111
|
+
collectionSlug: string
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ============================================================================
|
|
115
|
+
// AST Parsing Types
|
|
116
|
+
// ============================================================================
|
|
117
|
+
|
|
118
|
+
export interface ParsedAstroFile {
|
|
119
|
+
ast: AstroNode
|
|
120
|
+
frontmatterContent: string | null
|
|
121
|
+
frontmatterStartLine: number
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Minimal Babel AST node type for our usage */
|
|
125
|
+
export interface BabelNode {
|
|
126
|
+
type: string
|
|
127
|
+
[key: string]: unknown
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Minimal Babel File type */
|
|
131
|
+
export interface BabelFile {
|
|
132
|
+
type: 'File'
|
|
133
|
+
program: BabelNode & { body: BabelNode[] }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ============================================================================
|
|
137
|
+
// Match Result Types
|
|
138
|
+
// ============================================================================
|
|
139
|
+
|
|
140
|
+
export interface TemplateMatch {
|
|
141
|
+
line: number
|
|
142
|
+
type: 'static' | 'variable' | 'computed'
|
|
143
|
+
variableName?: string
|
|
144
|
+
/** For variables, the definition line in frontmatter */
|
|
145
|
+
definitionLine?: number
|
|
146
|
+
/** If true, the expression uses a variable from props that needs cross-file tracking */
|
|
147
|
+
usesProp?: boolean
|
|
148
|
+
/** The prop name if usesProp is true */
|
|
149
|
+
propName?: string
|
|
150
|
+
/** The full expression path if usesProp is true (e.g., 'items[0]') */
|
|
151
|
+
expressionPath?: string
|
|
152
|
+
/** If true, the expression uses a variable from an import */
|
|
153
|
+
usesImport?: boolean
|
|
154
|
+
/** The import info if usesImport is true */
|
|
155
|
+
importInfo?: ImportInfo
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Result type for findElementWithText - returns best match and all prop/import candidates */
|
|
159
|
+
export interface FindElementResult {
|
|
160
|
+
/** The best match found (local variables or static content) */
|
|
161
|
+
bestMatch: TemplateMatch | null
|
|
162
|
+
/** All prop-based matches for the tag (need cross-file verification) */
|
|
163
|
+
propCandidates: TemplateMatch[]
|
|
164
|
+
/** All import-based matches for the tag (need cross-file verification) */
|
|
165
|
+
importCandidates: TemplateMatch[]
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface ComponentPropMatch {
|
|
169
|
+
line: number
|
|
170
|
+
propName: string
|
|
171
|
+
propValue: string
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface ExpressionPropMatch {
|
|
175
|
+
componentName: string
|
|
176
|
+
propName: string
|
|
177
|
+
/** The expression text (e.g., 'navItems' from items={navItems}) */
|
|
178
|
+
expressionText: string
|
|
179
|
+
line: number
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface SpreadPropMatch {
|
|
183
|
+
componentName: string
|
|
184
|
+
/** The variable name being spread (e.g., 'cardProps' from {...cardProps}) */
|
|
185
|
+
spreadVarName: string
|
|
186
|
+
line: number
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface ImageMatch {
|
|
190
|
+
line: number
|
|
191
|
+
src: string
|
|
192
|
+
snippet: string
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// Line Transformer for AST Extraction
|
|
197
|
+
// ============================================================================
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Transforms Babel line numbers to actual file line numbers.
|
|
201
|
+
* Babel parses content starting at line 1, but frontmatter content
|
|
202
|
+
* may start at a different line in the actual file.
|
|
203
|
+
*/
|
|
204
|
+
export type LineTransformer = (babelLine: number) => number
|
|
205
|
+
|
|
206
|
+
/** Identity transformer - use for standalone files where Babel line = file line */
|
|
207
|
+
export const identityLine: LineTransformer = (line) => line
|
|
208
|
+
|
|
209
|
+
/** Create a transformer for frontmatter content that starts at a specific line */
|
|
210
|
+
export const createFrontmatterLineTransformer = (startLine: number): LineTransformer => (babelLine) => (babelLine - 1) + startLine
|