@jasonshimmy/vite-plugin-cer-app 0.19.2 → 0.20.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 (115) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/commits.txt +2 -1
  3. package/dist/cli/commands/preview.d.ts.map +1 -1
  4. package/dist/cli/commands/preview.js +2 -0
  5. package/dist/cli/commands/preview.js.map +1 -1
  6. package/dist/cli/create/templates/spa/package.json.tpl +2 -2
  7. package/dist/cli/create/templates/ssg/package.json.tpl +2 -2
  8. package/dist/cli/create/templates/ssr/package.json.tpl +2 -2
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/plugin/build-ssg.d.ts.map +1 -1
  12. package/dist/plugin/build-ssg.js +11 -0
  13. package/dist/plugin/build-ssg.js.map +1 -1
  14. package/dist/plugin/content/emitter.d.ts +19 -0
  15. package/dist/plugin/content/emitter.d.ts.map +1 -0
  16. package/dist/plugin/content/emitter.js +42 -0
  17. package/dist/plugin/content/emitter.js.map +1 -0
  18. package/dist/plugin/content/index.d.ts +32 -0
  19. package/dist/plugin/content/index.d.ts.map +1 -0
  20. package/dist/plugin/content/index.js +199 -0
  21. package/dist/plugin/content/index.js.map +1 -0
  22. package/dist/plugin/content/parser.d.ts +18 -0
  23. package/dist/plugin/content/parser.d.ts.map +1 -0
  24. package/dist/plugin/content/parser.js +158 -0
  25. package/dist/plugin/content/parser.js.map +1 -0
  26. package/dist/plugin/content/path-utils.d.ts +19 -0
  27. package/dist/plugin/content/path-utils.d.ts.map +1 -0
  28. package/dist/plugin/content/path-utils.js +40 -0
  29. package/dist/plugin/content/path-utils.js.map +1 -0
  30. package/dist/plugin/content/scanner.d.ts +12 -0
  31. package/dist/plugin/content/scanner.d.ts.map +1 -0
  32. package/dist/plugin/content/scanner.js +18 -0
  33. package/dist/plugin/content/scanner.js.map +1 -0
  34. package/dist/plugin/content/search.d.ts +9 -0
  35. package/dist/plugin/content/search.d.ts.map +1 -0
  36. package/dist/plugin/content/search.js +24 -0
  37. package/dist/plugin/content/search.js.map +1 -0
  38. package/dist/plugin/dts-generator.d.ts.map +1 -1
  39. package/dist/plugin/dts-generator.js +10 -1
  40. package/dist/plugin/dts-generator.js.map +1 -1
  41. package/dist/plugin/index.d.ts.map +1 -1
  42. package/dist/plugin/index.js +4 -1
  43. package/dist/plugin/index.js.map +1 -1
  44. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  45. package/dist/plugin/transforms/auto-import.js +2 -0
  46. package/dist/plugin/transforms/auto-import.js.map +1 -1
  47. package/dist/runtime/composables/index.d.ts +3 -0
  48. package/dist/runtime/composables/index.d.ts.map +1 -1
  49. package/dist/runtime/composables/index.js +2 -0
  50. package/dist/runtime/composables/index.js.map +1 -1
  51. package/dist/runtime/composables/use-content-search.d.ts +49 -0
  52. package/dist/runtime/composables/use-content-search.d.ts.map +1 -0
  53. package/dist/runtime/composables/use-content-search.js +101 -0
  54. package/dist/runtime/composables/use-content-search.js.map +1 -0
  55. package/dist/runtime/composables/use-content.d.ts +51 -0
  56. package/dist/runtime/composables/use-content.d.ts.map +1 -0
  57. package/dist/runtime/composables/use-content.js +127 -0
  58. package/dist/runtime/composables/use-content.js.map +1 -0
  59. package/dist/runtime/content/client.d.ts +20 -0
  60. package/dist/runtime/content/client.d.ts.map +1 -0
  61. package/dist/runtime/content/client.js +163 -0
  62. package/dist/runtime/content/client.js.map +1 -0
  63. package/dist/types/config.d.ts +2 -0
  64. package/dist/types/config.d.ts.map +1 -1
  65. package/dist/types/config.js.map +1 -1
  66. package/dist/types/content.d.ts +63 -0
  67. package/dist/types/content.d.ts.map +1 -0
  68. package/dist/types/content.js +2 -0
  69. package/dist/types/content.js.map +1 -0
  70. package/docs/composables.md +115 -10
  71. package/docs/configuration.md +33 -0
  72. package/docs/content.md +436 -0
  73. package/e2e/cypress/e2e/content.cy.ts +228 -0
  74. package/e2e/kitchen-sink/app/pages/content-blog.ts +37 -0
  75. package/e2e/kitchen-sink/app/pages/content-doc.ts +42 -0
  76. package/e2e/kitchen-sink/app/pages/content-index.ts +39 -0
  77. package/e2e/kitchen-sink/app/pages/content-search.ts +35 -0
  78. package/e2e/kitchen-sink/cer.config.ts +1 -0
  79. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +26 -0
  80. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +10 -0
  81. package/e2e/kitchen-sink/content/blog/index.md +8 -0
  82. package/e2e/kitchen-sink/content/docs/getting-started.md +46 -0
  83. package/e2e/kitchen-sink/content/index.md +16 -0
  84. package/package.json +10 -7
  85. package/src/__tests__/plugin/build-ssg.test.ts +2 -1
  86. package/src/__tests__/plugin/content/emitter.test.ts +117 -0
  87. package/src/__tests__/plugin/content/loader.test.ts +162 -0
  88. package/src/__tests__/plugin/content/parser.test.ts +239 -0
  89. package/src/__tests__/plugin/content/path-utils.test.ts +53 -0
  90. package/src/__tests__/plugin/content/search.test.ts +119 -0
  91. package/src/__tests__/plugin/dts-generator.test.ts +39 -0
  92. package/src/__tests__/plugin/transforms/auto-import.test.ts +14 -0
  93. package/src/__tests__/runtime/use-content-search.test.ts +139 -0
  94. package/src/__tests__/runtime/use-content.test.ts +226 -0
  95. package/src/cli/commands/preview.ts +2 -0
  96. package/src/cli/create/templates/spa/package.json.tpl +2 -2
  97. package/src/cli/create/templates/ssg/package.json.tpl +2 -2
  98. package/src/cli/create/templates/ssr/package.json.tpl +2 -2
  99. package/src/index.ts +3 -0
  100. package/src/plugin/build-ssg.ts +12 -0
  101. package/src/plugin/content/emitter.ts +50 -0
  102. package/src/plugin/content/index.ts +236 -0
  103. package/src/plugin/content/parser.ts +192 -0
  104. package/src/plugin/content/path-utils.ts +47 -0
  105. package/src/plugin/content/scanner.ts +26 -0
  106. package/src/plugin/content/search.ts +28 -0
  107. package/src/plugin/dts-generator.ts +10 -1
  108. package/src/plugin/index.ts +6 -1
  109. package/src/plugin/transforms/auto-import.ts +2 -0
  110. package/src/runtime/composables/index.ts +3 -0
  111. package/src/runtime/composables/use-content-search.ts +121 -0
  112. package/src/runtime/composables/use-content.ts +146 -0
  113. package/src/runtime/content/client.ts +168 -0
  114. package/src/types/config.ts +2 -0
  115. package/src/types/content.ts +66 -0
@@ -0,0 +1,49 @@
1
+ import type { ReactiveState } from '@jasonshimmy/custom-elements-runtime';
2
+ import type { ContentSearchResult } from '../../types/content.js';
3
+ /**
4
+ * Lazily loads the MiniSearch index from `/_content/search-index.json`.
5
+ * Returns the same Promise on repeated calls — the index is built at most once
6
+ * per session regardless of how many search components are mounted.
7
+ *
8
+ * @internal Exported for unit testing only.
9
+ */
10
+ export declare function loadIndex(): Promise<unknown>;
11
+ /** Resets the module-level singleton. Used in tests only. @internal */
12
+ export declare function resetIndexSingleton(): void;
13
+ export interface UseContentSearchReturn {
14
+ query: ReactiveState<string>;
15
+ results: ReactiveState<ContentSearchResult[]>;
16
+ }
17
+ /**
18
+ * Full-text content search composable.
19
+ *
20
+ * Loads a pre-built MiniSearch index lazily on first use by fetching
21
+ * `/_content/search-index.json`. Both MiniSearch and the index are loaded via
22
+ * dynamic import — neither is in the app bundle.
23
+ *
24
+ * Searches `title` and `description` fields. Results are empty until at least
25
+ * 2 characters are entered.
26
+ *
27
+ * **SSR note**: search is always client-side. In SSR mode the component renders
28
+ * with empty results and hydrates on mount.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * component('site-search', () => {
33
+ * const { query, results } = useContentSearch()
34
+ *
35
+ * return html`
36
+ * <input type="search" :model="${query}" placeholder="Search…" />
37
+ * ${when(results.value.length > 0, () => html`
38
+ * <ul>
39
+ * ${each(results.value, r => html`
40
+ * <li><a :href="${r._path}">${r.title}</a></li>
41
+ * `)}
42
+ * </ul>
43
+ * `)}
44
+ * `
45
+ * })
46
+ * ```
47
+ */
48
+ export declare function useContentSearch(): UseContentSearchReturn;
49
+ //# sourceMappingURL=use-content-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-content-search.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/use-content-search.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AASjE;;;;;;GAMG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAiBlD;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAID,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC5B,OAAO,EAAE,aAAa,CAAC,mBAAmB,EAAE,CAAC,CAAA;CAC9C;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,IAAI,sBAAsB,CAEzD"}
@@ -0,0 +1,101 @@
1
+ import { createComposable, ref, useOnConnected, watch, } from '@jasonshimmy/custom-elements-runtime';
2
+ import { contentSearchIndexUrl } from '../content/client.js';
3
+ // ─── Module-level singleton ───────────────────────────────────────────────────
4
+ // The MiniSearch instance is built lazily on first search from the manifest.
5
+ // The same promise is reused across all mounted instances so we only build once.
6
+ let _indexPromise = null;
7
+ /**
8
+ * Lazily loads the MiniSearch index from `/_content/search-index.json`.
9
+ * Returns the same Promise on repeated calls — the index is built at most once
10
+ * per session regardless of how many search components are mounted.
11
+ *
12
+ * @internal Exported for unit testing only.
13
+ */
14
+ export async function loadIndex() {
15
+ if (_indexPromise)
16
+ return _indexPromise;
17
+ _indexPromise = (async () => {
18
+ const [{ default: MiniSearch }, raw] = await Promise.all([
19
+ import('minisearch'),
20
+ fetch(contentSearchIndexUrl()).then((r) => {
21
+ if (!r.ok)
22
+ throw new Error(`Failed to fetch search index: ${r.status}`);
23
+ return r.text();
24
+ }),
25
+ ]);
26
+ return MiniSearch.loadJSON(raw, {
27
+ fields: ['title', 'description'],
28
+ storeFields: ['_path', 'title', 'description'],
29
+ idField: '_path',
30
+ });
31
+ })();
32
+ return _indexPromise;
33
+ }
34
+ /** Resets the module-level singleton. Used in tests only. @internal */
35
+ export function resetIndexSingleton() {
36
+ _indexPromise = null;
37
+ }
38
+ const _factory = createComposable(() => {
39
+ const query = ref('');
40
+ const results = ref([]);
41
+ // Pre-warm index on mount
42
+ useOnConnected(() => {
43
+ loadIndex().catch(() => { });
44
+ });
45
+ // Monotonic counter to discard stale async results
46
+ let _seq = 0;
47
+ watch(query, async (q) => {
48
+ const seq = ++_seq;
49
+ if (!q || q.length < 2) {
50
+ results.value = [];
51
+ return;
52
+ }
53
+ try {
54
+ const index = await loadIndex();
55
+ if (seq !== _seq)
56
+ return; // stale — a newer query is in flight
57
+ results.value = index.search(q, { prefix: true });
58
+ }
59
+ catch {
60
+ if (seq !== _seq)
61
+ return;
62
+ results.value = [];
63
+ }
64
+ });
65
+ return { query, results };
66
+ });
67
+ /**
68
+ * Full-text content search composable.
69
+ *
70
+ * Loads a pre-built MiniSearch index lazily on first use by fetching
71
+ * `/_content/search-index.json`. Both MiniSearch and the index are loaded via
72
+ * dynamic import — neither is in the app bundle.
73
+ *
74
+ * Searches `title` and `description` fields. Results are empty until at least
75
+ * 2 characters are entered.
76
+ *
77
+ * **SSR note**: search is always client-side. In SSR mode the component renders
78
+ * with empty results and hydrates on mount.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * component('site-search', () => {
83
+ * const { query, results } = useContentSearch()
84
+ *
85
+ * return html`
86
+ * <input type="search" :model="${query}" placeholder="Search…" />
87
+ * ${when(results.value.length > 0, () => html`
88
+ * <ul>
89
+ * ${each(results.value, r => html`
90
+ * <li><a :href="${r._path}">${r.title}</a></li>
91
+ * `)}
92
+ * </ul>
93
+ * `)}
94
+ * `
95
+ * })
96
+ * ```
97
+ */
98
+ export function useContentSearch() {
99
+ return _factory();
100
+ }
101
+ //# sourceMappingURL=use-content-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-content-search.js","sourceRoot":"","sources":["../../../src/runtime/composables/use-content-search.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,GAAG,EACH,cAAc,EACd,KAAK,GACN,MAAM,sCAAsC,CAAA;AAG7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,iFAAiF;AAEjF,6EAA6E;AAC7E,iFAAiF;AACjF,IAAI,aAAa,GAA4B,IAAI,CAAA;AAEjD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,aAAa;QAAE,OAAO,aAAa,CAAA;IACvC,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;QAC1B,MAAM,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvD,MAAM,CAAC,YAAY,CAAC;YACpB,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;gBACxC,IAAI,CAAC,CAAC,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;gBACvE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;YACjB,CAAC,CAAC;SACH,CAAC,CAAA;QACF,OAAO,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE;YAC9B,MAAM,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC;YAChC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC;YAC9C,OAAO,EAAE,OAAO;SACjB,CAAC,CAAA;IACJ,CAAC,CAAC,EAAE,CAAA;IACJ,OAAO,aAAa,CAAA;AACtB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,mBAAmB;IACjC,aAAa,GAAG,IAAI,CAAA;AACtB,CAAC;AASD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAA2B,EAAE;IAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA;IACrB,MAAM,OAAO,GAAG,GAAG,CAAwB,EAAE,CAAC,CAAA;IAE9C,0BAA0B;IAC1B,cAAc,CAAC,GAAG,EAAE;QAClB,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAuC,CAAC,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,mDAAmD;IACnD,IAAI,IAAI,GAAG,CAAC,CAAA;IAEZ,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,CAAS,EAAE,EAAE;QAC/B,MAAM,GAAG,GAAG,EAAE,IAAI,CAAA;QAElB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,GAAG,EAAE,CAAA;YAClB,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,SAAS,EAA+E,CAAA;YAC5G,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAM,CAAC,qCAAqC;YAC9D,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAA0B,CAAA;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAM;YACxB,OAAO,CAAC,KAAK,GAAG,EAAE,CAAA;QACpB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;AAC3B,CAAC,CAAC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,QAAQ,EAAE,CAAA;AACnB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { ContentItem, ContentMeta } from '../../types/content.js';
2
+ export declare class QueryBuilder {
3
+ private _prefix;
4
+ private _predicates;
5
+ private _sortField;
6
+ private _sortDir;
7
+ private _limit;
8
+ private _skip;
9
+ constructor(prefix?: string);
10
+ /** Filter results by a predicate. Receives a fully-typed `ContentMeta`. */
11
+ where(predicate: (doc: ContentMeta) => boolean): this;
12
+ /** Sort by a frontmatter field. Defaults to ascending order. */
13
+ sortBy(field: string, dir?: 'asc' | 'desc'): this;
14
+ /** Cap the result count. */
15
+ limit(n: number): this;
16
+ /** Skip the first `n` results (for pagination). */
17
+ skip(n: number): this;
18
+ /** Returns all matching `ContentMeta` items (no body loaded). */
19
+ find(): Promise<ContentMeta[]>;
20
+ /** Returns the count of matching documents (no body loaded). */
21
+ count(): Promise<number>;
22
+ /**
23
+ * Returns the full `ContentItem` (body + toc) for the first matching document.
24
+ * When a `_path` prefix is provided and no predicates/sort/pagination are set,
25
+ * this fetches the single document directly by path.
26
+ */
27
+ first(): Promise<ContentItem | null>;
28
+ private _applyFilters;
29
+ }
30
+ /**
31
+ * Content query composable.
32
+ *
33
+ * Returns a `QueryBuilder` scoped to the given `_path` prefix. Chain filter,
34
+ * sort, and pagination methods before calling a terminal method
35
+ * (`.find()`, `.first()`, or `.count()`).
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * // Single document
40
+ * const doc = await queryContent('/blog/hello').first()
41
+ *
42
+ * // Listing — no body loaded
43
+ * const posts = await queryContent('/blog')
44
+ * .where(doc => !doc.draft)
45
+ * .sortBy('date', 'desc')
46
+ * .limit(10)
47
+ * .find()
48
+ * ```
49
+ */
50
+ export declare function queryContent(path?: string): QueryBuilder;
51
+ //# sourceMappingURL=use-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-content.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/use-content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAKtE,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,WAAW,CAA2C;IAC9D,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,KAAK,CAAoB;gBAErB,MAAM,CAAC,EAAE,MAAM;IAI3B,2EAA2E;IAC3E,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,GAAG,IAAI;IAKrD,gEAAgE;IAChE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,KAAK,GAAG,MAAc,GAAG,IAAI;IAMxD,4BAA4B;IAC5B,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAKtB,mDAAmD;IACnD,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAKrB,iEAAiE;IAC3D,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAKpC,gEAAgE;IAC1D,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAK9B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAmB1C,OAAO,CAAC,aAAa;CA2CtB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAExD"}
@@ -0,0 +1,127 @@
1
+ import { ContentClient } from '../content/client.js';
2
+ // ─── QueryBuilder ─────────────────────────────────────────────────────────────
3
+ export class QueryBuilder {
4
+ _prefix;
5
+ _predicates = [];
6
+ _sortField;
7
+ _sortDir = 'asc';
8
+ _limit;
9
+ _skip;
10
+ constructor(prefix) {
11
+ this._prefix = prefix;
12
+ }
13
+ /** Filter results by a predicate. Receives a fully-typed `ContentMeta`. */
14
+ where(predicate) {
15
+ this._predicates.push(predicate);
16
+ return this;
17
+ }
18
+ /** Sort by a frontmatter field. Defaults to ascending order. */
19
+ sortBy(field, dir = 'asc') {
20
+ this._sortField = field;
21
+ this._sortDir = dir;
22
+ return this;
23
+ }
24
+ /** Cap the result count. */
25
+ limit(n) {
26
+ this._limit = n;
27
+ return this;
28
+ }
29
+ /** Skip the first `n` results (for pagination). */
30
+ skip(n) {
31
+ this._skip = n;
32
+ return this;
33
+ }
34
+ /** Returns all matching `ContentMeta` items (no body loaded). */
35
+ async find() {
36
+ const manifest = await ContentClient.getManifest();
37
+ return this._applyFilters(manifest);
38
+ }
39
+ /** Returns the count of matching documents (no body loaded). */
40
+ async count() {
41
+ const manifest = await ContentClient.getManifest();
42
+ return this._applyFilters(manifest).length;
43
+ }
44
+ /**
45
+ * Returns the full `ContentItem` (body + toc) for the first matching document.
46
+ * When a `_path` prefix is provided and no predicates/sort/pagination are set,
47
+ * this fetches the single document directly by path.
48
+ */
49
+ async first() {
50
+ // Fast path: no filters, no sort, no pagination — fetch directly by path
51
+ if (this._prefix !== undefined &&
52
+ this._predicates.length === 0 &&
53
+ this._sortField === undefined &&
54
+ this._limit === undefined &&
55
+ this._skip === undefined) {
56
+ return ContentClient.getItem(this._prefix);
57
+ }
58
+ // Slow path: apply filters on the manifest, then fetch the first match
59
+ const manifest = await ContentClient.getManifest();
60
+ const filtered = this._applyFilters(manifest);
61
+ if (filtered.length === 0)
62
+ return null;
63
+ return ContentClient.getItem(filtered[0]._path);
64
+ }
65
+ _applyFilters(items) {
66
+ let result = items;
67
+ // Prefix filter
68
+ if (this._prefix !== undefined) {
69
+ const p = this._prefix;
70
+ result = result.filter((doc) => doc._path === p || doc._path.startsWith(p + '/'));
71
+ }
72
+ // Where predicates
73
+ for (const pred of this._predicates) {
74
+ result = result.filter(pred);
75
+ }
76
+ // Sort
77
+ if (this._sortField !== undefined) {
78
+ const field = this._sortField;
79
+ const dir = this._sortDir;
80
+ result = [...result].sort((a, b) => {
81
+ const av = a[field];
82
+ const bv = b[field];
83
+ if (av === undefined && bv === undefined)
84
+ return 0;
85
+ if (av === undefined)
86
+ return 1;
87
+ if (bv === undefined)
88
+ return -1;
89
+ const cmp = av < bv ? -1 : av > bv ? 1 : 0;
90
+ return dir === 'asc' ? cmp : -cmp;
91
+ });
92
+ }
93
+ // Skip
94
+ if (this._skip !== undefined) {
95
+ result = result.slice(this._skip);
96
+ }
97
+ // Limit
98
+ if (this._limit !== undefined) {
99
+ result = result.slice(0, this._limit);
100
+ }
101
+ return result;
102
+ }
103
+ }
104
+ /**
105
+ * Content query composable.
106
+ *
107
+ * Returns a `QueryBuilder` scoped to the given `_path` prefix. Chain filter,
108
+ * sort, and pagination methods before calling a terminal method
109
+ * (`.find()`, `.first()`, or `.count()`).
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * // Single document
114
+ * const doc = await queryContent('/blog/hello').first()
115
+ *
116
+ * // Listing — no body loaded
117
+ * const posts = await queryContent('/blog')
118
+ * .where(doc => !doc.draft)
119
+ * .sortBy('date', 'desc')
120
+ * .limit(10)
121
+ * .find()
122
+ * ```
123
+ */
124
+ export function queryContent(path) {
125
+ return new QueryBuilder(path);
126
+ }
127
+ //# sourceMappingURL=use-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-content.js","sourceRoot":"","sources":["../../../src/runtime/composables/use-content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ContentItem, ContentMeta } from '../../types/content.js';
2
+ /** Returns the full URL for the search index (includes router.base prefix). */
3
+ export declare function contentSearchIndexUrl(): string;
4
+ /**
5
+ * Low-level content data access layer. Used by `queryContent()`.
6
+ *
7
+ * Resolution strategy:
8
+ * - **Server (dev + SSG build-time)**: reads from `globalThis.__CER_CONTENT_STORE__`
9
+ * populated by the `cerContent()` Vite plugin's `buildStart` hook.
10
+ * - **Server (production SSR runtime)**: `__CER_CONTENT_STORE__` is absent (no
11
+ * Vite build process at runtime), so falls back to `node:fs` reads from
12
+ * `dist/_content/`.
13
+ * - **Client (SPA / browser navigation)**: lazy-fetches `/_content/manifest.json`
14
+ * once (cached) for listing; fetches `/_content/[path].json` per `.first()`.
15
+ */
16
+ export declare const ContentClient: {
17
+ getManifest(): Promise<ContentMeta[]>;
18
+ getItem(path: string): Promise<ContentItem | null>;
19
+ };
20
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/runtime/content/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AA0BtE,+EAA+E;AAC/E,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAyBD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa;mBACH,OAAO,CAAC,WAAW,EAAE,CAAC;kBAiDvB,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;CAmDzD,CAAA"}
@@ -0,0 +1,163 @@
1
+ // ─── Types ─────────────────────────────────────────────────────────────────────
2
+ /** Reads `router.base` from `virtual:cer-app-config` at module initialisation. */
3
+ let _base = '';
4
+ try {
5
+ // Dynamic import is not viable for a module-level side effect, so we read from
6
+ // globalThis where the virtual module writes it during app bootstrap.
7
+ const g = globalThis;
8
+ const appConfig = g['__CER_APP_CONFIG__'];
9
+ _base = appConfig?.router?.base ?? '';
10
+ // Normalise: strip trailing slash, keep empty string for no base
11
+ if (_base === '/')
12
+ _base = '';
13
+ }
14
+ catch {
15
+ _base = '';
16
+ }
17
+ // ─── Path helpers ─────────────────────────────────────────────────────────────
18
+ function contentPathToJsonFile(path) {
19
+ if (path === '/')
20
+ return 'index.json';
21
+ return path.slice(1) + '.json';
22
+ }
23
+ /** Returns the full URL for the search index (includes router.base prefix). */
24
+ export function contentSearchIndexUrl() {
25
+ return `${_base}/_content/search-index.json`;
26
+ }
27
+ // ─── Lazy manifest cache ──────────────────────────────────────────────────────
28
+ let _manifestPromise = null;
29
+ function fetchManifest() {
30
+ if (_manifestPromise)
31
+ return _manifestPromise;
32
+ _manifestPromise = fetch(`${_base}/_content/manifest.json`).then((r) => {
33
+ if (!r.ok)
34
+ throw new Error(`Failed to fetch content manifest: ${r.status}`);
35
+ return r.json();
36
+ });
37
+ return _manifestPromise;
38
+ }
39
+ // ─── Server-side production caches ───────────────────────────────────────────
40
+ // In production SSR the Vite build process is not running, so __CER_CONTENT_STORE__
41
+ // is absent. We cache the manifest and per-document reads here to avoid repeated
42
+ // disk I/O on every request — critical at 10k+ pages where manifest.json is ~2MB.
43
+ let _ssrManifest = null;
44
+ const _ssrItemCache = new Map();
45
+ // ─── ContentClient ────────────────────────────────────────────────────────────
46
+ /**
47
+ * Low-level content data access layer. Used by `queryContent()`.
48
+ *
49
+ * Resolution strategy:
50
+ * - **Server (dev + SSG build-time)**: reads from `globalThis.__CER_CONTENT_STORE__`
51
+ * populated by the `cerContent()` Vite plugin's `buildStart` hook.
52
+ * - **Server (production SSR runtime)**: `__CER_CONTENT_STORE__` is absent (no
53
+ * Vite build process at runtime), so falls back to `node:fs` reads from
54
+ * `dist/_content/`.
55
+ * - **Client (SPA / browser navigation)**: lazy-fetches `/_content/manifest.json`
56
+ * once (cached) for listing; fetches `/_content/[path].json` per `.first()`.
57
+ */
58
+ export const ContentClient = {
59
+ async getManifest() {
60
+ const g = globalThis;
61
+ // Server: in-memory store (dev + SSG build-time rendering)
62
+ const store = g['__CER_CONTENT_STORE__'];
63
+ if (store) {
64
+ return store.map((item) => {
65
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
66
+ const { _file, body, toc, excerpt, ...meta } = item;
67
+ return meta;
68
+ });
69
+ }
70
+ // Server: production SSR runtime — resolve content files from the app root.
71
+ // The preview CLI sets process.env.__CER_APP_ROOT__ to the project root before
72
+ // loading the server bundle. Content files are written to dist/server/_content/
73
+ // and dist/client/_content/ by cerContent's closeBundle hook.
74
+ // _ssrManifest is a module-level cache — populated once and reused for the
75
+ // lifetime of the process so manifest.json is only read and parsed once at scale.
76
+ if (typeof window === 'undefined' && typeof process !== 'undefined') {
77
+ if (_ssrManifest)
78
+ return _ssrManifest;
79
+ try {
80
+ const { readFileSync, existsSync } = await import('node:fs');
81
+ const { join } = await import('node:path');
82
+ const appRoot = process.env.__CER_APP_ROOT__ ?? process.cwd();
83
+ const candidates = [
84
+ join(appRoot, 'dist', 'server', '_content', 'manifest.json'),
85
+ join(appRoot, 'dist', 'client', '_content', 'manifest.json'),
86
+ join(appRoot, 'dist', '_content', 'manifest.json'),
87
+ ];
88
+ for (const p of candidates) {
89
+ if (!existsSync(p))
90
+ continue;
91
+ try {
92
+ const raw = readFileSync(p, 'utf-8');
93
+ _ssrManifest = JSON.parse(raw);
94
+ return _ssrManifest;
95
+ }
96
+ catch { /* try next */ }
97
+ }
98
+ _ssrManifest = [];
99
+ return _ssrManifest;
100
+ }
101
+ catch {
102
+ return [];
103
+ }
104
+ }
105
+ // Client: fetch manifest (cached)
106
+ return fetchManifest();
107
+ },
108
+ async getItem(path) {
109
+ const g = globalThis;
110
+ // Server: in-memory store
111
+ const store = g['__CER_CONTENT_STORE__'];
112
+ if (store) {
113
+ return store.find((item) => item._path === path) ?? null;
114
+ }
115
+ // Server: production SSR runtime — see getManifest() for path resolution strategy.
116
+ // _ssrItemCache is a module-level Map so each document is read and parsed at
117
+ // most once per process lifetime, regardless of how many concurrent requests
118
+ // ask for the same path.
119
+ if (typeof window === 'undefined' && typeof process !== 'undefined') {
120
+ if (_ssrItemCache.has(path))
121
+ return _ssrItemCache.get(path) ?? null;
122
+ try {
123
+ const { readFileSync, existsSync } = await import('node:fs');
124
+ const { join } = await import('node:path');
125
+ const appRoot = process.env.__CER_APP_ROOT__ ?? process.cwd();
126
+ const jsonFile = contentPathToJsonFile(path);
127
+ const candidates = [
128
+ join(appRoot, 'dist', 'server', '_content', jsonFile),
129
+ join(appRoot, 'dist', 'client', '_content', jsonFile),
130
+ join(appRoot, 'dist', '_content', jsonFile),
131
+ ];
132
+ for (const p of candidates) {
133
+ if (!existsSync(p))
134
+ continue;
135
+ try {
136
+ const raw = readFileSync(p, 'utf-8');
137
+ const item = JSON.parse(raw);
138
+ _ssrItemCache.set(path, item);
139
+ return item;
140
+ }
141
+ catch { /* try next */ }
142
+ }
143
+ _ssrItemCache.set(path, null);
144
+ return null;
145
+ }
146
+ catch {
147
+ return null;
148
+ }
149
+ }
150
+ // Client: fetch individual document
151
+ const jsonFile = contentPathToJsonFile(path);
152
+ try {
153
+ const res = await fetch(`${_base}/_content/${jsonFile}`);
154
+ if (!res.ok)
155
+ return null;
156
+ return (await res.json());
157
+ }
158
+ catch {
159
+ return null;
160
+ }
161
+ },
162
+ };
163
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/runtime/content/client.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAElF,kFAAkF;AAClF,IAAI,KAAK,GAAW,EAAE,CAAA;AAEtB,IAAI,CAAC;IACH,+EAA+E;IAC/E,sEAAsE;IACtE,MAAM,CAAC,GAAG,UAAqC,CAAA;IAC/C,MAAM,SAAS,GAAG,CAAC,CAAC,oBAAoB,CAA+C,CAAA;IACvF,KAAK,GAAG,SAAS,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE,CAAA;IACrC,iEAAiE;IACjE,IAAI,KAAK,KAAK,GAAG;QAAE,KAAK,GAAG,EAAE,CAAA;AAC/B,CAAC;AAAC,MAAM,CAAC;IACP,KAAK,GAAG,EAAE,CAAA;AACZ,CAAC;AAED,iFAAiF;AAEjF,SAAS,qBAAqB,CAAC,IAAY;IACzC,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,YAAY,CAAA;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;AAChC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,qBAAqB;IACnC,OAAO,GAAG,KAAK,6BAA6B,CAAA;AAC9C,CAAC;AAED,iFAAiF;AAEjF,IAAI,gBAAgB,GAAkC,IAAI,CAAA;AAE1D,SAAS,aAAa;IACpB,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAA;IAC7C,gBAAgB,GAAG,KAAK,CAAC,GAAG,KAAK,yBAAyB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACrE,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;QAC3E,OAAO,CAAC,CAAC,IAAI,EAA4B,CAAA;IAC3C,CAAC,CAAC,CAAA;IACF,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAED,gFAAgF;AAChF,oFAAoF;AACpF,kFAAkF;AAClF,kFAAkF;AAElF,IAAI,YAAY,GAAyB,IAAI,CAAA;AAC7C,MAAM,aAAa,GAAG,IAAI,GAAG,EAA8B,CAAA;AAE3D,iFAAiF;AAEjF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,CAAC,WAAW;QACf,MAAM,CAAC,GAAG,UAAqC,CAAA;QAE/C,2DAA2D;QAC3D,MAAM,KAAK,GAAG,CAAC,CAAC,uBAAuB,CAA8B,CAAA;QACrE,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACxB,6DAA6D;gBAC7D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;gBACnD,OAAO,IAAmB,CAAA;YAC5B,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,4EAA4E;QAC5E,+EAA+E;QAC/E,gFAAgF;QAChF,8DAA8D;QAC9D,2EAA2E;QAC3E,kFAAkF;QAClF,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;YACpE,IAAI,YAAY;gBAAE,OAAO,YAAY,CAAA;YACrC,IAAI,CAAC;gBACH,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;gBAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;gBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;gBAC7D,MAAM,UAAU,GAAG;oBACjB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC;oBAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC;oBAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,CAAC;iBACnD,CAAA;gBACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;oBAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;wBAAE,SAAQ;oBAC5B,IAAI,CAAC;wBACH,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;wBACpC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAA;wBAC/C,OAAO,YAAY,CAAA;oBACrB,CAAC;oBAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;gBAC5B,CAAC;gBACD,YAAY,GAAG,EAAE,CAAA;gBACjB,OAAO,YAAY,CAAA;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAA;YACX,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,OAAO,aAAa,EAAE,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,MAAM,CAAC,GAAG,UAAqC,CAAA;QAE/C,0BAA0B;QAC1B,MAAM,KAAK,GAAG,CAAC,CAAC,uBAAuB,CAA8B,CAAA;QACrE,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,IAAI,CAAA;QAC1D,CAAC;QAED,mFAAmF;QACnF,6EAA6E;QAC7E,6EAA6E;QAC7E,yBAAyB;QACzB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;YACpE,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;YACnE,IAAI,CAAC;gBACH,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;gBAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;gBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;gBAC7D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;gBAC5C,MAAM,UAAU,GAAG;oBACjB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC;oBACrD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC;oBACrD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC;iBAC5C,CAAA;gBACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;oBAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;wBAAE,SAAQ;oBAC5B,IAAI,CAAC;wBACH,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;wBACpC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAA;wBAC3C,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;wBAC7B,OAAO,IAAI,CAAA;oBACb,CAAC;oBAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;gBAC5B,CAAC;gBACD,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;gBAC7B,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAC5C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,KAAK,aAAa,QAAQ,EAAE,CAAC,CAAA;YACxD,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAA;YACxB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgB,CAAA;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA"}
@@ -204,6 +204,8 @@ export interface RuntimeConfig {
204
204
  export interface CerAppConfig {
205
205
  mode?: 'spa' | 'ssr' | 'ssg';
206
206
  srcDir?: string;
207
+ /** File-based content layer configuration. Reads from `content/` at the project root by default. */
208
+ content?: import('./content.js').CerContentConfig;
207
209
  /**
208
210
  * Internationalisation (i18n) routing configuration.
209
211
  * When set, the framework generates locale-aware URL routes and enables `useLocale()`.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAwUA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AA0UA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,63 @@
1
+ /** Heading extracted from Markdown during parsing. The `id` is slugified from the heading text and added as an HTML `id` attribute. */
2
+ export interface ContentHeading {
3
+ depth: 1 | 2 | 3 | 4 | 5 | 6;
4
+ /** Slugified heading text — matches the `id` attribute in the rendered body HTML. */
5
+ id: string;
6
+ /** Plain text of the heading. */
7
+ text: string;
8
+ }
9
+ /**
10
+ * Lean per-document metadata — returned by `.find()` and `.count()`.
11
+ * Kept small deliberately: no `body`, no `toc`, no `excerpt`.
12
+ * Use `description` for listing previews; set it in frontmatter.
13
+ */
14
+ export interface ContentMeta {
15
+ /** URL path (e.g. `"/blog/hello"`). */
16
+ _path: string;
17
+ /** Source file type. */
18
+ _type: 'markdown' | 'json';
19
+ title?: string;
20
+ /** Use for listing previews — included in search index. */
21
+ description?: string;
22
+ date?: string;
23
+ draft?: boolean;
24
+ /** Any other frontmatter key. */
25
+ [key: string]: unknown;
26
+ }
27
+ /**
28
+ * Full document — returned by `.first()`.
29
+ * Superset of `ContentMeta`; includes `body`, `toc`, `_file`, and optional `excerpt`.
30
+ */
31
+ export interface ContentItem extends ContentMeta {
32
+ /** Relative path from `content/` at the project root (e.g. `"blog/hello.md"`). */
33
+ _file: string;
34
+ /** Rendered HTML (Markdown) or the raw file contents (JSON files). */
35
+ body: string;
36
+ /** Extracted headings. Empty array for JSON files. */
37
+ toc: ContentHeading[];
38
+ /** HTML content before `<!-- more -->`. Absent when the marker is not present. */
39
+ excerpt?: string;
40
+ }
41
+ /**
42
+ * Search result item returned by `useContentSearch()`.
43
+ * Contains only the MiniSearch stored fields: `_path`, `title`, `description`.
44
+ */
45
+ export interface ContentSearchResult {
46
+ _path: string;
47
+ title: string;
48
+ description?: string;
49
+ }
50
+ /** Content layer configuration. Controls the directory and draft behaviour. */
51
+ export interface CerContentConfig {
52
+ /**
53
+ * Content directory relative to the project root. Defaults to `'content'`,
54
+ * which resolves to `{root}/content/` — at the same level as `app/`, `server/`, and `public/`.
55
+ */
56
+ dir?: string;
57
+ /**
58
+ * When `true`, draft items (`draft: true` in frontmatter) are included in
59
+ * production builds. Defaults to `false`.
60
+ */
61
+ drafts?: boolean;
62
+ }
63
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/types/content.ts"],"names":[],"mappings":"AAAA,uIAAuI;AACvI,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,qFAAqF;IACrF,EAAE,EAAE,MAAM,CAAA;IACV,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,wBAAwB;IACxB,KAAK,EAAE,UAAU,GAAG,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,GAAG,EAAE,cAAc,EAAE,CAAA;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB"}