@setzkasten-cms/astro-admin 1.4.6 → 1.5.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.
Files changed (166) hide show
  1. package/dist/api-routes/_auth-guard.d.ts +27 -3
  2. package/dist/api-routes/_auth-guard.js +5 -2
  3. package/dist/api-routes/_dev-session-secret.d.ts +8 -0
  4. package/dist/api-routes/_dev-session-secret.js +8 -0
  5. package/dist/api-routes/_github-token.js +1 -1
  6. package/dist/api-routes/_role-resolver.js +6 -3
  7. package/dist/api-routes/_session-secret.d.ts +19 -0
  8. package/dist/api-routes/_session-secret.js +7 -0
  9. package/dist/api-routes/_session-signing.d.ts +45 -0
  10. package/dist/api-routes/_session-signing.js +8 -0
  11. package/dist/api-routes/_webhook-dispatcher.js +4 -4
  12. package/dist/api-routes/asset-proxy.js +1 -1
  13. package/dist/api-routes/auth-callback.js +12 -5
  14. package/dist/api-routes/auth-logout.d.ts +4 -4
  15. package/dist/api-routes/auth-logout.js +8 -2
  16. package/dist/api-routes/auth-session.d.ts +6 -0
  17. package/dist/api-routes/auth-session.js +19 -19
  18. package/dist/api-routes/auth-setzkasten-login.js +14 -7
  19. package/dist/api-routes/catalog-add.js +59 -17
  20. package/dist/api-routes/catalog-export.js +14 -4
  21. package/dist/api-routes/config.d.ts +10 -3
  22. package/dist/api-routes/config.js +26 -4
  23. package/dist/api-routes/deploy-hook.js +8 -8
  24. package/dist/api-routes/editors.d.ts +1 -1
  25. package/dist/api-routes/editors.js +5 -2
  26. package/dist/api-routes/github-proxy.js +30 -8
  27. package/dist/api-routes/global-config.js +6 -3
  28. package/dist/api-routes/history-rollback.js +31 -14
  29. package/dist/api-routes/history-version.js +8 -6
  30. package/dist/api-routes/history.js +5 -2
  31. package/dist/api-routes/icons-local.js +1 -1
  32. package/dist/api-routes/init-add-section.js +113 -47
  33. package/dist/api-routes/init-apply.js +56 -42
  34. package/dist/api-routes/init-migrate.js +43 -36
  35. package/dist/api-routes/init-scan-page.d.ts +1 -1
  36. package/dist/api-routes/init-scan-page.js +59 -13
  37. package/dist/api-routes/init-scan.js +22 -7
  38. package/dist/api-routes/migrate-to-multi.js +5 -2
  39. package/dist/api-routes/pages.js +15 -4
  40. package/dist/api-routes/section-add.js +68 -16
  41. package/dist/api-routes/section-commit-pending.js +70 -22
  42. package/dist/api-routes/section-delete.js +49 -14
  43. package/dist/api-routes/section-duplicate.js +65 -16
  44. package/dist/api-routes/section-prepare-copy.js +15 -2
  45. package/dist/api-routes/section-prepare.js +25 -4
  46. package/dist/api-routes/setup-github-app-bounce.js +15 -1
  47. package/dist/api-routes/setup-github-app-branches.js +9 -6
  48. package/dist/api-routes/setup-github-app-callback.js +24 -1
  49. package/dist/api-routes/setup-github-app-credentials.d.ts +27 -0
  50. package/dist/api-routes/setup-github-app-credentials.js +43 -0
  51. package/dist/api-routes/setup-github-app-installed.js +22 -1
  52. package/dist/api-routes/setup-github-app-repos.js +5 -2
  53. package/dist/api-routes/setup-github-app.d.ts +4 -0
  54. package/dist/api-routes/setup-github-app.js +19 -2
  55. package/dist/api-routes/updater-register.js +7 -1
  56. package/dist/api-routes/webhooks-status.js +5 -2
  57. package/dist/api-routes/webhooks-test.js +9 -8
  58. package/dist/api-routes/webhooks.js +12 -14
  59. package/dist/api-routes/websites-add.js +5 -2
  60. package/dist/api-routes/websites-remove.js +5 -2
  61. package/dist/{chunk-ZQDGGWJP.js → chunk-5KMGSFCZ.js} +2 -2
  62. package/dist/{chunk-Q3N336KR.js → chunk-CDXCYYQR.js} +29 -24
  63. package/dist/{chunk-NKDATSPA.js → chunk-DP6RTINQ.js} +1 -1
  64. package/dist/chunk-KENFINT4.js +76 -0
  65. package/dist/chunk-ONP6BRZO.js +47 -0
  66. package/dist/{chunk-INIWFKQ3.js → chunk-Q5HV47DW.js} +33 -19
  67. package/dist/chunk-QVCW6EF3.js +26 -0
  68. package/dist/{chunk-TD76R3A6.js → chunk-UHI6323G.js} +293 -174
  69. package/dist/{chunk-AM4DZXXM.js → chunk-UJAFZEX2.js} +76 -9
  70. package/package.json +12 -6
  71. package/src/api-routes/__tests__/_session-signing.test.ts +114 -0
  72. package/src/api-routes/__tests__/_session-test-helper.ts +27 -0
  73. package/src/api-routes/__tests__/add-section-helpers.test.ts +59 -25
  74. package/src/api-routes/__tests__/auth-guard.test.ts +46 -7
  75. package/src/api-routes/__tests__/catalog-api.test.ts +14 -6
  76. package/src/api-routes/__tests__/commit-trailers.test.ts +5 -5
  77. package/src/api-routes/__tests__/deferred-operations.test.ts +9 -12
  78. package/src/api-routes/__tests__/deploy-hook.test.ts +3 -8
  79. package/src/api-routes/__tests__/feature-gate.test.ts +1 -1
  80. package/src/api-routes/__tests__/github-cache.test.ts +1 -1
  81. package/src/api-routes/__tests__/github-token.test.ts +1 -1
  82. package/src/api-routes/__tests__/global-config-theme.test.ts +4 -4
  83. package/src/api-routes/__tests__/history-rollback.test.ts +6 -3
  84. package/src/api-routes/__tests__/history.test.ts +9 -6
  85. package/src/api-routes/__tests__/init-scan-page-resolve-config.test.ts +11 -3
  86. package/src/api-routes/__tests__/migrate-to-multi.test.ts +5 -1
  87. package/src/api-routes/__tests__/pages-meta-store.test.ts +10 -5
  88. package/src/api-routes/__tests__/pages.test.ts +7 -2
  89. package/src/api-routes/__tests__/patch-page-file.test.ts +71 -19
  90. package/src/api-routes/__tests__/route-registry.test.ts +11 -18
  91. package/src/api-routes/__tests__/scan-page-helpers.test.ts +13 -10
  92. package/src/api-routes/__tests__/section-management.test.ts +28 -28
  93. package/src/api-routes/__tests__/setup-github-app-callback.test.ts +58 -16
  94. package/src/api-routes/__tests__/setup-github-app-repos.test.ts +4 -5
  95. package/src/api-routes/__tests__/setup-github-app.test.ts +27 -7
  96. package/src/api-routes/__tests__/storage-config-for-request.test.ts +83 -0
  97. package/src/api-routes/__tests__/updater-register.test.ts +230 -0
  98. package/src/api-routes/__tests__/webhook-signing.test.ts +1 -1
  99. package/src/api-routes/__tests__/webhooks.test.ts +19 -7
  100. package/src/api-routes/__tests__/websites-add.test.ts +2 -1
  101. package/src/api-routes/__tests__/websites-remove.test.ts +2 -1
  102. package/src/api-routes/_auth-guard.ts +47 -15
  103. package/src/api-routes/_commit-trailers.ts +3 -2
  104. package/src/api-routes/_dev-session-secret.ts +79 -0
  105. package/src/api-routes/_github-token.ts +1 -1
  106. package/src/api-routes/_pages-meta-store.ts +2 -2
  107. package/src/api-routes/_role-resolver.ts +7 -5
  108. package/src/api-routes/_session-secret.ts +46 -0
  109. package/src/api-routes/_session-signing.ts +135 -0
  110. package/src/api-routes/_vercel-origin.ts +2 -6
  111. package/src/api-routes/_webhook-dispatcher.ts +12 -16
  112. package/src/api-routes/_website-resolver.ts +3 -10
  113. package/src/api-routes/auth-callback.ts +9 -5
  114. package/src/api-routes/auth-login.ts +5 -3
  115. package/src/api-routes/auth-logout.ts +18 -1
  116. package/src/api-routes/auth-session.ts +13 -21
  117. package/src/api-routes/auth-setzkasten-login.ts +12 -9
  118. package/src/api-routes/catalog-add.ts +89 -31
  119. package/src/api-routes/catalog-export.ts +30 -10
  120. package/src/api-routes/config.ts +39 -6
  121. package/src/api-routes/deploy-hook.ts +13 -11
  122. package/src/api-routes/editors.ts +33 -22
  123. package/src/api-routes/github-proxy.ts +25 -11
  124. package/src/api-routes/global-config.ts +103 -18
  125. package/src/api-routes/history-rollback.ts +41 -14
  126. package/src/api-routes/history-version.ts +5 -6
  127. package/src/api-routes/history.ts +3 -3
  128. package/src/api-routes/icons-local.ts +2 -2
  129. package/src/api-routes/init-add-section.ts +174 -79
  130. package/src/api-routes/init-apply.ts +71 -56
  131. package/src/api-routes/init-migrate.ts +54 -48
  132. package/src/api-routes/init-scan-page.ts +77 -30
  133. package/src/api-routes/init-scan.ts +19 -11
  134. package/src/api-routes/pages.ts +16 -11
  135. package/src/api-routes/section-add.ts +98 -27
  136. package/src/api-routes/section-commit-pending.ts +87 -34
  137. package/src/api-routes/section-delete.ts +76 -27
  138. package/src/api-routes/section-duplicate.ts +95 -28
  139. package/src/api-routes/section-management.ts +3 -7
  140. package/src/api-routes/section-prepare-copy.ts +29 -8
  141. package/src/api-routes/section-prepare.ts +38 -10
  142. package/src/api-routes/setup-github-app-bounce.ts +7 -1
  143. package/src/api-routes/setup-github-app-branches.ts +6 -7
  144. package/src/api-routes/setup-github-app-callback.ts +18 -1
  145. package/src/api-routes/setup-github-app-credentials.ts +55 -0
  146. package/src/api-routes/setup-github-app-installed.ts +12 -1
  147. package/src/api-routes/setup-github-app-repos.ts +2 -3
  148. package/src/api-routes/setup-github-app.ts +14 -5
  149. package/src/api-routes/updater-check.ts +6 -4
  150. package/src/api-routes/updater-register.ts +34 -20
  151. package/src/api-routes/updater-transfer.ts +8 -6
  152. package/src/api-routes/updater-unbind.ts +14 -10
  153. package/src/api-routes/webhooks-test.ts +9 -11
  154. package/src/api-routes/webhooks.ts +15 -19
  155. package/src/init/__tests__/page-level.test.ts +279 -105
  156. package/src/init/__tests__/page-list-coverage.test.ts +70 -70
  157. package/src/init/__tests__/patcher-child-component.test.ts +12 -3
  158. package/src/init/__tests__/patcher-edge-cases.test.ts +47 -23
  159. package/src/init/__tests__/patcher-mixed-content-wrapper.test.ts +16 -6
  160. package/src/init/__tests__/patcher-page-mode.test.ts +30 -20
  161. package/src/init/__tests__/section-pipeline.test.ts +53 -19
  162. package/src/init/astro-config-patcher.ts +4 -18
  163. package/src/init/astro-detector.ts +2 -7
  164. package/src/init/astro-section-analyzer-v2.ts +475 -193
  165. package/src/init/field-label-enricher.ts +6 -6
  166. package/src/init/template-patcher-v2.ts +218 -97
@@ -9,7 +9,7 @@
9
9
  * 5. removeOldVarDeclarations causes TDZ (alias placed before skData declaration)
10
10
  */
11
11
 
12
- import { describe, it, expect } from 'vitest'
12
+ import { describe, expect, it } from 'vitest'
13
13
  import { patchTemplateForFields } from '../../init/template-patcher-v2'
14
14
  import type { PatchField } from '../../init/template-patcher-v2'
15
15
 
@@ -60,14 +60,22 @@ import BaseLayout from '../layouts/BaseLayout.astro';
60
60
  `
61
61
 
62
62
  const fields: PatchField[] = [
63
- { key: 'items', type: 'array', defaultValue: [
64
- { name: '@setzkasten-cms/core', desc: 'Schema, Feldtypen, Validation' },
65
- { name: '@setzkasten-cms/ui', desc: 'React-UI: Provider, FormStore' },
66
- ]},
67
- { key: 'items2', type: 'array', defaultValue: [
68
- { title: 'Dependency Inversion', desc: 'UI haengt nur von Ports ab' },
69
- { title: 'Schema-First', desc: 'Alles leitet sich vom TypeScript-Schema ab' },
70
- ]},
63
+ {
64
+ key: 'items',
65
+ type: 'array',
66
+ defaultValue: [
67
+ { name: '@setzkasten-cms/core', desc: 'Schema, Feldtypen, Validation' },
68
+ { name: '@setzkasten-cms/ui', desc: 'React-UI: Provider, FormStore' },
69
+ ],
70
+ },
71
+ {
72
+ key: 'items2',
73
+ type: 'array',
74
+ defaultValue: [
75
+ { title: 'Dependency Inversion', desc: 'UI haengt nur von Ports ab' },
76
+ { title: 'Schema-First', desc: 'Alles leitet sich vom TypeScript-Schema ab' },
77
+ ],
78
+ },
71
79
  ]
72
80
 
73
81
  it('should reference skData?.items for the first array', async () => {
@@ -111,9 +119,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
111
119
  </BaseLayout>
112
120
  `
113
121
 
114
- const fields: PatchField[] = [
115
- { key: 'heading', type: 'text', defaultValue: 'Titel' },
116
- ]
122
+ const fields: PatchField[] = [{ key: 'heading', type: 'text', defaultValue: 'Titel' }]
117
123
 
118
124
  it('should add id="section-_page_test" to the <section> element', async () => {
119
125
  const patched = await patchTemplateForFields(source, '_page_test', fields, [], { mode: 'page' })
@@ -147,9 +153,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
147
153
  </BaseLayout>
148
154
  `
149
155
 
150
- const fields: PatchField[] = [
151
- { key: 'heading', type: 'text', defaultValue: 'Architektur' },
152
- ]
156
+ const fields: PatchField[] = [{ key: 'heading', type: 'text', defaultValue: 'Architektur' }]
153
157
 
154
158
  it('should add data-sk-field to the <h1> element', async () => {
155
159
  const patched = await patchTemplateForFields(source, '_page_test', fields, [], { mode: 'page' })
@@ -203,7 +207,7 @@ const fields = ['Alpha', 'Beta', 'Gamma'];
203
207
  const fmMatch = patched.match(/^---\n([\s\S]*?)\n---/)
204
208
  const frontmatter = fmMatch ? fmMatch[1]! : patched
205
209
 
206
- const lines = frontmatter.split('\n').map(l => l.trim())
210
+ const lines = frontmatter.split('\n').map((l) => l.trim())
207
211
  expect(lines).not.toContain(';')
208
212
  })
209
213
  })
@@ -239,7 +243,9 @@ const fields = ['Alpha', 'Beta', 'Gamma'];
239
243
  ]
240
244
 
241
245
  it('should place the fields alias AFTER the skData declaration', async () => {
242
- const patched = await patchTemplateForFields(source, '_page_test', patchFields, [], { mode: 'page' })
246
+ const patched = await patchTemplateForFields(source, '_page_test', patchFields, [], {
247
+ mode: 'page',
248
+ })
243
249
 
244
250
  const fmMatch = patched.match(/^---\n([\s\S]*?)\n---/)
245
251
  const frontmatter = fmMatch ? fmMatch[1]! : patched
@@ -253,17 +259,21 @@ const fields = ['Alpha', 'Beta', 'Gamma'];
253
259
  })
254
260
 
255
261
  it('should not contain a stray semicolon line in frontmatter', async () => {
256
- const patched = await patchTemplateForFields(source, '_page_test', patchFields, [], { mode: 'page' })
262
+ const patched = await patchTemplateForFields(source, '_page_test', patchFields, [], {
263
+ mode: 'page',
264
+ })
257
265
 
258
266
  const fmMatch = patched.match(/^---\n([\s\S]*?)\n---/)
259
267
  const frontmatter = fmMatch ? fmMatch[1]! : patched
260
268
 
261
- const lines = frontmatter.split('\n').map(l => l.trim())
269
+ const lines = frontmatter.split('\n').map((l) => l.trim())
262
270
  expect(lines).not.toContain(';')
263
271
  })
264
272
 
265
273
  it('should preserve fields.length in the template', async () => {
266
- const patched = await patchTemplateForFields(source, '_page_test', patchFields, [], { mode: 'page' })
274
+ const patched = await patchTemplateForFields(source, '_page_test', patchFields, [], {
275
+ mode: 'page',
276
+ })
267
277
 
268
278
  // Extract template (after closing ---)
269
279
  const templatePart = patched.split('\n---\n').slice(1).join('\n---\n')
@@ -12,9 +12,9 @@
12
12
  * - Stale frontmatter var cleanup
13
13
  */
14
14
 
15
- import { describe, it, expect, beforeAll } from 'vitest'
16
15
  import { readFileSync, readdirSync } from 'fs'
17
- import { join, basename } from 'path'
16
+ import { basename, join } from 'path'
17
+ import { beforeAll, describe, expect, it } from 'vitest'
18
18
  import { analyzeAstroSection } from '../../init/astro-section-analyzer-v2'
19
19
  import { patchTemplateForFields } from '../../init/template-patcher-v2'
20
20
 
@@ -23,7 +23,9 @@ import { patchTemplateForFields } from '../../init/template-patcher-v2'
23
23
  // ---------------------------------------------------------------------------
24
24
 
25
25
  const SECTIONS_DIR = join(import.meta.dirname!, '..', '..', '..', '..', '..', 'test-sections')
26
- const files = readdirSync(SECTIONS_DIR).filter(f => f.endsWith('.astro')).sort()
26
+ const files = readdirSync(SECTIONS_DIR)
27
+ .filter((f) => f.endsWith('.astro'))
28
+ .sort()
27
29
 
28
30
  // ---------------------------------------------------------------------------
29
31
  // Helpers (ported from test-sections-runner.mts)
@@ -40,12 +42,16 @@ function extractClassValues(src: string): string[] {
40
42
  function checkCssIntegrity(
41
43
  source: string,
42
44
  patched: string,
43
- groups: Array<{ tag: string; instances: Array<{ start: number; end: number }>; fields?: Array<{ key: string; defaultValues?: unknown[] }> }>,
45
+ groups: Array<{
46
+ tag: string
47
+ instances: Array<{ start: number; end: number }>
48
+ fields?: Array<{ key: string; defaultValues?: unknown[] }>
49
+ }>,
44
50
  ): { ok: boolean; lost: string[] } {
45
51
  const lost: string[] = []
46
52
  const dynamicClassValues = new Set<string>()
47
53
  for (const g of groups) {
48
- for (const f of (g.fields ?? [])) {
54
+ for (const f of g.fields ?? []) {
49
55
  if (f.key.startsWith('_class') && f.defaultValues) {
50
56
  for (const dv of f.defaultValues) {
51
57
  if (typeof dv === 'string') dynamicClassValues.add(dv)
@@ -133,9 +139,18 @@ function checkSkFieldBindings(
133
139
 
134
140
  for (const g of groups) {
135
141
  for (const innerField of g.fields) {
136
- if (innerField.type === 'array') { skipped.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key} (array)`); continue }
137
- if (!fieldNeedsSkBinding(innerField)) { skipped.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key} (${innerField.type})`); continue }
138
- if (!patched.includes(`item.${innerField.key}`)) { skipped.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key} (not replaced)`); continue }
142
+ if (innerField.type === 'array') {
143
+ skipped.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key} (array)`)
144
+ continue
145
+ }
146
+ if (!fieldNeedsSkBinding(innerField)) {
147
+ skipped.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key} (${innerField.type})`)
148
+ continue
149
+ }
150
+ if (!patched.includes(`item.${innerField.key}`)) {
151
+ skipped.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key} (not replaced)`)
152
+ continue
153
+ }
139
154
  const innerBinding = `${sectionKey}.${g.fieldKey}.\${_i}.${innerField.key}`
140
155
  if (patched.includes(innerBinding)) {
141
156
  found.push(`${sectionKey}.${g.fieldKey}.*.${innerField.key}`)
@@ -173,7 +188,13 @@ describe('Section Pipeline', () => {
173
188
  const getSectionMatch = isPageMode ? source.match(/getSection\(['"]([^'"]+)['"]\)/) : null
174
189
  sectionKey = getSectionMatch?.[1] ?? filenameKey
175
190
  const options = isPageMode ? { mode: 'page' as const } : undefined
176
- section = await analyzeAstroSection(source, sectionKey, name, `src/components/sections/${file}`, options)
191
+ section = await analyzeAstroSection(
192
+ source,
193
+ sectionKey,
194
+ name,
195
+ `src/components/sections/${file}`,
196
+ options,
197
+ )
177
198
  groups = (section as any)._analyzerResult?.repeatedGroups ?? []
178
199
  patched = await patchTemplateForFields(source, sectionKey, section.fields, groups, options)
179
200
  })
@@ -217,10 +238,13 @@ describe('Section Pipeline', () => {
217
238
  }
218
239
  }
219
240
  }
220
- const duplicateArrays = section.fields.filter((f: any) =>
221
- f.type === 'array' && innerArraySources.has(f.key),
241
+ const duplicateArrays = section.fields.filter(
242
+ (f: any) => f.type === 'array' && innerArraySources.has(f.key),
222
243
  )
223
- expect(duplicateArrays, `Duplicate arrays: ${duplicateArrays.map((f: any) => f.key).join(', ')}`).toHaveLength(0)
244
+ expect(
245
+ duplicateArrays,
246
+ `Duplicate arrays: ${duplicateArrays.map((f: any) => f.key).join(', ')}`,
247
+ ).toHaveLength(0)
224
248
  })
225
249
 
226
250
  it('should remove consumed frontmatter vars', () => {
@@ -267,7 +291,10 @@ describe('Section Pipeline', () => {
267
291
 
268
292
  for (const g of groups) {
269
293
  const arrayField = section.fields.find((f: any) => f.key === g.fieldKey)
270
- if (!arrayField) { issues.push(`No top-level field for group ${g.fieldKey}`); continue }
294
+ if (!arrayField) {
295
+ issues.push(`No top-level field for group ${g.fieldKey}`)
296
+ continue
297
+ }
271
298
 
272
299
  const items = arrayField.defaultValue as Array<Record<string, unknown>> | undefined
273
300
  if (!Array.isArray(items) || items.length === 0) {
@@ -294,7 +321,7 @@ describe('Section Pipeline', () => {
294
321
  }
295
322
  for (const refKey of referencedKeys) {
296
323
  if (['map', 'length', 'filter', 'forEach', 'join', 'slice'].includes(refKey)) continue
297
- const hasInAnyItem = items.some(item => refKey in item)
324
+ const hasInAnyItem = items.some((item) => refKey in item)
298
325
  if (!hasInAnyItem) {
299
326
  issues.push(`{item.${refKey}} used in template but missing in content JSON`)
300
327
  }
@@ -335,7 +362,9 @@ describe('Section Pipeline', () => {
335
362
  const origCount = originalClassCounts.get(val) ?? 0
336
363
  if (keys.length > origCount) {
337
364
  const label = instIdx === 0 ? 'template' : `instance ${instIdx}`
338
- issues.push(`${g.fieldKey} ${label}: "${val.slice(0, 40)}" assigned to [${keys.join(', ')}] but appears ${origCount}×`)
365
+ issues.push(
366
+ `${g.fieldKey} ${label}: "${val.slice(0, 40)}" assigned to [${keys.join(', ')}] but appears ${origCount}×`,
367
+ )
339
368
  }
340
369
  }
341
370
  }
@@ -380,7 +409,9 @@ describe('Section Pipeline', () => {
380
409
  const actualTag = lastPart.replace(/:\d+$/, '') || g.tag
381
410
 
382
411
  if (actualTag !== expectedTag) {
383
- issues.push(`${cf.key} instance ${instIdx}: expected <${expectedTag}> but on <${actualTag}>`)
412
+ issues.push(
413
+ `${cf.key} instance ${instIdx}: expected <${expectedTag}> but on <${actualTag}>`,
414
+ )
384
415
  }
385
416
  }
386
417
  }
@@ -422,7 +453,8 @@ describe('Section Pipeline', () => {
422
453
 
423
454
  it('should remove stale frontmatter vars from repeated component props', () => {
424
455
  const componentArrayFields = section.fields.filter(
425
- (f: any) => f.type === 'array' && f.options?.sourceComponent && Array.isArray(f.defaultValue),
456
+ (f: any) =>
457
+ f.type === 'array' && f.options?.sourceComponent && Array.isArray(f.defaultValue),
426
458
  )
427
459
  if (componentArrayFields.length === 0) return
428
460
  const fmEnd = patched.indexOf('---', patched.indexOf('---') + 3)
@@ -430,9 +462,11 @@ describe('Section Pipeline', () => {
430
462
  const staleVars: string[] = []
431
463
  for (const field of componentArrayFields) {
432
464
  const items = (field as any).defaultValue as Array<Record<string, unknown>>
433
- for (const innerField of ((field as any).options?.arrayItem?.fields ?? []) as Array<{ key: string }>) {
465
+ for (const innerField of ((field as any).options?.arrayItem?.fields ?? []) as Array<{
466
+ key: string
467
+ }>) {
434
468
  // Only string-array props might have been declared as frontmatter vars
435
- const allVarLike = items.every(item => Array.isArray(item[innerField.key]))
469
+ const allVarLike = items.every((item) => Array.isArray(item[innerField.key]))
436
470
  if (!allVarLike) continue
437
471
  const varNames = items.map((_, i) => `${innerField.key}${i === 0 ? '' : i + 1}`)
438
472
  for (const v of varNames) {
@@ -21,11 +21,7 @@ export function patchAstroConfig(source: string): string | null {
21
21
  // Find the last import statement
22
22
  const lastImportIndex = findLastImportEnd(result)
23
23
  if (lastImportIndex >= 0) {
24
- result =
25
- result.slice(0, lastImportIndex) +
26
- '\n' +
27
- importLine +
28
- result.slice(lastImportIndex)
24
+ result = result.slice(0, lastImportIndex) + '\n' + importLine + result.slice(lastImportIndex)
29
25
  } else {
30
26
  // No imports found — add at the very top
31
27
  result = importLine + '\n' + result
@@ -67,19 +63,11 @@ function addToIntegrations(source: string): string {
67
63
 
68
64
  // Check if array is empty
69
65
  if (after.startsWith(']')) {
70
- return (
71
- source.slice(0, insertPos) +
72
- 'setzkasten()' +
73
- source.slice(insertPos)
74
- )
66
+ return source.slice(0, insertPos) + 'setzkasten()' + source.slice(insertPos)
75
67
  }
76
68
 
77
69
  // Array has items — prepend
78
- return (
79
- source.slice(0, insertPos) +
80
- '\n setzkasten(),\n ' +
81
- source.slice(insertPos)
82
- )
70
+ return source.slice(0, insertPos) + '\n setzkasten(),\n ' + source.slice(insertPos)
83
71
  }
84
72
 
85
73
  // Case 2: No integrations array — add it to defineConfig
@@ -87,9 +75,7 @@ function addToIntegrations(source: string): string {
87
75
  if (defineConfigMatch && defineConfigMatch.index !== undefined) {
88
76
  const insertPos = defineConfigMatch.index + defineConfigMatch[0].length
89
77
  return (
90
- source.slice(0, insertPos) +
91
- '\n integrations: [setzkasten()],\n' +
92
- source.slice(insertPos)
78
+ source.slice(0, insertPos) + '\n integrations: [setzkasten()],\n' + source.slice(insertPos)
93
79
  )
94
80
  }
95
81
 
@@ -47,9 +47,7 @@ export function findAstroPages(files: RepoFile[], projectRoot: string): AstroPag
47
47
 
48
48
  const name = relativePath.replace(/\.astro$/, '')
49
49
  const isIndex = name === 'index' || name.endsWith('/index')
50
- const pageKey = isIndex
51
- ? name === 'index' ? 'index' : name.replace(/\/index$/, '')
52
- : name
50
+ const pageKey = isIndex ? (name === 'index' ? 'index' : name.replace(/\/index$/, '')) : name
53
51
 
54
52
  pages.push({
55
53
  filePath: file.path,
@@ -170,10 +168,7 @@ function resolveImportPath(
170
168
  // Handle alias imports like @/components/... or ~/components/...
171
169
  if (importPath.startsWith('@/') || importPath.startsWith('~/')) {
172
170
  const aliasPath = importPath.replace(/^[@~]\//, '')
173
- const candidates = [
174
- `${projectRoot}/src/${aliasPath}`,
175
- `${projectRoot}/src/${aliasPath}.astro`,
176
- ]
171
+ const candidates = [`${projectRoot}/src/${aliasPath}`, `${projectRoot}/src/${aliasPath}.astro`]
177
172
  for (const candidate of candidates) {
178
173
  if (allFiles.some((f) => f.path === candidate)) return candidate
179
174
  }