@byline/host-tanstack-start 4.15.0 → 4.17.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/admin-shell/chrome/admin-menu-drawer.d.ts +2 -1
- package/dist/admin-shell/chrome/admin-menu-drawer.js +17 -5
- package/dist/admin-shell/chrome/dashboard.js +41 -5
- package/dist/admin-shell/chrome/dashboard.test.d.ts +8 -0
- package/dist/admin-shell/collections/api.d.ts +2 -2
- package/dist/admin-shell/collections/create.d.ts +2 -2
- package/dist/admin-shell/collections/create.js +1 -0
- package/dist/admin-shell/collections/edit.d.ts +2 -2
- package/dist/admin-shell/collections/edit.js +1 -0
- package/dist/admin-shell/collections/history.d.ts +4 -12
- package/dist/admin-shell/collections/history.js +112 -303
- package/dist/admin-shell/collections/reindex-button.d.ts +1 -1
- package/dist/admin-shell/collections/reindex-button.js +5 -1
- package/dist/admin-shell/collections/restore-version-modal.d.ts +4 -4
- package/dist/admin-shell/collections/restore-version-modal.js +8 -24
- package/dist/admin-shell/collections/version-history.d.ts +72 -0
- package/dist/admin-shell/collections/version-history.js +259 -0
- package/dist/admin-shell/singletons/history.d.ts +19 -0
- package/dist/admin-shell/singletons/history.js +170 -0
- package/dist/admin-shell/singletons/history.test.d.ts +8 -0
- package/dist/admin-shell/singletons/preview-link.d.ts +12 -0
- package/dist/admin-shell/singletons/preview-link.js +54 -0
- package/dist/admin-shell/singletons/view-menu.d.ts +13 -0
- package/dist/admin-shell/singletons/view-menu.js +116 -0
- package/dist/admin-shell/singletons/view.d.ts +18 -0
- package/dist/admin-shell/singletons/view.js +259 -0
- package/dist/admin-shell/singletons/view.test.d.ts +8 -0
- package/dist/integrations/analytics-agent.d.ts +20 -0
- package/dist/integrations/analytics-agent.js +57 -0
- package/dist/integrations/analytics-events.d.ts +51 -0
- package/dist/integrations/analytics-events.js +129 -0
- package/dist/integrations/api-utils.d.ts +18 -4
- package/dist/integrations/api-utils.js +10 -3
- package/dist/integrations/serve-analytics-agent.d.ts +8 -0
- package/dist/integrations/serve-analytics-agent.js +11 -0
- package/dist/routes/analytics-range.d.ts +12 -0
- package/dist/routes/analytics-range.js +35 -0
- package/dist/routes/create-admin-analytics-route.d.ts +8 -0
- package/dist/routes/create-admin-analytics-route.js +108 -0
- package/dist/routes/create-admin-dashboard-route.js +2 -2
- package/dist/routes/create-admin-layout-route.js +10 -4
- package/dist/routes/create-collection-api-route.js +3 -3
- package/dist/routes/create-collection-create-route.js +4 -3
- package/dist/routes/create-collection-edit-route.js +4 -3
- package/dist/routes/create-collection-history-route.js +4 -3
- package/dist/routes/create-collection-list-route.js +4 -3
- package/dist/routes/create-singleton-history-route.d.ts +8 -0
- package/dist/routes/create-singleton-history-route.js +99 -0
- package/dist/routes/create-singleton-route.d.ts +35 -0
- package/dist/routes/create-singleton-route.js +130 -0
- package/dist/routes/get-multi-collection-definition.d.ts +10 -0
- package/dist/routes/get-multi-collection-definition.js +6 -0
- package/dist/routes/get-singleton-definition.d.ts +10 -0
- package/dist/routes/get-singleton-definition.js +6 -0
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.js +3 -0
- package/dist/server-fns/actors.d.ts +16 -0
- package/dist/server-fns/actors.js +25 -0
- package/dist/server-fns/admin-document-presentation.d.ts +30 -0
- package/dist/server-fns/admin-document-presentation.js +32 -0
- package/dist/server-fns/analytics/index.d.ts +9 -0
- package/dist/server-fns/analytics/index.js +2 -0
- package/dist/server-fns/analytics/maintenance.d.ts +22 -0
- package/dist/server-fns/analytics/maintenance.js +42 -0
- package/dist/server-fns/analytics/queries.d.ts +25 -0
- package/dist/server-fns/analytics/queries.js +54 -0
- package/dist/server-fns/collections/actors.d.ts +1 -10
- package/dist/server-fns/collections/actors.js +1 -25
- package/dist/server-fns/collections/get.js +9 -26
- package/dist/server-fns/collections/reorder.js +1 -1
- package/dist/server-fns/collections/scheduled-publication.js +2 -2
- package/dist/server-fns/collections/upload.js +3 -3
- package/dist/server-fns/collections/utils.d.ts +1 -7
- package/dist/server-fns/collections/utils.js +1 -4
- package/dist/server-fns/serialise.d.ts +14 -0
- package/dist/server-fns/serialise.js +4 -0
- package/dist/server-fns/singleton-document-read.d.ts +20 -0
- package/dist/server-fns/singleton-document-read.js +10 -0
- package/dist/server-fns/singletons/cancel-scheduled-publish.d.ts +12 -0
- package/dist/server-fns/singletons/cancel-scheduled-publish.js +7 -0
- package/dist/server-fns/singletons/change-status.d.ts +14 -0
- package/dist/server-fns/singletons/change-status.js +7 -0
- package/dist/server-fns/singletons/confirm-scheduled-publish.d.ts +14 -0
- package/dist/server-fns/singletons/confirm-scheduled-publish.js +9 -0
- package/dist/server-fns/singletons/copy-to-locale.d.ts +18 -0
- package/dist/server-fns/singletons/copy-to-locale.js +11 -0
- package/dist/server-fns/singletons/find-by-version.d.ts +16 -0
- package/dist/server-fns/singletons/find-by-version.js +9 -0
- package/dist/server-fns/singletons/get-scheduled-publish.d.ts +12 -0
- package/dist/server-fns/singletons/get-scheduled-publish.js +7 -0
- package/dist/server-fns/singletons/get.d.ts +24 -0
- package/dist/server-fns/singletons/get.js +6 -0
- package/dist/server-fns/singletons/history.d.ts +31 -0
- package/dist/server-fns/singletons/history.js +22 -0
- package/dist/server-fns/singletons/index.d.ts +19 -0
- package/dist/server-fns/singletons/index.js +12 -0
- package/dist/server-fns/singletons/restore-version.d.ts +14 -0
- package/dist/server-fns/singletons/restore-version.js +7 -0
- package/dist/server-fns/singletons/schedule-publish.d.ts +16 -0
- package/dist/server-fns/singletons/schedule-publish.js +10 -0
- package/dist/server-fns/singletons/unpublish.d.ts +12 -0
- package/dist/server-fns/singletons/unpublish.js +7 -0
- package/dist/server-fns/singletons/update.d.ts +14 -0
- package/dist/server-fns/singletons/update.js +14 -0
- package/dist/vite/analytics-dev.d.ts +22 -0
- package/dist/vite/analytics-dev.js +28 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.js +1 -0
- package/dist/vitest-jsdom.test.d.ts +8 -0
- package/package.json +28 -16
- package/src/admin-shell/chrome/admin-menu-drawer.tsx +19 -5
- package/src/admin-shell/chrome/dashboard.test.tsx +199 -0
- package/src/admin-shell/chrome/dashboard.tsx +43 -9
- package/src/admin-shell/collections/api.tsx +2 -2
- package/src/admin-shell/collections/create.tsx +6 -2
- package/src/admin-shell/collections/edit.tsx +6 -2
- package/src/admin-shell/collections/history.module.css +1 -1
- package/src/admin-shell/collections/history.tsx +162 -442
- package/src/admin-shell/collections/reindex-button.tsx +4 -2
- package/src/admin-shell/collections/restore-version-modal.tsx +19 -25
- package/src/admin-shell/collections/version-history.tsx +349 -0
- package/src/admin-shell/singletons/history.test.tsx +407 -0
- package/src/admin-shell/singletons/history.tsx +185 -0
- package/src/admin-shell/singletons/preview-link.tsx +75 -0
- package/src/admin-shell/singletons/view-menu.tsx +136 -0
- package/src/admin-shell/singletons/view.test.tsx +400 -0
- package/src/admin-shell/singletons/view.tsx +351 -0
- package/src/integrations/analytics-agent.tsx +91 -0
- package/src/integrations/analytics-events.test.node.ts +245 -0
- package/src/integrations/analytics-events.ts +224 -0
- package/src/integrations/api-utils.ts +34 -9
- package/src/integrations/serve-analytics-agent.test.node.ts +20 -0
- package/src/integrations/serve-analytics-agent.ts +19 -0
- package/src/routes/analytics-range.ts +55 -0
- package/src/routes/create-admin-analytics-route.test.node.ts +46 -0
- package/src/routes/create-admin-analytics-route.tsx +109 -0
- package/src/routes/create-admin-dashboard-route.test.node.ts +70 -0
- package/src/routes/create-admin-dashboard-route.tsx +10 -2
- package/src/routes/create-admin-layout-route.tsx +15 -8
- package/src/routes/create-collection-api-route.tsx +4 -4
- package/src/routes/create-collection-create-route.tsx +5 -8
- package/src/routes/create-collection-edit-route.tsx +5 -4
- package/src/routes/create-collection-history-route.tsx +5 -8
- package/src/routes/create-collection-list-route.tsx +5 -8
- package/src/routes/create-singleton-history-route.test.node.ts +148 -0
- package/src/routes/create-singleton-history-route.tsx +116 -0
- package/src/routes/create-singleton-route.test.node.ts +172 -0
- package/src/routes/create-singleton-route.tsx +176 -0
- package/src/routes/get-multi-collection-definition.ts +16 -0
- package/src/routes/get-singleton-definition.ts +16 -0
- package/src/routes/index.ts +3 -0
- package/src/server-fns/actors.ts +43 -0
- package/src/server-fns/admin-document-presentation.ts +78 -0
- package/src/server-fns/analytics/index.ts +23 -0
- package/src/server-fns/analytics/maintenance.ts +54 -0
- package/src/server-fns/analytics/queries.ts +86 -0
- package/src/server-fns/collections/actors.ts +1 -52
- package/src/server-fns/collections/get.ts +10 -49
- package/src/server-fns/collections/reorder.ts +1 -1
- package/src/server-fns/collections/scheduled-publication.ts +7 -1
- package/src/server-fns/collections/upload-singleton.test.node.ts +164 -0
- package/src/server-fns/collections/upload.ts +7 -3
- package/src/server-fns/collections/utils.ts +1 -9
- package/src/server-fns/serialise.ts +17 -0
- package/src/server-fns/singleton-document-read.ts +32 -0
- package/src/server-fns/singletons/cancel-scheduled-publish.ts +19 -0
- package/src/server-fns/singletons/change-status.ts +19 -0
- package/src/server-fns/singletons/confirm-scheduled-publish.ts +23 -0
- package/src/server-fns/singletons/copy-to-locale.ts +32 -0
- package/src/server-fns/singletons/find-by-version.ts +23 -0
- package/src/server-fns/singletons/get-scheduled-publish.ts +19 -0
- package/src/server-fns/singletons/get.ts +32 -0
- package/src/server-fns/singletons/history.ts +41 -0
- package/src/server-fns/singletons/index.ts +20 -0
- package/src/server-fns/singletons/restore-version.ts +19 -0
- package/src/server-fns/singletons/schedule-publish.ts +24 -0
- package/src/server-fns/singletons/singletons.test.node.ts +298 -0
- package/src/server-fns/singletons/unpublish.ts +19 -0
- package/src/server-fns/singletons/update.ts +31 -0
- package/src/vite/analytics-dev.test.node.ts +126 -0
- package/src/vite/analytics-dev.ts +56 -0
- package/src/vite/index.ts +1 -0
- package/src/vitest-jsdom.test.tsx +27 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createFileRoute, notFound } from "@tanstack/react-router";
|
|
3
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
4
|
+
import { getAdminBylineClient, getAdminRequestContext } from "@byline/client/server";
|
|
5
|
+
import { buildInitialDataFromFields, documentAbilityKey, getServerConfig, getSingletonAdminConfig } from "@byline/core";
|
|
6
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { BreadcrumbsClient } from "../admin-shell/chrome/breadcrumbs/breadcrumbs-client.js";
|
|
9
|
+
import { SingletonView } from "../admin-shell/singletons/view.js";
|
|
10
|
+
import { bylineCore } from "../integrations/byline-core.js";
|
|
11
|
+
import { serialise } from "../server-fns/serialise.js";
|
|
12
|
+
import { readSingletonDocument } from "../server-fns/singleton-document-read.js";
|
|
13
|
+
import { getAdminRoutePath } from "./admin-path.js";
|
|
14
|
+
import { getContentLocaleRouteConfig } from "./get-content-locale-route-config.js";
|
|
15
|
+
import { getSingletonDefinition } from "./get-singleton-definition.js";
|
|
16
|
+
const searchSchema = z.object({
|
|
17
|
+
locale: z.string().optional()
|
|
18
|
+
});
|
|
19
|
+
const getSingletonRouteDocument = createServerFn({
|
|
20
|
+
method: 'GET'
|
|
21
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
22
|
+
const definition = getSingletonDefinition(data.singleton);
|
|
23
|
+
if (null == definition) return null;
|
|
24
|
+
const document = await readSingletonDocument({
|
|
25
|
+
singleton: data.singleton,
|
|
26
|
+
locale: data.locale,
|
|
27
|
+
populateRelations: true
|
|
28
|
+
});
|
|
29
|
+
if (null == document) return {
|
|
30
|
+
document: null,
|
|
31
|
+
initialData: serialise(await buildInitialDataFromFields(definition.fields, {
|
|
32
|
+
locale: data.locale ?? getServerConfig().i18n.content.defaultLocale
|
|
33
|
+
}))
|
|
34
|
+
};
|
|
35
|
+
const config = getServerConfig();
|
|
36
|
+
const record = bylineCore().getCollectionRecord(data.singleton);
|
|
37
|
+
let publishedVersion = null;
|
|
38
|
+
if ('published' !== document.status) {
|
|
39
|
+
const published = await config.db.queries.documents.getPublishedVersion({
|
|
40
|
+
collection_id: record.collectionId,
|
|
41
|
+
document_id: String(document.id)
|
|
42
|
+
});
|
|
43
|
+
publishedVersion = published ? serialise({
|
|
44
|
+
id: published.document_id,
|
|
45
|
+
versionId: published.document_version_id,
|
|
46
|
+
status: published.status,
|
|
47
|
+
createdAt: published.created_at,
|
|
48
|
+
updatedAt: published.updated_at
|
|
49
|
+
}) : null;
|
|
50
|
+
}
|
|
51
|
+
const scheduledPublicationEnabled = config.scheduledPublication?.enabled === true;
|
|
52
|
+
let canSchedulePublication = false;
|
|
53
|
+
let scheduledPublish = null;
|
|
54
|
+
if (scheduledPublicationEnabled) {
|
|
55
|
+
const actor = (await getAdminRequestContext()).actor;
|
|
56
|
+
canSchedulePublication = actor?.hasAbility(documentAbilityKey(definition, 'changeStatus')) === true && actor.hasAbility(documentAbilityKey(definition, 'publish'));
|
|
57
|
+
if (canSchedulePublication) scheduledPublish = await getAdminBylineClient().singleton(data.singleton).getScheduledPublish();
|
|
58
|
+
}
|
|
59
|
+
const serializedSchedule = null == scheduledPublish ? null : serialise(scheduledPublish);
|
|
60
|
+
return {
|
|
61
|
+
document: {
|
|
62
|
+
...document,
|
|
63
|
+
_publishedVersion: publishedVersion,
|
|
64
|
+
_scheduledPublicationEnabled: scheduledPublicationEnabled,
|
|
65
|
+
_canSchedulePublication: canSchedulePublication,
|
|
66
|
+
_scheduledPublish: serializedSchedule,
|
|
67
|
+
...null == serializedSchedule ? {} : {
|
|
68
|
+
scheduledPublishAt: serializedSchedule.publishAt,
|
|
69
|
+
scheduledPublishVersionId: serializedSchedule.targetVersionId
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
initialData: void 0
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
function createSingletonRoute(path) {
|
|
76
|
+
const Route = createFileRoute(path)({
|
|
77
|
+
validateSearch: searchSchema,
|
|
78
|
+
loaderDeps: ({ search })=>({
|
|
79
|
+
locale: search.locale
|
|
80
|
+
}),
|
|
81
|
+
loader: async ({ params, deps })=>{
|
|
82
|
+
if (null == getSingletonDefinition(params.singleton)) throw notFound();
|
|
83
|
+
return getSingletonRouteDocument({
|
|
84
|
+
data: {
|
|
85
|
+
singleton: params.singleton,
|
|
86
|
+
locale: deps.locale
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
staleTime: 0,
|
|
91
|
+
gcTime: 0,
|
|
92
|
+
shouldReload: true,
|
|
93
|
+
component: function() {
|
|
94
|
+
const routeState = Route.useLoaderData();
|
|
95
|
+
const { singleton } = Route.useParams();
|
|
96
|
+
const { locale } = Route.useSearch();
|
|
97
|
+
const definition = getSingletonDefinition(singleton);
|
|
98
|
+
if (null == definition) throw notFound();
|
|
99
|
+
const { t } = useTranslation('byline-admin');
|
|
100
|
+
const { contentLocales, defaultContentLocale } = getContentLocaleRouteConfig();
|
|
101
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
102
|
+
children: [
|
|
103
|
+
/*#__PURE__*/ jsx(BreadcrumbsClient, {
|
|
104
|
+
breadcrumbs: [
|
|
105
|
+
{
|
|
106
|
+
label: t('chrome.menu.dashboard'),
|
|
107
|
+
href: getAdminRoutePath()
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
label: definition.label,
|
|
111
|
+
href: getAdminRoutePath('singletons', singleton)
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}),
|
|
115
|
+
/*#__PURE__*/ jsx(SingletonView, {
|
|
116
|
+
singletonDefinition: definition,
|
|
117
|
+
adminConfig: getSingletonAdminConfig(singleton) ?? void 0,
|
|
118
|
+
document: routeState.document,
|
|
119
|
+
initialData: routeState.initialData,
|
|
120
|
+
locale: locale,
|
|
121
|
+
contentLocales: contentLocales,
|
|
122
|
+
defaultContentLocale: defaultContentLocale
|
|
123
|
+
})
|
|
124
|
+
]
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return Route;
|
|
129
|
+
}
|
|
130
|
+
export { createSingletonRoute, getSingletonRouteDocument };
|
|
@@ -0,0 +1,10 @@
|
|
|
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 type { MultiCollectionDefinition } from '@byline/core';
|
|
9
|
+
/** Resolve only the resource kind supported by the collection route family. */
|
|
10
|
+
export declare function getMultiCollectionDefinition(path: string): MultiCollectionDefinition | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCollectionDefinition, isSingleton } from "@byline/core";
|
|
2
|
+
function getMultiCollectionDefinition(path) {
|
|
3
|
+
const definition = getCollectionDefinition(path);
|
|
4
|
+
return null == definition || isSingleton(definition) ? null : definition;
|
|
5
|
+
}
|
|
6
|
+
export { getMultiCollectionDefinition };
|
|
@@ -0,0 +1,10 @@
|
|
|
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 type { SingletonDefinition } from '@byline/core';
|
|
9
|
+
/** Resolve only the resource kind supported by the singleton route family. */
|
|
10
|
+
export declare function getSingletonDefinition(path: string): SingletonDefinition | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCollectionDefinition, isSingleton } from "@byline/core";
|
|
2
|
+
function getSingletonDefinition(path) {
|
|
3
|
+
const definition = getCollectionDefinition(path);
|
|
4
|
+
return null != definition && isSingleton(definition) ? definition : null;
|
|
5
|
+
}
|
|
6
|
+
export { getSingletonDefinition };
|
package/dist/routes/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export { getSignInRoutePath } from './sign-in-path.js';
|
|
|
23
23
|
*/
|
|
24
24
|
export { createAdminAccountRoute } from './create-admin-account-route.js';
|
|
25
25
|
export { createAdminActivityRoute } from './create-admin-activity-route.js';
|
|
26
|
+
export { createAdminAnalyticsRoute } from './create-admin-analytics-route.js';
|
|
26
27
|
export { createAdminDashboardRoute } from './create-admin-dashboard-route.js';
|
|
27
28
|
export { createAdminLayoutRoute } from './create-admin-layout-route.js';
|
|
28
29
|
export { createAdminPermissionsRoute } from './create-admin-permissions-route.js';
|
|
@@ -37,3 +38,5 @@ export { createCollectionEditRoute } from './create-collection-edit-route.js';
|
|
|
37
38
|
export { createCollectionHistoryRoute } from './create-collection-history-route.js';
|
|
38
39
|
export { createCollectionListRoute } from './create-collection-list-route.js';
|
|
39
40
|
export { type CreateSignInRouteOptions, createSignInRoute, } from './create-sign-in-route.js';
|
|
41
|
+
export { createSingletonHistoryRoute } from './create-singleton-history-route.js';
|
|
42
|
+
export { createSingletonRoute } from './create-singleton-route.js';
|
package/dist/routes/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { getAdminRouteId, getAdminRoutePath, isAdminRoutePathActive, isRoutePath
|
|
|
2
2
|
export { getSignInRoutePath } from "./sign-in-path.js";
|
|
3
3
|
export { createAdminAccountRoute } from "./create-admin-account-route.js";
|
|
4
4
|
export { createAdminActivityRoute } from "./create-admin-activity-route.js";
|
|
5
|
+
export { createAdminAnalyticsRoute } from "./create-admin-analytics-route.js";
|
|
5
6
|
export { createAdminDashboardRoute } from "./create-admin-dashboard-route.js";
|
|
6
7
|
export { createAdminLayoutRoute } from "./create-admin-layout-route.js";
|
|
7
8
|
export { createAdminPermissionsRoute } from "./create-admin-permissions-route.js";
|
|
@@ -16,3 +17,5 @@ export { createCollectionEditRoute } from "./create-collection-edit-route.js";
|
|
|
16
17
|
export { createCollectionHistoryRoute } from "./create-collection-history-route.js";
|
|
17
18
|
export { createCollectionListRoute } from "./create-collection-list-route.js";
|
|
18
19
|
export { createSignInRoute } from "./create-sign-in-route.js";
|
|
20
|
+
export { createSingletonHistoryRoute } from "./create-singleton-history-route.js";
|
|
21
|
+
export { createSingletonRoute } from "./create-singleton-route.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
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 type ActorLabelMap = Record<string, {
|
|
9
|
+
label: string;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Batch-resolve admin-user ids to display labels. The admin server-fn layer
|
|
13
|
+
* owns this presentation concern so both collection and singleton history
|
|
14
|
+
* can share it without teaching document storage about admin-realm tables.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveActorLabels(ids: Iterable<string | null | undefined>): Promise<ActorLabelMap>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { bylineCore } from "../integrations/byline-core.js";
|
|
2
|
+
function labelFor(row) {
|
|
3
|
+
const name = [
|
|
4
|
+
row.given_name,
|
|
5
|
+
row.family_name
|
|
6
|
+
].filter(Boolean).join(' ');
|
|
7
|
+
return name || row.username || row.email;
|
|
8
|
+
}
|
|
9
|
+
async function resolveActorLabels(ids) {
|
|
10
|
+
const unique = [
|
|
11
|
+
...new Set([
|
|
12
|
+
...ids
|
|
13
|
+
].filter((id)=>'string' == typeof id && id.length > 0))
|
|
14
|
+
];
|
|
15
|
+
if (0 === unique.length) return {};
|
|
16
|
+
const store = bylineCore().adminStore;
|
|
17
|
+
if (null == store) return {};
|
|
18
|
+
const rows = await store.adminUsers.getByIds(unique);
|
|
19
|
+
const map = {};
|
|
20
|
+
for (const row of rows)map[row.id] = {
|
|
21
|
+
label: labelFor(row)
|
|
22
|
+
};
|
|
23
|
+
return map;
|
|
24
|
+
}
|
|
25
|
+
export { resolveActorLabels };
|
|
@@ -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 { type CollectionDefinition, type PopulateSpec } from '@byline/core';
|
|
9
|
+
export interface AdminDocumentReadInput {
|
|
10
|
+
locale?: string;
|
|
11
|
+
depth?: number;
|
|
12
|
+
populateRelations?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface AdminDocumentReadOptions {
|
|
15
|
+
locale: string;
|
|
16
|
+
populate?: PopulateSpec;
|
|
17
|
+
depth?: number;
|
|
18
|
+
status: 'any';
|
|
19
|
+
onMissingLocale: 'empty';
|
|
20
|
+
lenient: true;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the shared read controls used by collection and singleton editors.
|
|
24
|
+
* Explicit depth is the API-preview mode; otherwise relation-summary mode
|
|
25
|
+
* projects only each target's picker/title fields for first-paint tiles.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveAdminDocumentRead(definition: CollectionDefinition | null, input: AdminDocumentReadInput): {
|
|
28
|
+
options: AdminDocumentReadOptions;
|
|
29
|
+
populatedTree: boolean;
|
|
30
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { buildRelationSummaryPopulateMap, getCollectionAdminConfig, getCollectionDefinition } from "@byline/core";
|
|
2
|
+
function resolveAdminDocumentRead(definition, input) {
|
|
3
|
+
const populateRequested = 'number' == typeof input.depth && input.depth > 0;
|
|
4
|
+
const autoRelationsActive = !populateRequested && true === input.populateRelations;
|
|
5
|
+
let populate;
|
|
6
|
+
let depth;
|
|
7
|
+
if (populateRequested) {
|
|
8
|
+
populate = '*';
|
|
9
|
+
depth = input.depth;
|
|
10
|
+
} else if (autoRelationsActive && null != definition) {
|
|
11
|
+
const populateMap = buildRelationSummaryPopulateMap(definition.fields, (targetPath)=>({
|
|
12
|
+
def: getCollectionDefinition(targetPath),
|
|
13
|
+
admin: getCollectionAdminConfig(targetPath)
|
|
14
|
+
}));
|
|
15
|
+
if (Object.keys(populateMap).length > 0) {
|
|
16
|
+
populate = populateMap;
|
|
17
|
+
depth = 1;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
options: {
|
|
22
|
+
locale: input.locale ?? 'en',
|
|
23
|
+
populate,
|
|
24
|
+
depth,
|
|
25
|
+
status: 'any',
|
|
26
|
+
onMissingLocale: 'empty',
|
|
27
|
+
lenient: true
|
|
28
|
+
},
|
|
29
|
+
populatedTree: populateRequested || autoRelationsActive
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export { resolveAdminDocumentRead };
|
|
@@ -0,0 +1,9 @@
|
|
|
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 { type DeleteAnalyticsEventsInput, deleteAnalyticsEvents, rebuildAnalyticsDay, } from './maintenance.js';
|
|
9
|
+
export { type AnalyticsRuntimeState, type AnalyticsTopInput, getAnalyticsCountries, getAnalyticsReferrers, getAnalyticsReportCoverage, getAnalyticsRuntime, getAnalyticsSummary, getAnalyticsTop, } from './queries.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
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 interface DeleteAnalyticsEventsInput {
|
|
9
|
+
from: string;
|
|
10
|
+
to: string;
|
|
11
|
+
visitorHash?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const deleteAnalyticsEvents: import("@tanstack/react-start").RequiredFetcher<undefined, (input: DeleteAnalyticsEventsInput) => DeleteAnalyticsEventsInput, Promise<{
|
|
14
|
+
deleted: number;
|
|
15
|
+
}>>;
|
|
16
|
+
export declare const rebuildAnalyticsDay: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
|
|
17
|
+
day: string;
|
|
18
|
+
}) => {
|
|
19
|
+
day: string;
|
|
20
|
+
}, Promise<{
|
|
21
|
+
rebuilt: string;
|
|
22
|
+
}>>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
2
|
+
import { assertAdminActor } from "@byline/admin";
|
|
3
|
+
import { ANALYTICS_ABILITIES } from "@byline/admin/analytics";
|
|
4
|
+
import { getAdminRequestContext } from "@byline/client/server";
|
|
5
|
+
const deleteAnalyticsEvents = createServerFn({
|
|
6
|
+
method: 'POST'
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
|
+
await assertAnalyticsMaintenance();
|
|
9
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
10
|
+
const from = parseInstant(data.from, 'from');
|
|
11
|
+
const to = parseInstant(data.to, 'to');
|
|
12
|
+
const deleted = await getAnalytics().deleteEvents({
|
|
13
|
+
from,
|
|
14
|
+
to,
|
|
15
|
+
...null == data.visitorHash ? {} : {
|
|
16
|
+
visitorHash: data.visitorHash
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
deleted
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
const rebuildAnalyticsDay = createServerFn({
|
|
24
|
+
method: 'POST'
|
|
25
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
26
|
+
await assertAnalyticsMaintenance();
|
|
27
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
28
|
+
await getAnalytics().rebuildDay(data.day);
|
|
29
|
+
return {
|
|
30
|
+
rebuilt: data.day
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
async function assertAnalyticsMaintenance() {
|
|
34
|
+
const context = await getAdminRequestContext();
|
|
35
|
+
assertAdminActor(context, ANALYTICS_ABILITIES.maintain);
|
|
36
|
+
}
|
|
37
|
+
function parseInstant(value, label) {
|
|
38
|
+
const date = new Date(value);
|
|
39
|
+
if (Number.isNaN(date.valueOf())) throw new Error(`analytics ${label} must be an ISO instant`);
|
|
40
|
+
return date;
|
|
41
|
+
}
|
|
42
|
+
export { deleteAnalyticsEvents, rebuildAnalyticsDay };
|
|
@@ -0,0 +1,25 @@
|
|
|
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 type { AnalyticsCountryTotal, AnalyticsDateRange, AnalyticsEventKind, AnalyticsPathTotal, AnalyticsRankedTotals, AnalyticsReferrerTotal, AnalyticsReportCoverage, AnalyticsSummary } from '@byline/analytics';
|
|
9
|
+
export interface AnalyticsTopInput extends AnalyticsDateRange {
|
|
10
|
+
kind: AnalyticsEventKind;
|
|
11
|
+
limit?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface AnalyticsRuntimeState {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const getAnalyticsRuntime: import("@tanstack/react-start").OptionalFetcher<undefined, undefined, Promise<AnalyticsRuntimeState>>;
|
|
17
|
+
export declare const getAnalyticsSummary: import("@tanstack/react-start").RequiredFetcher<undefined, (input: AnalyticsDateRange) => AnalyticsDateRange, Promise<AnalyticsSummary>>;
|
|
18
|
+
export declare const getAnalyticsReportCoverage: import("@tanstack/react-start").OptionalFetcher<undefined, undefined, Promise<AnalyticsReportCoverage>>;
|
|
19
|
+
export declare const getAnalyticsTop: import("@tanstack/react-start").RequiredFetcher<undefined, (input: AnalyticsTopInput) => AnalyticsTopInput, Promise<AnalyticsRankedTotals<AnalyticsPathTotal>>>;
|
|
20
|
+
export declare const getAnalyticsReferrers: import("@tanstack/react-start").RequiredFetcher<undefined, (input: AnalyticsDateRange & {
|
|
21
|
+
limit?: number;
|
|
22
|
+
}) => AnalyticsDateRange & {
|
|
23
|
+
limit?: number;
|
|
24
|
+
}, Promise<AnalyticsRankedTotals<AnalyticsReferrerTotal>>>;
|
|
25
|
+
export declare const getAnalyticsCountries: import("@tanstack/react-start").RequiredFetcher<undefined, (input: AnalyticsDateRange) => AnalyticsDateRange, Promise<AnalyticsCountryTotal[]>>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
2
|
+
import { assertAdminActor, requireAdminActor } from "@byline/admin";
|
|
3
|
+
import { ANALYTICS_ABILITIES } from "@byline/admin/analytics";
|
|
4
|
+
import { getAdminRequestContext } from "@byline/client/server";
|
|
5
|
+
const getAnalyticsRuntime = createServerFn({
|
|
6
|
+
method: 'GET'
|
|
7
|
+
}).handler(async ()=>{
|
|
8
|
+
const context = await getAdminRequestContext();
|
|
9
|
+
requireAdminActor(context, 'reading analytics runtime state');
|
|
10
|
+
const { isAnalyticsRegistered } = await import("@byline/analytics");
|
|
11
|
+
return {
|
|
12
|
+
enabled: isAnalyticsRegistered()
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
const getAnalyticsSummary = createServerFn({
|
|
16
|
+
method: 'GET'
|
|
17
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
18
|
+
await assertAnalyticsRead();
|
|
19
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
20
|
+
return getAnalytics().getSummary(data);
|
|
21
|
+
});
|
|
22
|
+
const getAnalyticsReportCoverage = createServerFn({
|
|
23
|
+
method: 'GET'
|
|
24
|
+
}).handler(async ()=>{
|
|
25
|
+
await assertAnalyticsRead();
|
|
26
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
27
|
+
return getAnalytics().getReportCoverage();
|
|
28
|
+
});
|
|
29
|
+
const getAnalyticsTop = createServerFn({
|
|
30
|
+
method: 'GET'
|
|
31
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
32
|
+
await assertAnalyticsRead();
|
|
33
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
34
|
+
return getAnalytics().getTopPaths(data);
|
|
35
|
+
});
|
|
36
|
+
const getAnalyticsReferrers = createServerFn({
|
|
37
|
+
method: 'GET'
|
|
38
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
39
|
+
await assertAnalyticsRead();
|
|
40
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
41
|
+
return getAnalytics().getReferrers(data);
|
|
42
|
+
});
|
|
43
|
+
const getAnalyticsCountries = createServerFn({
|
|
44
|
+
method: 'GET'
|
|
45
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
46
|
+
await assertAnalyticsRead();
|
|
47
|
+
const { getAnalytics } = await import("@byline/analytics");
|
|
48
|
+
return getAnalytics().getCountries(data);
|
|
49
|
+
});
|
|
50
|
+
async function assertAnalyticsRead() {
|
|
51
|
+
const context = await getAdminRequestContext();
|
|
52
|
+
assertAdminActor(context, ANALYTICS_ABILITIES.read);
|
|
53
|
+
}
|
|
54
|
+
export { getAnalyticsCountries, getAnalyticsReferrers, getAnalyticsReportCoverage, getAnalyticsRuntime, getAnalyticsSummary, getAnalyticsTop };
|
|
@@ -5,13 +5,4 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Copyright (c) Infonomic Company Limited
|
|
7
7
|
*/
|
|
8
|
-
export type ActorLabelMap
|
|
9
|
-
label: string;
|
|
10
|
-
}>;
|
|
11
|
-
/**
|
|
12
|
-
* Batch-resolve admin-user ids to display labels. Accepts the raw
|
|
13
|
-
* `createdBy` values straight off a page of shaped documents — nullish
|
|
14
|
-
* and duplicate entries are tolerated and deduplicated. Returns `{}`
|
|
15
|
-
* when there is nothing to resolve or no admin store is configured.
|
|
16
|
-
*/
|
|
17
|
-
export declare function resolveActorLabels(ids: Iterable<string | null | undefined>): Promise<ActorLabelMap>;
|
|
8
|
+
export { type ActorLabelMap, resolveActorLabels } from '../actors.js';
|
|
@@ -1,25 +1 @@
|
|
|
1
|
-
|
|
2
|
-
function labelFor(row) {
|
|
3
|
-
const name = [
|
|
4
|
-
row.given_name,
|
|
5
|
-
row.family_name
|
|
6
|
-
].filter(Boolean).join(' ');
|
|
7
|
-
return name || row.username || row.email;
|
|
8
|
-
}
|
|
9
|
-
async function resolveActorLabels(ids) {
|
|
10
|
-
const unique = [
|
|
11
|
-
...new Set([
|
|
12
|
-
...ids
|
|
13
|
-
].filter((id)=>'string' == typeof id && id.length > 0))
|
|
14
|
-
];
|
|
15
|
-
if (0 === unique.length) return {};
|
|
16
|
-
const store = bylineCore().adminStore;
|
|
17
|
-
if (null == store) return {};
|
|
18
|
-
const rows = await store.adminUsers.getByIds(unique);
|
|
19
|
-
const map = {};
|
|
20
|
-
for (const row of rows)map[row.id] = {
|
|
21
|
-
label: labelFor(row)
|
|
22
|
-
};
|
|
23
|
-
return map;
|
|
24
|
-
}
|
|
25
|
-
export { resolveActorLabels };
|
|
1
|
+
export { resolveActorLabels } from "../actors.js";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { getAdminBylineClient, getAdminRequestContext } from "@byline/client/server";
|
|
3
|
-
import { BylineError, ERR_NOT_FOUND, ErrorCodes,
|
|
3
|
+
import { BylineError, ERR_NOT_FOUND, ErrorCodes, documentAbilityKey, getCollectionSchemasForPath, getLogger, getServerConfig } from "@byline/core";
|
|
4
4
|
import { ensureCollection } from "../../integrations/api-utils.js";
|
|
5
|
+
import { resolveAdminDocumentRead } from "../admin-document-presentation.js";
|
|
5
6
|
import { serialise } from "./utils.js";
|
|
6
7
|
const getDocumentFn = createServerFn({
|
|
7
8
|
method: 'GET'
|
|
@@ -17,30 +18,13 @@ const getDocumentFn = createServerFn({
|
|
|
17
18
|
}).log(logger);
|
|
18
19
|
const client = getAdminBylineClient();
|
|
19
20
|
const handle = client.collection(path);
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
populate = '*';
|
|
26
|
-
resolvedDepth = depth;
|
|
27
|
-
} else if (autoRelationsActive) {
|
|
28
|
-
const populateMap = buildRelationSummaryPopulateMap(config.definition.fields, (targetPath)=>({
|
|
29
|
-
def: getCollectionDefinition(targetPath),
|
|
30
|
-
admin: getCollectionAdminConfig(targetPath)
|
|
31
|
-
}));
|
|
32
|
-
if (Object.keys(populateMap).length > 0) {
|
|
33
|
-
populate = populateMap;
|
|
34
|
-
resolvedDepth = 1;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
21
|
+
const { options: readOptions, populatedTree } = resolveAdminDocumentRead(config.definition, {
|
|
22
|
+
locale,
|
|
23
|
+
depth,
|
|
24
|
+
populateRelations
|
|
25
|
+
});
|
|
37
26
|
const document = await handle.findById(id, {
|
|
38
|
-
|
|
39
|
-
populate,
|
|
40
|
-
depth: resolvedDepth,
|
|
41
|
-
status: 'any',
|
|
42
|
-
onMissingLocale: 'empty',
|
|
43
|
-
lenient: true
|
|
27
|
+
...readOptions
|
|
44
28
|
});
|
|
45
29
|
if (!document) throw ERR_NOT_FOUND({
|
|
46
30
|
message: 'Document not found',
|
|
@@ -50,7 +34,6 @@ const getDocumentFn = createServerFn({
|
|
|
50
34
|
}
|
|
51
35
|
}).log(logger);
|
|
52
36
|
const serialised = serialise(document);
|
|
53
|
-
const populatedTree = populateRequested || autoRelationsActive;
|
|
54
37
|
const parsed = 'all' === locale || populatedTree ? serialised : (()=>{
|
|
55
38
|
const { get } = getCollectionSchemasForPath(path);
|
|
56
39
|
return get.parse(serialised);
|
|
@@ -77,7 +60,7 @@ const getDocumentFn = createServerFn({
|
|
|
77
60
|
let scheduledPublish = null;
|
|
78
61
|
if (scheduledPublicationEnabled) {
|
|
79
62
|
const actor = (await getAdminRequestContext()).actor;
|
|
80
|
-
canSchedulePublication = actor?.hasAbility(
|
|
63
|
+
canSchedulePublication = actor?.hasAbility(documentAbilityKey(config.definition, 'changeStatus')) === true && actor.hasAbility(documentAbilityKey(config.definition, 'publish'));
|
|
81
64
|
if (canSchedulePublication) scheduledPublish = await handle.getScheduledPublish(id);
|
|
82
65
|
}
|
|
83
66
|
const serializedSchedule = null == scheduledPublish ? null : serialise(scheduledPublish);
|
|
@@ -21,7 +21,7 @@ const reorderCollectionDocument = createServerFn({
|
|
|
21
21
|
}
|
|
22
22
|
}).log(logger);
|
|
23
23
|
const requestContext = await getAdminRequestContext();
|
|
24
|
-
assertActorCanPerform(requestContext,
|
|
24
|
+
assertActorCanPerform(requestContext, config.definition, 'update');
|
|
25
25
|
const serverConfig = getServerConfig();
|
|
26
26
|
const collectionId = config.collection.id;
|
|
27
27
|
const canonical = await serverConfig.db.queries.documents.getCanonicalDocumentOrder({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { getAdminBylineClient, getAdminRequestContext } from "@byline/client/server";
|
|
3
|
-
import { ERR_NOT_FOUND, ERR_VALIDATION } from "@byline/core";
|
|
3
|
+
import { ERR_NOT_FOUND, ERR_VALIDATION, isSingleton } from "@byline/core";
|
|
4
4
|
import { listDocumentPublishSchedules } from "@byline/core/services";
|
|
5
5
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
6
6
|
import { omitScheduleExecutionState } from "./scheduled-publication-response.js";
|
|
@@ -138,7 +138,7 @@ const listScheduledPublications = createServerFn({
|
|
|
138
138
|
return {
|
|
139
139
|
...serializeSchedule(schedule),
|
|
140
140
|
collectionPath: definition?.path ?? schedule.collectionId,
|
|
141
|
-
collectionLabel: definition
|
|
141
|
+
collectionLabel: null == definition ? schedule.collectionId : isSingleton(definition) ? definition.label : definition.labels.plural,
|
|
142
142
|
documentPath,
|
|
143
143
|
lastAuthorizedByName: null == schedule.lastAuthorizedBy ? null : authorizerNames.get(schedule.lastAuthorizedBy) ?? null
|
|
144
144
|
};
|
|
@@ -4,7 +4,7 @@ import { ERR_NOT_FOUND, ERR_VALIDATION, getServerConfig, getUploadFields } from
|
|
|
4
4
|
import { extractImageMeta, generateImageVariants, isBypassMimeType } from "@byline/core/image";
|
|
5
5
|
import { getLogger, withLogContext } from "@byline/core/logger";
|
|
6
6
|
import { uploadField } from "@byline/core/services";
|
|
7
|
-
import {
|
|
7
|
+
import { ensureDocumentResource } from "../../integrations/api-utils.js";
|
|
8
8
|
function parseUploadFormData(data) {
|
|
9
9
|
if (!(data instanceof FormData)) throw new Error('Expected FormData upload payload.');
|
|
10
10
|
const collectionEntry = data.get('collection');
|
|
@@ -64,9 +64,9 @@ const uploadCollectionField = createServerFn({
|
|
|
64
64
|
module: 'upload',
|
|
65
65
|
function: 'uploadCollectionField'
|
|
66
66
|
}, async ()=>{
|
|
67
|
-
const config = await
|
|
67
|
+
const config = await ensureDocumentResource(collectionPath);
|
|
68
68
|
if (null == config) throw ERR_NOT_FOUND({
|
|
69
|
-
message: '
|
|
69
|
+
message: 'Document resource not found.',
|
|
70
70
|
details: {
|
|
71
71
|
collectionPath
|
|
72
72
|
}
|
|
@@ -5,10 +5,4 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Copyright (c) Infonomic Company Limited
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
* Deep-serialise a value through JSON to convert Date objects to ISO strings.
|
|
10
|
-
* TanStack Start server functions pass return values directly during SSR
|
|
11
|
-
* (no automatic JSON round-trip), so Date instances from the DB driver would
|
|
12
|
-
* fail downstream Zod z.string() checks without this explicit step.
|
|
13
|
-
*/
|
|
14
|
-
export declare function serialise<T>(value: T): T;
|
|
8
|
+
export { serialise } from '../serialise.js';
|