@byline/cli 0.1.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/LICENSE +373 -0
- package/README.md +23 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +72 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +36 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +76 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/context.d.ts +38 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +37 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/pg-url.d.ts +11 -0
- package/dist/lib/pg-url.d.ts.map +1 -0
- package/dist/lib/pg-url.js +22 -0
- package/dist/lib/pg-url.js.map +1 -0
- package/dist/manifest/deps.d.ts +29 -0
- package/dist/manifest/deps.d.ts.map +1 -0
- package/dist/manifest/deps.js +97 -0
- package/dist/manifest/deps.js.map +1 -0
- package/dist/manifest/env.d.ts +18 -0
- package/dist/manifest/env.d.ts.map +1 -0
- package/dist/manifest/env.js +38 -0
- package/dist/manifest/env.js.map +1 -0
- package/dist/phases/db-init.d.ts +3 -0
- package/dist/phases/db-init.d.ts.map +1 -0
- package/dist/phases/db-init.js +163 -0
- package/dist/phases/db-init.js.map +1 -0
- package/dist/phases/db.d.ts +11 -0
- package/dist/phases/db.d.ts.map +1 -0
- package/dist/phases/db.js +93 -0
- package/dist/phases/db.js.map +1 -0
- package/dist/phases/deps.d.ts +3 -0
- package/dist/phases/deps.d.ts.map +1 -0
- package/dist/phases/deps.js +115 -0
- package/dist/phases/deps.js.map +1 -0
- package/dist/phases/env.d.ts +3 -0
- package/dist/phases/env.d.ts.map +1 -0
- package/dist/phases/env.js +172 -0
- package/dist/phases/env.js.map +1 -0
- package/dist/phases/host.d.ts +3 -0
- package/dist/phases/host.d.ts.map +1 -0
- package/dist/phases/host.js +99 -0
- package/dist/phases/host.js.map +1 -0
- package/dist/phases/index.d.ts +7 -0
- package/dist/phases/index.d.ts.map +1 -0
- package/dist/phases/index.js +40 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/phases/preflight.d.ts +4 -0
- package/dist/phases/preflight.d.ts.map +1 -0
- package/dist/phases/preflight.js +81 -0
- package/dist/phases/preflight.js.map +1 -0
- package/dist/phases/routes.d.ts +3 -0
- package/dist/phases/routes.d.ts.map +1 -0
- package/dist/phases/routes.js +145 -0
- package/dist/phases/routes.js.map +1 -0
- package/dist/phases/scaffold.d.ts +3 -0
- package/dist/phases/scaffold.d.ts.map +1 -0
- package/dist/phases/scaffold.js +113 -0
- package/dist/phases/scaffold.js.map +1 -0
- package/dist/phases/stub.d.ts +3 -0
- package/dist/phases/stub.d.ts.map +1 -0
- package/dist/phases/stub.js +25 -0
- package/dist/phases/stub.js.map +1 -0
- package/dist/phases/ui.d.ts +3 -0
- package/dist/phases/ui.d.ts.map +1 -0
- package/dist/phases/ui.js +93 -0
- package/dist/phases/ui.js.map +1 -0
- package/dist/phases/wire/index.d.ts +3 -0
- package/dist/phases/wire/index.d.ts.map +1 -0
- package/dist/phases/wire/index.js +67 -0
- package/dist/phases/wire/index.js.map +1 -0
- package/dist/phases/wire/root-tsx.d.ts +3 -0
- package/dist/phases/wire/root-tsx.d.ts.map +1 -0
- package/dist/phases/wire/root-tsx.js +57 -0
- package/dist/phases/wire/root-tsx.js.map +1 -0
- package/dist/phases/wire/server-ts.d.ts +3 -0
- package/dist/phases/wire/server-ts.d.ts.map +1 -0
- package/dist/phases/wire/server-ts.js +54 -0
- package/dist/phases/wire/server-ts.js.map +1 -0
- package/dist/phases/wire/shared.d.ts +34 -0
- package/dist/phases/wire/shared.d.ts.map +1 -0
- package/dist/phases/wire/shared.js +2 -0
- package/dist/phases/wire/shared.js.map +1 -0
- package/dist/phases/wire/start-ts.d.ts +3 -0
- package/dist/phases/wire/start-ts.d.ts.map +1 -0
- package/dist/phases/wire/start-ts.js +149 -0
- package/dist/phases/wire/start-ts.js.map +1 -0
- package/dist/phases/wire/tsconfig.d.ts +3 -0
- package/dist/phases/wire/tsconfig.d.ts.map +1 -0
- package/dist/phases/wire/tsconfig.js +105 -0
- package/dist/phases/wire/tsconfig.js.map +1 -0
- package/dist/phases/wire/vite-config.d.ts +3 -0
- package/dist/phases/wire/vite-config.d.ts.map +1 -0
- package/dist/phases/wire/vite-config.js +46 -0
- package/dist/phases/wire/vite-config.js.map +1 -0
- package/dist/prompts.d.ts +34 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +49 -0
- package/dist/prompts.js.map +1 -0
- package/dist/runner.d.ts +5 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +91 -0
- package/dist/runner.js.map +1 -0
- package/dist/state.d.ts +18 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +68 -0
- package/dist/state.js.map +1 -0
- package/dist/templates/byline/admin.config.ts +41 -0
- package/dist/templates/byline/i18n.ts +47 -0
- package/dist/templates/byline/routes.ts +28 -0
- package/dist/templates/byline/seed.ts +19 -0
- package/dist/templates/byline/seeds/admin.ts +62 -0
- package/dist/templates/byline/server.config.ts +92 -0
- package/dist/templates/byline-examples/admin.config.ts +74 -0
- package/dist/templates/byline-examples/blocks/photo-block.ts +59 -0
- package/dist/templates/byline-examples/blocks/richtext-block.ts +35 -0
- package/dist/templates/byline-examples/collections/doc-example-flat-locale-all.ts +373 -0
- package/dist/templates/byline-examples/collections/doc-example-flat-locale-en.ts +283 -0
- package/dist/templates/byline-examples/collections/doc-example-tree-locale-all.ts +278 -0
- package/dist/templates/byline-examples/collections/doc-example-tree-locale-en.ts +205 -0
- package/dist/templates/byline-examples/collections/docs/admin.tsx +204 -0
- package/dist/templates/byline-examples/collections/docs/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs/components/feature-formatter.tsx +10 -0
- package/dist/templates/byline-examples/collections/docs/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs/index.ts +10 -0
- package/dist/templates/byline-examples/collections/docs/schema.ts +209 -0
- package/dist/templates/byline-examples/collections/docs-categories/admin.tsx +78 -0
- package/dist/templates/byline-examples/collections/docs-categories/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs-categories/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs-categories/index.ts +10 -0
- package/dist/templates/byline-examples/collections/docs-categories/schema.ts +33 -0
- package/dist/templates/byline-examples/collections/media/admin.tsx +188 -0
- package/dist/templates/byline-examples/collections/media/components/media-list-view.tsx +330 -0
- package/dist/templates/byline-examples/collections/media/components/media-thumbnail.tsx +63 -0
- package/dist/templates/byline-examples/collections/media/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/media/index.ts +10 -0
- package/dist/templates/byline-examples/collections/media/schema.ts +157 -0
- package/dist/templates/byline-examples/collections/news/admin.tsx +192 -0
- package/dist/templates/byline-examples/collections/news/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news/index.ts +10 -0
- package/dist/templates/byline-examples/collections/news/schema.ts +91 -0
- package/dist/templates/byline-examples/collections/news-categories/admin.tsx +78 -0
- package/dist/templates/byline-examples/collections/news-categories/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news-categories/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news-categories/index.ts +10 -0
- package/dist/templates/byline-examples/collections/news-categories/schema.ts +33 -0
- package/dist/templates/byline-examples/collections/pages/admin.tsx +183 -0
- package/dist/templates/byline-examples/collections/pages/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/pages/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/pages/index.ts +10 -0
- package/dist/templates/byline-examples/collections/pages/schema.ts +96 -0
- package/dist/templates/byline-examples/components/length-indicator.tsx +138 -0
- package/dist/templates/byline-examples/components/pill.tsx +38 -0
- package/dist/templates/byline-examples/components/summary-length.tsx +39 -0
- package/dist/templates/byline-examples/fields/available-languages-field.ts +90 -0
- package/dist/templates/byline-examples/fields/lexical-richtext-compact.ts +88 -0
- package/dist/templates/byline-examples/i18n.ts +47 -0
- package/dist/templates/byline-examples/routes.ts +28 -0
- package/dist/templates/byline-examples/scripts/regenerate-media.ts +275 -0
- package/dist/templates/byline-examples/seed.ts +25 -0
- package/dist/templates/byline-examples/seeds/admin.ts +62 -0
- package/dist/templates/byline-examples/seeds/doc-categories.ts +71 -0
- package/dist/templates/byline-examples/seeds/docs.ts +293 -0
- package/dist/templates/byline-examples/seeds/news-categories.ts +71 -0
- package/dist/templates/byline-examples/server.config.ts +179 -0
- package/dist/templates/host/vite.config.ts +41 -0
- package/dist/templates/migrations/0000_condemned_kronos.sql +324 -0
- package/dist/templates/migrations/0001_sudden_phantom_reporter.sql +1 -0
- package/dist/templates/migrations/meta/0000_snapshot.json +2793 -0
- package/dist/templates/migrations/meta/0001_snapshot.json +2799 -0
- package/dist/templates/migrations/meta/_journal.json +20 -0
- package/dist/templates/routes/(byline)/admin/account/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/$id/api.tsx +16 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/$id/history.tsx +19 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/$id/index.tsx +16 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/create.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/permissions/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/roles/$id/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/roles/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/route.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/users/$id/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/users/index.tsx +11 -0
- package/dist/templates/routes/(byline)/sign-in.tsx +11 -0
- package/dist/templates/ui-byline/blocks/photo-block/index.tsx +80 -0
- package/dist/templates/ui-byline/blocks/richtext-block/index.tsx +46 -0
- package/dist/templates/ui-byline/components/admonition/index.tsx +40 -0
- package/dist/templates/ui-byline/components/code/code-serializer.tsx +20 -0
- package/dist/templates/ui-byline/components/code/code.tsx +50 -0
- package/dist/templates/ui-byline/components/code/index.module.scss +137 -0
- package/dist/templates/ui-byline/components/code/index.ts +2 -0
- package/dist/templates/ui-byline/components/code/types.ts +5 -0
- package/dist/templates/ui-byline/components/code/utils.ts +20 -0
- package/dist/templates/ui-byline/components/heading-anchor/heading-anchor.tsx +69 -0
- package/dist/templates/ui-byline/components/heading-anchor/index.ts +1 -0
- package/dist/templates/ui-byline/components/heading-anchor/utils.ts +15 -0
- package/dist/templates/ui-byline/components/inline-image/index.tsx +109 -0
- package/dist/templates/ui-byline/components/layout/index.tsx +63 -0
- package/dist/templates/ui-byline/components/link/lang-link.tsx +70 -0
- package/dist/templates/ui-byline/components/link/link-field.tsx +298 -0
- package/dist/templates/ui-byline/components/link/link-lexical.tsx +191 -0
- package/dist/templates/ui-byline/components/list/index.ts +2 -0
- package/dist/templates/ui-byline/components/list/list-item.tsx +32 -0
- package/dist/templates/ui-byline/components/list/list.tsx +17 -0
- package/dist/templates/ui-byline/components/responsive-image/index.tsx +205 -0
- package/dist/templates/ui-byline/components/richtext-lexical/index.tsx +31 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/index.tsx +249 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/richtext-node-formats.ts +66 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/types.ts +48 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/utils.ts +15 -0
- package/dist/templates/ui-byline/components/table-cell/index.tsx +36 -0
- package/dist/templates/ui-byline/components/vimeo/index.tsx +21 -0
- package/dist/templates/ui-byline/components/youtube/index.tsx +22 -0
- package/dist/templates/ui-byline/render-blocks.tsx +71 -0
- package/dist/templates/ui-byline/types/i18n.ts +14 -0
- package/dist/templates/ui-byline/utils/image-sources.ts +102 -0
- package/dist/templates/ui-byline/utils/to-kebab-case.ts +5 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/diff.d.ts +4 -0
- package/dist/ui/diff.d.ts.map +1 -0
- package/dist/ui/diff.js +23 -0
- package/dist/ui/diff.js.map +1 -0
- package/dist/ui/grid.d.ts +7 -0
- package/dist/ui/grid.d.ts.map +1 -0
- package/dist/ui/grid.js +24 -0
- package/dist/ui/grid.js.map +1 -0
- package/dist/ui/logger.d.ts +14 -0
- package/dist/ui/logger.d.ts.map +1 -0
- package/dist/ui/logger.js +30 -0
- package/dist/ui/logger.js.map +1 -0
- package/dist/ui/snippet.d.ts +2 -0
- package/dist/ui/snippet.d.ts.map +1 -0
- package/dist/ui/snippet.js +7 -0
- package/dist/ui/snippet.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,293 @@
|
|
|
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
|
+
import { getCollectionDefinition, getDefaultStatus, getServerConfig, slugify } from '@byline/core'
|
|
10
|
+
|
|
11
|
+
// Complex test document with many fields and arrays. The system `path`
|
|
12
|
+
// is supplied separately to `createDocumentVersion` as a top-level
|
|
13
|
+
// argument — it is no longer a user-defined field.
|
|
14
|
+
const sampleDocument = {
|
|
15
|
+
title: {
|
|
16
|
+
en: 'My First Document',
|
|
17
|
+
es: 'Mi Primer Documento',
|
|
18
|
+
},
|
|
19
|
+
summary: {
|
|
20
|
+
en: 'This is a sample document for testing purposes.',
|
|
21
|
+
es: 'Este es un documento de muestra para fines de prueba.',
|
|
22
|
+
},
|
|
23
|
+
// category: {
|
|
24
|
+
// targetCollectionId: "cat-123",
|
|
25
|
+
// targetDocumentId: "electronics-audio"
|
|
26
|
+
// },
|
|
27
|
+
featured: false,
|
|
28
|
+
publishedOn: new Date('2024-01-15T10:00:00'),
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
_type: 'richTextBlock',
|
|
32
|
+
richText: {
|
|
33
|
+
en: {
|
|
34
|
+
root: {
|
|
35
|
+
children: [
|
|
36
|
+
{
|
|
37
|
+
children: [
|
|
38
|
+
{
|
|
39
|
+
detail: 0,
|
|
40
|
+
format: 0,
|
|
41
|
+
mode: 'normal',
|
|
42
|
+
style: '',
|
|
43
|
+
text: 'Some richtext here...',
|
|
44
|
+
type: 'text',
|
|
45
|
+
version: 1,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
direction: 'ltr',
|
|
49
|
+
format: '',
|
|
50
|
+
indent: 0,
|
|
51
|
+
type: 'paragraph',
|
|
52
|
+
version: 1,
|
|
53
|
+
textFormat: 0,
|
|
54
|
+
textStyle: '',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
direction: 'ltr',
|
|
58
|
+
format: '',
|
|
59
|
+
indent: 0,
|
|
60
|
+
type: 'root',
|
|
61
|
+
version: 1,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
es: {
|
|
65
|
+
root: {
|
|
66
|
+
children: [
|
|
67
|
+
{
|
|
68
|
+
children: [
|
|
69
|
+
{
|
|
70
|
+
detail: 0,
|
|
71
|
+
format: 0,
|
|
72
|
+
mode: 'normal',
|
|
73
|
+
style: '',
|
|
74
|
+
text: 'Aquí hay un campo de texto enriquecido...',
|
|
75
|
+
type: 'text',
|
|
76
|
+
version: 1,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
direction: 'ltr',
|
|
80
|
+
format: '',
|
|
81
|
+
indent: 0,
|
|
82
|
+
type: 'paragraph',
|
|
83
|
+
version: 1,
|
|
84
|
+
textFormat: 0,
|
|
85
|
+
textStyle: '',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
direction: 'ltr',
|
|
89
|
+
format: '',
|
|
90
|
+
indent: 0,
|
|
91
|
+
type: 'root',
|
|
92
|
+
version: 1,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
constrainedWidth: true,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
_type: 'photoBlock',
|
|
100
|
+
display: 'wide',
|
|
101
|
+
alt: 'Some alt text here',
|
|
102
|
+
caption: {
|
|
103
|
+
en: {
|
|
104
|
+
root: {
|
|
105
|
+
children: [
|
|
106
|
+
{
|
|
107
|
+
children: [
|
|
108
|
+
{
|
|
109
|
+
detail: 0,
|
|
110
|
+
format: 0,
|
|
111
|
+
mode: 'normal',
|
|
112
|
+
style: '',
|
|
113
|
+
text: 'Here is a richtext field Here is a richtext field Here is a richtext field Here is a rich text field.',
|
|
114
|
+
type: 'text',
|
|
115
|
+
version: 1,
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
direction: 'ltr',
|
|
119
|
+
format: '',
|
|
120
|
+
indent: 0,
|
|
121
|
+
type: 'paragraph',
|
|
122
|
+
version: 1,
|
|
123
|
+
textFormat: 0,
|
|
124
|
+
textStyle: '',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
direction: 'ltr',
|
|
128
|
+
format: '',
|
|
129
|
+
indent: 0,
|
|
130
|
+
type: 'root',
|
|
131
|
+
version: 1,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
es: {
|
|
135
|
+
root: {
|
|
136
|
+
children: [
|
|
137
|
+
{
|
|
138
|
+
children: [
|
|
139
|
+
{
|
|
140
|
+
detail: 0,
|
|
141
|
+
format: 0,
|
|
142
|
+
mode: 'normal',
|
|
143
|
+
style: '',
|
|
144
|
+
text: 'Aquí hay un campo de texto enriquecido. Aquí hay un campo de texto enriquecido. Aquí hay un campo de texto enriquecido. Aquí hay un campo de texto enriquecido.',
|
|
145
|
+
type: 'text',
|
|
146
|
+
version: 1,
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
direction: 'ltr',
|
|
150
|
+
format: '',
|
|
151
|
+
indent: 0,
|
|
152
|
+
type: 'paragraph',
|
|
153
|
+
version: 1,
|
|
154
|
+
textFormat: 0,
|
|
155
|
+
textStyle: '',
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
direction: 'ltr',
|
|
159
|
+
format: '',
|
|
160
|
+
indent: 0,
|
|
161
|
+
type: 'root',
|
|
162
|
+
version: 1,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
reviews: [
|
|
169
|
+
{
|
|
170
|
+
reviewItem: {
|
|
171
|
+
rating: 5,
|
|
172
|
+
comment: {
|
|
173
|
+
root: {
|
|
174
|
+
children: [
|
|
175
|
+
{
|
|
176
|
+
children: [
|
|
177
|
+
{
|
|
178
|
+
detail: 0,
|
|
179
|
+
format: 0,
|
|
180
|
+
mode: 'normal',
|
|
181
|
+
style: '',
|
|
182
|
+
text: 'Some review text here...',
|
|
183
|
+
type: 'text',
|
|
184
|
+
version: 1,
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
direction: 'ltr',
|
|
188
|
+
format: '',
|
|
189
|
+
indent: 0,
|
|
190
|
+
type: 'paragraph',
|
|
191
|
+
version: 1,
|
|
192
|
+
textFormat: 0,
|
|
193
|
+
textStyle: '',
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
direction: 'ltr',
|
|
197
|
+
format: '',
|
|
198
|
+
indent: 0,
|
|
199
|
+
type: 'root',
|
|
200
|
+
version: 1,
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
reviewItem: {
|
|
207
|
+
rating: 3,
|
|
208
|
+
comment: {
|
|
209
|
+
root: {
|
|
210
|
+
children: [
|
|
211
|
+
{
|
|
212
|
+
children: [
|
|
213
|
+
{
|
|
214
|
+
detail: 0,
|
|
215
|
+
format: 0,
|
|
216
|
+
mode: 'normal',
|
|
217
|
+
style: '',
|
|
218
|
+
text: 'Some review text here...',
|
|
219
|
+
type: 'text',
|
|
220
|
+
version: 1,
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
direction: 'ltr',
|
|
224
|
+
format: '',
|
|
225
|
+
indent: 0,
|
|
226
|
+
type: 'paragraph',
|
|
227
|
+
version: 1,
|
|
228
|
+
textFormat: 0,
|
|
229
|
+
textStyle: '',
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
direction: 'ltr',
|
|
233
|
+
format: '',
|
|
234
|
+
indent: 0,
|
|
235
|
+
type: 'root',
|
|
236
|
+
version: 1,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
links: [{ link: 'https://example.com' }, { link: 'https://another-example.com' }],
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export async function seedDocs(count = 1000) {
|
|
246
|
+
const db = getServerConfig().db
|
|
247
|
+
|
|
248
|
+
const collectionDefinition = getCollectionDefinition('docs')
|
|
249
|
+
|
|
250
|
+
if (!collectionDefinition) {
|
|
251
|
+
console.error('Collection definition not found for "docs"')
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// `initBylineCore` already registered the collection row via
|
|
256
|
+
// `ensureCollections()` when byline/server.config was imported, so we
|
|
257
|
+
// look the row up rather than re-inserting (which would violate the
|
|
258
|
+
// unique-path constraint).
|
|
259
|
+
const existing = await db.queries.collections.getCollectionByPath('docs')
|
|
260
|
+
if (!existing) {
|
|
261
|
+
throw new Error(
|
|
262
|
+
"seedDocuments: expected the 'docs' collection to be registered by initBylineCore()"
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const bulkDocsCollection = {
|
|
267
|
+
id: existing.id as string,
|
|
268
|
+
name: existing.path as string,
|
|
269
|
+
version: (existing.version as number | undefined) ?? 1,
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
console.log(`Seeding into Docs collection (${bulkDocsCollection.name})`)
|
|
273
|
+
|
|
274
|
+
for (let i = 0; i < count; i++) {
|
|
275
|
+
const docData = structuredClone(sampleDocument)
|
|
276
|
+
docData.title.en = `A bulk created document. ${i + 1}` // Ensure unique names
|
|
277
|
+
const seedPath = slugify(docData.title.en, {
|
|
278
|
+
locale: 'en',
|
|
279
|
+
collectionPath: 'docs',
|
|
280
|
+
})
|
|
281
|
+
await db.commands.documents.createDocumentVersion({
|
|
282
|
+
collectionId: bulkDocsCollection.id,
|
|
283
|
+
collectionVersion: bulkDocsCollection.version,
|
|
284
|
+
collectionConfig: collectionDefinition,
|
|
285
|
+
action: 'create',
|
|
286
|
+
documentData: docData,
|
|
287
|
+
path: seedPath,
|
|
288
|
+
status: getDefaultStatus(collectionDefinition),
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
console.log(` - seeded ${count} docs`)
|
|
293
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
import { getCollectionDefinition, getDefaultStatus, getServerConfig, slugify } from '@byline/core'
|
|
10
|
+
|
|
11
|
+
const categories = [
|
|
12
|
+
{
|
|
13
|
+
name: { en: 'Local' },
|
|
14
|
+
description: { en: 'Hyper-local news.' },
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: { en: 'Regional' },
|
|
18
|
+
description: { en: 'News and updates from the surrounding region.' },
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: { en: 'World' },
|
|
22
|
+
description: { en: 'International news and updates.' },
|
|
23
|
+
},
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
export async function seedNewsCategories() {
|
|
27
|
+
const db = getServerConfig().db
|
|
28
|
+
|
|
29
|
+
const collectionDefinition = getCollectionDefinition('news-categories')
|
|
30
|
+
|
|
31
|
+
if (!collectionDefinition) {
|
|
32
|
+
console.error('Collection definition not found for "news-categories"')
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// `initBylineCore` already registered the collection row via
|
|
37
|
+
// `ensureCollections()` when byline/server.config was imported, so we
|
|
38
|
+
// look the row up rather than re-inserting (which would violate the
|
|
39
|
+
// unique-path constraint).
|
|
40
|
+
const existing = await db.queries.collections.getCollectionByPath('news-categories')
|
|
41
|
+
if (!existing) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
"seedNewsCategories: expected the 'news-categories' collection to be registered by initBylineCore()"
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const categoriesCollection = {
|
|
48
|
+
id: existing.id as string,
|
|
49
|
+
name: existing.path as string,
|
|
50
|
+
version: (existing.version as number | undefined) ?? 1,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log(`Seeding into News Categories collection (${categoriesCollection.name})`)
|
|
54
|
+
|
|
55
|
+
for (const category of categories) {
|
|
56
|
+
const seedPath = slugify(category.name.en, {
|
|
57
|
+
locale: 'en',
|
|
58
|
+
collectionPath: 'news-categories',
|
|
59
|
+
})
|
|
60
|
+
await db.commands.documents.createDocumentVersion({
|
|
61
|
+
collectionId: categoriesCollection.id,
|
|
62
|
+
collectionVersion: categoriesCollection.version,
|
|
63
|
+
collectionConfig: collectionDefinition,
|
|
64
|
+
action: 'create',
|
|
65
|
+
documentData: category,
|
|
66
|
+
path: seedPath,
|
|
67
|
+
status: getDefaultStatus(collectionDefinition),
|
|
68
|
+
})
|
|
69
|
+
console.log(` - seeded category: ${category.name.en} (${seedPath})`)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
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
|
+
* Server-side Byline bootstrap. Imported as a side-effect from
|
|
11
|
+
* `src/server.ts` (and from any seed / migration script that needs the
|
|
12
|
+
* configured runtime). Resolves the composed `BylineCore` and registers
|
|
13
|
+
* it on the process global via `initBylineCore()` — server-side callers
|
|
14
|
+
* read it back with `getBylineCore<AdminStore>()`.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type AdminStore, registerAdminAbilities } from '@byline/admin'
|
|
18
|
+
import { JwtSessionProvider } from '@byline/admin/auth'
|
|
19
|
+
import { type BylineCore, initBylineCore } from '@byline/core'
|
|
20
|
+
import { pgAdapter } from '@byline/db-postgres'
|
|
21
|
+
import { createAdminStore } from '@byline/db-postgres/admin'
|
|
22
|
+
import { getAdminBylineClient } from '@byline/host-tanstack-start/integrations/byline-client'
|
|
23
|
+
import { lexicalEditorServer } from '@byline/richtext-lexical/server'
|
|
24
|
+
import { localStorageProvider } from '@byline/storage-local'
|
|
25
|
+
|
|
26
|
+
// Import collection definitions directly from schema files — NOT the full
|
|
27
|
+
// admin config or index barrels. The admin config / index files pull in
|
|
28
|
+
// admin UI configs (React components, CSS modules) that are not loadable
|
|
29
|
+
// outside Vite (e.g. when running seeds via tsx).
|
|
30
|
+
import { Docs } from './collections/docs/schema.js'
|
|
31
|
+
import { DocsCategories } from './collections/docs-categories/schema.js'
|
|
32
|
+
import { Media } from './collections/media/schema.js'
|
|
33
|
+
import { News } from './collections/news/schema.js'
|
|
34
|
+
import { NewsCategories } from './collections/news-categories/schema.js'
|
|
35
|
+
import { Pages } from './collections/pages/schema.js'
|
|
36
|
+
import { i18n } from './i18n.js'
|
|
37
|
+
import { DEFAULT_SERVER_URL, routes } from './routes.js'
|
|
38
|
+
|
|
39
|
+
const serverURL = process.env.VITE_SERVER_URL || DEFAULT_SERVER_URL
|
|
40
|
+
|
|
41
|
+
const collections = [Docs, News, Pages, Media, DocsCategories, NewsCategories]
|
|
42
|
+
|
|
43
|
+
// HMR-safe singleton. Vite's program reload re-evaluates this module
|
|
44
|
+
// without disposing the previous module's resources — every reload
|
|
45
|
+
// would otherwise allocate a fresh pg `Pool` (max: 20) inside
|
|
46
|
+
// `pgAdapter`, the previous pool would orphan but stay alive, and
|
|
47
|
+
// after a handful of HMR cycles Postgres' `max_connections` is
|
|
48
|
+
// exhausted and every query fails with `53300 sorry, too many clients
|
|
49
|
+
// already`. Stashing the resolving `Promise` (so concurrent reloads
|
|
50
|
+
// converge on one build) lets module reloads reuse the same pool.
|
|
51
|
+
// Production has no HMR so this guard is a no-op there.
|
|
52
|
+
declare global {
|
|
53
|
+
// biome-ignore lint: globalThis augmentation requires `var` rather than `let`
|
|
54
|
+
var __bylineCoreSingleton__: Promise<BylineCore<AdminStore>> | undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function buildBylineCore(): Promise<BylineCore<AdminStore>> {
|
|
58
|
+
// Construct the db adapter up-front so we can thread its drizzle handle
|
|
59
|
+
// into the session provider without a second connection pool. The admin
|
|
60
|
+
// store bundles the four admin repositories (users / roles / permissions
|
|
61
|
+
// / refresh tokens) that `JwtSessionProvider`, the admin-user server
|
|
62
|
+
// fns, and the super-admin seed all consume. Built once here and
|
|
63
|
+
// surfaced on `bylineCore.adminStore` so downstream callers talk to
|
|
64
|
+
// `AdminStore` — the interface — rather than casting the adapter.
|
|
65
|
+
//
|
|
66
|
+
// Future approaches, if/when the wiring grows:
|
|
67
|
+
//
|
|
68
|
+
// Option B — Adapter-owned admin store. Have `pgAdapter()` return
|
|
69
|
+
// `{ ..., adminStore }` directly so the integration point doesn't
|
|
70
|
+
// need the separate `createAdminStore(db.drizzle)` call or the
|
|
71
|
+
// `@byline/db-postgres/admin` import. Widens the adapter contract
|
|
72
|
+
// slightly but removes one more concrete-adapter mention from this
|
|
73
|
+
// file.
|
|
74
|
+
//
|
|
75
|
+
// Option C — Full DI via `@byline/core`'s `Registry`. Register
|
|
76
|
+
// `adminStore` as a typed factory keyed off `db`; adapters
|
|
77
|
+
// contribute the factory, `initBylineCore()` composes it. Most
|
|
78
|
+
// flexible (lazy construction, test wiring, multi-store setups) but
|
|
79
|
+
// heavier until we have a second adapter or a second DI consumer
|
|
80
|
+
// to justify the ceremony.
|
|
81
|
+
const db = pgAdapter({
|
|
82
|
+
connectionString: process.env.DB_CONNECTION_STRING || '',
|
|
83
|
+
collections,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const adminStore = createAdminStore(db.drizzle)
|
|
87
|
+
|
|
88
|
+
// Built-in JWT session provider. Signing secret comes from the
|
|
89
|
+
// environment — see `.env.example`. Phase 5 uses HS256 with Byline's
|
|
90
|
+
// default TTLs (15-minute access, 30-day refresh). Alternative providers
|
|
91
|
+
// (Lucia, better-auth, WorkOS, Clerk, institutional SSO) can be dropped
|
|
92
|
+
// in here by implementing the `SessionProvider` interface from
|
|
93
|
+
// `@byline/auth`.
|
|
94
|
+
const signingSecret = process.env.BYLINE_JWT_SECRET
|
|
95
|
+
if (!signingSecret || signingSecret.length < 32) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
'BYLINE_JWT_SECRET must be set and carry at least 32 bytes of entropy. ' +
|
|
98
|
+
'Generate one with `openssl rand -base64 48` and add it to your .env.'
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const sessionProvider = new JwtSessionProvider({
|
|
103
|
+
store: adminStore,
|
|
104
|
+
signingSecret,
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const core = await initBylineCore<AdminStore>({
|
|
108
|
+
serverURL,
|
|
109
|
+
i18n,
|
|
110
|
+
routes,
|
|
111
|
+
collections,
|
|
112
|
+
db,
|
|
113
|
+
adminStore,
|
|
114
|
+
// Site-wide default storage provider — used by any upload collection
|
|
115
|
+
// that does not specify its own `upload.storage` override.
|
|
116
|
+
//
|
|
117
|
+
// To route a specific collection to a different backend, set `storage`
|
|
118
|
+
// inside that collection's `upload` config block instead of (or in
|
|
119
|
+
// addition to) this site-wide default.
|
|
120
|
+
//
|
|
121
|
+
// Local filesystem is suitable for development and self-hosted
|
|
122
|
+
// deployments. Swap for '@byline/storage-s3' (s3StorageProvider) for
|
|
123
|
+
// cloud/production. The `uploadDir` is served as a static path at
|
|
124
|
+
// `baseUrl` by your web server.
|
|
125
|
+
storage: localStorageProvider({
|
|
126
|
+
uploadDir: './public/uploads',
|
|
127
|
+
baseUrl: '/uploads',
|
|
128
|
+
}),
|
|
129
|
+
sessionProvider,
|
|
130
|
+
fields: {
|
|
131
|
+
// Server-side richtext adapter — refreshes embedded relation
|
|
132
|
+
// envelopes (link `{ title, path }`, inline-image `{ title, altText,
|
|
133
|
+
// image, sizes }`) on every read, gated per-field by
|
|
134
|
+
// `populateRelationsOnRead`. See docs/RICHTEXT.md for the full design.
|
|
135
|
+
//
|
|
136
|
+
// `getClient` returns a `BylineClient` — the SDK over the storage
|
|
137
|
+
// primitives that the populate visitors use to batch-fetch target
|
|
138
|
+
// documents (e.g. `client.collection('media').find({ where: { id:
|
|
139
|
+
// { $in: [...] } } })`). The client carries the DB adapter, the
|
|
140
|
+
// collection registry, the request-context resolver, and every
|
|
141
|
+
// read-pipeline phase (`beforeRead` → populate → `afterRead`), so
|
|
142
|
+
// populate's nested reads run under the *same* authenticated actor
|
|
143
|
+
// and the *same* `ReadContext` as the request that triggered them.
|
|
144
|
+
// That's what makes A→B→A cycle protection and visited-set dedup
|
|
145
|
+
// work across relation populate, richtext populate, and any user-
|
|
146
|
+
// land `afterRead` hooks.
|
|
147
|
+
//
|
|
148
|
+
// We pass `getAdminBylineClient` (not the public client) because
|
|
149
|
+
// admin server fns are the only call sites that read documents in
|
|
150
|
+
// the admin webapp today — the populate phase inherits whichever
|
|
151
|
+
// actor the request resolved. A future public-facing host would
|
|
152
|
+
// register its own client whose `requestContext` factory resolves
|
|
153
|
+
// an end-user actor instead. See `@byline/host-tanstack-start/
|
|
154
|
+
// integrations/byline-client.ts` for how the admin client is built.
|
|
155
|
+
//
|
|
156
|
+
// Why a getter, not a value: `getAdminBylineClient()` reads the
|
|
157
|
+
// server config singleton, which is only populated *after*
|
|
158
|
+
// `initBylineCore()` returns. Passing a factory defers resolution
|
|
159
|
+
// to populate-call time so registration order here doesn't matter.
|
|
160
|
+
richText: { populate: lexicalEditorServer({ getClient: getAdminBylineClient }) },
|
|
161
|
+
},
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// Register admin-subsystem abilities (admin.users.*, admin.roles.*) on
|
|
165
|
+
// the shared registry. Collection abilities are auto-registered by
|
|
166
|
+
// `initBylineCore()`; admin abilities are opt-in here so `@byline/core`
|
|
167
|
+
// does not depend on `@byline/admin`.
|
|
168
|
+
registerAdminAbilities(core.abilities)
|
|
169
|
+
|
|
170
|
+
return core
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Cache the *Promise*, not the resolved value, so concurrent module
|
|
174
|
+
// loads during a reload race converge on a single build rather than
|
|
175
|
+
// each starting their own. The top-level `await` surfaces init errors
|
|
176
|
+
// at module load time; downstream callers retrieve the resolved core
|
|
177
|
+
// via `getBylineCore<AdminStore>()` from `@byline/core`.
|
|
178
|
+
globalThis.__bylineCoreSingleton__ ??= buildBylineCore()
|
|
179
|
+
await globalThis.__bylineCoreSingleton__
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
|
2
|
+
|
|
3
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
4
|
+
import react from '@vitejs/plugin-react'
|
|
5
|
+
import { defineConfig } from 'vite'
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
server: {
|
|
9
|
+
port: 5173,
|
|
10
|
+
},
|
|
11
|
+
resolve: {
|
|
12
|
+
tsconfigPaths: true,
|
|
13
|
+
},
|
|
14
|
+
ssr: {
|
|
15
|
+
noExternal: ['@byline/ui'],
|
|
16
|
+
// Packages that load platform-specific native `.node` binaries at
|
|
17
|
+
// runtime via dynamic require(). Rollup cannot bundle these, so we
|
|
18
|
+
// keep them external and let Node.js resolve them from node_modules
|
|
19
|
+
// at runtime.
|
|
20
|
+
// - sharp + @byline/storage-local — image processing
|
|
21
|
+
// - @byline/db-postgres — adapter depends on pg native bindings
|
|
22
|
+
external: ['sharp', '@byline/storage-local', '@byline/admin', '@byline/db-postgres'],
|
|
23
|
+
},
|
|
24
|
+
// The same packages need to be kept out of Vite's client-side dep
|
|
25
|
+
// pre-bundling step. TanStack Start strips server-only imports from
|
|
26
|
+
// server-fn modules during its own compile pass, but Vite's
|
|
27
|
+
// `optimizeDeps` runs BEFORE that and tries to pre-bundle anything
|
|
28
|
+
// a client-reachable file imports — including transitive imports
|
|
29
|
+
// reached via `@byline/admin/admin-*` subpath barrels. Excluding the
|
|
30
|
+
// package roots here keeps Vite from touching them on the client side.
|
|
31
|
+
optimizeDeps: {
|
|
32
|
+
exclude: ['sharp', '@byline/storage-local', '@byline/admin', '@byline/db-postgres'],
|
|
33
|
+
},
|
|
34
|
+
plugins: [
|
|
35
|
+
tanstackStart(),
|
|
36
|
+
// NOTE: react() must come AFTER tanstackStart()
|
|
37
|
+
react(),
|
|
38
|
+
tailwindcss(),
|
|
39
|
+
],
|
|
40
|
+
clearScreen: false,
|
|
41
|
+
})
|