@byline/cli 2.7.0 → 3.0.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/dist/templates/byline-examples/collections/docs/admin.tsx +1 -1
- package/dist/templates/byline-examples/collections/docs/schema.ts +1 -2
- package/dist/templates/byline-examples/collections/news/admin.tsx +1 -1
- package/dist/templates/byline-examples/collections/news/schema.ts +1 -2
- package/dist/templates/byline-examples/collections/pages/admin.tsx +1 -1
- package/dist/templates/byline-examples/collections/pages/schema.ts +1 -2
- package/dist/templates/byline-examples/scripts/backfill-version-locales.ts +46 -0
- package/dist/templates/byline-examples/scripts/import-docs.ts +107 -23
- package/dist/templates/byline-examples/scripts/lib/mdast-to-lexical.test.node.ts +262 -0
- package/dist/templates/byline-examples/scripts/lib/mdast-to-lexical.ts +8 -3
- package/dist/templates/byline-examples/scripts/lib/rewrite-doc-links.ts +141 -0
- package/dist/templates/byline-examples/scripts/lib/strip-leading-h1.test.node.ts +66 -0
- package/dist/templates/byline-examples/scripts/re-anchor.ts +102 -0
- package/dist/templates/byline-examples/scripts/regenerate-media.ts +1 -1
- package/dist/templates/migrations/{0000_black_sabra.sql → 0000_yielding_northstar.sql} +22 -2
- package/dist/templates/migrations/meta/0000_snapshot.json +164 -3
- package/dist/templates/migrations/meta/_journal.json +2 -2
- package/dist/templates/routes/_byline/route.lazy.tsx +16 -6
- package/dist/templates/routes/_byline/route.tsx +34 -9
- package/package.json +1 -1
- package/dist/templates/byline-examples/fields/available-languages-field.ts +0 -99
|
@@ -9,9 +9,19 @@
|
|
|
9
9
|
/**
|
|
10
10
|
* Lazy companion to `_byline/route.tsx`. TanStack Router loads this on
|
|
11
11
|
* demand when a `_byline/*` URL matches, so the Byline UI providers,
|
|
12
|
-
* stylesheets, and the admin config side-effect import (which
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* stylesheets, and the admin config side-effect import (which transitively
|
|
13
|
+
* pulls in the Lexical editor module graph) only run when an admin route is
|
|
14
|
+
* actually visited — public routes stay clean.
|
|
15
|
+
*
|
|
16
|
+
* The `byline/admin.config` import below registers the client config in the
|
|
17
|
+
* *client component graph* — it runs whenever this lazy module loads (component
|
|
18
|
+
* render / initial hydration), where the sibling `route.tsx` `beforeLoad` does
|
|
19
|
+
* NOT help: on initial hydration TanStack Start reuses the dehydrated SSR result
|
|
20
|
+
* and does not re-run `beforeLoad`, yet the admin layout component still calls
|
|
21
|
+
* `getClientConfig()` at render. The two registration points are complementary —
|
|
22
|
+
* `beforeLoad` (a dynamic import) covers the *loader* phase before any
|
|
23
|
+
* `_byline/*` child loader; this import covers component render / hydration.
|
|
24
|
+
* Both call `defineClientConfig` idempotently.
|
|
15
25
|
*
|
|
16
26
|
* If you also want to use the Byline UI components on your public site,
|
|
17
27
|
* import the same stylesheets from your front-end's pathless layout
|
|
@@ -26,9 +36,9 @@ import { ToastProvider, ToastViewport } from '@byline/ui/react'
|
|
|
26
36
|
import '@byline/ui/reset.css'
|
|
27
37
|
import '@byline/ui/styles.css'
|
|
28
38
|
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
39
|
+
// Register the Byline client config (component-render / hydration entry point —
|
|
40
|
+
// see the file header). The sibling `route.tsx` `beforeLoad` covers the loader
|
|
41
|
+
// phase. Lexical's module graph only loads when a `_byline/*` URL matches.
|
|
32
42
|
import '../../../byline/admin.config'
|
|
33
43
|
|
|
34
44
|
export const Route = createLazyFileRoute('/_byline')({
|
|
@@ -12,17 +12,42 @@
|
|
|
12
12
|
* to URL paths — `/_byline/admin/...` resolves to `/admin/...` and
|
|
13
13
|
* `/_byline/sign-in` resolves to `/sign-in`.
|
|
14
14
|
*
|
|
15
|
-
* This file is intentionally
|
|
16
|
-
* at startup to build the tree for URL matching, so anything
|
|
17
|
-
* here ends up in the eager module graph (and Vite will
|
|
18
|
-
* its dependencies on every page).
|
|
15
|
+
* This file is intentionally light. The router needs the route definition
|
|
16
|
+
* at startup to build the tree for URL matching, so anything *statically*
|
|
17
|
+
* imported here ends up in the eager module graph (and Vite will
|
|
18
|
+
* modulepreload its dependencies on every page).
|
|
19
19
|
*
|
|
20
|
-
* The component, providers, Byline UI stylesheets
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* The component, providers, and Byline UI stylesheets live in the sibling
|
|
21
|
+
* `route.lazy.tsx` — TanStack Router loads that file on demand when a
|
|
22
|
+
* `_byline/*` URL matches, so the editor + admin shell deps stay out of
|
|
23
|
+
* public-route bundles.
|
|
24
|
+
*
|
|
25
|
+
* Registering the Byline client config has two complementary entry points
|
|
26
|
+
* (both call `defineClientConfig` idempotently):
|
|
27
|
+
* - the `beforeLoad` below — covers the *loader* phase, resolving before any
|
|
28
|
+
* `_byline/*` child loader reads the config (e.g. the admin dashboard
|
|
29
|
+
* loader's `getClientConfig()`);
|
|
30
|
+
* - the side-effect import in `route.lazy.tsx` — covers component render /
|
|
31
|
+
* initial hydration, where `beforeLoad` is not re-run.
|
|
32
|
+
* Both use `byline/admin.config` (a dynamic import here), so its module graph
|
|
33
|
+
* (incl. the Lexical editor) stays code-split out of the eager/public bundle.
|
|
24
34
|
*/
|
|
25
35
|
|
|
26
36
|
import { createFileRoute } from '@tanstack/react-router'
|
|
27
37
|
|
|
28
|
-
export const Route = createFileRoute('/_byline')({
|
|
38
|
+
export const Route = createFileRoute('/_byline')({
|
|
39
|
+
beforeLoad: async () => {
|
|
40
|
+
// Register the Byline client config (`defineClientConfig` runs as a
|
|
41
|
+
// side-effect of importing `byline/admin.config`) before any `_byline/*`
|
|
42
|
+
// child loader reads it. A parent route's `beforeLoad` resolves before its
|
|
43
|
+
// children's loaders, closing the dev race where a loader outran the lazy
|
|
44
|
+
// component module's side-effect import (on the client there is no
|
|
45
|
+
// server-config fallback, so `getClientConfig()` threw "Byline has not been
|
|
46
|
+
// configured yet"). The dynamic import keeps `admin.config` out of the
|
|
47
|
+
// eager/public bundle and evaluates once (cached). NOTE: `beforeLoad` is
|
|
48
|
+
// not re-run on initial client hydration (the SSR result is dehydrated), so
|
|
49
|
+
// the `route.lazy.tsx` side-effect import registers the config for the
|
|
50
|
+
// hydrated component render.
|
|
51
|
+
await import('../../../byline/admin.config')
|
|
52
|
+
},
|
|
53
|
+
})
|
package/package.json
CHANGED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
-
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
-
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
-
*
|
|
6
|
-
* Copyright (c) Infonomic Company Limited
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* **Schema-side helper.** Returns a `GroupField` schema that emits one
|
|
11
|
-
* `checkbox` field per configured content locale. Drop the result into
|
|
12
|
-
* a collection's `fields` array in `<collection>/schema.ts`. Pure data;
|
|
13
|
-
* the only imports are `@byline/core` types and the i18n locale list.
|
|
14
|
-
*
|
|
15
|
-
* See `docs/FIELDS.md` for the schema-vs-admin model.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import type { GroupField } from '@byline/core'
|
|
19
|
-
|
|
20
|
-
import { contentLocales, type LocaleDefinition } from '../i18n.js'
|
|
21
|
-
|
|
22
|
-
type Options = Partial<Omit<GroupField, 'type' | 'fields'>> & {
|
|
23
|
-
locales?: readonly LocaleDefinition[]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
type LocaleFields<T extends readonly LocaleDefinition[]> = {
|
|
27
|
-
[K in keyof T]: {
|
|
28
|
-
name: T[K]['code']
|
|
29
|
-
label: T[K]['label']
|
|
30
|
-
type: 'checkbox'
|
|
31
|
-
optional: true
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type WithOverride<O, K extends string, V, D> = O extends { [P in K]: V } ? O[K] : D
|
|
36
|
-
|
|
37
|
-
type AvailableLanguagesField<Opts extends Options> = Omit<GroupField, 'name' | 'fields'> & {
|
|
38
|
-
name: WithOverride<Opts, 'name', string, 'availableLanguages'>
|
|
39
|
-
fields: LocaleFields<
|
|
40
|
-
WithOverride<Opts, 'locales', readonly LocaleDefinition[], typeof contentLocales>
|
|
41
|
-
>
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const builtInValidate = (value: Record<string, boolean> | undefined): string | undefined => {
|
|
45
|
-
const hasSelection =
|
|
46
|
-
value != null &&
|
|
47
|
-
typeof value === 'object' &&
|
|
48
|
-
!Array.isArray(value) &&
|
|
49
|
-
Object.values(value).some(Boolean)
|
|
50
|
-
if (!hasSelection) {
|
|
51
|
-
return 'At least one language must be selected'
|
|
52
|
-
}
|
|
53
|
-
return undefined
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Returns a `GroupField` that renders one checkbox per locale entry.
|
|
58
|
-
* Validation requires at least one language to be selected; if the caller
|
|
59
|
-
* supplies its own `validate`, the built-in rule runs first and the caller's
|
|
60
|
-
* validator only runs when the built-in passes.
|
|
61
|
-
*
|
|
62
|
-
* @description This field is intended for use in a document's "Edit" view
|
|
63
|
-
* to allow editors to specify which languages a document is available in.
|
|
64
|
-
* It is orthogonal to the defined workflow system and is here as a 'signal'
|
|
65
|
-
* to frontend websites / consumers - allowing them to implement their own
|
|
66
|
-
* logic around content availability per language.
|
|
67
|
-
*
|
|
68
|
-
* @param options - Optional overrides. Accepts any `GroupField` property
|
|
69
|
-
* except `type` and `fields` (which are computed), plus a `locales` array
|
|
70
|
-
* that drives the generated checkbox set.
|
|
71
|
-
*/
|
|
72
|
-
export function availableLanguagesField<const Opts extends Options>(
|
|
73
|
-
options: Opts = {} as Opts
|
|
74
|
-
): AvailableLanguagesField<Opts> {
|
|
75
|
-
const { name, label, helpText, locales, validate: userValidate, ...rest } = options
|
|
76
|
-
|
|
77
|
-
const validate = userValidate
|
|
78
|
-
? (value: any, data: Record<string, any>) => {
|
|
79
|
-
const builtInError = builtInValidate(value)
|
|
80
|
-
if (builtInError) return builtInError
|
|
81
|
-
return userValidate(value, data)
|
|
82
|
-
}
|
|
83
|
-
: builtInValidate
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
...rest,
|
|
87
|
-
name: (name ?? 'availableLanguages') as any,
|
|
88
|
-
label: label ?? 'Published Languages',
|
|
89
|
-
helpText: helpText ?? 'Select the languages this document is available in.',
|
|
90
|
-
type: 'group',
|
|
91
|
-
fields: (locales ?? contentLocales).map(({ code, label }) => ({
|
|
92
|
-
name: code,
|
|
93
|
-
label,
|
|
94
|
-
type: 'checkbox' as const,
|
|
95
|
-
optional: true,
|
|
96
|
-
})) as any,
|
|
97
|
-
validate,
|
|
98
|
-
}
|
|
99
|
-
}
|