@brandon_m_behring/book-scaffold-astro 4.30.0 → 5.0.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 (90) hide show
  1. package/CLAUDE.md +40 -3
  2. package/MIGRATION-v4-to-v5.md +183 -0
  3. package/README.md +30 -1
  4. package/bin/book-scaffold.mjs +1 -1
  5. package/components/AssessmentTest.astro +26 -5
  6. package/components/BookLink.astro +6 -3
  7. package/components/ChapterNav.astro +1 -1
  8. package/components/Cite.astro +37 -4
  9. package/components/ExerciseSolutions.astro +24 -4
  10. package/components/Figure.astro +7 -6
  11. package/components/Flashcards.tsx +19 -11
  12. package/components/NavContent.astro +60 -11
  13. package/components/ObjectiveMap.astro +14 -2
  14. package/components/PartReview.astro +32 -4
  15. package/components/PatternTimeline.astro +6 -2
  16. package/components/Rationale.astro +20 -3
  17. package/components/Sidebar.astro +11 -3
  18. package/components/SourceArchive.astro +33 -3
  19. package/components/Term.astro +18 -1
  20. package/components/Theorem.astro +15 -5
  21. package/components/TipsCard.astro +40 -3
  22. package/components/XRef.astro +14 -2
  23. package/dist/components/ExamRunner.d.ts +1 -1
  24. package/dist/components/Flashcards.d.ts +6 -1
  25. package/dist/components/Flashcards.mjs +14 -11
  26. package/dist/{exam-manifest-X9IrX1G3.d.ts → exam-manifest-DttY7kyZ.d.ts} +1 -1
  27. package/dist/index.d.ts +76 -8
  28. package/dist/index.mjs +517 -43
  29. package/dist/schemas.d.ts +1 -1
  30. package/dist/schemas.mjs +311 -32
  31. package/dist/{types-DgSlAew3.d.ts → types-D1QZgKMO.d.ts} +73 -21
  32. package/layouts/Base.astro +38 -9
  33. package/layouts/Chapter.astro +10 -2
  34. package/package.json +6 -2
  35. package/pages/answers.astro +25 -6
  36. package/pages/book.astro +75 -0
  37. package/pages/chapters/[...slug].astro +39 -7
  38. package/pages/chapters-book.astro +17 -0
  39. package/pages/chapters.astro +87 -9
  40. package/pages/convergence.astro +40 -10
  41. package/pages/corpus-apparatus/answers.astro +15 -0
  42. package/pages/corpus-apparatus/convergence.astro +15 -0
  43. package/pages/corpus-apparatus/exercises.astro +15 -0
  44. package/pages/corpus-apparatus/flashcards.astro +15 -0
  45. package/pages/corpus-apparatus/glossary.astro +15 -0
  46. package/pages/corpus-apparatus/practice-exam.astro +15 -0
  47. package/pages/corpus-apparatus/print.astro +15 -0
  48. package/pages/corpus-apparatus/references.astro +15 -0
  49. package/pages/corpus-apparatus/tips.astro +15 -0
  50. package/pages/exercises.astro +18 -5
  51. package/pages/flashcards.astro +26 -5
  52. package/pages/glossary.astro +20 -3
  53. package/pages/index.astro +54 -1
  54. package/pages/practice-exam.astro +8 -2
  55. package/pages/print.astro +7 -2
  56. package/pages/references.astro +26 -6
  57. package/pages/search.astro +65 -4
  58. package/pages/tips.astro +17 -4
  59. package/recipes/03-asset-pipelines.md +12 -4
  60. package/recipes/09-validation.md +1 -1
  61. package/recipes/15-defining-styles.md +6 -6
  62. package/recipes/16-tikz-figures.md +13 -2
  63. package/recipes/20-anki-export.md +15 -8
  64. package/recipes/21-multi-guide-single-app.md +293 -44
  65. package/recipes/22-responsive-nav-and-multibook-routing.md +7 -1
  66. package/recipes/24-figure-authoring-standard.md +241 -0
  67. package/recipes/README.md +3 -2
  68. package/scripts/build-bib.mjs +113 -35
  69. package/scripts/build-exercises.mjs +101 -24
  70. package/scripts/build-figures.mjs +13 -10
  71. package/scripts/build-labels.mjs +199 -194
  72. package/scripts/build-tips.mjs +95 -23
  73. package/scripts/corpus-tooling.mjs +268 -0
  74. package/scripts/render-notebooks.mjs +2 -1
  75. package/scripts/resolve-book-config.mjs +99 -1
  76. package/scripts/sync-figure-tokens.mjs +44 -0
  77. package/scripts/validate.mjs +676 -100
  78. package/scripts/walk-mdx.mjs +16 -4
  79. package/src/lib/book-link.ts +72 -0
  80. package/src/lib/chapters.ts +10 -4
  81. package/src/lib/corpus-collateral.ts +9 -0
  82. package/src/lib/corpus.ts +458 -0
  83. package/src/lib/define-style.ts +28 -15
  84. package/src/lib/exam-manifest.ts +4 -1
  85. package/src/lib/figure-palette.mjs +162 -0
  86. package/src/lib/figure.mjs +113 -37
  87. package/src/lib/patterns.ts +15 -6
  88. package/src/lib/questions.ts +8 -3
  89. package/src/types.ts +603 -0
  90. package/styles/tokens.css +73 -9
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { AstroUserConfig, AstroIntegration, MarkdownHeading } from 'astro';
2
- import { c as BookConfigOptions, f as BookScaffoldIntegrationOptions, h as ChaptersRenderer, p as SiblingBooks, r as Style } from './types-DgSlAew3.js';
3
- export { B as BOOK_PRESETS, a as BOOK_PROFILES, b as BookConfigError, d as BookPreset, e as BookProfile, g as BookSchemasOptions, C as ChapterFor, F as FreshnessAffordance, i as FrontmatterRouteConfig, N as NUMBER_STYLES, j as NumberStyle, P as PartKey, k as PartialRouteToggles, l as ProfileDefinition, R as ReleaseStatusConfig, m as RouteToggles, S as SecurityHeadersConfig, n as SiblingBookDescriptor, o as SiblingBookEntry, q as StatusBadge, s as StyleInput, V as VolatilityBadge, t as composeStyles, u as defineProfile, v as defineStyle, w as normalizeFrontmatterConfig, x as resolvePreset, y as resolveProfile } from './types-DgSlAew3.js';
2
+ import { c as BookConfigOptions, h as BookScaffoldIntegrationOptions, d as BookCorpus, l as CorpusApparatusRoute, e as BookCorpusInput, m as CorpusBook, k as ChaptersRenderer, v as SiblingBooks, x as Style } from './types-D1QZgKMO.js';
3
+ export { B as BOOK_PRESETS, a as BOOK_PROFILES, b as BookConfigError, f as BookPreset, g as BookProfile, i as BookSchemasOptions, C as CORPUS_APPARATUS_ROUTES, j as ChapterFor, n as CorpusBookInput, F as FreshnessAffordance, o as FrontmatterRouteConfig, N as NUMBER_STYLES, p as NumberStyle, P as PartKey, q as PartialRouteToggles, r as ProfileDefinition, R as ReleaseStatusConfig, s as RouteToggles, S as SecurityHeadersConfig, t as SiblingBookDescriptor, u as SiblingBookEntry, w as StatusBadge, y as StyleInput, V as VolatilityBadge, z as composeStyles, A as defineProfile, D as defineStyle, E as normalizeFrontmatterConfig, G as resolvePreset, H as resolveProfile } from './types-D1QZgKMO.js';
4
4
  import { E as volatilityLevels, c as academicParts, Q as Question } from './schemas-CKipJ5Ie.js';
5
5
  export { A as AcademicChapter, B as BloomLevel, C as CourseNotesChapter, G as GlossaryTerm, M as MinimalChapter, P as Provenance, a as QuestionType, R as ResearchPortfolioChapter, T as ToolsChapter, b as academicChapterSchema, d as bloomLevels, e as changeKinds, f as changelogSchema, g as chapterStatus, h as citationBackstops, i as courseNotesChapterSchema, j as glossarySchema, l as layoutModes, m as minimalChapterSchema, p as patternCategories, k as patternsSchema, n as provenanceObject, o as provenanceSchema, q as questionDifficulties, r as questionSchema, s as questionTypes, t as refineQuestion, u as refinedQuestionSchema, v as researchPortfolioChapterSchema, w as sourceTiers, x as sourceTiersResearch, y as sourcesSchema, z as toolSlugs, D as toolsChapterSchema } from './schemas-CKipJ5Ie.js';
6
6
  export { KIND_LABEL, ResolvedTheoremLabel, THEOREM_KINDS, TheoremKind, TheoremLabelProps, resolveTheoremNumber, theoremLabel } from './lib/theorem-label.js';
7
7
  export { ssmMacros } from './lib/katex-macros.js';
8
8
  export { ChapterLike, apparatusHref, baseNoSlash, bookOf, chapterHref, isCurrentChapter, normalizeBase, slugOf } from './lib/nav-href.js';
9
- export { D as DomainScore, E as ExamBlueprint, a as ExamQuestion, b as ExamResult, R as RoutingChapter, c as buildExamManifest, d as deriveDomainRouting, s as sampleExam, e as scoreExam, f as shuffle, g as spreadBlueprint } from './exam-manifest-X9IrX1G3.js';
9
+ export { D as DomainScore, E as ExamBlueprint, a as ExamQuestion, b as ExamResult, R as RoutingChapter, c as buildExamManifest, d as deriveDomainRouting, s as sampleExam, e as scoreExam, f as shuffle, g as spreadBlueprint } from './exam-manifest-DttY7kyZ.js';
10
10
  export { F as FlashcardRef, b as buildFlashcardDeck } from './flashcards-okekZcl8.js';
11
11
  import 'astro/zod';
12
12
 
@@ -30,6 +30,69 @@ declare function defineBookConfig(opts: BookConfigOptions): Promise<AstroUserCon
30
30
 
31
31
  declare function bookScaffoldIntegration(opts: BookScaffoldIntegrationOptions): AstroIntegration;
32
32
 
33
+ /** Pure corpus-manifest validation and lookup helpers (#80). */
34
+
35
+ /**
36
+ * First-segment names owned by application routes/assets or shared content
37
+ * collection roots rather than a corpus book.
38
+ */
39
+ declare const RESERVED_CORPUS_BOOK_IDS: readonly ["assets", "chapters", "search", "questions", "glossary", "frontmatter", "_astro", "_og", "pagefind"];
40
+ /**
41
+ * Public URL slug -> `RouteToggles` key. Keep this explicit: the public
42
+ * `practice-exam` route is intentionally not the camel-cased config key.
43
+ */
44
+ declare const CORPUS_APPARATUS_TOGGLE_BY_ROUTE: Readonly<{
45
+ readonly references: "references";
46
+ readonly print: "print";
47
+ readonly convergence: "convergence";
48
+ readonly tips: "tips";
49
+ readonly exercises: "exercises";
50
+ readonly 'practice-exam': "practiceExam";
51
+ readonly glossary: "glossary";
52
+ readonly flashcards: "flashcards";
53
+ readonly answers: "answers";
54
+ }>;
55
+ /**
56
+ * Define and eagerly validate one homogeneous-preset book corpus.
57
+ *
58
+ * The returned value is safe to share between `astro.config.mjs` and
59
+ * `src/content.config.ts`; no filesystem or Astro virtual module is touched.
60
+ */
61
+ declare function defineBookCorpus(inputValue: BookCorpusInput): BookCorpus;
62
+ /** Validate that a value came from this major's `defineBookCorpus`. */
63
+ declare function assertBookCorpus(value: unknown): asserts value is BookCorpus;
64
+ /** Return the effective apparatus routes for one manifest book. */
65
+ declare function corpusApparatusRoutesForBook(corpus: BookCorpus, bookId: string, inheritedRoutes?: readonly CorpusApparatusRoute[]): readonly CorpusApparatusRoute[];
66
+ /** True when a public apparatus route is enabled for one manifest book. */
67
+ declare function corpusBookHasApparatusRoute(corpus: BookCorpus, bookId: string, route: CorpusApparatusRoute, inheritedRoutes?: readonly CorpusApparatusRoute[]): boolean;
68
+ /**
69
+ * Select the current book's payload from a v1 corpus artifact envelope.
70
+ * Single-book mode deliberately returns the input unchanged, preserving the
71
+ * legacy JSON contract byte-for-byte.
72
+ */
73
+ declare function selectBookArtifact<Payload>(value: unknown, corpus: BookCorpus | null | undefined, bookId: string | null | undefined, artifact?: string): Payload;
74
+ /** Resolve one manifest book or fail with the complete known-id set. */
75
+ declare function resolveCorpusBook(corpus: BookCorpus, id: string): CorpusBook;
76
+ /** Return the registered first entry-id segment, or null outside the corpus. */
77
+ declare function corpusBookIdOf(corpus: BookCorpus, entryId: string): string | null;
78
+ /** Strip the registered `<book>/` prefix from one collection entry id. */
79
+ declare function localCorpusEntryId(corpus: BookCorpus, bookId: string, entryId: string): string;
80
+ /** Filter content entries to the current registered book. */
81
+ declare function filterCorpusEntries<Entry extends {
82
+ id: string;
83
+ }>(entries: readonly Entry[], corpus: BookCorpus | null | undefined, bookId: string | null | undefined): Entry[];
84
+ /**
85
+ * Derive a collision-safe collection id from a corpus-relative source path.
86
+ * A legacy `book:` field may agree with the path-derived owner, but can never
87
+ * override it; disagreement fails before schema parsing can silently strip it.
88
+ */
89
+ declare function corpusCollectionEntryId(corpus: BookCorpus, entry: string, data: Record<string, unknown>, options?: {
90
+ label?: string;
91
+ slugField?: string;
92
+ }): string;
93
+ /** Resolve current book identity from canonical corpus routes. */
94
+ declare function corpusBookIdFromPath(corpus: BookCorpus, pathname: string, baseUrl?: string): string | null;
95
+
33
96
  /**
34
97
  * Identity helper — consumers wrap their mdx-components map for TS inference.
35
98
  * Same pattern as Vite/Astro defineConfig: a generic identity function that
@@ -309,6 +372,13 @@ declare function assertEnumProp<T extends string>(value: unknown, allowed: reado
309
372
  * validator uses `labels` to check literal sibling path/fragment targets.
310
373
  */
311
374
 
375
+ /**
376
+ * Resolve a link to another book inside the same corpus application.
377
+ *
378
+ * Chapter targets retain the scaffold's `/chapters/<book>/…` namespace;
379
+ * every other relative target lives below the book landing namespace.
380
+ */
381
+ declare function resolveCorpusBookHref(book: string, to: string, baseUrl?: string): string;
312
382
  declare function resolveBookHref(siblingBooks: SiblingBooks | null | undefined, book: string, to: string): string;
313
383
 
314
384
  /**
@@ -496,11 +566,9 @@ declare const academicStyle: Style;
496
566
  declare const toolsStyle: Style;
497
567
  /** Minimal preset — single-author essays / manifestos. */
498
568
  declare const minimalStyle: Style;
499
- /** Course-notes preset — chapters derived from a video course / MOOC / book.
500
- * `deploy` is retained as deprecated metadata only (#180). */
569
+ /** Course-notes preset — chapters derived from a video course / MOOC / book. */
501
570
  declare const courseNotesStyle: Style;
502
- /** Research-portfolio preset — academic structure + tools-style provenance + portfolio components.
503
- * `deploy` is retained as deprecated metadata only (#180); frontmatter routes remain enabled. */
571
+ /** Research-portfolio preset — academic structure + tools-style provenance + portfolio components. */
504
572
  declare const researchPortfolioStyle: Style;
505
573
  /**
506
574
  * Registry of all toolkit-shipped styles, keyed by their preset name.
@@ -567,4 +635,4 @@ type TipsConfigInput = Omit<TipsConfig, typeof TipsConfigBrand | '__tipsConfigVe
567
635
  */
568
636
  declare function defineTips(opts: TipsConfigInput): TipsConfig;
569
637
 
570
- export { ACADEMIC_PART_NAMES, BRANDON_PORTFOLIO_DEFAULT, BUILTIN_STYLES, BookConfigOptions, BookScaffoldIntegrationOptions, ChaptersRenderer, DEFAULT_GITHUB_BRANCH, type Freshness, type FreshnessStatus, type PartReviewGroup, type PartReviewSelection, Question, type ReviewChapter, type ReviewExercise, SiblingBooks, Style, type TipsConfig, type TipsConfigInput, UNKNOWN_PART_ORDINAL, type VisibleHeading, type VolatilityLevel, academicChaptersRenderer, academicPartHeading, academicPartName, academicPartOrdinal, academicParts, academicStyle, assertEnumProp, assertKnownDomain, bookScaffoldIntegration, buildGithubUrl, chapterLabel, chapterSortKey, courseNotesStyle, defineBookConfig, defineMdxComponents, defineTips, deriveObjectiveMap, distinctChaptersSorted, fallbackChaptersRenderer, freshnessLabel, getFreshness, groupByChapter, groupByDomain, minimalStyle, originUrlFromGitConfig, parseRepoSlug, pickActive, researchPortfolioChaptersRenderer, researchPortfolioStyle, resolveBookHref, resolveGithubRepo, selectPartExercises, sortQuestions, tocHeadings, toolsChaptersRenderer, toolsStyle, volatilityLevels };
638
+ export { ACADEMIC_PART_NAMES, BRANDON_PORTFOLIO_DEFAULT, BUILTIN_STYLES, BookConfigOptions, BookCorpus, BookCorpusInput, BookScaffoldIntegrationOptions, CORPUS_APPARATUS_TOGGLE_BY_ROUTE, ChaptersRenderer, CorpusApparatusRoute, CorpusBook, DEFAULT_GITHUB_BRANCH, type Freshness, type FreshnessStatus, type PartReviewGroup, type PartReviewSelection, Question, RESERVED_CORPUS_BOOK_IDS, type ReviewChapter, type ReviewExercise, SiblingBooks, Style, type TipsConfig, type TipsConfigInput, UNKNOWN_PART_ORDINAL, type VisibleHeading, type VolatilityLevel, academicChaptersRenderer, academicPartHeading, academicPartName, academicPartOrdinal, academicParts, academicStyle, assertBookCorpus, assertEnumProp, assertKnownDomain, bookScaffoldIntegration, buildGithubUrl, chapterLabel, chapterSortKey, corpusApparatusRoutesForBook, corpusBookHasApparatusRoute, corpusBookIdFromPath, corpusBookIdOf, corpusCollectionEntryId, courseNotesStyle, defineBookConfig, defineBookCorpus, defineMdxComponents, defineTips, deriveObjectiveMap, distinctChaptersSorted, fallbackChaptersRenderer, filterCorpusEntries, freshnessLabel, getFreshness, groupByChapter, groupByDomain, localCorpusEntryId, minimalStyle, originUrlFromGitConfig, parseRepoSlug, pickActive, researchPortfolioChaptersRenderer, researchPortfolioStyle, resolveBookHref, resolveCorpusBook, resolveCorpusBookHref, resolveGithubRepo, selectBookArtifact, selectPartExercises, sortQuestions, tocHeadings, toolsChaptersRenderer, toolsStyle, volatilityLevels };