@lupinum/ginko-content 0.1.2 → 0.1.3

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 (189) hide show
  1. package/README.md +18 -4
  2. package/compatibility.json +1 -1
  3. package/dist/cli.mjs +317 -294
  4. package/dist/cms-import/index.js +5 -1
  5. package/dist/config.d.mts +1 -1
  6. package/dist/config.mjs +1 -1
  7. package/dist/core/cache-hints.d.ts +9 -1
  8. package/dist/core/content/collection.js +1 -1
  9. package/dist/core/content/path.js +1 -1
  10. package/dist/core/errors.js +5 -1
  11. package/dist/core/provider-errors +1 -0
  12. package/dist/core/provider-errors.d.ts +10 -0
  13. package/dist/core/provider-errors.js +27 -0
  14. package/dist/core/query/execute.js +12 -3
  15. package/dist/core/query/filter.js +2 -2
  16. package/dist/core/query/lower.js +5 -4
  17. package/dist/features/navigation/build.js +14 -6
  18. package/dist/features/navigation/canonical.js +1 -1
  19. package/dist/features/sitemap/query.js +2 -2
  20. package/dist/integrations/nitro/ingest.d.ts +3 -3
  21. package/dist/integrations/nitro/ingest.js +3 -3
  22. package/dist/integrations/nitro/storage.js +3 -1
  23. package/dist/module.d.mts +151 -526
  24. package/dist/module.json +1 -1
  25. package/dist/module.mjs +1091 -722
  26. package/dist/parsers/csv.js +4 -3
  27. package/dist/parsers/index.d.ts +2 -5
  28. package/dist/parsers/index.js +2 -2
  29. package/dist/parsers/markdown-plugins.d.ts +1 -0
  30. package/dist/parsers/markdown-plugins.js +83 -1
  31. package/dist/parsers/markdown.js +1 -1
  32. package/dist/public/client.d.ts +3 -2
  33. package/dist/public/client.js +2 -2
  34. package/dist/public/provider-errors.d.ts +2 -1
  35. package/dist/public/provider-errors.js +1 -18
  36. package/dist/public/provider.d.ts +3 -10
  37. package/dist/public/server.d.ts +6 -1
  38. package/dist/public/server.js +33 -0
  39. package/dist/runtime/agent-paths +1 -0
  40. package/dist/runtime/agent-paths.d.ts +6 -0
  41. package/dist/runtime/agent-paths.js +41 -0
  42. package/dist/runtime/app/components/internal/MarkdownRenderer.d.ts +1 -1
  43. package/dist/runtime/app/composables/head.d.ts +3 -0
  44. package/dist/runtime/app/composables/head.js +2 -1
  45. package/dist/runtime/app/composables/hot-reload +1 -0
  46. package/dist/runtime/app/composables/hot-reload.d.ts +5 -0
  47. package/dist/runtime/app/composables/hot-reload.js +15 -0
  48. package/dist/runtime/app/composables/locale-context.d.ts +1 -1
  49. package/dist/runtime/app/composables/locale-context.js +2 -1
  50. package/dist/runtime/app/composables/locale.js +2 -2
  51. package/dist/runtime/app/composables/search.js +10 -6
  52. package/dist/runtime/app/composables/use-content-document +1 -0
  53. package/dist/runtime/app/composables/use-content-document.d.ts +29 -0
  54. package/dist/runtime/app/composables/use-content-document.js +44 -0
  55. package/dist/runtime/app/composables/use-content-list +1 -0
  56. package/dist/runtime/app/composables/use-content-list.d.ts +43 -0
  57. package/dist/runtime/app/composables/use-content-list.js +98 -0
  58. package/dist/runtime/app/composables/use-content-navigation +1 -0
  59. package/dist/runtime/app/composables/use-content-navigation.d.ts +40 -0
  60. package/dist/runtime/app/composables/use-content-navigation.js +102 -0
  61. package/dist/runtime/app/composables/use-content-page +1 -0
  62. package/dist/runtime/app/composables/use-content-page.d.ts +47 -0
  63. package/dist/runtime/app/composables/use-content-page.js +142 -0
  64. package/dist/runtime/app/composables/use-content-shared +1 -0
  65. package/dist/runtime/app/composables/use-content-shared.d.ts +13 -0
  66. package/dist/runtime/app/composables/use-content-shared.js +29 -0
  67. package/dist/runtime/app/composables/use-content.d.ts +11 -206
  68. package/dist/runtime/app/composables/use-content.js +4 -377
  69. package/dist/runtime/app/plugins/hot-reload +1 -0
  70. package/dist/runtime/app/plugins/hot-reload.js +6 -0
  71. package/dist/runtime/query/backlinks +1 -0
  72. package/dist/runtime/query/backlinks.d.ts +8 -0
  73. package/dist/runtime/query/backlinks.js +90 -0
  74. package/dist/runtime/query/context +1 -0
  75. package/dist/runtime/query/context.d.ts +20 -0
  76. package/dist/runtime/query/context.js +0 -0
  77. package/dist/runtime/query/documents +1 -0
  78. package/dist/runtime/query/documents.d.ts +6 -0
  79. package/dist/runtime/query/documents.js +98 -0
  80. package/dist/runtime/query/errors +1 -0
  81. package/dist/runtime/query/errors.d.ts +1 -0
  82. package/dist/runtime/query/errors.js +4 -0
  83. package/dist/runtime/query/handles +1 -0
  84. package/dist/runtime/query/handles.d.ts +2 -0
  85. package/dist/runtime/query/handles.js +7 -0
  86. package/dist/runtime/query/locale-options +1 -0
  87. package/dist/runtime/query/locale-options.d.ts +5 -0
  88. package/dist/runtime/query/locale-options.js +14 -0
  89. package/dist/runtime/query/localized-docs +1 -0
  90. package/dist/runtime/query/localized-docs.d.ts +17 -0
  91. package/dist/runtime/query/localized-docs.js +44 -0
  92. package/dist/runtime/query/navigation +1 -0
  93. package/dist/runtime/query/navigation.d.ts +22 -0
  94. package/dist/runtime/query/navigation.js +73 -0
  95. package/dist/runtime/query/pagination +1 -0
  96. package/dist/runtime/query/pagination.d.ts +7 -0
  97. package/dist/runtime/query/pagination.js +78 -0
  98. package/dist/runtime/query/populate +1 -0
  99. package/dist/runtime/query/populate.d.ts +9 -0
  100. package/dist/runtime/query/populate.js +106 -0
  101. package/dist/runtime/query/responses +1 -0
  102. package/dist/runtime/query/responses.d.ts +10 -0
  103. package/dist/runtime/query/responses.js +47 -0
  104. package/dist/runtime/query/unified.d.ts +4 -20
  105. package/dist/runtime/query/unified.js +14 -544
  106. package/dist/runtime/query/variants +1 -0
  107. package/dist/runtime/query/variants.d.ts +11 -0
  108. package/dist/runtime/query/variants.js +36 -0
  109. package/dist/runtime/server/agent-http +1 -0
  110. package/dist/runtime/server/agent-http.d.ts +7 -0
  111. package/dist/runtime/server/agent-http.js +36 -0
  112. package/dist/runtime/server/agent-markdown +1 -0
  113. package/dist/runtime/server/agent-markdown.d.ts +83 -0
  114. package/dist/runtime/server/agent-markdown.js +449 -0
  115. package/dist/runtime/server/agent-site +1 -0
  116. package/dist/runtime/server/agent-site.d.ts +38 -0
  117. package/dist/runtime/server/agent-site.js +273 -0
  118. package/dist/runtime/server/api/agent-llms +1 -0
  119. package/dist/runtime/server/api/agent-llms-full +1 -0
  120. package/dist/runtime/server/api/agent-llms-full.d.ts +2 -0
  121. package/dist/runtime/server/api/agent-llms-full.js +13 -0
  122. package/dist/runtime/server/api/agent-llms.d.ts +2 -0
  123. package/dist/runtime/server/api/agent-llms.js +14 -0
  124. package/dist/runtime/server/api/agent-raw +1 -0
  125. package/dist/runtime/server/api/agent-raw.d.ts +2 -0
  126. package/dist/runtime/server/api/agent-raw.js +17 -0
  127. package/dist/runtime/server/api/locales.d.ts +2 -2
  128. package/dist/runtime/server/api/locales.js +4 -2
  129. package/dist/runtime/server/api/navigation.d.ts +1 -1
  130. package/dist/runtime/server/api/query.d.ts +1 -1
  131. package/dist/runtime/server/api/query.js +4 -1
  132. package/dist/runtime/server/api/revalidate.js +2 -2
  133. package/dist/runtime/server/api/site-data.d.ts +1 -1
  134. package/dist/runtime/server/collection-helpers.js +2 -1
  135. package/dist/runtime/server/middleware/agent-link-headers +1 -0
  136. package/dist/runtime/server/middleware/agent-link-headers.d.ts +2 -0
  137. package/dist/runtime/server/middleware/agent-link-headers.js +42 -0
  138. package/dist/runtime/server/middleware/agent-markdown +1 -0
  139. package/dist/runtime/server/middleware/agent-markdown.d.ts +2 -0
  140. package/dist/runtime/server/middleware/agent-markdown.js +43 -0
  141. package/dist/runtime/server/plugins/sitemap.js +1 -0
  142. package/dist/runtime/server/provider-query.d.ts +8 -5
  143. package/dist/runtime/server/provider-query.js +50 -8
  144. package/dist/runtime/server/provider-result.d.ts +19 -2
  145. package/dist/runtime/server/providers/filesystem.js +4 -1
  146. package/dist/runtime/server/providers/index.d.ts +3 -1
  147. package/dist/runtime/server/providers/index.js +2 -2
  148. package/dist/runtime/server/query-api.js +2 -1
  149. package/dist/runtime/server/query-executor.d.ts +3 -2
  150. package/dist/runtime/server/query-executor.js +13 -5
  151. package/dist/runtime/server/search.js +1 -1
  152. package/dist/runtime/server/sitemap-provider.js +40 -1
  153. package/dist/runtime/server/sitemap.js +3 -2
  154. package/dist/runtime/transformers/component-resolver.js +2 -1
  155. package/dist/runtime/utils/content-components.d.ts +0 -5
  156. package/dist/storage/content.d.ts +2 -9
  157. package/dist/storage/references.d.ts +1 -8
  158. package/dist/storage/references.js +9 -4
  159. package/dist/testing/provider-contract.js +3 -4
  160. package/dist/testing/provider-fixture.d.ts +3 -1
  161. package/dist/testing/provider-fixture.js +27 -14
  162. package/dist/types/config.d.ts +77 -0
  163. package/dist/types/config.js +23 -0
  164. package/dist/types/module.d.ts +15 -5
  165. package/dist/types/query-parts/collections +1 -0
  166. package/dist/types/query-parts/collections.d.ts +15 -0
  167. package/dist/types/query-parts/collections.js +0 -0
  168. package/dist/types/query-parts/public +1 -0
  169. package/dist/types/query-parts/public.d.ts +202 -0
  170. package/dist/types/query-parts/public.js +0 -0
  171. package/dist/types/query-parts/results +1 -0
  172. package/dist/types/query-parts/results.d.ts +95 -0
  173. package/dist/types/query-parts/results.js +0 -0
  174. package/dist/types/query-parts/transport +1 -0
  175. package/dist/types/query-parts/transport.d.ts +103 -0
  176. package/dist/types/query-parts/transport.js +0 -0
  177. package/dist/types/query.d.ts +4 -870
  178. package/dist/types/query.js +4 -0
  179. package/dist/types/runtime.d.ts +2 -2
  180. package/dist/types/virtual.d.ts +54 -0
  181. package/dist/types.d.mts +2 -2
  182. package/dist/web-types.json +1 -1
  183. package/package.json +5 -5
  184. package/dist/runtime/app/composables/web-socket +0 -1
  185. package/dist/runtime/app/composables/web-socket.d.ts +0 -3
  186. package/dist/runtime/app/composables/web-socket.js +0 -65
  187. package/dist/runtime/app/plugins/ws +0 -1
  188. package/dist/runtime/app/plugins/ws.js +0 -7
  189. /package/dist/runtime/app/plugins/{ws.d.ts → hot-reload.d.ts} +0 -0
@@ -1,208 +1,13 @@
1
- import type { ComputedRef, MaybeRefOrGetter } from 'vue';
2
- import { createError } from '#imports';
3
- import type { BacklinksOptions, BacklinksResult, BacklinkSource, ContentCollectionTarget, ContentVariant, ContentTreeItem, ContentResolvedMeta, DocumentFromHandle, LocalePathEntry, LocaleFallback, ManyOptions, LocalizedDoc, NeighborsOptions, NeighborsResult, OneOptions, PopulateSpec, PopulateFromOptions, PopulatedDocument, PaginationOptions, PaginationResult, ResolveOneOptions, ResolveOneResult, SortSpec, TreeOptions, VariantsOptions } from '../../../types/query';
4
- type ReactiveLeaf<T> = T | MaybeRefOrGetter<T>;
5
- type ReactiveValue<V> = V extends ((...args: never[]) => unknown) | readonly unknown[] ? ReactiveLeaf<V> : V extends object | undefined ? ReactiveLeaf<V> | {
6
- [P in keyof NonNullable<V>]?: ReactiveLeaf<NonNullable<V>[P]>;
7
- } : ReactiveLeaf<V>;
8
- type Reactive<T> = {
9
- [K in keyof T]: ReactiveValue<T[K]>;
10
- };
11
- type DocFromHandle<H> = DocumentFromHandle<H>;
12
- interface UseContentOneReturn<T> {
13
- data: ComputedRef<LocalizedDoc<T> | null>;
14
- pending: ComputedRef<boolean>;
15
- status: ComputedRef<string>;
16
- error: ComputedRef<unknown>;
17
- refresh: () => Promise<void>;
18
- }
19
1
  /**
20
- * Reactively resolve a single document. Reruns when any reactive source on
21
- * `options` changes. Caching follows Nuxt's standard `useAsyncData` semantics
22
- * keyed by `${collection}:${stableHash(options)}`.
23
- */
24
- export declare function useContentOne<const H extends ContentCollectionTarget, O extends OneOptions<H, PopulateSpec | undefined>>(handle: H, options: Reactive<O>): Promise<UseContentOneReturn<PopulatedDocument<DocFromHandle<H>, PopulateFromOptions<O>>>>;
25
- type ContentPageSurroundOptions<H> = boolean | Omit<NeighborsOptions<H>, 'by' | 'locale' | 'fallback'>;
26
- type ContentPageOneOptions<H, P extends PopulateSpec | undefined> = Omit<OneOptions<H, P>, 'by' | 'locale' | 'fallback'> & {
27
- /**
28
- * Optional locale override. Route pages may omit this even for typed i18n
29
- * handles because the route selector is the source of truth for the active
30
- * public URL.
31
- */
32
- locale?: string;
33
- fallback?: LocaleFallback;
34
- };
35
- export type UseContentPageOptions<H = unknown, P extends PopulateSpec | undefined = undefined> = Reactive<ContentPageOneOptions<H, P>> & {
36
- /**
37
- * Load previous/next items alongside the page.
38
- *
39
- * Pass `true` for the default surround query, or an options object to choose
40
- * fields. The page query remains one request unless this is enabled.
41
- */
42
- surround?: ContentPageSurroundOptions<H>;
43
- /**
44
- * Override the error raised when the current route does not resolve to a
45
- * content page. Set `false` to render a local empty/not-found state.
46
- */
47
- notFound?: false | (() => Parameters<typeof createError>[0]);
48
- };
49
- interface UseContentPageReturn<T> {
50
- data: ComputedRef<LocalizedDoc<T> | undefined>;
51
- page: ComputedRef<LocalizedDoc<T> | undefined>;
52
- previous: ComputedRef<ContentTreeItem<T> | null>;
53
- next: ComputedRef<ContentTreeItem<T> | null>;
54
- surround: ComputedRef<Array<ContentTreeItem<T>>>;
55
- pending: ComputedRef<boolean>;
56
- status: ComputedRef<string>;
57
- error: ComputedRef<unknown>;
58
- refresh: () => Promise<void>;
59
- }
60
- /**
61
- * Ergonomic route-page helper. This is the product-level default for Nuxt page
62
- * components; the explicit `useContentOne` selector remains the lower-level
63
- * primitive for custom reads.
64
- */
65
- export declare function useContentPage<const H extends ContentCollectionTarget, P extends PopulateSpec | undefined = undefined>(handle: H, options?: UseContentPageOptions<H, P>): Promise<UseContentPageReturn<PopulatedDocument<DocFromHandle<H>, P>>>;
66
- interface UseContentResolveOneReturn<T> {
67
- doc: ComputedRef<LocalizedDoc<T> | null>;
68
- explain: ComputedRef<ResolveOneResult<T>['explain'] | null>;
69
- status: ComputedRef<string>;
70
- error: ComputedRef<unknown>;
71
- refresh: () => Promise<void>;
72
- }
73
- /**
74
- * Reactively resolve a single document with a first-class diagnostic envelope.
75
- */
76
- export declare function useContentResolveOne<const H extends ContentCollectionTarget, O extends ResolveOneOptions<H, PopulateSpec | undefined>>(handle: H, options: Reactive<O>): Promise<UseContentResolveOneReturn<PopulatedDocument<DocFromHandle<H>, PopulateFromOptions<O>>>>;
77
- interface UseContentManyReturn<T> {
78
- data: ComputedRef<Array<LocalizedDoc<T>>>;
79
- status: ComputedRef<string>;
80
- error: ComputedRef<unknown>;
81
- refresh: () => Promise<void>;
82
- }
83
- interface UseContentPaginationReturn<T> {
84
- data: ComputedRef<Array<LocalizedDoc<T>>>;
85
- page: ComputedRef<number>;
86
- limit: ComputedRef<number>;
87
- total: ComputedRef<number>;
88
- pageCount: ComputedRef<number>;
89
- hasNext: ComputedRef<boolean>;
90
- hasPrev: ComputedRef<boolean>;
91
- nextPage: ComputedRef<number | null>;
92
- prevPage: ComputedRef<number | null>;
93
- status: ComputedRef<string>;
94
- error: ComputedRef<unknown>;
95
- refresh: () => Promise<void>;
96
- }
97
- /**
98
- * Reactively resolve a list of documents.
99
- */
100
- export declare function useContentMany<const H extends ContentCollectionTarget, O extends ManyOptions<H, PopulateSpec | undefined>>(handle: H, options?: Reactive<O>): Promise<UseContentManyReturn<PopulatedDocument<DocFromHandle<H>, PopulateFromOptions<O>>>>;
101
- /**
102
- * Reactively resolve one page of documents plus total/page navigation metadata.
103
- */
104
- export declare function useContentPagination<const H extends ContentCollectionTarget, O extends PaginationOptions<H, PopulateSpec | undefined>>(handle: H, options: Reactive<O>): Promise<UseContentPaginationReturn<PopulatedDocument<DocFromHandle<H>, PopulateFromOptions<O>>>>;
105
- interface UseContentBacklinksReturn<T> {
106
- data: ComputedRef<T[]>;
107
- status: ComputedRef<string>;
108
- error: ComputedRef<unknown>;
109
- refresh: () => Promise<void>;
110
- }
111
- /**
112
- * Reactively resolve source documents that reference a target document.
113
- */
114
- export declare function useContentBacklinks<const Target extends ContentCollectionTarget, const Source extends BacklinkSource | ReadonlyArray<BacklinkSource>, P extends PopulateSpec | undefined = undefined>(handle: Target, options: Reactive<BacklinksOptions<Target, Source, P>> & {
115
- from: ReactiveValue<Source>;
116
- }): Promise<UseContentBacklinksReturn<BacklinksResult<Source, P>[number]>>;
117
- interface UseContentVariantsReturn<T> {
118
- data: ComputedRef<Array<ContentVariant<T>>>;
119
- status: ComputedRef<string>;
120
- error: ComputedRef<unknown>;
121
- refresh: () => Promise<void>;
122
- }
123
- /**
124
- * Reactively resolve every locale variant of a single document — used by
125
- * locale switchers. Returns one entry per configured locale, with a
126
- * `translated` flag.
127
- */
128
- export declare function useContentVariants<H extends ContentCollectionTarget>(handle: H, options: Reactive<VariantsOptions<H>>): Promise<UseContentVariantsReturn<DocFromHandle<H>>>;
129
- interface UseContentTreeReturn<T> {
130
- data: ComputedRef<T[]>;
131
- status: ComputedRef<string>;
132
- error: ComputedRef<unknown>;
133
- refresh: () => Promise<void>;
134
- }
135
- export type ContentNavigationNode<T> = Omit<ContentTreeItem<T>, 'children'> & {
136
- id: string;
137
- path: string;
138
- title: string;
139
- children: Array<ContentNavigationNode<T>>;
140
- };
141
- interface UseContentNavigationReturn<T> {
142
- data: ComputedRef<Array<ContentNavigationNode<T>>>;
143
- firstPage: ComputedRef<ContentNavigationNode<T> | null>;
144
- paths: ComputedRef<Set<string>>;
145
- status: ComputedRef<string>;
146
- error: ComputedRef<unknown>;
147
- refresh: () => Promise<void>;
148
- }
149
- /**
150
- * Reactively resolve the navigation tree for a collection.
151
- */
152
- export declare function useContentTree<H extends ContentCollectionTarget>(handle: H, options?: Reactive<TreeOptions<H>>): Promise<UseContentTreeReturn<ContentTreeItem<DocFromHandle<H>>>>;
153
- /**
154
- * Reactively resolve normalized navigation for sidebars and active-state UI.
155
- */
156
- export declare function useContentNavigation<H extends ContentCollectionTarget>(handle: H, options?: Reactive<TreeOptions<H>>): Promise<UseContentNavigationReturn<DocFromHandle<H>>>;
157
- interface UseContentNeighborsReturn<T> {
158
- data: ComputedRef<NeighborsResult<T>>;
159
- pending: ComputedRef<boolean>;
160
- status: ComputedRef<string>;
161
- error: ComputedRef<unknown>;
162
- refresh: () => Promise<void>;
163
- }
164
- /**
165
- * Reactively resolve previous/next surroundings for a document.
166
- */
167
- export declare function useContentNeighbors<H extends ContentCollectionTarget>(handle: H, options: Reactive<NeighborsOptions<H>>): Promise<UseContentNeighborsReturn<DocFromHandle<H>>>;
168
- interface UseContentLocaleSwitchReturn<T> {
169
- /**
170
- * Per-locale path map of the resolved document, keyed by locale code.
171
- * Empty object when the document hasn't resolved yet or returned `null`.
172
- */
173
- paths: ComputedRef<Record<string, LocalePathEntry>>;
174
- /**
175
- * Resolve a switch destination for a given locale. Returns the content's
176
- * translated path when available; otherwise `null` so the caller can fall
177
- * back to a route-only switch (e.g. `useSwitchLocalePath`).
178
- */
179
- switchTo: (locale: string) => string | null;
180
- /**
181
- * The resolved document, exposed so the caller can read additional fields
182
- * (title, description, ...) from the same query without a second fetch.
183
- */
184
- data: ComputedRef<LocalizedDoc<T> | null>;
185
- }
186
- /**
187
- * Resolve every per-locale path for a content document. Thin wrapper over
188
- * `useContentOne` that exposes the document's `localePaths` plus a `switchTo`
189
- * helper for rendering locale switchers.
190
- *
191
- * Layouts and pages typically call this with the same options — `useAsyncData`
192
- * dedupes by key, so it's a single round-trip:
2
+ * Public facade for Layer 2 of the unified query API (ADR-0016).
193
3
  *
194
- * ```vue
195
- * <script setup>
196
- * const { switchTo } = useContentLocaleSwitch(docs, {
197
- * locale: () => locale.value,
198
- * by: { path: () => route.path },
199
- * fallback: true
200
- * })
201
- *
202
- * // In the template:
203
- * // <a :href="switchTo('de') || useSwitchLocalePath()('de')">Deutsch</a>
204
- * </script>
205
- * ```
206
- */
207
- export declare function useContentLocaleSwitch<const H extends ContentCollectionTarget, O extends OneOptions<H, PopulateSpec | undefined>>(handle: H, options: Reactive<O>): Promise<UseContentLocaleSwitchReturn<PopulatedDocument<DocFromHandle<H>, PopulateFromOptions<O>>>>;
208
- export type { ManyOptions, OneOptions, BacklinksOptions, BacklinksResult, LocalizedDoc, ContentResolvedMeta, ContentCollectionTarget, DocumentFromHandle, NeighborsOptions, NeighborsResult, PaginationOptions, PaginationResult, PopulateSpec, PopulateFromOptions, PopulatedDocument, ResolveOneOptions, ResolveOneResult, SortSpec, TreeOptions, VariantsOptions, ContentVariant };
4
+ * Runtime imports and `#content/client` intentionally keep pointing at this
5
+ * module; focused implementation modules live beside it.
6
+ */
7
+ export { useContentOne, useContentResolveOne } from './use-content-document';
8
+ export { useContentPage } from './use-content-page';
9
+ export type { UseContentPageOptions } from './use-content-page';
10
+ export { useContentMany, useContentPagination, useContentBacklinks, useContentVariants } from './use-content-list';
11
+ export { useContentTree, useContentNavigation, useContentNeighbors } from './use-content-navigation';
12
+ export type { ContentNavigationNode } from './use-content-navigation';
13
+ export type { ManyOptions, OneOptions, BacklinksOptions, BacklinksResult, LocalizedDoc, ContentResolvedMeta, ContentCollectionTarget, DocumentFromHandle, NeighborsOptions, NeighborsResult, PaginationOptions, PaginationResult, PopulateSpec, PopulateFromOptions, PopulatedDocument, ResolveOneOptions, ResolveOneResult, SortSpec, TreeOptions, VariantsOptions, ContentVariant } from '../../../types/query';
@@ -1,377 +1,4 @@
1
- import { computed, shallowRef, toValue, watch } from "vue";
2
- import { hash } from "ohash";
3
- import { createError, useAsyncData, useRoute } from "#imports";
4
- import { createClientContentQueryContext } from "./query-api.js";
5
- import { resolveCollectionI18n } from "../../../features/localization/path";
6
- import {
7
- backlinks as backlinksWithContext,
8
- many as manyWithContext,
9
- neighbors as neighborsWithContext,
10
- one as oneWithContext,
11
- paginate as paginateWithContext,
12
- resolveOne as resolveOneWithContext,
13
- tree as treeWithContext,
14
- variants as variantsWithContext
15
- } from "../../query/unified.js";
16
- import { resolveActiveLocale } from "./locale.js";
17
- import { useContentRoute } from "./route.js";
18
- import { getContentRuntime } from "./runtime.js";
19
- const unwrapDeep = (value, seen = /* @__PURE__ */ new WeakSet()) => {
20
- if (value === null || value === void 0) return value;
21
- if (typeof value === "function") return unwrapDeep(toValue(value), seen);
22
- if (typeof value === "object" && "__v_isRef" in value) {
23
- return unwrapDeep(toValue(value), seen);
24
- }
25
- if (Array.isArray(value)) return value.map((item) => unwrapDeep(item, seen));
26
- if (typeof value === "object" && value.constructor === Object) {
27
- if (seen.has(value)) return value;
28
- seen.add(value);
29
- const out = {};
30
- for (const [k, v] of Object.entries(value)) {
31
- out[k] = unwrapDeep(v, seen);
32
- }
33
- return out;
34
- }
35
- return value;
36
- };
37
- const resolveOptions = (reactive) => {
38
- return unwrapDeep(reactive);
39
- };
40
- const stableKey = (prefix, name, options) => `${prefix}:${name}:${hash(options)}`;
41
- const contentCollectionName = (handle) => typeof handle === "string" ? handle : handle.name;
42
- export async function useContentOne(handle, options) {
43
- const resolved = computed(() => resolveOptions(options));
44
- const key = computed(() => stableKey("content-one", typeof handle === "string" ? handle : handle.name, resolved.value));
45
- const context = createClientContentQueryContext();
46
- const asyncData = await useAsyncData(
47
- key,
48
- () => oneWithContext(context, handle, resolved.value),
49
- { watch: [resolved], default: () => null }
50
- );
51
- return {
52
- data: computed(() => asyncData.data.value),
53
- pending: computed(() => asyncData.pending.value),
54
- status: computed(() => asyncData.status.value),
55
- error: computed(() => asyncData.error.value),
56
- refresh: () => asyncData.refresh()
57
- };
58
- }
59
- const defaultPageNotFound = () => createError({
60
- statusCode: 404,
61
- statusMessage: "Page not found",
62
- fatal: true
63
- });
64
- const normalizePageNotFound = (notFound) => {
65
- if (notFound === false) return void 0;
66
- return createError(notFound ? notFound() : defaultPageNotFound());
67
- };
68
- const normalizePageSurround = (surround) => {
69
- if (!surround) return void 0;
70
- return surround === true ? {} : surround;
71
- };
72
- const normalizeRoutePath = (path) => {
73
- if (typeof path !== "string") return void 0;
74
- const normalized = path.replace(/\/+$/, "");
75
- return normalized || "/";
76
- };
77
- const localePathMatches = (entry, path) => {
78
- const normalizedPath = normalizeRoutePath(path);
79
- if (typeof entry === "string") return normalizeRoutePath(entry) === normalizedPath;
80
- return Boolean(entry && typeof entry === "object" && "path" in entry && normalizeRoutePath(entry.path) === normalizedPath);
81
- };
82
- const routeMetaMatchesPath = (value, path) => {
83
- if (!value) return false;
84
- const normalizedPath = normalizeRoutePath(path);
85
- const legacyPath = value;
86
- if (normalizeRoutePath(legacyPath._path) === normalizedPath || normalizeRoutePath(legacyPath._requestedPath) === normalizedPath || normalizeRoutePath(legacyPath._requestedRoute) === normalizedPath) return true;
87
- const requestedRoute = value.resolved?.requestedRoute ?? value._requestedRoute;
88
- return normalizeRoutePath(value.path) === normalizedPath || normalizeRoutePath(value.canonicalPath) === normalizedPath || normalizeRoutePath(requestedRoute) === normalizedPath || Object.values(value.localePaths || {}).some((entry) => localePathMatches(entry, path));
89
- };
90
- export async function useContentPage(handle, options = {}) {
91
- const route = useRoute();
92
- const isBrowser = import.meta.client && typeof window !== "undefined";
93
- const { notFound, surround, ...oneOptions } = options;
94
- const routeSelector = { route: () => normalizeRoutePath(route.path) };
95
- const runtime = getContentRuntime();
96
- const activeLocale = computed(() => {
97
- const explicitLocale = toValue(oneOptions.locale);
98
- if (explicitLocale) {
99
- return explicitLocale;
100
- }
101
- const { locales, defaultLocale } = resolveCollectionI18n(contentCollectionName(handle), runtime);
102
- if (!locales.length && !defaultLocale) {
103
- return void 0;
104
- }
105
- return resolveActiveLocale(locales, defaultLocale);
106
- });
107
- const rawPage = shallowRef(null);
108
- const resolvingRoute = shallowRef(false);
109
- const sawRouteQueryPending = shallowRef(false);
110
- const page = computed(() => {
111
- const current = rawPage.value;
112
- return routeMetaMatchesPath(current, route.path) ? current : void 0;
113
- });
114
- useContentRoute(page);
115
- const pageResultPromise = useContentOne(handle, {
116
- ...oneOptions,
117
- locale: () => activeLocale.value,
118
- by: routeSelector
119
- });
120
- const surroundOptions = normalizePageSurround(surround);
121
- const surroundResultPromise = surroundOptions ? useContentNeighbors(handle, {
122
- ...surroundOptions,
123
- locale: () => activeLocale.value,
124
- ..."fallback" in oneOptions ? { fallback: oneOptions.fallback } : {},
125
- by: routeSelector
126
- }) : void 0;
127
- const pageResult = await pageResultPromise;
128
- rawPage.value = pageResult.data.value;
129
- if (isBrowser && rawPage.value && !routeMetaMatchesPath(rawPage.value, route.path)) {
130
- resolvingRoute.value = true;
131
- }
132
- watch(() => route.path, () => {
133
- resolvingRoute.value = true;
134
- sawRouteQueryPending.value = false;
135
- }, { flush: "sync" });
136
- watch(pageResult.data, (value) => {
137
- rawPage.value = value;
138
- const resolved = value;
139
- if (resolved && routeMetaMatchesPath(resolved, route.path)) {
140
- resolvingRoute.value = false;
141
- }
142
- });
143
- watch(() => pageResult.pending.value, (pending2) => {
144
- if (pending2) {
145
- sawRouteQueryPending.value = true;
146
- return;
147
- }
148
- if (sawRouteQueryPending.value) {
149
- const resolved = pageResult.data.value;
150
- if (!resolved || routeMetaMatchesPath(resolved, route.path)) {
151
- resolvingRoute.value = false;
152
- }
153
- }
154
- });
155
- const surroundResult = surroundResultPromise ? await surroundResultPromise : void 0;
156
- const pending = computed(() => pageResult.pending.value || Boolean(surroundResult?.pending.value));
157
- const pageError = computed(() => {
158
- if (pageResult.error.value) return pageResult.error.value;
159
- if (surroundResult?.error.value) return surroundResult.error.value;
160
- if (pending.value || resolvingRoute.value || page.value || notFound === false) return void 0;
161
- return normalizePageNotFound(notFound);
162
- });
163
- if (!isBrowser && pageError.value) {
164
- throw pageError.value;
165
- }
166
- const previous = computed(() => {
167
- if (!page.value || !surroundResult) return null;
168
- return surroundResult.data.value.prev;
169
- });
170
- const next = computed(() => {
171
- if (!page.value || !surroundResult) return null;
172
- return surroundResult.data.value.next;
173
- });
174
- const pageSurround = computed(() => {
175
- return [previous.value, next.value].filter((item) => Boolean(item));
176
- });
177
- return {
178
- data: page,
179
- page,
180
- surround: pageSurround,
181
- previous,
182
- next,
183
- pending,
184
- status: computed(() => pageResult.status.value),
185
- error: pageError,
186
- refresh: async () => {
187
- await pageResult.refresh();
188
- if (surroundResult) await surroundResult.refresh();
189
- }
190
- };
191
- }
192
- export async function useContentResolveOne(handle, options) {
193
- const resolved = computed(() => resolveOptions(options));
194
- const key = computed(() => stableKey("content-resolve-one", typeof handle === "string" ? handle : handle.name, resolved.value));
195
- const context = createClientContentQueryContext();
196
- const asyncData = await useAsyncData(
197
- key,
198
- () => resolveOneWithContext(context, handle, resolved.value),
199
- { watch: [resolved] }
200
- );
201
- return {
202
- doc: computed(() => asyncData.data.value?.doc ?? null),
203
- explain: computed(() => asyncData.data.value?.explain ?? null),
204
- status: computed(() => asyncData.status.value),
205
- error: computed(() => asyncData.error.value),
206
- refresh: () => asyncData.refresh()
207
- };
208
- }
209
- export async function useContentMany(handle, options = {}) {
210
- const resolved = computed(() => resolveOptions(options));
211
- const key = computed(() => stableKey("content-many", typeof handle === "string" ? handle : handle.name, resolved.value));
212
- const context = createClientContentQueryContext();
213
- const asyncData = await useAsyncData(
214
- key,
215
- () => manyWithContext(context, handle, resolved.value),
216
- { watch: [resolved], default: () => [] }
217
- );
218
- return {
219
- data: computed(() => asyncData.data.value || []),
220
- status: computed(() => asyncData.status.value),
221
- error: computed(() => asyncData.error.value),
222
- refresh: () => asyncData.refresh()
223
- };
224
- }
225
- const emptyPagination = () => ({
226
- data: [],
227
- page: 1,
228
- limit: 10,
229
- total: 0,
230
- pageCount: 0,
231
- hasNext: false,
232
- hasPrev: false,
233
- nextPage: null,
234
- prevPage: null
235
- });
236
- export async function useContentPagination(handle, options) {
237
- const resolved = computed(() => resolveOptions(options));
238
- const key = computed(() => stableKey("content-pagination", typeof handle === "string" ? handle : handle.name, resolved.value));
239
- const context = createClientContentQueryContext();
240
- const asyncData = await useAsyncData(
241
- key,
242
- () => paginateWithContext(context, handle, resolved.value),
243
- { watch: [resolved], default: () => emptyPagination() }
244
- );
245
- const result = computed(() => asyncData.data.value || emptyPagination());
246
- return {
247
- data: computed(() => result.value.data),
248
- page: computed(() => result.value.page),
249
- limit: computed(() => result.value.limit),
250
- total: computed(() => result.value.total),
251
- pageCount: computed(() => result.value.pageCount),
252
- hasNext: computed(() => result.value.hasNext),
253
- hasPrev: computed(() => result.value.hasPrev),
254
- nextPage: computed(() => result.value.nextPage),
255
- prevPage: computed(() => result.value.prevPage),
256
- status: computed(() => asyncData.status.value),
257
- error: computed(() => asyncData.error.value),
258
- refresh: () => asyncData.refresh()
259
- };
260
- }
261
- export async function useContentBacklinks(handle, options) {
262
- const resolved = computed(() => resolveOptions(options));
263
- const key = computed(() => stableKey("content-backlinks", typeof handle === "string" ? handle : handle.name, resolved.value));
264
- const context = createClientContentQueryContext();
265
- const asyncData = await useAsyncData(
266
- key,
267
- () => backlinksWithContext(context, handle, resolved.value),
268
- { watch: [resolved], default: () => [] }
269
- );
270
- return {
271
- data: computed(() => asyncData.data.value || []),
272
- status: computed(() => asyncData.status.value),
273
- error: computed(() => asyncData.error.value),
274
- refresh: () => asyncData.refresh()
275
- };
276
- }
277
- export async function useContentVariants(handle, options) {
278
- const resolved = computed(() => resolveOptions(options));
279
- const key = computed(() => stableKey("content-variants", typeof handle === "string" ? handle : handle.name, resolved.value));
280
- const context = createClientContentQueryContext();
281
- const asyncData = await useAsyncData(
282
- key,
283
- () => variantsWithContext(context, handle, resolved.value),
284
- { watch: [resolved], default: () => [] }
285
- );
286
- return {
287
- data: computed(() => asyncData.data.value || []),
288
- status: computed(() => asyncData.status.value),
289
- error: computed(() => asyncData.error.value),
290
- refresh: () => asyncData.refresh()
291
- };
292
- }
293
- const navigationNodeId = (item) => {
294
- const id = item.id ?? item._id ?? item._canonicalKey ?? item.path ?? item._path ?? item.title;
295
- return typeof id === "string" && id.length ? id : item.title;
296
- };
297
- const normalizeContentNavigation = (items = []) => {
298
- return items.map((item) => {
299
- const source = item;
300
- return {
301
- ...item,
302
- id: navigationNodeId(source),
303
- path: item.path,
304
- title: item.title,
305
- children: normalizeContentNavigation(item.children || [])
306
- };
307
- });
308
- };
309
- const findFirstContentNavigationPage = (items) => {
310
- for (const item of items) {
311
- if (item.path) return item;
312
- const child = findFirstContentNavigationPage(item.children);
313
- if (child) return child;
314
- }
315
- return null;
316
- };
317
- const collectContentNavigationPaths = (items, paths = /* @__PURE__ */ new Set()) => {
318
- for (const item of items) {
319
- if (item.path) paths.add(item.path);
320
- collectContentNavigationPaths(item.children, paths);
321
- }
322
- return paths;
323
- };
324
- export async function useContentTree(handle, options = {}) {
325
- const resolved = computed(() => resolveOptions(options));
326
- const key = computed(() => stableKey("content-tree", typeof handle === "string" ? handle : handle.name, resolved.value));
327
- const context = createClientContentQueryContext();
328
- const asyncData = await useAsyncData(
329
- key,
330
- () => treeWithContext(context, handle, resolved.value),
331
- { watch: [resolved], default: () => [] }
332
- );
333
- return {
334
- data: computed(() => asyncData.data.value || []),
335
- status: computed(() => asyncData.status.value),
336
- error: computed(() => asyncData.error.value),
337
- refresh: () => asyncData.refresh()
338
- };
339
- }
340
- export async function useContentNavigation(handle, options = {}) {
341
- const tree = await useContentTree(handle, options);
342
- const data = computed(() => normalizeContentNavigation(tree.data.value));
343
- return {
344
- data,
345
- firstPage: computed(() => findFirstContentNavigationPage(data.value)),
346
- paths: computed(() => collectContentNavigationPaths(data.value)),
347
- status: tree.status,
348
- error: tree.error,
349
- refresh: tree.refresh
350
- };
351
- }
352
- export async function useContentNeighbors(handle, options) {
353
- const resolved = computed(() => resolveOptions(options));
354
- const key = computed(() => stableKey("content-neighbors", typeof handle === "string" ? handle : handle.name, resolved.value));
355
- const context = createClientContentQueryContext();
356
- const asyncData = await useAsyncData(
357
- key,
358
- () => neighborsWithContext(context, handle, resolved.value),
359
- { watch: [resolved], default: () => ({ prev: null, next: null }) }
360
- );
361
- return {
362
- data: computed(() => asyncData.data.value || { prev: null, next: null }),
363
- pending: computed(() => asyncData.pending.value),
364
- status: computed(() => asyncData.status.value),
365
- error: computed(() => asyncData.error.value),
366
- refresh: () => asyncData.refresh()
367
- };
368
- }
369
- export async function useContentLocaleSwitch(handle, options) {
370
- const { data } = await useContentOne(handle, options);
371
- const paths = computed(() => {
372
- const localePaths = data.value?.localePaths;
373
- return localePaths || {};
374
- });
375
- const switchTo = (locale) => paths.value?.[locale]?.path ?? null;
376
- return { paths, switchTo, data };
377
- }
1
+ export { useContentOne, useContentResolveOne } from "./use-content-document.js";
2
+ export { useContentPage } from "./use-content-page.js";
3
+ export { useContentMany, useContentPagination, useContentBacklinks, useContentVariants } from "./use-content-list.js";
4
+ export { useContentTree, useContentNavigation, useContentNeighbors } from "./use-content-navigation.js";
@@ -0,0 +1 @@
1
+ export * from './hot-reload.js'
@@ -0,0 +1,6 @@
1
+ import { defineNuxtPlugin } from "#imports";
2
+ export default defineNuxtPlugin(() => {
3
+ if (import.meta.client && import.meta.hot) {
4
+ import("../composables/hot-reload.js").then(({ registerContentHotReload }) => registerContentHotReload());
5
+ }
6
+ });
@@ -0,0 +1 @@
1
+ export * from './backlinks.js'
@@ -0,0 +1,8 @@
1
+ import type { ParsedContent } from '../../types/content';
2
+ import type { ContentCollectionHandle } from '../../types/config';
3
+ import type { BacklinkSource, BacklinksOptions, BacklinksResult, LocalizedDoc, ManyOptions, OneOptions, PopulateSpec } from '../../types/query';
4
+ import type { ContentQueryContext } from './context';
5
+ type OneResolver = <H extends ContentCollectionHandle | string>(context: ContentQueryContext, handle: H, options: OneOptions<H>) => Promise<LocalizedDoc<ParsedContent> | null>;
6
+ type ManyResolver = <H extends ContentCollectionHandle | string, P extends PopulateSpec | undefined>(context: ContentQueryContext, handle: H, options: ManyOptions<H, P>) => Promise<Array<LocalizedDoc<ParsedContent>>>;
7
+ export declare function resolveBacklinks<const Target extends ContentCollectionHandle | string, const Source extends BacklinkSource | ReadonlyArray<BacklinkSource>, P extends PopulateSpec | undefined = undefined>(context: ContentQueryContext, one: OneResolver, many: ManyResolver, targetHandle: Target, options: BacklinksOptions<Target, Source, P>): Promise<BacklinksResult<Source, P>>;
8
+ export {};