@byline/core 6.0.3 → 6.1.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/dist/@types/admin-types.d.ts +15 -0
- package/dist/@types/singleton-admin-config.test.node.js +7 -0
- package/dist/config/resolve-item-view-columns.test.node.d.ts +8 -0
- package/dist/config/resolve-item-view-columns.test.node.js +30 -0
- package/dist/config/validate-admin-configs.js +1 -0
- package/dist/config/validate-admin-configs.test.node.js +7 -0
- package/dist/services/field-upload.test.node.js +6 -6
- package/package.json +2 -2
|
@@ -392,6 +392,19 @@ export interface CollectionAdminConfig<T = any> extends FormAdminConfig {
|
|
|
392
392
|
locale?: string;
|
|
393
393
|
}) => string | null;
|
|
394
394
|
};
|
|
395
|
+
/**
|
|
396
|
+
* Declares this collection's document paths managed — minted by the system
|
|
397
|
+
* or an import rather than typed by an editor. The admin path widget then
|
|
398
|
+
* renders read-only in both modes, with no preview or "Regenerate" action,
|
|
399
|
+
* and renders even when the collection declares no `useAsPath`.
|
|
400
|
+
*
|
|
401
|
+
* An admin-interface guard only: it does not make the path immutable, and
|
|
402
|
+
* it is independent of `useAsPath`. See
|
|
403
|
+
* [Document paths](../../../../docs/04-collections/05-document-paths.md).
|
|
404
|
+
*
|
|
405
|
+
* @default false
|
|
406
|
+
*/
|
|
407
|
+
lockPath?: boolean;
|
|
395
408
|
/**
|
|
396
409
|
* Custom list-view component for this collection.
|
|
397
410
|
*
|
|
@@ -458,6 +471,8 @@ export interface SingletonAdminConfig<T = any> extends FormAdminConfig {
|
|
|
458
471
|
itemViewSort?: never;
|
|
459
472
|
listView?: never;
|
|
460
473
|
listActions?: never;
|
|
474
|
+
/** A singleton has no document path and no path widget. */
|
|
475
|
+
lockPath?: never;
|
|
461
476
|
}
|
|
462
477
|
/** Admin presentation config for either registered document-resource kind. */
|
|
463
478
|
export type AdminResourceConfig<T = any> = CollectionAdminConfig<T> | SingletonAdminConfig<T>;
|
|
@@ -52,6 +52,13 @@ describe('singleton admin config', () => {
|
|
|
52
52
|
columns: [{ fieldName: 'title', label: 'Title' }],
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
|
+
it('rejects lockPath at the singleton definition site and accepts it on a collection', () => {
|
|
56
|
+
defineSingletonAdmin(settings, {
|
|
57
|
+
// @ts-expect-error — a singleton has no document path and no path widget.
|
|
58
|
+
lockPath: true,
|
|
59
|
+
});
|
|
60
|
+
expect(defineAdmin(pages, { lockPath: true }).lockPath).toBe(true);
|
|
61
|
+
});
|
|
55
62
|
it('keeps the singleton preview document pathless', () => {
|
|
56
63
|
defineSingletonAdmin(settings, {
|
|
57
64
|
preview: {
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
import { describe, expect, it } from 'vitest';
|
|
9
|
+
import { resolveItemViewColumns } from './config.js';
|
|
10
|
+
const itemViewCols = [{ fieldName: 'title', label: 'Title' }];
|
|
11
|
+
const pickerCols = [{ fieldName: 'name', label: 'Name' }];
|
|
12
|
+
const cfg = (over) => ({ slug: 'x', ...over });
|
|
13
|
+
describe('resolveItemViewColumns', () => {
|
|
14
|
+
it('returns itemView when present', () => {
|
|
15
|
+
expect(resolveItemViewColumns(cfg({ itemView: itemViewCols }))).toBe(itemViewCols);
|
|
16
|
+
});
|
|
17
|
+
it('falls back to the deprecated picker alias', () => {
|
|
18
|
+
expect(resolveItemViewColumns(cfg({ picker: pickerCols }))).toBe(pickerCols);
|
|
19
|
+
});
|
|
20
|
+
it('prefers itemView over picker when both are present', () => {
|
|
21
|
+
expect(resolveItemViewColumns(cfg({ itemView: itemViewCols, picker: pickerCols }))).toBe(itemViewCols);
|
|
22
|
+
});
|
|
23
|
+
it('returns undefined when neither is set', () => {
|
|
24
|
+
expect(resolveItemViewColumns(cfg({}))).toBeUndefined();
|
|
25
|
+
});
|
|
26
|
+
it('tolerates null / undefined config', () => {
|
|
27
|
+
expect(resolveItemViewColumns(null)).toBeUndefined();
|
|
28
|
+
expect(resolveItemViewColumns(undefined)).toBeUndefined();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -72,6 +72,13 @@ describe('validateAdminConfigs', () => {
|
|
|
72
72
|
};
|
|
73
73
|
expect(() => validateAdminConfigs([admin], [collection, singleton])).toThrow(/columns.*not allowed on a singleton admin config/);
|
|
74
74
|
});
|
|
75
|
+
it('rejects the collection-only lockPath option on a singleton from untyped callers', () => {
|
|
76
|
+
const admin = {
|
|
77
|
+
...defineSingletonAdmin(singleton, {}),
|
|
78
|
+
lockPath: true,
|
|
79
|
+
};
|
|
80
|
+
expect(() => validateAdminConfigs([admin], [collection, singleton])).toThrow(/lockPath.*not allowed on a singleton admin config/);
|
|
81
|
+
});
|
|
75
82
|
it('rejects a singleton admin config targeting a multi-collection', () => {
|
|
76
83
|
const admin = { ...defineSingletonAdmin(singleton, {}), slug: collection.path };
|
|
77
84
|
expect(() => validateAdminConfigs([admin], [collection, singleton])).toThrow(/targets a collection definition/);
|
|
@@ -452,7 +452,7 @@ describe('uploadField service', () => {
|
|
|
452
452
|
it('beforeStore { storagePath } threads targetStoragePath verbatim and derives the filename from its basename', async () => {
|
|
453
453
|
const definition = withFieldUpload(uploadCollection, 'image', (f) => {
|
|
454
454
|
f.upload.hooks = {
|
|
455
|
-
beforeStore: () => ({ storagePath: 'publications/
|
|
455
|
+
beforeStore: () => ({ storagePath: 'publications/pub-0000447-0001-en.png' }),
|
|
456
456
|
};
|
|
457
457
|
});
|
|
458
458
|
const { ctx, upload } = buildCtx({ definition });
|
|
@@ -466,17 +466,17 @@ describe('uploadField service', () => {
|
|
|
466
466
|
// Explicit key is handed to the provider verbatim — no entropy suffix,
|
|
467
467
|
// no collection-derived key.
|
|
468
468
|
expect(upload).toHaveBeenCalledWith(expect.any(Buffer), expect.objectContaining({
|
|
469
|
-
targetStoragePath: 'publications/
|
|
470
|
-
filename: '
|
|
469
|
+
targetStoragePath: 'publications/pub-0000447-0001-en.png',
|
|
470
|
+
filename: 'pub-0000447-0001-en.png',
|
|
471
471
|
}));
|
|
472
472
|
// Stored filename follows the explicit key's basename.
|
|
473
|
-
expect(result.storedFile.filename).toBe('
|
|
473
|
+
expect(result.storedFile.filename).toBe('pub-0000447-0001-en.png');
|
|
474
474
|
});
|
|
475
475
|
it('beforeStore { storagePath, filename } honours both; a leading slash is stripped from the key', async () => {
|
|
476
476
|
const definition = withFieldUpload(uploadCollection, 'image', (f) => {
|
|
477
477
|
f.upload.hooks = {
|
|
478
478
|
beforeStore: () => ({
|
|
479
|
-
storagePath: '/publications/
|
|
479
|
+
storagePath: '/publications/pub-0000447-0002-en.png',
|
|
480
480
|
filename: 'display-name.png',
|
|
481
481
|
}),
|
|
482
482
|
};
|
|
@@ -490,7 +490,7 @@ describe('uploadField service', () => {
|
|
|
490
490
|
shouldCreateDocument: false,
|
|
491
491
|
});
|
|
492
492
|
expect(upload).toHaveBeenCalledWith(expect.any(Buffer), expect.objectContaining({
|
|
493
|
-
targetStoragePath: 'publications/
|
|
493
|
+
targetStoragePath: 'publications/pub-0000447-0002-en.png',
|
|
494
494
|
filename: 'display-name.png',
|
|
495
495
|
}));
|
|
496
496
|
expect(result.storedFile.filename).toBe('display-name.png');
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/core",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "6.0
|
|
5
|
+
"version": "6.1.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"sharp": "^0.35.4",
|
|
88
88
|
"uuid": "^14.0.2",
|
|
89
89
|
"zod": "^4.6.2",
|
|
90
|
-
"@byline/auth": "6.0
|
|
90
|
+
"@byline/auth": "6.1.0"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
93
|
"@biomejs/biome": "2.5.13",
|