@byline/cli 3.20.3 → 3.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/phases/scaffold.d.ts +2 -0
- package/dist/phases/scaffold.d.ts.map +1 -1
- package/dist/phases/scaffold.js +26 -0
- package/dist/phases/scaffold.js.map +1 -1
- package/dist/phases/scaffold.test.d.ts +2 -0
- package/dist/phases/scaffold.test.d.ts.map +1 -0
- package/dist/phases/scaffold.test.js +29 -0
- package/dist/phases/scaffold.test.js.map +1 -0
- package/dist/templates/byline/admin.config.ts +8 -7
- package/dist/templates/byline/client.server.ts +32 -0
- package/dist/templates/byline/collection-types.contract.ts +42 -0
- package/dist/templates/byline/collections/index.ts +17 -0
- package/dist/templates/byline/generated/collection-types.ts +11 -0
- package/dist/templates/byline/i18n.ts +3 -3
- package/dist/templates/byline/locales.ts +9 -9
- package/dist/templates/byline/public.ts +12 -0
- package/dist/templates/byline/scripts/generate-types.ts +81 -0
- package/dist/templates/byline/server.config.ts +3 -5
- package/dist/templates/byline-examples/admin.config.ts +12 -10
- package/dist/templates/byline-examples/client.server.ts +32 -0
- package/dist/templates/byline-examples/collection-types.contract.ts +42 -0
- package/dist/templates/byline-examples/collections/docs/hooks.ts +11 -11
- package/dist/templates/byline-examples/collections/docs/schema.ts +21 -12
- package/dist/templates/byline-examples/collections/index.ts +22 -0
- package/dist/templates/byline-examples/collections/media/schema.ts +13 -0
- package/dist/templates/byline-examples/collections/news/schema.ts +13 -0
- package/dist/templates/byline-examples/collections/news-categories/schema.ts +13 -0
- package/dist/templates/byline-examples/collections/pages/schema.ts +13 -0
- package/dist/templates/byline-examples/generated/collection-types.ts +139 -0
- package/dist/templates/byline-examples/i18n.ts +3 -3
- package/dist/templates/byline-examples/locales.ts +9 -9
- package/dist/templates/byline-examples/public.ts +12 -0
- package/dist/templates/byline-examples/scripts/generate-types.ts +81 -0
- package/dist/templates/byline-examples/server.config.ts +2 -12
- package/dist/templates/routes/_byline/admin/collections/$collection/$id/api.tsx +1 -6
- package/dist/templates/routes/_byline/admin/collections/$collection/$id/history.tsx +1 -7
- package/dist/templates/routes/_byline/admin/collections/$collection/$id/index.tsx +1 -6
- package/dist/templates/ui-byline/blocks/photo-block/index.tsx +1 -2
- package/dist/templates/ui-byline/blocks/richtext-block/index.tsx +1 -1
- package/dist/templates/ui-byline/render-blocks.tsx +3 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,20 @@ byline doctor Inspect the current app and report what's wired.
|
|
|
22
22
|
|
|
23
23
|
See `byline init --help` for the full flag list.
|
|
24
24
|
|
|
25
|
+
### Generated collection types
|
|
26
|
+
|
|
27
|
+
`byline init` commits `byline/generated/collection-types.ts` and adds two application scripts:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
pnpm byline:generate # regenerate after changing collection or block schemas
|
|
31
|
+
pnpm byline:generate:check # fail without writing when the artifact is missing or stale
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The application script evaluates `byline/collections/index.ts`; it does not load
|
|
35
|
+
`server.config.ts`. That collection tuple remains the runtime registry, while the generated module
|
|
36
|
+
is its deterministic, standalone TypeScript projection for typed clients and frontend code. Keep
|
|
37
|
+
the artifact committed and run the check in CI.
|
|
38
|
+
|
|
25
39
|
### Already-wired apps (post-manual-config)
|
|
26
40
|
|
|
27
41
|
If you wired Byline into your app by hand (collections, `server.config.ts`, env, routes, scaffold files all in place) and just need to provision the database and seed, use `setup` instead of `init`:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/phases/scaffold.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/phases/scaffold.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAkBxC,eAAO,MAAM,aAAa,EAAE,KA8D3B,CAAA;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAmB9D"}
|
package/dist/phases/scaffold.js
CHANGED
|
@@ -3,6 +3,10 @@ import { dirname, join, relative } from 'node:path';
|
|
|
3
3
|
const TARGET_DIR = 'byline';
|
|
4
4
|
const BASE_TEMPLATE = 'byline';
|
|
5
5
|
const EXAMPLES_TEMPLATE = 'byline-examples';
|
|
6
|
+
const GENERATION_SCRIPTS = {
|
|
7
|
+
'byline:generate': 'tsx byline/scripts/generate-types.ts',
|
|
8
|
+
'byline:generate:check': 'tsx byline/scripts/generate-types.ts --check',
|
|
9
|
+
};
|
|
6
10
|
export const scaffoldPhase = {
|
|
7
11
|
id: 'scaffold',
|
|
8
12
|
title: 'Scaffold — copy byline/ config tree into the app root',
|
|
@@ -48,9 +52,31 @@ export const scaffoldPhase = {
|
|
|
48
52
|
if (skipped > 0) {
|
|
49
53
|
ctx.logger.info(`${skipped} file(s) already existed and were left untouched — re-running scaffold is non-destructive`);
|
|
50
54
|
}
|
|
55
|
+
const addedScripts = ensureGenerationScripts(ctx);
|
|
56
|
+
if (addedScripts.length > 0) {
|
|
57
|
+
ctx.logger.success(`added package.json scripts: ${addedScripts.join(', ')}`);
|
|
58
|
+
}
|
|
51
59
|
return { state: 'done' };
|
|
52
60
|
},
|
|
53
61
|
};
|
|
62
|
+
export function ensureGenerationScripts(ctx) {
|
|
63
|
+
const packagePath = ctx.resolve('package.json');
|
|
64
|
+
if (!existsSync(packagePath))
|
|
65
|
+
return [];
|
|
66
|
+
const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
|
|
67
|
+
const scripts = { ...(pkg.scripts ?? {}) };
|
|
68
|
+
const added = [];
|
|
69
|
+
for (const [name, command] of Object.entries(GENERATION_SCRIPTS)) {
|
|
70
|
+
if (scripts[name] !== undefined)
|
|
71
|
+
continue;
|
|
72
|
+
scripts[name] = command;
|
|
73
|
+
added.push(name);
|
|
74
|
+
}
|
|
75
|
+
if (added.length === 0)
|
|
76
|
+
return added;
|
|
77
|
+
writeFileSync(packagePath, `${JSON.stringify({ ...pkg, scripts }, null, 2)}\n`, 'utf8');
|
|
78
|
+
return added;
|
|
79
|
+
}
|
|
54
80
|
function collectEntries(ctx, examples, importDocs) {
|
|
55
81
|
const targetRoot = ctx.resolve(TARGET_DIR);
|
|
56
82
|
const baseRoot = join(ctx.templatesDir(), BASE_TEMPLATE);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/phases/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACnG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAKnD,MAAM,UAAU,GAAG,QAAQ,CAAA;AAC3B,MAAM,aAAa,GAAG,QAAQ,CAAA;AAC9B,MAAM,iBAAiB,GAAG,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/phases/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.test.d.ts","sourceRoot":"","sources":["../../src/phases/scaffold.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { ensureGenerationScripts } from './scaffold.js';
|
|
6
|
+
const temporaryDirectories = [];
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
for (const directory of temporaryDirectories.splice(0)) {
|
|
9
|
+
rmSync(directory, { recursive: true, force: true });
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
describe('ensureGenerationScripts', () => {
|
|
13
|
+
it('adds generation commands without replacing an existing script', () => {
|
|
14
|
+
const directory = mkdtempSync(join(tmpdir(), 'byline-scaffold-'));
|
|
15
|
+
temporaryDirectories.push(directory);
|
|
16
|
+
writeFileSync(join(directory, 'package.json'), `${JSON.stringify({ scripts: { 'byline:generate': 'custom-generator' } }, null, 2)}\n`, 'utf8');
|
|
17
|
+
const ctx = {
|
|
18
|
+
resolve: (...parts) => resolve(directory, ...parts),
|
|
19
|
+
};
|
|
20
|
+
expect(ensureGenerationScripts(ctx)).toEqual(['byline:generate:check']);
|
|
21
|
+
const pkg = JSON.parse(readFileSync(join(directory, 'package.json'), 'utf8'));
|
|
22
|
+
expect(pkg.scripts).toEqual({
|
|
23
|
+
'byline:generate': 'custom-generator',
|
|
24
|
+
'byline:generate:check': 'tsx byline/scripts/generate-types.ts --check',
|
|
25
|
+
});
|
|
26
|
+
expect(ensureGenerationScripts(ctx)).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=scaffold.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.test.js","sourceRoot":"","sources":["../../src/phases/scaffold.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAGvD,MAAM,oBAAoB,GAAa,EAAE,CAAA;AAEzC,SAAS,CAAC,GAAG,EAAE;IACb,KAAK,MAAM,SAAS,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAA;QACjE,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACpC,aAAa,CACX,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAC/B,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EACtF,MAAM,CACP,CAAA;QACD,MAAM,GAAG,GAAG;YACV,OAAO,EAAE,CAAC,GAAG,KAAe,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC;SACnD,CAAA;QAEZ,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAA;QACvE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE3E,CAAA;QACD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;YAC1B,iBAAiB,EAAE,kBAAkB;YACrC,uBAAuB,EAAE,8CAA8C;SACxE,CAAC,CAAA;QACF,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -8,20 +8,21 @@
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Registers Byline's client-side config (collection admin UI configs,
|
|
11
|
-
* field editors, i18n, routes) in the current module graph.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* field editors, i18n, routes) in the current module graph. The `_byline`
|
|
12
|
+
* route registers it from two complementary points: a dynamic import in
|
|
13
|
+
* `route.tsx` covers child loaders, while the side-effect import in
|
|
14
|
+
* `route.lazy.tsx` covers component render and initial hydration. Keeping
|
|
15
|
+
* both imports behind `_byline/*` keeps the admin graph off public routes.
|
|
15
16
|
*
|
|
16
17
|
* This is the minimal scaffold: no example collections registered. Add
|
|
17
|
-
*
|
|
18
|
-
* arrays as you create them.
|
|
18
|
+
* schemas to `collections/index.ts` and presentation configs to `admin`.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import type { ClientConfig } from '@byline/core'
|
|
22
22
|
import { defineClientConfig } from '@byline/core'
|
|
23
23
|
import { RichTextField as LexicalRichTextField } from '@byline/richtext-lexical'
|
|
24
24
|
|
|
25
|
+
import { collections } from './collections/index.js'
|
|
25
26
|
import { i18n } from './i18n.js'
|
|
26
27
|
import { DEFAULT_SERVER_URL, routes } from './routes.js'
|
|
27
28
|
|
|
@@ -31,7 +32,7 @@ export const config: ClientConfig = {
|
|
|
31
32
|
serverURL,
|
|
32
33
|
i18n,
|
|
33
34
|
routes,
|
|
34
|
-
collections
|
|
35
|
+
collections,
|
|
35
36
|
admin: [],
|
|
36
37
|
fields: {
|
|
37
38
|
richText: { editor: LexicalRichTextField },
|
|
@@ -0,0 +1,32 @@
|
|
|
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-only application boundary for the host-owned client singletons.
|
|
11
|
+
* The host stays config-agnostic; this assertion binds it to the app registry.
|
|
12
|
+
*/
|
|
13
|
+
import type { BylineClient } from '@byline/client'
|
|
14
|
+
import {
|
|
15
|
+
getAdminBylineClient as getHostAdminBylineClient,
|
|
16
|
+
getSystemBylineClient as getHostSystemBylineClient,
|
|
17
|
+
} from '@byline/host-tanstack-start/integrations/byline-client'
|
|
18
|
+
import { getPublicBylineClient as getHostPublicBylineClient } from '@byline/host-tanstack-start/integrations/byline-public-client'
|
|
19
|
+
import {
|
|
20
|
+
getViewerBylineClient as getHostViewerBylineClient,
|
|
21
|
+
isPreviewActive,
|
|
22
|
+
} from '@byline/host-tanstack-start/integrations/byline-viewer-client'
|
|
23
|
+
|
|
24
|
+
import type { BylineCollections } from './collections/index.js'
|
|
25
|
+
|
|
26
|
+
type AppBylineClient = BylineClient<BylineCollections>
|
|
27
|
+
|
|
28
|
+
export const getAdminBylineClient = getHostAdminBylineClient as () => AppBylineClient
|
|
29
|
+
export const getPublicBylineClient = getHostPublicBylineClient as () => AppBylineClient
|
|
30
|
+
export const getSystemBylineClient = getHostSystemBylineClient as () => AppBylineClient
|
|
31
|
+
export const getViewerBylineClient = getHostViewerBylineClient as () => AppBylineClient
|
|
32
|
+
export { isPreviewActive }
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CollectionFieldData, CollectionFieldDataAllLocales } from '@byline/core'
|
|
2
|
+
|
|
3
|
+
import type { collections } from './collections/index.js'
|
|
4
|
+
import type {
|
|
5
|
+
CollectionFieldsAllLocalesByPath,
|
|
6
|
+
CollectionFieldsByPath,
|
|
7
|
+
} from './generated/collection-types.js'
|
|
8
|
+
|
|
9
|
+
type InferredFieldsByPath = {
|
|
10
|
+
[Definition in (typeof collections)[number] as Definition['path']]: CollectionFieldData<Definition>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type InferredFieldsAllLocalesByPath = {
|
|
14
|
+
[Definition in (typeof collections)[number] as Definition['path']]: CollectionFieldDataAllLocales<Definition>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type IsAny<Value> = 0 extends 1 & Value ? true : false
|
|
18
|
+
type Exact<Left, Right> = IsAny<Left> extends true
|
|
19
|
+
? IsAny<Right>
|
|
20
|
+
: IsAny<Right> extends true
|
|
21
|
+
? false
|
|
22
|
+
: (<Value>() => Value extends Left ? 1 : 2) extends <Value>() =>
|
|
23
|
+
Value extends Right ? 1 : 2
|
|
24
|
+
? (<Value>() => Value extends Right ? 1 : 2) extends <Value>() =>
|
|
25
|
+
Value extends Left ? 1 : 2
|
|
26
|
+
? true
|
|
27
|
+
: false
|
|
28
|
+
: false
|
|
29
|
+
type Assert<Value extends true> = Value
|
|
30
|
+
|
|
31
|
+
type GeneratedKeysMatchRuntimeRegistry = Assert<
|
|
32
|
+
Exact<keyof CollectionFieldsByPath, keyof InferredFieldsByPath>
|
|
33
|
+
>
|
|
34
|
+
type GeneratedFieldsMatchRuntimeRegistry = Assert<
|
|
35
|
+
Exact<CollectionFieldsByPath, InferredFieldsByPath>
|
|
36
|
+
>
|
|
37
|
+
type GeneratedAllLocalesKeysMatchRuntimeRegistry = Assert<
|
|
38
|
+
Exact<keyof CollectionFieldsAllLocalesByPath, keyof InferredFieldsAllLocalesByPath>
|
|
39
|
+
>
|
|
40
|
+
type GeneratedAllLocalesFieldsMatchRuntimeRegistry = Assert<
|
|
41
|
+
Exact<CollectionFieldsAllLocalesByPath, InferredFieldsAllLocalesByPath>
|
|
42
|
+
>
|
|
@@ -0,0 +1,17 @@
|
|
|
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 type { InferCollectionRegistry } from '@byline/core'
|
|
10
|
+
|
|
11
|
+
import type { CollectionFieldsByPath } from '../generated/collection-types.js'
|
|
12
|
+
|
|
13
|
+
/** Add schema-only collection imports here; keep admin presentation separate. */
|
|
14
|
+
export const collections = [] as const
|
|
15
|
+
|
|
16
|
+
export type InferredBylineCollections = InferCollectionRegistry<typeof collections>
|
|
17
|
+
export type BylineCollections = CollectionFieldsByPath
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Generated by @byline/core/codegen
|
|
2
|
+
// Format version: 1
|
|
3
|
+
// Hash: 4ef42b796dc35fceb394f97eaef885c5795c52031ba91f9ca6ca7e0fd2f20608
|
|
4
|
+
|
|
5
|
+
export type CollectionFieldsByPath = {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type CollectionFieldsAllLocalesByPath = {
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type CollectionPath = keyof CollectionFieldsByPath
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* translation bundle.
|
|
13
13
|
*
|
|
14
14
|
* The locale arrays themselves live in `./locales.ts`, a dependency-free leaf
|
|
15
|
-
* module
|
|
16
|
-
* translation graph this file depends on. Re-exported here for
|
|
17
|
-
* with existing `~/i18n` importers.
|
|
15
|
+
* module exposed to public frontend code by `./public.ts`, without pulling in
|
|
16
|
+
* the admin translation graph this file depends on. Re-exported here for
|
|
17
|
+
* back-compat with existing `~/i18n` importers.
|
|
18
18
|
*
|
|
19
19
|
* `interface` locales govern the CMS admin UI language.
|
|
20
20
|
* `content` locales govern the languages a document can be published in.
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
* registry). `byline/i18n.ts` consumes these to assemble the
|
|
13
13
|
* `defineServerConfig` / `defineClientConfig` payload.
|
|
14
14
|
*
|
|
15
|
-
* Kept separate from `byline/i18n.ts` so
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* (`@byline/i18n/admin`) that `i18n.ts` depends on.
|
|
19
|
-
* would; importing this won't — which keeps the lazy
|
|
20
|
-
* (`src/routes/_byline/route.lazy.tsx`) intact.
|
|
15
|
+
* Kept separate from `byline/i18n.ts` so `byline/public.ts` can expose the
|
|
16
|
+
* locale arrays to a public frontend (or a collection schema file loaded
|
|
17
|
+
* outside Vite — e.g. when running seeds via tsx) without dragging in the
|
|
18
|
+
* admin translation graph (`@byline/i18n/admin`) that `i18n.ts` depends on.
|
|
19
|
+
* Importing `byline/i18n.ts` would; importing this won't — which keeps the lazy
|
|
20
|
+
* admin/public bundle split (`src/routes/_byline/route.lazy.tsx`) intact.
|
|
21
21
|
*
|
|
22
22
|
* `interface` locales govern the CMS admin UI language; `content` locales
|
|
23
23
|
* govern the languages a document can be published in.
|
|
@@ -33,10 +33,10 @@ export interface LocaleDefinition {
|
|
|
33
33
|
// (or a third-party plugin merged in via `mergeTranslations(...)`).
|
|
34
34
|
// `adminTranslations({ locales })` in `byline/i18n.ts` throws at boot if a
|
|
35
35
|
// requested code is not bundled — `@byline/i18n/admin` ships English and French.
|
|
36
|
-
export const interfaceLocales
|
|
36
|
+
export const interfaceLocales = [
|
|
37
37
|
{ code: 'en', label: 'English' },
|
|
38
38
|
{ code: 'fr', label: 'Français' },
|
|
39
|
-
]
|
|
39
|
+
] as const satisfies readonly LocaleDefinition[]
|
|
40
40
|
|
|
41
41
|
/** Locales a document can be published in. */
|
|
42
42
|
export const contentLocales = [
|
|
@@ -44,4 +44,4 @@ export const contentLocales = [
|
|
|
44
44
|
{ code: 'fr', label: 'Français' },
|
|
45
45
|
{ code: 'es', label: 'Español' },
|
|
46
46
|
{ code: 'de', label: 'Deutsch' },
|
|
47
|
-
] as const
|
|
47
|
+
] as const satisfies readonly LocaleDefinition[]
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
/** Client-safe public configuration. Keep this barrel free of admin and server imports. */
|
|
10
|
+
export { contentLocales, interfaceLocales } from './locales.js'
|
|
11
|
+
export { routes } from './routes.js'
|
|
12
|
+
export type { LocaleDefinition } from './locales.js'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto'
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { dirname, resolve } from 'node:path'
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
5
|
+
|
|
6
|
+
import { emitCollectionTypes } from '@byline/core/codegen'
|
|
7
|
+
|
|
8
|
+
import { collections } from '../collections/index.js'
|
|
9
|
+
|
|
10
|
+
const defaultOutputPath = fileURLToPath(
|
|
11
|
+
new URL('../generated/collection-types.ts', import.meta.url)
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
export type GenerationStatus = 'current' | 'unchanged' | 'written'
|
|
15
|
+
|
|
16
|
+
export function writeCollectionTypes(
|
|
17
|
+
outputPath: string,
|
|
18
|
+
source: string,
|
|
19
|
+
check: boolean
|
|
20
|
+
): GenerationStatus {
|
|
21
|
+
const existing = existsSync(outputPath) ? readFileSync(outputPath, 'utf8') : undefined
|
|
22
|
+
|
|
23
|
+
if (check) {
|
|
24
|
+
if (existing === undefined) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`generated collection types are missing: ${outputPath}. Run pnpm byline:generate`
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
if (existing !== source) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`generated collection types are stale: ${outputPath}. Run pnpm byline:generate`
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
return 'current'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (existing === source) return 'unchanged'
|
|
38
|
+
|
|
39
|
+
mkdirSync(dirname(outputPath), { recursive: true })
|
|
40
|
+
const temporaryPath = `${outputPath}.${process.pid}.${randomUUID()}.tmp`
|
|
41
|
+
try {
|
|
42
|
+
writeFileSync(temporaryPath, source, 'utf8')
|
|
43
|
+
renameSync(temporaryPath, outputPath)
|
|
44
|
+
} finally {
|
|
45
|
+
rmSync(temporaryPath, { force: true })
|
|
46
|
+
}
|
|
47
|
+
return 'written'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function parseArgs(args: readonly string[]): { check: boolean } {
|
|
51
|
+
const unknown = args.filter((arg) => arg !== '--check')
|
|
52
|
+
if (unknown.length > 0) throw new Error(`unknown argument: ${unknown.join(', ')}`)
|
|
53
|
+
if (args.filter((arg) => arg === '--check').length > 1) {
|
|
54
|
+
throw new Error('duplicate argument: --check')
|
|
55
|
+
}
|
|
56
|
+
return { check: args.includes('--check') }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function generateCollectionTypes(
|
|
60
|
+
outputPath = defaultOutputPath,
|
|
61
|
+
check = false
|
|
62
|
+
): { hash: string; status: GenerationStatus } {
|
|
63
|
+
const { source, hash } = emitCollectionTypes(collections)
|
|
64
|
+
return { hash, status: writeCollectionTypes(outputPath, source, check) }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function main(): void {
|
|
68
|
+
const { check } = parseArgs(process.argv.slice(2))
|
|
69
|
+
const { hash, status } = generateCollectionTypes(defaultOutputPath, check)
|
|
70
|
+
console.log(`collection types: ${collections.length} collections ${hash.slice(0, 12)} ${status}`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const entryPath = process.argv[1]
|
|
74
|
+
if (entryPath !== undefined && pathToFileURL(resolve(entryPath)).href === import.meta.url) {
|
|
75
|
+
try {
|
|
76
|
+
main()
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error(`collection type generation failed: ${(error as Error).message}`)
|
|
79
|
+
process.exitCode = 1
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
* read it back with `getBylineCore<AdminStore>()`.
|
|
15
15
|
*
|
|
16
16
|
* This is the minimal scaffold: no example collections registered. Add
|
|
17
|
-
* collection schemas to the
|
|
18
|
-
* `byline/collections/<name>/schema.ts`.
|
|
17
|
+
* collection schemas to the shared tuple in `byline/collections/index.ts`.
|
|
19
18
|
*/
|
|
20
19
|
|
|
21
20
|
import { type AdminStore, registerAdminAbilities } from '@byline/admin'
|
|
@@ -23,7 +22,6 @@ import { JwtSessionProvider } from '@byline/admin/auth'
|
|
|
23
22
|
import { type BylineCore, initBylineCore } from '@byline/core'
|
|
24
23
|
import { pgAdapter } from '@byline/db-postgres'
|
|
25
24
|
import { createAdminStore } from '@byline/db-postgres/admin'
|
|
26
|
-
import { getAdminBylineClient } from '@byline/host-tanstack-start/integrations/byline-client'
|
|
27
25
|
import {
|
|
28
26
|
lexicalEditorEmbedServer,
|
|
29
27
|
lexicalEditorPopulateServer,
|
|
@@ -31,13 +29,13 @@ import {
|
|
|
31
29
|
} from '@byline/richtext-lexical/server'
|
|
32
30
|
import { localStorageProvider } from '@byline/storage-local'
|
|
33
31
|
|
|
32
|
+
import { getAdminBylineClient } from './client.server.js'
|
|
33
|
+
import { collections } from './collections/index.js'
|
|
34
34
|
import { i18n } from './i18n.js'
|
|
35
35
|
import { DEFAULT_SERVER_URL, routes } from './routes.js'
|
|
36
36
|
|
|
37
37
|
const serverURL = process.env.VITE_SERVER_URL || DEFAULT_SERVER_URL
|
|
38
38
|
|
|
39
|
-
const collections: Parameters<typeof pgAdapter>[0]['collections'] = []
|
|
40
|
-
|
|
41
39
|
// HMR-safe singleton. Vite's program reload re-evaluates this module
|
|
42
40
|
// without disposing the previous module's resources — every reload
|
|
43
41
|
// would otherwise allocate a fresh pg `Pool` (max: 20) inside
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Registers Byline's client-side config (collection admin UI configs,
|
|
11
|
-
* field editors, i18n, routes) in the current module graph.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* field editors, i18n, routes) in the current module graph. The `_byline`
|
|
12
|
+
* route registers it from two complementary points: a dynamic import in
|
|
13
|
+
* `route.tsx` covers child loaders, while the side-effect import in
|
|
14
|
+
* `route.lazy.tsx` covers component render and initial hydration. Keeping
|
|
15
|
+
* both imports behind `_byline/*` keeps the admin graph off public routes.
|
|
15
16
|
*
|
|
16
17
|
* In TanStack Start with Vite 6 the server entry (`src/server.ts`) and
|
|
17
18
|
* the SSR rendering context run in separate Vite environments, so
|
|
@@ -28,11 +29,12 @@ import { RichTextField as LexicalRichTextField } from '@byline/richtext-lexical'
|
|
|
28
29
|
// commented `richText` block below for the exact shape.
|
|
29
30
|
// import { lexicalEditor } from '@byline/richtext-lexical'
|
|
30
31
|
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
32
|
+
import { collections } from './collections/index.js'
|
|
33
|
+
import { DocsAdmin } from './collections/docs/admin.js'
|
|
34
|
+
import { MediaAdmin } from './collections/media/admin.js'
|
|
35
|
+
import { NewsAdmin } from './collections/news/admin.js'
|
|
36
|
+
import { NewsCategoriesAdmin } from './collections/news-categories/admin.js'
|
|
37
|
+
import { PagesAdmin } from './collections/pages/admin.js'
|
|
36
38
|
import { i18n } from './i18n.js'
|
|
37
39
|
import { DEFAULT_SERVER_URL, routes } from './routes.js'
|
|
38
40
|
|
|
@@ -42,7 +44,7 @@ export const config: ClientConfig = {
|
|
|
42
44
|
serverURL,
|
|
43
45
|
i18n,
|
|
44
46
|
routes,
|
|
45
|
-
collections
|
|
47
|
+
collections,
|
|
46
48
|
admin: [DocsAdmin, NewsAdmin, PagesAdmin, MediaAdmin, NewsCategoriesAdmin],
|
|
47
49
|
fields: {
|
|
48
50
|
// Default registration — every `type: 'richText'` field gets the full
|
|
@@ -0,0 +1,32 @@
|
|
|
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-only application boundary for the host-owned client singletons.
|
|
11
|
+
* The host stays config-agnostic; this assertion binds it to the app registry.
|
|
12
|
+
*/
|
|
13
|
+
import type { BylineClient } from '@byline/client'
|
|
14
|
+
import {
|
|
15
|
+
getAdminBylineClient as getHostAdminBylineClient,
|
|
16
|
+
getSystemBylineClient as getHostSystemBylineClient,
|
|
17
|
+
} from '@byline/host-tanstack-start/integrations/byline-client'
|
|
18
|
+
import { getPublicBylineClient as getHostPublicBylineClient } from '@byline/host-tanstack-start/integrations/byline-public-client'
|
|
19
|
+
import {
|
|
20
|
+
getViewerBylineClient as getHostViewerBylineClient,
|
|
21
|
+
isPreviewActive,
|
|
22
|
+
} from '@byline/host-tanstack-start/integrations/byline-viewer-client'
|
|
23
|
+
|
|
24
|
+
import type { BylineCollections } from './collections/index.js'
|
|
25
|
+
|
|
26
|
+
type AppBylineClient = BylineClient<BylineCollections>
|
|
27
|
+
|
|
28
|
+
export const getAdminBylineClient = getHostAdminBylineClient as () => AppBylineClient
|
|
29
|
+
export const getPublicBylineClient = getHostPublicBylineClient as () => AppBylineClient
|
|
30
|
+
export const getSystemBylineClient = getHostSystemBylineClient as () => AppBylineClient
|
|
31
|
+
export const getViewerBylineClient = getHostViewerBylineClient as () => AppBylineClient
|
|
32
|
+
export { isPreviewActive }
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CollectionFieldData, CollectionFieldDataAllLocales } from '@byline/core'
|
|
2
|
+
|
|
3
|
+
import type { collections } from './collections/index.js'
|
|
4
|
+
import type {
|
|
5
|
+
CollectionFieldsAllLocalesByPath,
|
|
6
|
+
CollectionFieldsByPath,
|
|
7
|
+
} from './generated/collection-types.js'
|
|
8
|
+
|
|
9
|
+
type InferredFieldsByPath = {
|
|
10
|
+
[Definition in (typeof collections)[number] as Definition['path']]: CollectionFieldData<Definition>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type InferredFieldsAllLocalesByPath = {
|
|
14
|
+
[Definition in (typeof collections)[number] as Definition['path']]: CollectionFieldDataAllLocales<Definition>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type IsAny<Value> = 0 extends 1 & Value ? true : false
|
|
18
|
+
type Exact<Left, Right> = IsAny<Left> extends true
|
|
19
|
+
? IsAny<Right>
|
|
20
|
+
: IsAny<Right> extends true
|
|
21
|
+
? false
|
|
22
|
+
: (<Value>() => Value extends Left ? 1 : 2) extends <Value>() =>
|
|
23
|
+
Value extends Right ? 1 : 2
|
|
24
|
+
? (<Value>() => Value extends Right ? 1 : 2) extends <Value>() =>
|
|
25
|
+
Value extends Left ? 1 : 2
|
|
26
|
+
? true
|
|
27
|
+
: false
|
|
28
|
+
: false
|
|
29
|
+
type Assert<Value extends true> = Value
|
|
30
|
+
|
|
31
|
+
type GeneratedKeysMatchRuntimeRegistry = Assert<
|
|
32
|
+
Exact<keyof CollectionFieldsByPath, keyof InferredFieldsByPath>
|
|
33
|
+
>
|
|
34
|
+
type GeneratedFieldsMatchRuntimeRegistry = Assert<
|
|
35
|
+
Exact<CollectionFieldsByPath, InferredFieldsByPath>
|
|
36
|
+
>
|
|
37
|
+
type GeneratedAllLocalesKeysMatchRuntimeRegistry = Assert<
|
|
38
|
+
Exact<keyof CollectionFieldsAllLocalesByPath, keyof InferredFieldsAllLocalesByPath>
|
|
39
|
+
>
|
|
40
|
+
type GeneratedAllLocalesFieldsMatchRuntimeRegistry = Assert<
|
|
41
|
+
Exact<CollectionFieldsAllLocalesByPath, InferredFieldsAllLocalesByPath>
|
|
42
|
+
>
|