davaux 0.8.0 → 0.8.1

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 (90) hide show
  1. package/package.json +6 -2
  2. package/BASELINE.md +0 -169
  3. package/CLAUDE.md +0 -518
  4. package/ROADMAP.md +0 -198
  5. package/build.mjs +0 -101
  6. package/client/control.ts +0 -247
  7. package/client/hydrate.ts +0 -37
  8. package/client/index.ts +0 -19
  9. package/client/jsx-runtime.ts +0 -209
  10. package/client/resource.ts +0 -122
  11. package/client/signal.ts +0 -211
  12. package/client/store.ts +0 -110
  13. package/client/useHead.ts +0 -63
  14. package/pka.config.json +0 -32
  15. package/src/build/config.ts +0 -42
  16. package/src/build/index.ts +0 -6
  17. package/src/build/plugins.ts +0 -118
  18. package/src/cli.ts +0 -502
  19. package/src/config.ts +0 -197
  20. package/src/create-multisite.ts +0 -310
  21. package/src/create.ts +0 -194
  22. package/src/dev/blueprints.ts +0 -75
  23. package/src/dev/components.ts +0 -108
  24. package/src/dev/insert.ts +0 -221
  25. package/src/dev/remove.ts +0 -677
  26. package/src/dev/watch.ts +0 -3098
  27. package/src/errors.ts +0 -64
  28. package/src/generate.ts +0 -228
  29. package/src/index.ts +0 -67
  30. package/src/island.ts +0 -47
  31. package/src/jsx-runtime.d.ts +0 -408
  32. package/src/jsx-runtime.d.ts.map +0 -1
  33. package/src/jsx-runtime.ts +0 -536
  34. package/src/link.ts +0 -49
  35. package/src/oml/fragment.ts +0 -54
  36. package/src/oml/index.ts +0 -21
  37. package/src/oml/jsx-runtime.ts +0 -121
  38. package/src/oml/jsx.ts +0 -151
  39. package/src/oml/page.ts +0 -13
  40. package/src/oml/render.ts +0 -181
  41. package/src/oml/types.ts +0 -159
  42. package/src/router/handler.ts +0 -515
  43. package/src/router/matcher.ts +0 -52
  44. package/src/router/scanner.ts +0 -272
  45. package/src/server/index.ts +0 -49
  46. package/src/signal.ts +0 -39
  47. package/src/ssg.ts +0 -253
  48. package/src/test/actions.test.ts +0 -40
  49. package/src/test/body-limits.test.ts +0 -83
  50. package/src/test/errors.test.ts +0 -53
  51. package/src/test/fixtures/routes/[id].page.ts +0 -3
  52. package/src/test/fixtures/routes/_error.ts +0 -6
  53. package/src/test/fixtures/routes/_global.ts +0 -8
  54. package/src/test/fixtures/routes/_layout-template.ts +0 -7
  55. package/src/test/fixtures/routes/_layout.ts +0 -7
  56. package/src/test/fixtures/routes/_layout_scripts.ts +0 -8
  57. package/src/test/fixtures/routes/_middleware.ts +0 -8
  58. package/src/test/fixtures/routes/_redirect301_mw.ts +0 -5
  59. package/src/test/fixtures/routes/_redirect_mw.ts +0 -5
  60. package/src/test/fixtures/routes/about.page.ts +0 -6
  61. package/src/test/fixtures/routes/action.page.ts +0 -11
  62. package/src/test/fixtures/routes/api/form-all.post.ts +0 -5
  63. package/src/test/fixtures/routes/api/form-limited.post.ts +0 -6
  64. package/src/test/fixtures/routes/api/response-obj.get.ts +0 -17
  65. package/src/test/fixtures/routes/api/upload.post.ts +0 -14
  66. package/src/test/fixtures/routes/api/users.get.ts +0 -3
  67. package/src/test/fixtures/routes/api/xml.get.ts +0 -5
  68. package/src/test/fixtures/routes/auth/_middleware.ts +0 -11
  69. package/src/test/fixtures/routes/auth/protected.page.ts +0 -3
  70. package/src/test/fixtures/routes/index.page.ts +0 -3
  71. package/src/test/fixtures/routes/oml.page.ts +0 -7
  72. package/src/test/fixtures/routes/redirect.page.ts +0 -3
  73. package/src/test/fixtures/routes/ssg/[slug].page.ts +0 -8
  74. package/src/test/fixtures/routes/ssg/server.page.ts +0 -5
  75. package/src/test/fixtures/routes/state.page.ts +0 -4
  76. package/src/test/fixtures/routes/throw.page.ts +0 -5
  77. package/src/test/fixtures/routes/wiki/[...slug].page.ts +0 -3
  78. package/src/test/helpers.ts +0 -132
  79. package/src/test/layouts.test.ts +0 -76
  80. package/src/test/middleware.test.ts +0 -69
  81. package/src/test/multipart.test.ts +0 -91
  82. package/src/test/oml-routing.test.ts +0 -59
  83. package/src/test/oml.test.ts +0 -429
  84. package/src/test/redirects.test.ts +0 -32
  85. package/src/test/routing.test.ts +0 -118
  86. package/src/test/ssg.test.ts +0 -273
  87. package/src/test/web-response.test.ts +0 -33
  88. package/src/types.ts +0 -670
  89. package/tsconfig.client.json +0 -17
  90. package/tsconfig.json +0 -20
package/src/dev/insert.ts DELETED
@@ -1,221 +0,0 @@
1
- import { readFileSync, writeFileSync } from 'node:fs'
2
-
3
- export type InsertResult =
4
- | { inserted: true; file: string; warning?: string }
5
- | { inserted: false; error: string }
6
-
7
- function leadingWs(line: string): string {
8
- return line.match(/^(\s*)/)?.[1] ?? ''
9
- }
10
-
11
- function findInsertPoint(lines: string[]): { idx: number; indent: string } | null {
12
- // Explicit marker takes priority
13
- for (let i = 0; i < lines.length; i++) {
14
- if (lines[i].includes('@davaux-insert')) {
15
- return { idx: i, indent: leadingWs(lines[i]) }
16
- }
17
- }
18
-
19
- // Find `return (` line
20
- let returnIdx = -1
21
- for (let i = 0; i < lines.length; i++) {
22
- if (/return\s*\(/.test(lines[i])) {
23
- returnIdx = i
24
- break
25
- }
26
- }
27
- if (returnIdx === -1) return null
28
-
29
- // Find the closing `)` of the return at the same or shallower indent
30
- const returnIndentLen = leadingWs(lines[returnIdx]).length
31
- let returnCloseIdx = -1
32
- for (let i = returnIdx + 1; i < lines.length; i++) {
33
- const t = lines[i].trim()
34
- const indLen = leadingWs(lines[i]).length
35
- if ((t === ')' || t === ');') && indLen <= returnIndentLen + 2) {
36
- returnCloseIdx = i
37
- break
38
- }
39
- }
40
- if (returnCloseIdx === -1) return null
41
-
42
- // Find the outermost JSX wrapper element
43
- let wrapperIdx = -1
44
- let wrapperTag = ''
45
- let wrapperIndent = ''
46
- for (let i = returnIdx + 1; i < returnCloseIdx; i++) {
47
- const t = lines[i].trim()
48
- if (!t) continue
49
- // Fragment
50
- if (t === '<>') {
51
- wrapperIdx = i
52
- wrapperTag = ''
53
- wrapperIndent = leadingWs(lines[i])
54
- break
55
- }
56
- // Single-line opening tag: <Tag> or <Tag attr="x">
57
- const m = t.match(/^<([A-Za-z][A-Za-z0-9.]*)(?:\s[^>]*)?>$/)
58
- if (m) {
59
- wrapperIdx = i
60
- wrapperTag = m[1]
61
- wrapperIndent = leadingWs(lines[i])
62
- break
63
- }
64
- }
65
- if (wrapperIdx === -1) return null
66
-
67
- // Find the closing tag at the same indent level
68
- const closeTag = wrapperTag ? `</${wrapperTag}>` : '</>'
69
- let closingIdx = -1
70
- for (let i = wrapperIdx + 1; i < returnCloseIdx; i++) {
71
- if (leadingWs(lines[i]) === wrapperIndent && lines[i].trim() === closeTag) {
72
- closingIdx = i
73
- break
74
- }
75
- }
76
- if (closingIdx === -1) return null
77
-
78
- const useTabs = wrapperIndent.includes('\t')
79
- const childIndent = wrapperIndent + (useTabs ? '\t' : ' ')
80
- return { idx: closingIdx, indent: childIndent }
81
- }
82
-
83
- function addMissingImports(lines: string[], imports: Record<string, string>): number {
84
- let lastImportIdx = -1
85
- for (let i = 0; i < lines.length; i++) {
86
- if (lines[i].trimStart().startsWith('import ')) lastImportIdx = i
87
- }
88
- let added = 0
89
- for (const [name, path] of Object.entries(imports)) {
90
- const already = lines.some(
91
- (l) =>
92
- l.includes(`import ${name}`) ||
93
- l.includes(`{ ${name} }`) ||
94
- new RegExp(`\\b${name}\\b`).test(l.replace(/^import\s+/, '')),
95
- )
96
- if (!already) {
97
- lines.splice(lastImportIdx + 1 + added, 0, `import ${name} from '${path}'`)
98
- added++
99
- }
100
- }
101
- return added
102
- }
103
-
104
- // Find the full span of the Nth element (opening through matching closing tag).
105
- // Mirrors findFullElementSpan in remove.ts — kept local to avoid a circular dep.
106
- function findElemSpan(lines: string[], tagName: string, instanceIndex: number): [number, number] | null {
107
- // PascalCase components: anchor to start-of-line so inline prop occurrences are not counted.
108
- // This keeps the index consistent with the OML tree traversal in countNameBefore.
109
- const isPascal = /^[A-Z]/.test(tagName)
110
- const openRe = isPascal
111
- ? new RegExp(`^\\s*<${tagName}(\\s|/>|>|$)`)
112
- : new RegExp(`<${tagName}(\\s|>|\\/)`)
113
- let count = 0
114
- for (let i = 0; i < lines.length; i++) {
115
- if (openRe.test(lines[i])) {
116
- if (count === instanceIndex) {
117
- const tagPos = lines[i].search(openRe)
118
- const openIndent = lines[i].match(/^(\s*)/)?.[1] ?? ''
119
- const rest = lines[i].slice(tagPos)
120
- if (/\/>/.test(rest) || new RegExp(`</${tagName}>`).test(rest)) return [i, i]
121
- for (let j = i + 1; j < lines.length; j++) {
122
- const t = lines[j].trim()
123
- const ind = lines[j].match(/^(\s*)/)?.[1] ?? ''
124
- if (t.startsWith(`</${tagName}>`) && ind.length <= openIndent.length) return [i, j]
125
- if (t && ind.length < openIndent.length) break
126
- }
127
- return [i, i]
128
- }
129
- count++
130
- }
131
- }
132
- return null
133
- }
134
-
135
- export function insertAfterElement(
136
- filePath: string,
137
- tagName: string,
138
- instanceIndex: number,
139
- newJsx: string,
140
- componentImports: Record<string, string> = {},
141
- ): InsertResult {
142
- let source: string
143
- try {
144
- source = readFileSync(filePath, 'utf-8')
145
- } catch {
146
- return { inserted: false, error: `Cannot read file: ${filePath}` }
147
- }
148
-
149
- const lines = source.split('\n')
150
- const span = findElemSpan(lines, tagName, instanceIndex)
151
- if (!span) return { inserted: false, error: `No <${tagName}> found at index ${instanceIndex}` }
152
-
153
- const importCount = addMissingImports(lines, componentImports)
154
- const adjustedEnd = span[1] + importCount
155
-
156
- const indent = leadingWs(lines[span[0] + importCount])
157
- const formatted = newJsx
158
- .split('\n')
159
- .map((l) => (l ? indent + l : l))
160
- .join('\n')
161
-
162
- lines.splice(adjustedEnd + 1, 0, formatted)
163
-
164
- try {
165
- writeFileSync(filePath, lines.join('\n'), 'utf-8')
166
- } catch {
167
- return { inserted: false, error: `Cannot write file: ${filePath}` }
168
- }
169
-
170
- return { inserted: true, file: filePath }
171
- }
172
-
173
- export function insertJsx(
174
- filePath: string,
175
- jsxSnippet: string,
176
- componentImports: Record<string, string>,
177
- ): InsertResult {
178
- let source: string
179
- try {
180
- source = readFileSync(filePath, 'utf-8')
181
- } catch {
182
- return { inserted: false, error: `Cannot read file: ${filePath}` }
183
- }
184
-
185
- const lines = source.split('\n')
186
- const point = findInsertPoint(lines)
187
- if (!point) {
188
- return {
189
- inserted: false,
190
- error:
191
- 'Cannot find insertion point. Add {/* @davaux-insert */} in your JSX where you want components to be inserted.',
192
- }
193
- }
194
-
195
- const importCount = addMissingImports(lines, componentImports)
196
- const insertIdx = point.idx + importCount
197
-
198
- const formatted = jsxSnippet
199
- .split('\n')
200
- .map((l) => (l ? point.indent + l : l))
201
- .join('\n')
202
-
203
- lines.splice(insertIdx, 0, formatted)
204
-
205
- try {
206
- writeFileSync(filePath, lines.join('\n'), 'utf-8')
207
- } catch {
208
- return { inserted: false, error: `Cannot write file: ${filePath}` }
209
- }
210
-
211
- // Warn if an uppercase component was inserted without a matching import in the file
212
- const componentName = jsxSnippet.match(/^<([A-Z][A-Za-z0-9.]*)/)?.[1]
213
- const hasImport =
214
- !componentName ||
215
- lines.some((l) => l.trimStart().startsWith('import') && l.includes(componentName))
216
- const warning = hasImport
217
- ? undefined
218
- : `No import found for ${componentName}. Add an import manually, or set the "imports" field in the blueprint JSON to automate it.`
219
-
220
- return { inserted: true, file: filePath, warning }
221
- }