@astrojs/starlight 0.37.7 → 0.38.1
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.
- package/CHANGELOG.md +76 -0
- package/components/ContentNotice.astro +1 -1
- package/components/MobileTableOfContents.astro +2 -2
- package/components/Page.astro +3 -3
- package/components/Select.astro +2 -2
- package/components/SocialIcons.astro +1 -1
- package/components/TableOfContents.astro +2 -2
- package/global.d.ts +9 -3
- package/index.ts +39 -1
- package/integrations/asides.ts +1 -1
- package/integrations/remark-rehype.ts +2 -11
- package/integrations/virtual-user-config.ts +31 -17
- package/integrations/vite-layer-order.ts +38 -35
- package/package.json +12 -148
- package/schema.ts +5 -11
- package/schemas/badge.ts +9 -8
- package/schemas/components.ts +1 -1
- package/schemas/expressiveCode.ts +0 -3
- package/schemas/favicon.ts +4 -6
- package/schemas/head.ts +3 -2
- package/schemas/hero.ts +1 -1
- package/schemas/i18n.ts +148 -153
- package/schemas/icon.ts +1 -1
- package/schemas/pagefind.ts +5 -4
- package/schemas/prevNextLink.ts +6 -8
- package/schemas/sidebar.ts +33 -27
- package/schemas/site-title.ts +4 -6
- package/schemas/social.ts +3 -2
- package/schemas/tableOfContents.ts +17 -15
- package/style/props.css +7 -2
- package/types.ts +1 -1
- package/user-components/Aside.astro +1 -1
- package/user-components/Card.astro +1 -1
- package/user-components/Icon.astro +1 -1
- package/user-components/LinkButton.astro +1 -1
- package/user-components/TabItem.astro +1 -1
- package/user-components/rehype-file-tree.ts +1 -1
- package/user-components/rehype-tabs.ts +1 -1
- package/utils/createTranslationSystem.ts +1 -1
- package/utils/error-map.ts +98 -57
- package/utils/navigation.ts +11 -10
- package/utils/plugins.ts +75 -40
- package/utils/routing/data.ts +3 -9
- package/utils/routing/index.ts +16 -24
- package/utils/routing/types.ts +5 -17
- package/utils/slugs.ts +11 -12
- package/utils/starlight-page.ts +13 -23
- package/utils/translations.ts +3 -4
- package/utils/user-config.ts +30 -67
- package/virtual.d.ts +6 -3
- /package/{components → components-internals}/Icons.ts +0 -0
- /package/{components → components-internals}/SidebarPersistState.ts +0 -0
- /package/{components → components-internals}/TableOfContents/TableOfContentsList.astro +0 -0
- /package/{components → components-internals}/TableOfContents/starlight-toc.ts +0 -0
package/utils/plugins.ts
CHANGED
|
@@ -183,8 +183,8 @@ export function injectPluginTranslationsTypes(
|
|
|
183
183
|
// https://github.com/withastro/astro/blob/910eb00fe0b70ca80bd09520ae100e8c78b675b5/packages/astro/src/core/config/schema.ts#L113
|
|
184
184
|
const astroIntegrationSchema = z.object({
|
|
185
185
|
name: z.string(),
|
|
186
|
-
hooks: z.
|
|
187
|
-
}) as z.
|
|
186
|
+
hooks: z.looseObject({}).default({}),
|
|
187
|
+
}) as z.ZodType<AstroIntegration, AstroIntegration>;
|
|
188
188
|
|
|
189
189
|
const routeMiddlewareConfigSchema = z.object({
|
|
190
190
|
entrypoint: z.string(),
|
|
@@ -196,9 +196,12 @@ const baseStarlightPluginSchema = z.object({
|
|
|
196
196
|
name: z.string(),
|
|
197
197
|
});
|
|
198
198
|
|
|
199
|
+
type StarlightConfigUpdate = Partial<Omit<StarlightUserConfig, 'routeMiddleware'>>;
|
|
200
|
+
type StarlightI18nTFactory = Awaited<ReturnType<typeof createTranslationSystemFromFs>>;
|
|
201
|
+
|
|
199
202
|
const configSetupHookSchema = z
|
|
200
|
-
.function(
|
|
201
|
-
|
|
203
|
+
.function({
|
|
204
|
+
input: [
|
|
202
205
|
z.object({
|
|
203
206
|
/**
|
|
204
207
|
* A read-only copy of the user-supplied Starlight configuration.
|
|
@@ -206,9 +209,10 @@ const configSetupHookSchema = z
|
|
|
206
209
|
* Note that this configuration may have been updated by other plugins configured
|
|
207
210
|
* before this one.
|
|
208
211
|
*/
|
|
209
|
-
config: z.any() as z.
|
|
212
|
+
config: z.any() as z.ZodType<
|
|
210
213
|
// The configuration passed to plugins should contains the list of plugins.
|
|
211
|
-
|
|
214
|
+
StarlightUserConfigWithPlugins,
|
|
215
|
+
StarlightUserConfigWithPlugins
|
|
212
216
|
>,
|
|
213
217
|
/**
|
|
214
218
|
* A callback function to update the user-supplied Starlight configuration.
|
|
@@ -228,12 +232,15 @@ const configSetupHookSchema = z
|
|
|
228
232
|
* }
|
|
229
233
|
* }
|
|
230
234
|
*/
|
|
231
|
-
updateConfig: z.function(
|
|
232
|
-
|
|
233
|
-
z.record(z.any()) as z.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
updateConfig: z.function({
|
|
236
|
+
input: [
|
|
237
|
+
z.record(z.string(), z.any()) as z.ZodType<
|
|
238
|
+
StarlightConfigUpdate,
|
|
239
|
+
StarlightConfigUpdate
|
|
240
|
+
>,
|
|
241
|
+
],
|
|
242
|
+
output: z.void(),
|
|
243
|
+
}),
|
|
237
244
|
/**
|
|
238
245
|
* A callback function to add an Astro integration required by this plugin.
|
|
239
246
|
*
|
|
@@ -256,7 +263,10 @@ const configSetupHookSchema = z
|
|
|
256
263
|
* }
|
|
257
264
|
* }
|
|
258
265
|
*/
|
|
259
|
-
addIntegration: z.function(
|
|
266
|
+
addIntegration: z.function({
|
|
267
|
+
input: [astroIntegrationSchema],
|
|
268
|
+
output: z.void(),
|
|
269
|
+
}),
|
|
260
270
|
/**
|
|
261
271
|
* A callback function to register additional route middleware handlers.
|
|
262
272
|
*
|
|
@@ -273,7 +283,10 @@ const configSetupHookSchema = z
|
|
|
273
283
|
* },
|
|
274
284
|
* }
|
|
275
285
|
*/
|
|
276
|
-
addRouteMiddleware: z.function(
|
|
286
|
+
addRouteMiddleware: z.function({
|
|
287
|
+
input: [routeMiddlewareConfigSchema],
|
|
288
|
+
output: z.void(),
|
|
289
|
+
}),
|
|
277
290
|
/**
|
|
278
291
|
* A read-only copy of the user-supplied Astro configuration.
|
|
279
292
|
*
|
|
@@ -281,26 +294,38 @@ const configSetupHookSchema = z
|
|
|
281
294
|
*
|
|
282
295
|
* @see https://docs.astro.build/en/reference/integrations-reference/#config-option
|
|
283
296
|
*/
|
|
284
|
-
astroConfig: z.any() as z.
|
|
297
|
+
astroConfig: z.any() as z.ZodType<
|
|
298
|
+
StarlightPluginContext['config'],
|
|
299
|
+
StarlightPluginContext['config']
|
|
300
|
+
>,
|
|
285
301
|
/**
|
|
286
302
|
* The command used to run Starlight.
|
|
287
303
|
*
|
|
288
304
|
* @see https://docs.astro.build/en/reference/integrations-reference/#command-option
|
|
289
305
|
*/
|
|
290
|
-
command: z.any() as z.
|
|
306
|
+
command: z.any() as z.ZodType<
|
|
307
|
+
StarlightPluginContext['command'],
|
|
308
|
+
StarlightPluginContext['command']
|
|
309
|
+
>,
|
|
291
310
|
/**
|
|
292
311
|
* `false` when the dev server starts, `true` when a reload is triggered.
|
|
293
312
|
*
|
|
294
313
|
* @see https://docs.astro.build/en/reference/integrations-reference/#isrestart-option
|
|
295
314
|
*/
|
|
296
|
-
isRestart: z.any() as z.
|
|
315
|
+
isRestart: z.any() as z.ZodType<
|
|
316
|
+
StarlightPluginContext['isRestart'],
|
|
317
|
+
StarlightPluginContext['isRestart']
|
|
318
|
+
>,
|
|
297
319
|
/**
|
|
298
320
|
* An instance of the Astro integration logger with all logged messages prefixed with the
|
|
299
321
|
* plugin name.
|
|
300
322
|
*
|
|
301
323
|
* @see https://docs.astro.build/en/reference/integrations-reference/#astrointegrationlogger
|
|
302
324
|
*/
|
|
303
|
-
logger: z.any() as z.
|
|
325
|
+
logger: z.any() as z.ZodType<
|
|
326
|
+
StarlightPluginContext['logger'],
|
|
327
|
+
StarlightPluginContext['logger']
|
|
328
|
+
>,
|
|
304
329
|
/**
|
|
305
330
|
* A callback function to generate a utility function to access UI strings for a given
|
|
306
331
|
* language.
|
|
@@ -319,9 +344,7 @@ const configSetupHookSchema = z
|
|
|
319
344
|
* }
|
|
320
345
|
* }
|
|
321
346
|
*/
|
|
322
|
-
useTranslations: z.any() as z.
|
|
323
|
-
Awaited<ReturnType<typeof createTranslationSystemFromFs>>
|
|
324
|
-
>,
|
|
347
|
+
useTranslations: z.any() as z.ZodType<StarlightI18nTFactory, StarlightI18nTFactory>,
|
|
325
348
|
/**
|
|
326
349
|
* A callback function to get the language for a given absolute file path. The returned
|
|
327
350
|
* language can be used with the `useTranslations` helper to get UI strings for that
|
|
@@ -344,11 +367,17 @@ const configSetupHookSchema = z
|
|
|
344
367
|
* }
|
|
345
368
|
* }
|
|
346
369
|
*/
|
|
347
|
-
absolutePathToLang: z.function(
|
|
370
|
+
absolutePathToLang: z.function({
|
|
371
|
+
input: [z.string()],
|
|
372
|
+
output: z.string(),
|
|
373
|
+
}),
|
|
348
374
|
}),
|
|
349
|
-
]
|
|
350
|
-
|
|
351
|
-
|
|
375
|
+
],
|
|
376
|
+
// We still rely on the deprecated `z.promise()` to define the function output as the only
|
|
377
|
+
// non-deprecated way to define an async function is to use `.implementAsync()` but we don't
|
|
378
|
+
// want to implement the function using Zod.
|
|
379
|
+
output: z.promise(z.void()),
|
|
380
|
+
})
|
|
352
381
|
.optional();
|
|
353
382
|
|
|
354
383
|
/**
|
|
@@ -356,8 +385,9 @@ const configSetupHookSchema = z
|
|
|
356
385
|
* user config schema but properly typed for user convenience because we do not want to run any of
|
|
357
386
|
* the Zod `transform`s used in the user config schema when running plugins.
|
|
358
387
|
*/
|
|
359
|
-
const starlightPluginSchema =
|
|
360
|
-
.
|
|
388
|
+
const starlightPluginSchema = z
|
|
389
|
+
.object({
|
|
390
|
+
...baseStarlightPluginSchema.shape,
|
|
361
391
|
/** The different hooks available to the plugin. */
|
|
362
392
|
hooks: z.object({
|
|
363
393
|
/**
|
|
@@ -366,8 +396,8 @@ const starlightPluginSchema = baseStarlightPluginSchema
|
|
|
366
396
|
* and plugin UI.
|
|
367
397
|
*/
|
|
368
398
|
'i18n:setup': z
|
|
369
|
-
.function(
|
|
370
|
-
|
|
399
|
+
.function({
|
|
400
|
+
input: [
|
|
371
401
|
z.object({
|
|
372
402
|
/**
|
|
373
403
|
* A callback function to add or update translations strings.
|
|
@@ -391,14 +421,17 @@ const starlightPluginSchema = baseStarlightPluginSchema
|
|
|
391
421
|
* }
|
|
392
422
|
* }
|
|
393
423
|
*/
|
|
394
|
-
injectTranslations: z.function(
|
|
395
|
-
|
|
396
|
-
z.void()
|
|
397
|
-
),
|
|
424
|
+
injectTranslations: z.function({
|
|
425
|
+
input: [z.record(z.string(), z.record(z.string(), z.string()))],
|
|
426
|
+
output: z.void(),
|
|
427
|
+
}),
|
|
398
428
|
}),
|
|
399
|
-
]
|
|
400
|
-
|
|
401
|
-
|
|
429
|
+
],
|
|
430
|
+
// We still rely on the deprecated `z.promise()` to define the function output as the
|
|
431
|
+
// only non-deprecated way to define an async function is to use `.implementAsync()` but
|
|
432
|
+
// we don't want to implement the function using Zod.
|
|
433
|
+
output: z.promise(z.void()),
|
|
434
|
+
})
|
|
402
435
|
.optional(),
|
|
403
436
|
/**
|
|
404
437
|
* Plugin configuration setup function called with an object containing various values that
|
|
@@ -414,17 +447,19 @@ const starlightPluginSchema = baseStarlightPluginSchema
|
|
|
414
447
|
})
|
|
415
448
|
.superRefine((plugin, ctx) => {
|
|
416
449
|
if (!plugin.hooks['config:setup'] && !plugin.hooks.setup) {
|
|
417
|
-
ctx.
|
|
418
|
-
code:
|
|
450
|
+
ctx.issues.push({
|
|
451
|
+
code: 'custom',
|
|
419
452
|
message: 'A plugin must define at least a `config:setup` hook.',
|
|
453
|
+
input: plugin,
|
|
420
454
|
});
|
|
421
455
|
} else if (plugin.hooks['config:setup'] && plugin.hooks.setup) {
|
|
422
|
-
ctx.
|
|
423
|
-
code:
|
|
456
|
+
ctx.issues.push({
|
|
457
|
+
code: 'custom',
|
|
424
458
|
message:
|
|
425
459
|
'A plugin cannot define both a `config:setup` and `setup` hook. ' +
|
|
426
460
|
'As `setup` is deprecated and will be removed in a future version, ' +
|
|
427
461
|
'consider using `config:setup` instead.',
|
|
462
|
+
input: plugin,
|
|
428
463
|
});
|
|
429
464
|
}
|
|
430
465
|
});
|
package/utils/routing/data.ts
CHANGED
|
@@ -6,12 +6,7 @@ import { getNewestCommitDate } from 'virtual:starlight/git-info';
|
|
|
6
6
|
import { getPrevNextLinks, getSidebar } from '../navigation';
|
|
7
7
|
import { ensureTrailingSlash } from '../path';
|
|
8
8
|
import { getRouteBySlugParam, normalizeCollectionEntry } from '../routing';
|
|
9
|
-
import type {
|
|
10
|
-
Route,
|
|
11
|
-
StarlightDocsCollectionEntry,
|
|
12
|
-
StarlightDocsEntry,
|
|
13
|
-
StarlightRouteData,
|
|
14
|
-
} from './types';
|
|
9
|
+
import type { Route, StarlightDocsEntry, StarlightRouteData } from './types';
|
|
15
10
|
import { formatPath } from '../format-path';
|
|
16
11
|
import { useTranslations } from '../translations';
|
|
17
12
|
import { BuiltInDefaultLocale } from '../i18n';
|
|
@@ -137,7 +132,6 @@ async function get404Route(locals: App.Locals): Promise<Route> {
|
|
|
137
132
|
const entryMeta = { dir, lang, locale };
|
|
138
133
|
|
|
139
134
|
const fallbackEntry: StarlightDocsEntry = {
|
|
140
|
-
slug: '404',
|
|
141
135
|
id: '404',
|
|
142
136
|
body: '',
|
|
143
137
|
collection: 'docs',
|
|
@@ -154,7 +148,7 @@ async function get404Route(locals: App.Locals): Promise<Route> {
|
|
|
154
148
|
filePath: `${getCollectionPathFromRoot('docs', project)}/404.md`,
|
|
155
149
|
};
|
|
156
150
|
|
|
157
|
-
const userEntry =
|
|
151
|
+
const userEntry = await getEntry('docs', '404');
|
|
158
152
|
const entry = userEntry ? normalizeCollectionEntry(userEntry) : fallbackEntry;
|
|
159
|
-
return { ...entryMeta, entryMeta, entry, id: entry.id
|
|
153
|
+
return { ...entryMeta, entryMeta, entry, id: entry.id };
|
|
160
154
|
}
|
package/utils/routing/index.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { GetStaticPathsItem } from 'astro';
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
3
|
import config from 'virtual:starlight/user-config';
|
|
4
|
-
import
|
|
5
|
-
import { getCollectionPathFromRoot } from '../collection';
|
|
6
|
-
import { localizedId, localizedSlug, slugToLocaleData, slugToParam } from '../slugs';
|
|
4
|
+
import { localizedSlug, slugToLocaleData, slugToParam } from '../slugs';
|
|
7
5
|
import { validateLogoImports } from '../validateLogoImports';
|
|
8
6
|
import { BuiltInDefaultLocale } from '../i18n';
|
|
9
7
|
import type { Route, StarlightDocsCollectionEntry, StarlightDocsEntry } from './types';
|
|
@@ -24,17 +22,14 @@ interface Path extends GetStaticPathsItem {
|
|
|
24
22
|
*/
|
|
25
23
|
const normalizeIndexSlug = (slug: string) => (slug === 'index' ? '' : slug);
|
|
26
24
|
|
|
27
|
-
/** Normalize
|
|
25
|
+
/** Normalize a collection entry. */
|
|
28
26
|
export function normalizeCollectionEntry(entry: StarlightDocsCollectionEntry): StarlightDocsEntry {
|
|
29
|
-
const slug = normalizeIndexSlug(entry.slug ?? entry.id);
|
|
30
27
|
return {
|
|
31
28
|
...entry,
|
|
32
|
-
//
|
|
33
|
-
id: entry.
|
|
34
|
-
//
|
|
35
|
-
filePath: entry.filePath
|
|
36
|
-
// In a collection with a loader, the `slug` property is replaced by the `id`.
|
|
37
|
-
slug: normalizeIndexSlug(entry.slug ?? entry.id),
|
|
29
|
+
// The `id` is a slug and should be normalized.
|
|
30
|
+
id: normalizeIndexSlug(entry.id),
|
|
31
|
+
// At the moment, Starlight only supports file-based loaders which always include a `filePath`.
|
|
32
|
+
filePath: entry.filePath!,
|
|
38
33
|
};
|
|
39
34
|
}
|
|
40
35
|
|
|
@@ -49,10 +44,9 @@ const docs: StarlightDocsEntry[] = (
|
|
|
49
44
|
function getRoutes(): Route[] {
|
|
50
45
|
const routes: Route[] = docs.map((entry) => ({
|
|
51
46
|
entry,
|
|
52
|
-
slug: entry.slug,
|
|
53
47
|
id: entry.id,
|
|
54
|
-
entryMeta: slugToLocaleData(entry.
|
|
55
|
-
...slugToLocaleData(entry.
|
|
48
|
+
entryMeta: slugToLocaleData(entry.id),
|
|
49
|
+
...slugToLocaleData(entry.id),
|
|
56
50
|
}));
|
|
57
51
|
|
|
58
52
|
// In multilingual sites, add required fallback routes.
|
|
@@ -68,19 +62,17 @@ function getRoutes(): Route[] {
|
|
|
68
62
|
const locale = key === 'root' ? undefined : key;
|
|
69
63
|
const localeDocs = getLocaleDocs(locale);
|
|
70
64
|
for (const fallback of defaultLocaleDocs) {
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const doesNotNeedFallback = localeDocs.some((doc) => doc.slug === slug);
|
|
65
|
+
const id = localizedSlug(fallback.id, locale);
|
|
66
|
+
const doesNotNeedFallback = localeDocs.some((doc) => doc.id === id);
|
|
74
67
|
if (doesNotNeedFallback) continue;
|
|
75
68
|
routes.push({
|
|
76
69
|
entry: fallback,
|
|
77
|
-
slug,
|
|
78
70
|
id,
|
|
79
71
|
isFallback: true,
|
|
80
72
|
lang: localeConfig.lang || BuiltInDefaultLocale.lang,
|
|
81
73
|
locale,
|
|
82
74
|
dir: localeConfig.dir,
|
|
83
|
-
entryMeta: slugToLocaleData(fallback.
|
|
75
|
+
entryMeta: slugToLocaleData(fallback.id),
|
|
84
76
|
});
|
|
85
77
|
}
|
|
86
78
|
}
|
|
@@ -93,7 +85,7 @@ export const routes = getRoutes();
|
|
|
93
85
|
function getParamRouteMapping(): ReadonlyMap<string | undefined, Route> {
|
|
94
86
|
const map = new Map<string | undefined, Route>();
|
|
95
87
|
for (const route of routes) {
|
|
96
|
-
map.set(slugToParam(route.
|
|
88
|
+
map.set(slugToParam(route.id), route);
|
|
97
89
|
}
|
|
98
90
|
return map;
|
|
99
91
|
}
|
|
@@ -105,7 +97,7 @@ export function getRouteBySlugParam(slugParam: string | undefined): Route | unde
|
|
|
105
97
|
|
|
106
98
|
function getPaths(): Path[] {
|
|
107
99
|
return routes.map((route) => ({
|
|
108
|
-
params: { slug: slugToParam(route.
|
|
100
|
+
params: { slug: slugToParam(route.id) },
|
|
109
101
|
props: route,
|
|
110
102
|
}));
|
|
111
103
|
}
|
|
@@ -128,15 +120,15 @@ function getLocaleDocs(locale: string | undefined): StarlightDocsEntry[] {
|
|
|
128
120
|
}
|
|
129
121
|
|
|
130
122
|
/** Filter an array to find items whose slug matches the passed locale. */
|
|
131
|
-
function filterByLocale<T extends {
|
|
123
|
+
function filterByLocale<T extends { id: string }>(items: T[], locale: string | undefined): T[] {
|
|
132
124
|
if (config.locales) {
|
|
133
125
|
if (locale && locale in config.locales) {
|
|
134
|
-
return items.filter((i) => i.
|
|
126
|
+
return items.filter((i) => i.id === locale || i.id.startsWith(locale + '/'));
|
|
135
127
|
} else if (config.locales.root) {
|
|
136
128
|
const langKeys = Object.keys(config.locales).filter((k) => k !== 'root');
|
|
137
129
|
const isLangIndex = new RegExp(`^(${langKeys.join('|')})$`);
|
|
138
130
|
const isLangDir = new RegExp(`^(${langKeys.join('|')})/`);
|
|
139
|
-
return items.filter((i) => !isLangIndex.test(i.
|
|
131
|
+
return items.filter((i) => !isLangIndex.test(i.id) && !isLangDir.test(i.id));
|
|
140
132
|
}
|
|
141
133
|
}
|
|
142
134
|
return items;
|
package/utils/routing/types.ts
CHANGED
|
@@ -40,23 +40,13 @@ export interface PaginationLinks {
|
|
|
40
40
|
next: SidebarLink | undefined;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
export type StarlightDocsCollectionEntry = Omit<
|
|
46
|
-
CollectionEntry<'docs'>,
|
|
47
|
-
'id' | 'filePath' | 'render' | 'slug'
|
|
48
|
-
> & {
|
|
49
|
-
// Update the `id` property to be a string like in the loader type.
|
|
50
|
-
id: string;
|
|
51
|
-
// Add the `filePath` property which is only present in the loader type.
|
|
52
|
-
filePath?: string;
|
|
53
|
-
// Add the `slug` property which is only present in the legacy type.
|
|
54
|
-
slug?: string;
|
|
55
|
-
};
|
|
43
|
+
// A type representing a docs collection entry returned by the `docsLoader()`.
|
|
44
|
+
export type StarlightDocsCollectionEntry = CollectionEntry<'docs'>;
|
|
56
45
|
|
|
46
|
+
// A normalized type representing a docs collection entry used throughout Starlight.
|
|
57
47
|
export type StarlightDocsEntry = StarlightDocsCollectionEntry & {
|
|
48
|
+
// At the moment, Starlight only supports file-based loaders which always include a `filePath`.
|
|
58
49
|
filePath: string;
|
|
59
|
-
slug: string;
|
|
60
50
|
};
|
|
61
51
|
|
|
62
52
|
export interface Route extends LocaleData {
|
|
@@ -64,9 +54,7 @@ export interface Route extends LocaleData {
|
|
|
64
54
|
entry: StarlightDocsEntry;
|
|
65
55
|
/** Locale metadata for the page content. Can be different from top-level locale values when a page is using fallback content. */
|
|
66
56
|
entryMeta: LocaleData;
|
|
67
|
-
/**
|
|
68
|
-
slug: string;
|
|
69
|
-
/** The slug or unique ID if using the `legacy.collections` flag. */
|
|
57
|
+
/** The slug. */
|
|
70
58
|
id: string;
|
|
71
59
|
/** Whether this page is untranslated in the current language and using fallback content from the default locale. */
|
|
72
60
|
isFallback?: boolean;
|
package/utils/slugs.ts
CHANGED
|
@@ -80,24 +80,23 @@ export function localizedSlug(slug: string, locale: string | undefined): string
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
* Convert a
|
|
84
|
-
* locale.
|
|
85
|
-
* For example, passing an ID of `en/home.md` and a locale of `fr` results in `fr/home.md`.
|
|
83
|
+
* Convert a file path relative to the collection root to a different locale.
|
|
84
|
+
* For example, passing a file path of `en/home.md` and a locale of `fr` results in `fr/home.md`.
|
|
86
85
|
* An undefined locale is treated as the root locale, resulting in `home.md`.
|
|
87
|
-
* @param
|
|
86
|
+
* @param filePath A collection entry file path relative to the collection root
|
|
88
87
|
* @param locale The target locale
|
|
89
88
|
* @example
|
|
90
|
-
*
|
|
91
|
-
*
|
|
89
|
+
* localizedFilePath('en/home.md', 'fr') // => 'fr/home.md'
|
|
90
|
+
* localizedFilePath('en/home.md', undefined) // => 'home.md'
|
|
92
91
|
*/
|
|
93
|
-
export function
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
96
|
-
return
|
|
92
|
+
export function localizedFilePath(filePath: string, locale: string | undefined): string {
|
|
93
|
+
const filePathLocale = slugToLocale(filePath);
|
|
94
|
+
if (filePathLocale) {
|
|
95
|
+
return filePath.replace(filePathLocale + '/', locale ? locale + '/' : '');
|
|
97
96
|
} else if (locale) {
|
|
98
|
-
return locale + '/' +
|
|
97
|
+
return locale + '/' + filePath;
|
|
99
98
|
} else {
|
|
100
|
-
return
|
|
99
|
+
return filePath;
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
102
|
|
package/utils/starlight-page.ts
CHANGED
|
@@ -83,7 +83,7 @@ const validateSidebarProp = (
|
|
|
83
83
|
*/
|
|
84
84
|
export type StarlightPageProps = Prettify<
|
|
85
85
|
// Remove the index signature from `Route`, omit undesired properties and make the rest optional.
|
|
86
|
-
Partial<Omit<RemoveIndexSignature<PageProps>, 'entry' | 'entryMeta' | 'id' | 'locale'
|
|
86
|
+
Partial<Omit<RemoveIndexSignature<PageProps>, 'entry' | 'entryMeta' | 'id' | 'locale'>> &
|
|
87
87
|
// Add the sidebar definitions for a Starlight page.
|
|
88
88
|
Partial<Pick<StarlightRouteData, 'hasSidebar'>> & {
|
|
89
89
|
sidebar?: StarlightUserConfig['sidebar'];
|
|
@@ -97,13 +97,7 @@ export type StarlightPageProps = Prettify<
|
|
|
97
97
|
* to a `StarlightDocsEntry`.
|
|
98
98
|
* A Starlight page docs entry cannot be rendered like a content collection entry.
|
|
99
99
|
*/
|
|
100
|
-
type StarlightPageDocsEntry = Omit<StarlightDocsEntry, '
|
|
101
|
-
/**
|
|
102
|
-
* The unique ID if using the `legacy.collections` for this Starlight page which cannot be
|
|
103
|
-
* inferred from codegen like content collection entries or the slug.
|
|
104
|
-
*/
|
|
105
|
-
id: string;
|
|
106
|
-
};
|
|
100
|
+
type StarlightPageDocsEntry = Omit<StarlightDocsEntry, 'render'>;
|
|
107
101
|
|
|
108
102
|
export async function generateStarlightPageRouteData({
|
|
109
103
|
props,
|
|
@@ -114,20 +108,18 @@ export async function generateStarlightPageRouteData({
|
|
|
114
108
|
}): Promise<StarlightRouteData> {
|
|
115
109
|
const { frontmatter, ...routeProps } = props;
|
|
116
110
|
const { url } = context;
|
|
117
|
-
const
|
|
111
|
+
const id = urlToSlug(url);
|
|
118
112
|
const pageFrontmatter = await getStarlightPageFrontmatter(frontmatter);
|
|
119
|
-
const
|
|
120
|
-
const localeData = slugToLocaleData(slug);
|
|
113
|
+
const localeData = slugToLocaleData(id);
|
|
121
114
|
const sidebar = props.sidebar
|
|
122
115
|
? getSidebarFromConfig(validateSidebarProp(props.sidebar), url.pathname, localeData.locale)
|
|
123
116
|
: getSidebar(url.pathname, localeData.locale);
|
|
124
117
|
const headings = props.headings ?? [];
|
|
125
118
|
const pageDocsEntry: StarlightPageDocsEntry = {
|
|
126
119
|
id,
|
|
127
|
-
slug,
|
|
128
120
|
body: '',
|
|
129
121
|
collection: 'docs',
|
|
130
|
-
filePath: `${getCollectionPathFromRoot('docs', project)}/${stripLeadingAndTrailingSlashes(
|
|
122
|
+
filePath: `${getCollectionPathFromRoot('docs', project)}/${stripLeadingAndTrailingSlashes(id)}.md`,
|
|
131
123
|
data: {
|
|
132
124
|
...pageFrontmatter,
|
|
133
125
|
sidebar: {
|
|
@@ -153,7 +145,6 @@ export async function generateStarlightPageRouteData({
|
|
|
153
145
|
headings,
|
|
154
146
|
id,
|
|
155
147
|
locale: localeData.locale,
|
|
156
|
-
slug,
|
|
157
148
|
};
|
|
158
149
|
const siteTitle = getSiteTitle(localeData.lang);
|
|
159
150
|
const routeData: StarlightRouteData = {
|
|
@@ -171,7 +162,6 @@ export async function generateStarlightPageRouteData({
|
|
|
171
162
|
sidebar,
|
|
172
163
|
siteTitle,
|
|
173
164
|
siteTitleHref: getSiteTitleHref(localeData.locale),
|
|
174
|
-
slug,
|
|
175
165
|
toc: getToC(pageProps),
|
|
176
166
|
};
|
|
177
167
|
return routeData;
|
|
@@ -185,16 +175,16 @@ async function getStarlightPageFrontmatter(frontmatter: StarlightPageFrontmatter
|
|
|
185
175
|
// https://github.com/withastro/astro/blob/cf993bc263b58502096f00d383266cd179f331af/packages/astro/src/assets/types.ts#L32
|
|
186
176
|
// It uses a custom validation approach because imported SVGs have a type of `function` as
|
|
187
177
|
// well as containing the metadata properties and this ensures we handle those correctly.
|
|
188
|
-
z.custom(
|
|
178
|
+
z.custom<ReturnType<ImageFunction>>(
|
|
189
179
|
(value) =>
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
180
|
+
value &&
|
|
181
|
+
(typeof value === 'function' || typeof value === 'object') &&
|
|
182
|
+
'src' in value &&
|
|
183
|
+
'width' in value &&
|
|
184
|
+
'height' in value &&
|
|
185
|
+
'format' in value,
|
|
196
186
|
'Invalid image passed to `<StarlightPage>` component. Expected imported `ImageMetadata` object.'
|
|
197
|
-
)) as ImageFunction,
|
|
187
|
+
)) as unknown as ImageFunction,
|
|
198
188
|
});
|
|
199
189
|
|
|
200
190
|
// Starting with Astro 4.14.0, a frontmatter schema that contains collection references will
|
package/utils/translations.ts
CHANGED
|
@@ -32,10 +32,9 @@ async function loadTranslations() {
|
|
|
32
32
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
33
33
|
// @ts-ignore — may be a type error in projects without an i18n collection
|
|
34
34
|
(await getCollection('i18n')).map(({ id, data, filePath }) => {
|
|
35
|
-
const lang =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
: stripExtension(stripLeadingSlash(filePath.replace(i18nCollectionPathFromRoot, '')));
|
|
35
|
+
const lang = !filePath
|
|
36
|
+
? id
|
|
37
|
+
: stripExtension(stripLeadingSlash(filePath.replace(i18nCollectionPathFromRoot, '')));
|
|
39
38
|
return [lang, data] as const;
|
|
40
39
|
})
|
|
41
40
|
);
|