@setzkasten-cms/astro-admin 0.6.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 (49) hide show
  1. package/LICENSE +37 -0
  2. package/package.json +70 -0
  3. package/src/admin-page.astro +148 -0
  4. package/src/api-routes/__tests__/add-section-helpers.test.ts +383 -0
  5. package/src/api-routes/__tests__/catalog-api.test.ts +115 -0
  6. package/src/api-routes/__tests__/deferred-operations.test.ts +232 -0
  7. package/src/api-routes/__tests__/deploy-hook.test.ts +134 -0
  8. package/src/api-routes/__tests__/patch-page-file.test.ts +193 -0
  9. package/src/api-routes/__tests__/scan-page-helpers.test.ts +162 -0
  10. package/src/api-routes/__tests__/section-management.test.ts +284 -0
  11. package/src/api-routes/_storage-config.ts +54 -0
  12. package/src/api-routes/asset-proxy.ts +76 -0
  13. package/src/api-routes/auth-callback.ts +105 -0
  14. package/src/api-routes/auth-login.ts +87 -0
  15. package/src/api-routes/auth-logout.ts +9 -0
  16. package/src/api-routes/auth-session.ts +36 -0
  17. package/src/api-routes/catalog-add.ts +151 -0
  18. package/src/api-routes/catalog-export.ts +86 -0
  19. package/src/api-routes/catalog-helpers.ts +83 -0
  20. package/src/api-routes/catalog-list.ts +12 -0
  21. package/src/api-routes/config.ts +30 -0
  22. package/src/api-routes/deploy-hook.ts +69 -0
  23. package/src/api-routes/github-proxy.ts +111 -0
  24. package/src/api-routes/init-add-section.ts +511 -0
  25. package/src/api-routes/init-apply.ts +270 -0
  26. package/src/api-routes/init-migrate.ts +262 -0
  27. package/src/api-routes/init-scan-page.ts +336 -0
  28. package/src/api-routes/init-scan.ts +162 -0
  29. package/src/api-routes/pages.ts +17 -0
  30. package/src/api-routes/section-add.ts +189 -0
  31. package/src/api-routes/section-commit-pending.ts +147 -0
  32. package/src/api-routes/section-delete.ts +141 -0
  33. package/src/api-routes/section-duplicate.ts +144 -0
  34. package/src/api-routes/section-management.ts +95 -0
  35. package/src/api-routes/section-prepare-copy.ts +93 -0
  36. package/src/api-routes/section-prepare.ts +121 -0
  37. package/src/env.d.ts +7 -0
  38. package/src/init/__tests__/page-level.test.ts +1033 -0
  39. package/src/init/__tests__/page-list-coverage.test.ts +474 -0
  40. package/src/init/__tests__/patcher-edge-cases.test.ts +434 -0
  41. package/src/init/__tests__/patcher-page-mode.test.ts +272 -0
  42. package/src/init/__tests__/section-pipeline.test.ts +393 -0
  43. package/src/init/analyzer-types.ts +92 -0
  44. package/src/init/astro-config-patcher.ts +98 -0
  45. package/src/init/astro-detector.ts +207 -0
  46. package/src/init/astro-section-analyzer-v2.ts +1663 -0
  47. package/src/init/field-label-enricher.ts +72 -0
  48. package/src/init/template-patcher-v2.ts +1957 -0
  49. package/tsconfig.json +9 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Phase 2: Cosmetic label enrichment for inner fields of repeated elements.
3
+ *
4
+ * This module is purely cosmetic — it sets `.label` on InnerFieldInfo objects.
5
+ * It NEVER changes keys, types, positions, or structural data.
6
+ *
7
+ * Rules are fuzzy and best-effort. If no rule matches, the generic key remains.
8
+ * All text analysis ignores special characters (€, /, <, >) and works only
9
+ * with letters, digits, and whitespace.
10
+ */
11
+
12
+ import type { InnerFieldInfo } from './analyzer-types.js'
13
+
14
+ /**
15
+ * Enrich fields with human-friendly labels based on tag context and text patterns.
16
+ * Mutates `field.label` in place.
17
+ */
18
+ export function enrichFieldLabels(fields: InnerFieldInfo[]): void {
19
+ for (const field of fields) {
20
+ const label = inferLabel(field)
21
+ if (label) field.label = label
22
+ }
23
+ }
24
+
25
+ function inferLabel(field: InnerFieldInfo): string | undefined {
26
+ // 1. HTML tag context (most reliable)
27
+ if (/^h[1-6]$/.test(field.tag)) return 'Überschrift'
28
+ if (field.type === 'array') return 'Liste'
29
+ if (field.tag === 'a' && field.type === 'link') return 'Link'
30
+ if (field.tag === 'a' && field.type === 'text') return 'Link-Text'
31
+
32
+ // 2. Text content analysis — use ORIGINAL values (with special chars) for some checks
33
+ const rawValues = field.defaultValues.filter((v): v is string => typeof v === 'string')
34
+ const cleanValues = rawValues.map(v => stripSpecialChars(v))
35
+
36
+ if (rawValues.length === 0) return undefined
37
+
38
+ // Short single-word text (all instances) → Label / Overline / Name
39
+ if (rawValues.every(v => v.trim().length > 0 && v.trim().length < 20 && !v.includes(' '))) {
40
+ return 'Label'
41
+ }
42
+
43
+ // Contains currency symbols in ANY value + all short → Preis
44
+ // (e.g. "9 €", "29 €", "Auf Anfrage" — the last is a price placeholder)
45
+ if (rawValues.some(v => /[€$£¥₹]/.test(v)) && rawValues.every(v => v.length < 25)) {
46
+ return 'Preis'
47
+ }
48
+ // All values contain digits and are short → Preis
49
+ if (rawValues.every(v => /\d/.test(v) && v.length < 25)) {
50
+ return 'Preis'
51
+ }
52
+
53
+ // Long text → Beschreibung
54
+ if (cleanValues.every(v => v.length > 40)) {
55
+ return 'Beschreibung'
56
+ }
57
+
58
+ // Medium text in <p> → Beschreibung
59
+ if (field.tag === 'p' && cleanValues.every(v => v.length > 15)) {
60
+ return 'Beschreibung'
61
+ }
62
+
63
+ return undefined
64
+ }
65
+
66
+ /**
67
+ * Strip everything except letters, digits, umlauts, and whitespace.
68
+ * This makes text comparison robust against currency symbols, slashes, etc.
69
+ */
70
+ function stripSpecialChars(str: string): string {
71
+ return str.replace(/[^a-zA-Z0-9äöüÄÖÜß\s]/g, '').trim()
72
+ }