@byline/host-tanstack-start 4.19.0 → 5.0.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.
Files changed (142) hide show
  1. package/dist/admin-shell/collections/edit.d.ts +1 -1
  2. package/dist/admin-shell/collections/edit.js +151 -31
  3. package/dist/admin-shell/collections/history.js +4 -2
  4. package/dist/admin-shell/collections/list.js +30 -6
  5. package/dist/admin-shell/collections/restore-version-modal.d.ts +3 -1
  6. package/dist/admin-shell/collections/restore-version-modal.js +9 -4
  7. package/dist/admin-shell/collections/tree-list.js +16 -6
  8. package/dist/admin-shell/collections/version-history.d.ts +2 -1
  9. package/dist/admin-shell/collections/version-history.js +11 -2
  10. package/dist/admin-shell/document-mutation-notice.d.ts +6 -0
  11. package/dist/admin-shell/document-mutation-notice.js +53 -0
  12. package/dist/admin-shell/document-mutation-state.d.ts +22 -0
  13. package/dist/admin-shell/document-mutation-state.js +71 -0
  14. package/dist/admin-shell/document-mutation-state.test.d.ts +1 -0
  15. package/dist/admin-shell/scheduled-publications/list.js +15 -5
  16. package/dist/admin-shell/singletons/history.js +4 -2
  17. package/dist/admin-shell/singletons/view.d.ts +1 -1
  18. package/dist/admin-shell/singletons/view.js +98 -19
  19. package/dist/integrations/byline-field-services.js +2 -9
  20. package/dist/routes/create-collection-edit-route.js +1 -1
  21. package/dist/routes/create-collection-list-route.d.ts +0 -7
  22. package/dist/routes/create-collection-list-route.js +7 -9
  23. package/dist/routes/create-singleton-route.d.ts +2 -0
  24. package/dist/routes/create-singleton-route.js +4 -3
  25. package/dist/server-fns/collections/copy-to-locale.d.ts +2 -7
  26. package/dist/server-fns/collections/copy-to-locale.js +4 -2
  27. package/dist/server-fns/collections/create.d.ts +1 -7
  28. package/dist/server-fns/collections/create.js +5 -3
  29. package/dist/server-fns/collections/delete-locale.d.ts +2 -7
  30. package/dist/server-fns/collections/delete-locale.js +4 -2
  31. package/dist/server-fns/collections/delete-outcome.d.ts +7 -3
  32. package/dist/server-fns/collections/delete-outcome.js +4 -0
  33. package/dist/server-fns/collections/delete.d.ts +2 -7
  34. package/dist/server-fns/collections/delete.js +5 -3
  35. package/dist/server-fns/collections/duplicate.d.ts +2 -7
  36. package/dist/server-fns/collections/duplicate.js +5 -3
  37. package/dist/server-fns/collections/get.d.ts +1 -7
  38. package/dist/server-fns/collections/get.js +5 -4
  39. package/dist/server-fns/collections/list.d.ts +0 -7
  40. package/dist/server-fns/collections/list.js +11 -3
  41. package/dist/server-fns/collections/reorder.d.ts +7 -8
  42. package/dist/server-fns/collections/reorder.js +20 -76
  43. package/dist/server-fns/collections/restore-version.d.ts +3 -7
  44. package/dist/server-fns/collections/restore-version.js +5 -2
  45. package/dist/server-fns/collections/save-outcome.d.ts +1 -0
  46. package/dist/server-fns/collections/save-outcome.js +1 -0
  47. package/dist/server-fns/collections/scheduled-publication.d.ts +49 -9
  48. package/dist/server-fns/collections/scheduled-publication.js +31 -21
  49. package/dist/server-fns/collections/status.d.ts +8 -7
  50. package/dist/server-fns/collections/status.js +13 -5
  51. package/dist/server-fns/collections/tree-mutation.d.ts +7 -6
  52. package/dist/server-fns/collections/tree-mutation.js +17 -5
  53. package/dist/server-fns/collections/tree.d.ts +14 -8
  54. package/dist/server-fns/collections/tree.js +21 -17
  55. package/dist/server-fns/collections/update.d.ts +12 -11
  56. package/dist/server-fns/collections/update.js +34 -20
  57. package/dist/server-fns/collections/upload.d.ts +1 -0
  58. package/dist/server-fns/collections/upload.js +3 -2
  59. package/dist/server-fns/document-mutation-errors.d.ts +5 -0
  60. package/dist/server-fns/document-mutation-errors.js +50 -0
  61. package/dist/server-fns/editable-revision.d.ts +9 -0
  62. package/dist/server-fns/editable-revision.js +11 -0
  63. package/dist/server-fns/singleton-document-read.d.ts +1 -1
  64. package/dist/server-fns/singleton-document-read.js +7 -3
  65. package/dist/server-fns/singletons/cancel-scheduled-publish.d.ts +6 -8
  66. package/dist/server-fns/singletons/cancel-scheduled-publish.js +4 -1
  67. package/dist/server-fns/singletons/change-status.d.ts +2 -7
  68. package/dist/server-fns/singletons/change-status.js +4 -1
  69. package/dist/server-fns/singletons/confirm-scheduled-publish.d.ts +5 -8
  70. package/dist/server-fns/singletons/confirm-scheduled-publish.js +4 -2
  71. package/dist/server-fns/singletons/copy-to-locale.d.ts +2 -7
  72. package/dist/server-fns/singletons/copy-to-locale.js +4 -2
  73. package/dist/server-fns/singletons/get.d.ts +4 -4
  74. package/dist/server-fns/singletons/restore-version.d.ts +2 -7
  75. package/dist/server-fns/singletons/restore-version.js +6 -3
  76. package/dist/server-fns/singletons/schedule-publish.d.ts +5 -8
  77. package/dist/server-fns/singletons/schedule-publish.js +4 -2
  78. package/dist/server-fns/singletons/unpublish.d.ts +2 -7
  79. package/dist/server-fns/singletons/unpublish.js +4 -1
  80. package/dist/server-fns/singletons/update.d.ts +4 -11
  81. package/dist/server-fns/singletons/update.js +5 -4
  82. package/dist/server-fns/structural-receipt.d.ts +4 -0
  83. package/dist/server-fns/structural-receipt.js +31 -0
  84. package/package.json +11 -11
  85. package/src/admin-shell/collections/edit.tsx +173 -54
  86. package/src/admin-shell/collections/history.tsx +11 -2
  87. package/src/admin-shell/collections/list.tsx +22 -6
  88. package/src/admin-shell/collections/restore-version-modal.tsx +12 -3
  89. package/src/admin-shell/collections/save-navigation.test.tsx +156 -8
  90. package/src/admin-shell/collections/tree-list.tsx +16 -6
  91. package/src/admin-shell/collections/version-history.tsx +13 -3
  92. package/src/admin-shell/document-mutation-notice.tsx +45 -0
  93. package/src/admin-shell/document-mutation-state.test.tsx +146 -0
  94. package/src/admin-shell/document-mutation-state.ts +95 -0
  95. package/src/admin-shell/scheduled-publications/list.tsx +16 -6
  96. package/src/admin-shell/singletons/history.test.tsx +3 -1
  97. package/src/admin-shell/singletons/history.tsx +10 -2
  98. package/src/admin-shell/singletons/view.test.tsx +59 -18
  99. package/src/admin-shell/singletons/view.tsx +110 -29
  100. package/src/integrations/byline-field-services.ts +2 -3
  101. package/src/routes/create-collection-edit-route.tsx +1 -0
  102. package/src/routes/create-collection-list-route.tsx +13 -2
  103. package/src/routes/create-singleton-route.test.node.ts +10 -2
  104. package/src/routes/create-singleton-route.tsx +6 -4
  105. package/src/server-fns/collections/copy-to-locale.ts +41 -36
  106. package/src/server-fns/collections/create.ts +54 -50
  107. package/src/server-fns/collections/delete-locale.ts +41 -32
  108. package/src/server-fns/collections/delete-outcome.test.node.ts +16 -0
  109. package/src/server-fns/collections/delete-outcome.ts +27 -16
  110. package/src/server-fns/collections/delete.ts +44 -38
  111. package/src/server-fns/collections/duplicate.ts +38 -32
  112. package/src/server-fns/collections/get.ts +8 -4
  113. package/src/server-fns/collections/list.ts +8 -3
  114. package/src/server-fns/collections/reorder.ts +32 -124
  115. package/src/server-fns/collections/restore-version.ts +47 -39
  116. package/src/server-fns/collections/revision-input.test.node.ts +108 -0
  117. package/src/server-fns/collections/save-outcome.test.node.ts +3 -0
  118. package/src/server-fns/collections/save-outcome.ts +2 -0
  119. package/src/server-fns/collections/scheduled-publication.ts +138 -111
  120. package/src/server-fns/collections/status.ts +86 -64
  121. package/src/server-fns/collections/tree-mutation.test.node.ts +87 -29
  122. package/src/server-fns/collections/tree-mutation.ts +28 -11
  123. package/src/server-fns/collections/tree.ts +150 -122
  124. package/src/server-fns/collections/update.ts +110 -86
  125. package/src/server-fns/collections/upload-singleton.test.node.ts +3 -7
  126. package/src/server-fns/collections/upload.ts +81 -77
  127. package/src/server-fns/document-mutation-errors.ts +67 -0
  128. package/src/server-fns/document-mutation-transport.test.node.ts +211 -0
  129. package/src/server-fns/editable-revision.test.node.ts +23 -0
  130. package/src/server-fns/editable-revision.ts +18 -0
  131. package/src/server-fns/singleton-document-read.ts +7 -3
  132. package/src/server-fns/singletons/cancel-scheduled-publish.ts +10 -3
  133. package/src/server-fns/singletons/change-status.ts +10 -3
  134. package/src/server-fns/singletons/confirm-scheduled-publish.ts +12 -6
  135. package/src/server-fns/singletons/copy-to-locale.ts +20 -15
  136. package/src/server-fns/singletons/get.ts +3 -3
  137. package/src/server-fns/singletons/restore-version.ts +17 -12
  138. package/src/server-fns/singletons/schedule-publish.ts +18 -7
  139. package/src/server-fns/singletons/singletons.test.node.ts +63 -25
  140. package/src/server-fns/singletons/unpublish.ts +10 -3
  141. package/src/server-fns/singletons/update.ts +21 -16
  142. package/src/server-fns/structural-receipt.ts +41 -0
@@ -1,10 +1,3 @@
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
1
  import type { DuplicateDocumentResult } from '@byline/core/services';
9
2
  import { type CollectionDocumentCommittedHookFailureResponse } from './save-outcome.js';
10
3
  /**
@@ -19,9 +12,11 @@ import { type CollectionDocumentCommittedHookFailureResponse } from './save-outc
19
12
  * TanStack Start's transport layer for the client to branch on.
20
13
  */
21
14
  export declare const duplicateCollectionDocument: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
15
+ expectedRevision: number;
22
16
  collection: string;
23
17
  id: string;
24
18
  }) => {
19
+ expectedRevision: number;
25
20
  collection: string;
26
21
  id: string;
27
22
  }, Promise<CollectionDocumentCommittedHookFailureResponse | DuplicateDocumentResult>>;
@@ -1,3 +1,4 @@
1
+ import { withDocumentMutationErrors } from "../document-mutation-errors.js";
1
2
  import { createServerFn } from "@tanstack/react-start";
2
3
  import { getAdminRequestContext } from "@byline/client/server";
3
4
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
@@ -6,7 +7,7 @@ import { ensureCollection } from "../../integrations/api-utils.js";
6
7
  import { toCommittedDocumentHookFailureResponse } from "./save-outcome.js";
7
8
  const duplicateCollectionDocument = createServerFn({
8
9
  method: 'POST'
9
- }).validator((input)=>input).handler(async ({ data: input })=>{
10
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data: input })=>{
10
11
  const { collection: path, id: sourceDocumentId } = input;
11
12
  const logger = getLogger();
12
13
  const config = await ensureCollection(path);
@@ -30,12 +31,13 @@ const duplicateCollectionDocument = createServerFn({
30
31
  };
31
32
  try {
32
33
  return await duplicateDocument(ctx, {
33
- sourceDocumentId
34
+ sourceDocumentId,
35
+ expectedRevision: input.expectedRevision
34
36
  });
35
37
  } catch (error) {
36
38
  const committedFailure = toCommittedDocumentHookFailureResponse(error);
37
39
  if (null != committedFailure) return committedFailure;
38
40
  throw error;
39
41
  }
40
- });
42
+ }));
41
43
  export { duplicateCollectionDocument };
@@ -1,10 +1,3 @@
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
1
  /**
9
2
  * Fetch a single document by ID. Returns `null` when the document is not found
10
3
  * so callers can degrade gracefully (e.g. `notFound()`).
@@ -16,6 +9,7 @@
16
9
  * `{target_document_id, target_collection_id}` refs.
17
10
  */
18
11
  export declare function getCollectionDocument(collection: string, id: string, locale?: string, depth?: number, populateRelations?: boolean): Promise<{
12
+ revision: number;
19
13
  _publishedVersion: Record<string, any> | null;
20
14
  _restoreWarnings?: string[] | undefined;
21
15
  availableLocales?: string[] | undefined;
@@ -1,3 +1,4 @@
1
+ import { withEditableRevision } from "../editable-revision.js";
1
2
  import { createServerFn } from "@tanstack/react-start";
2
3
  import { getAdminBylineClient, getAdminRequestContext } from "@byline/client/server";
3
4
  import { BylineError, ERR_NOT_FOUND, ErrorCodes, documentAbilityKey, getCollectionSchemasForPath, getLogger, getServerConfig } from "@byline/core";
@@ -18,12 +19,12 @@ const getDocumentFn = createServerFn({
18
19
  }).log(logger);
19
20
  const client = getAdminBylineClient();
20
21
  const handle = client.collection(path);
21
- const { options: readOptions, populatedTree } = resolveAdminDocumentRead(config.definition, {
22
+ const { options: { status: _status, ...readOptions }, populatedTree } = resolveAdminDocumentRead(config.definition, {
22
23
  locale,
23
24
  depth,
24
25
  populateRelations
25
26
  });
26
- const document = await handle.findById(id, {
27
+ const document = await handle.findByIdForEdit(id, {
27
28
  ...readOptions
28
29
  });
29
30
  if (!document) throw ERR_NOT_FOUND({
@@ -61,11 +62,11 @@ const getDocumentFn = createServerFn({
61
62
  if (scheduledPublicationEnabled) {
62
63
  const actor = (await getAdminRequestContext()).actor;
63
64
  canSchedulePublication = actor?.hasAbility(documentAbilityKey(config.definition, 'changeStatus')) === true && actor.hasAbility(documentAbilityKey(config.definition, 'publish'));
64
- if (canSchedulePublication) scheduledPublish = await handle.getScheduledPublish(id);
65
+ if (canSchedulePublication) scheduledPublish = document.scheduledPublication;
65
66
  }
66
67
  const serializedSchedule = null == scheduledPublish ? null : serialise(scheduledPublish);
67
68
  return {
68
- ...parsed,
69
+ ...withEditableRevision(parsed, document),
69
70
  _publishedVersion: publishedVersion,
70
71
  ...restoreWarnings && restoreWarnings.length > 0 ? {
71
72
  _restoreWarnings: restoreWarnings
@@ -1,10 +1,3 @@
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
1
  export interface CollectionSearchParams {
9
2
  page?: number;
10
3
  page_size?: number;
@@ -1,3 +1,4 @@
1
+ import { withEditableRevision } from "../editable-revision.js";
1
2
  import { createServerFn } from "@tanstack/react-start";
2
3
  import { getPreferenceCommand } from "@byline/admin/admin-preferences";
3
4
  import { getAdminBylineClient, getAdminRequestContext } from "@byline/client/server";
@@ -61,7 +62,7 @@ const getCollectionDocuments = createServerFn({
61
62
  }));
62
63
  const hasRelations = Object.keys(populateMap).length > 0;
63
64
  const populate = hasRelations ? populateMap : void 0;
64
- const result = await handle.find({
65
+ const result = await handle.findForEdit({
65
66
  where: Object.keys(where).length > 0 ? where : void 0,
66
67
  sort: viewState.sort,
67
68
  locale: params.locale ?? 'en',
@@ -70,7 +71,6 @@ const getCollectionDocuments = createServerFn({
70
71
  select: params.fields,
71
72
  populate,
72
73
  depth: hasRelations ? 1 : void 0,
73
- status: 'any',
74
74
  onMissingLocale: 'empty'
75
75
  });
76
76
  const documentIds = result.docs.map((d)=>d.id);
@@ -104,6 +104,14 @@ const getCollectionDocuments = createServerFn({
104
104
  const serialised = serialise(response);
105
105
  const { list } = getCollectionSchemasForPath(path);
106
106
  if (hasRelations) return serialised;
107
- return list.parse(serialised);
107
+ const parsed = list.parse(serialised);
108
+ const observations = new Map(result.docs.map((doc)=>[
109
+ doc.id,
110
+ doc
111
+ ]));
112
+ return {
113
+ ...parsed,
114
+ docs: parsed.docs.map((doc)=>withEditableRevision(doc, observations.get(doc.id)))
115
+ };
108
116
  });
109
117
  export { getCollectionDocuments };
@@ -1,21 +1,20 @@
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
1
  export declare const reorderCollectionDocument: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
2
+ expectedRevision: number;
9
3
  collection: string;
10
4
  documentId: string;
11
5
  beforeDocumentId?: string | null;
12
6
  afterDocumentId?: string | null;
13
7
  }) => {
8
+ expectedRevision: number;
14
9
  collection: string;
15
10
  documentId: string;
16
11
  beforeDocumentId?: string | null;
17
12
  afterDocumentId?: string | null;
18
13
  }, Promise<{
19
- status: 'ok';
14
+ documentId: string;
15
+ revision: number;
16
+ affectedDocuments: import("@byline/core").DocumentRevisionReceipt[];
17
+ scheduledPublicationsNeedReconfirmation: boolean;
20
18
  orderKey: string;
19
+ status: 'ok';
21
20
  }>>;
@@ -1,10 +1,11 @@
1
+ import { withDocumentMutationErrors } from "../document-mutation-errors.js";
1
2
  import { createServerFn } from "@tanstack/react-start";
2
3
  import { getAdminRequestContext } from "@byline/client/server";
3
- import { ERR_NOT_FOUND, ERR_VALIDATION, assertActorCanPerform, generateKeyBetween, generateNKeysBetween, getLogger, getServerConfig } from "@byline/core";
4
+ import { ERR_NOT_FOUND, getLogger, getServerConfig, reorderDocument } from "@byline/core";
4
5
  import { ensureCollection } from "../../integrations/api-utils.js";
5
6
  const reorderCollectionDocument = createServerFn({
6
7
  method: 'POST'
7
- }).validator((input)=>input).handler(async ({ data: input })=>{
8
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data: input })=>{
8
9
  const { collection: path, documentId, beforeDocumentId, afterDocumentId } = input;
9
10
  const logger = getLogger();
10
11
  const config = await ensureCollection(path);
@@ -14,83 +15,26 @@ const reorderCollectionDocument = createServerFn({
14
15
  collectionPath: path
15
16
  }
16
17
  }).log(logger);
17
- if (true !== config.definition.orderable) throw ERR_VALIDATION({
18
- message: `collection '${path}' is not orderable; set \`orderable: true\` on its collection definition to enable reordering`,
19
- details: {
20
- collectionPath: path
21
- }
22
- }).log(logger);
23
- const requestContext = await getAdminRequestContext();
24
- assertActorCanPerform(requestContext, config.definition, 'update');
25
18
  const serverConfig = getServerConfig();
26
- const collectionId = config.collection.id;
27
- const canonical = await serverConfig.db.queries.documents.getCanonicalDocumentOrder({
28
- collection_id: collectionId
29
- });
30
- let corrupted = false;
31
- {
32
- const seen = new Set();
33
- let lastKey = null;
34
- for (const doc of canonical)if (null != doc.order_key) {
35
- if (seen.has(doc.order_key)) {
36
- corrupted = true;
37
- break;
38
- }
39
- if (null != lastKey && doc.order_key <= lastKey) {
40
- corrupted = true;
41
- break;
42
- }
43
- seen.add(doc.order_key);
44
- lastKey = doc.order_key;
45
- }
46
- }
47
- if (corrupted) {
48
- const allKeys = generateNKeysBetween(null, null, canonical.length);
49
- for(let i = 0; i < canonical.length; i++)await serverConfig.db.commands.documents.setOrderKey({
50
- document_id: canonical[i]?.id,
51
- order_key: allKeys[i]
52
- });
53
- } else {
54
- const firstNullIdx = canonical.findIndex((d)=>null == d.order_key);
55
- if (-1 !== firstNullIdx) {
56
- const nullDocs = canonical.slice(firstNullIdx);
57
- const lastExistingKey = 0 === firstNullIdx ? null : canonical[firstNullIdx - 1]?.order_key;
58
- const newKeys = generateNKeysBetween(lastExistingKey, null, nullDocs.length);
59
- for(let i = 0; i < nullDocs.length; i++)await serverConfig.db.commands.documents.setOrderKey({
60
- document_id: nullDocs[i]?.id,
61
- order_key: newKeys[i]
62
- });
63
- }
64
- }
65
- const { left, right } = await serverConfig.db.queries.documents.getNeighborOrderKeys({
66
- collection_id: collectionId,
67
- before_document_id: beforeDocumentId ?? null,
68
- after_document_id: afterDocumentId ?? null
69
- });
70
- let newKey;
71
- try {
72
- newKey = generateKeyBetween(left, right);
73
- } catch (err) {
74
- throw ERR_VALIDATION({
75
- message: 'cannot generate order_key between supplied neighbors',
76
- details: {
77
- collectionPath: path,
78
- documentId,
79
- beforeDocumentId,
80
- afterDocumentId,
81
- left,
82
- right,
83
- cause: err instanceof Error ? err.message : String(err)
84
- }
85
- }).log(logger);
86
- }
87
- await serverConfig.db.commands.documents.setOrderKey({
88
- document_id: documentId,
89
- order_key: newKey
19
+ const result = await reorderDocument({
20
+ db: serverConfig.db,
21
+ definition: config.definition,
22
+ collectionId: config.collection.id,
23
+ collectionVersion: config.collection.version,
24
+ collectionPath: path,
25
+ requestContext: await getAdminRequestContext(),
26
+ logger,
27
+ defaultLocale: serverConfig.i18n.content.defaultLocale,
28
+ slugifier: serverConfig.slugifier
29
+ }, {
30
+ documentId,
31
+ expectedRevision: input.expectedRevision,
32
+ beforeDocumentId,
33
+ afterDocumentId
90
34
  });
91
35
  return {
92
36
  status: 'ok',
93
- orderKey: newKey
37
+ ...result
94
38
  };
95
- });
39
+ }));
96
40
  export { reorderCollectionDocument };
@@ -1,21 +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
1
  export declare const restoreDocumentVersion: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
2
+ expectedRevision: number;
9
3
  collection: string;
10
4
  id: string;
11
5
  versionId: string;
12
6
  }) => {
7
+ expectedRevision: number;
13
8
  collection: string;
14
9
  id: string;
15
10
  versionId: string;
16
11
  }, Promise<import("./save-outcome.js").CollectionDocumentCommittedHookFailureResponse | {
17
12
  status: 'ok';
18
13
  documentId: string;
14
+ revision: number;
19
15
  documentVersionId: string;
20
16
  sourceVersionId: string;
21
17
  }>>;
@@ -1,3 +1,4 @@
1
+ import { withDocumentMutationErrors } from "../document-mutation-errors.js";
1
2
  import { createServerFn } from "@tanstack/react-start";
2
3
  import { getAdminRequestContext } from "@byline/client/server";
3
4
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
@@ -6,7 +7,7 @@ import { ensureCollection } from "../../integrations/api-utils.js";
6
7
  import { toCommittedDocumentHookFailureResponse } from "./save-outcome.js";
7
8
  const restore_version_restoreDocumentVersion = createServerFn({
8
9
  method: 'POST'
9
- }).validator((input)=>input).handler(async ({ data: input })=>{
10
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data: input })=>{
10
11
  const { collection: path, id, versionId } = input;
11
12
  const logger = getLogger();
12
13
  const config = await ensureCollection(path);
@@ -31,11 +32,13 @@ const restore_version_restoreDocumentVersion = createServerFn({
31
32
  try {
32
33
  const result = await restoreDocumentVersion(ctx, {
33
34
  documentId: id,
35
+ expectedRevision: input.expectedRevision,
34
36
  sourceVersionId: versionId
35
37
  });
36
38
  return {
37
39
  status: 'ok',
38
40
  documentId: result.documentId,
41
+ revision: result.revision,
39
42
  documentVersionId: result.documentVersionId,
40
43
  sourceVersionId: result.sourceVersionId
41
44
  };
@@ -44,5 +47,5 @@ const restore_version_restoreDocumentVersion = createServerFn({
44
47
  if (null != committedFailure) return committedFailure;
45
48
  throw error;
46
49
  }
47
- });
50
+ }));
48
51
  export { restore_version_restoreDocumentVersion as restoreDocumentVersion };
@@ -10,6 +10,7 @@ export interface CollectionDocumentCommittedHookFailureResponse {
10
10
  status: 'committed-hook-failed';
11
11
  documentId: string;
12
12
  documentVersionId: string;
13
+ revision: number;
13
14
  sideEffectFailure: {
14
15
  phase: DocumentHookCommittedPhase;
15
16
  code: DocumentHookSideEffectCode;
@@ -6,6 +6,7 @@ function toCommittedDocumentHookFailureResponse(error) {
6
6
  status: 'committed-hook-failed',
7
7
  documentId: details.documentId,
8
8
  documentVersionId: details.documentVersionId,
9
+ revision: details.revision,
9
10
  sideEffectFailure: {
10
11
  phase: details.phase,
11
12
  code: details.sideEffectCode
@@ -1,10 +1,3 @@
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
1
  import type { DocumentPublishScheduleInfo } from '@byline/client';
9
2
  import { type DocumentPublishScheduleState, type RecurringTaskHealth } from '@byline/core';
10
3
  export interface ScheduledPublicationRuntime {
@@ -31,6 +24,7 @@ export type SerializedDocumentPublishSchedule = Omit<DocumentPublishScheduleInfo
31
24
  nextAttemptAt: string;
32
25
  };
33
26
  export interface ScheduledPublicationListItem extends SerializedDocumentPublishSchedule {
27
+ revision: number;
34
28
  collectionPath: string;
35
29
  collectionLabel: string;
36
30
  documentPath: string | null;
@@ -56,37 +50,83 @@ export interface ScheduledPublicationListResponse {
56
50
  /** Authenticated feature discovery for the admin shell and health warning. */
57
51
  export declare const getScheduledPublicationRuntime: import("@tanstack/react-start").OptionalFetcher<undefined, undefined, Promise<ScheduledPublicationRuntime>>;
58
52
  export declare const scheduleCollectionDocumentPublish: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
53
+ expectedRevision: number;
59
54
  collection: string;
60
55
  id: string;
61
56
  publishAt: string;
62
57
  expectedVersionId: string;
63
58
  }) => {
59
+ expectedRevision: number;
64
60
  collection: string;
65
61
  id: string;
66
62
  publishAt: string;
67
63
  expectedVersionId: string;
68
- }, Promise<SerializedDocumentPublishSchedule>>;
64
+ }, Promise<{
65
+ authorizedRevision: number | null;
66
+ documentId: string;
67
+ collectionId: string;
68
+ targetVersionId: string;
69
+ state: DocumentPublishScheduleState;
70
+ suspendedReason: ("content_edited" | "document_metadata_changed" | "upgrade_invalidated") | null;
71
+ scheduledBy: string | null;
72
+ lastAuthorizedBy: string | null;
73
+ attemptCount: number;
74
+ lastError: string | null;
75
+ publishAt: string;
76
+ suspendedAt: string | null;
77
+ lastAuthorizedAt: string;
78
+ scheduledAt: string;
79
+ updatedAt: string;
80
+ lastAttemptAt: string | null;
81
+ nextAttemptAt: string;
82
+ revision: number;
83
+ }>>;
69
84
  export declare const confirmCollectionDocumentScheduledPublish: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
85
+ expectedRevision: number;
70
86
  collection: string;
71
87
  id: string;
72
88
  expectedVersionId: string;
73
89
  }) => {
90
+ expectedRevision: number;
74
91
  collection: string;
75
92
  id: string;
76
93
  expectedVersionId: string;
77
- }, Promise<SerializedDocumentPublishSchedule>>;
94
+ }, Promise<{
95
+ authorizedRevision: number | null;
96
+ documentId: string;
97
+ collectionId: string;
98
+ targetVersionId: string;
99
+ state: DocumentPublishScheduleState;
100
+ suspendedReason: ("content_edited" | "document_metadata_changed" | "upgrade_invalidated") | null;
101
+ scheduledBy: string | null;
102
+ lastAuthorizedBy: string | null;
103
+ attemptCount: number;
104
+ lastError: string | null;
105
+ publishAt: string;
106
+ suspendedAt: string | null;
107
+ lastAuthorizedAt: string;
108
+ scheduledAt: string;
109
+ updatedAt: string;
110
+ lastAttemptAt: string | null;
111
+ nextAttemptAt: string;
112
+ revision: number;
113
+ }>>;
78
114
  export declare const cancelCollectionDocumentScheduledPublish: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
115
+ expectedRevision: number;
79
116
  collection: string;
80
117
  id: string;
81
118
  }) => {
119
+ expectedRevision: number;
82
120
  collection: string;
83
121
  id: string;
84
122
  }, Promise<{
85
123
  status: 'not_found';
124
+ revision: number;
86
125
  schedule?: undefined;
87
126
  } | {
88
127
  status: 'cancelled';
89
128
  schedule: SerializedDocumentPublishSchedule;
129
+ revision: number;
90
130
  }>>;
91
131
  export declare const listScheduledPublications: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
92
132
  states?: readonly DocumentPublishScheduleState[];
@@ -1,3 +1,4 @@
1
+ import { withDocumentMutationErrors } from "../document-mutation-errors.js";
1
2
  import { createServerFn } from "@tanstack/react-start";
2
3
  import { getAdminBylineClient, getAdminRequestContext } from "@byline/client/server";
3
4
  import { ERR_NOT_FOUND, ERR_VALIDATION, isSingleton } from "@byline/core";
@@ -52,44 +53,56 @@ async function scheduledPublicationRuntime() {
52
53
  }
53
54
  const getScheduledPublicationRuntime = createServerFn({
54
55
  method: 'GET'
55
- }).handler(async ()=>{
56
+ }).handler(withDocumentMutationErrors(async ()=>{
56
57
  await getAdminRequestContext();
57
58
  return scheduledPublicationRuntime();
58
- });
59
+ }));
59
60
  const scheduleCollectionDocumentPublish = createServerFn({
60
61
  method: 'POST'
61
- }).validator((input)=>input).handler(async ({ data })=>{
62
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data })=>{
62
63
  assertFeatureEnabled();
63
64
  const schedule = await getAdminBylineClient().collection(data.collection).schedulePublish(data.id, {
64
65
  publishAt: data.publishAt,
66
+ expectedRevision: data.expectedRevision,
65
67
  expectedVersionId: data.expectedVersionId
66
68
  });
67
- return serializeSchedule(schedule);
68
- });
69
+ return {
70
+ ...serializeSchedule(schedule),
71
+ revision: schedule.revision
72
+ };
73
+ }));
69
74
  const confirmCollectionDocumentScheduledPublish = createServerFn({
70
75
  method: 'POST'
71
- }).validator((input)=>input).handler(async ({ data })=>{
76
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data })=>{
72
77
  assertFeatureEnabled();
73
78
  const schedule = await getAdminBylineClient().collection(data.collection).confirmScheduledPublish(data.id, {
79
+ expectedRevision: data.expectedRevision,
74
80
  expectedVersionId: data.expectedVersionId
75
81
  });
76
- return serializeSchedule(schedule);
77
- });
82
+ return {
83
+ ...serializeSchedule(schedule),
84
+ revision: schedule.revision
85
+ };
86
+ }));
78
87
  const cancelCollectionDocumentScheduledPublish = createServerFn({
79
88
  method: 'POST'
80
- }).validator((input)=>input).handler(async ({ data })=>{
89
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data })=>{
81
90
  assertFeatureEnabled();
82
- const schedule = await getAdminBylineClient().collection(data.collection).cancelScheduledPublish(data.id);
83
- return null == schedule ? {
84
- status: 'not_found'
91
+ const schedule = await getAdminBylineClient().collection(data.collection).cancelScheduledPublish(data.id, {
92
+ expectedRevision: data.expectedRevision
93
+ });
94
+ return null == schedule.schedule ? {
95
+ status: 'not_found',
96
+ revision: schedule.revision
85
97
  } : {
86
98
  status: 'cancelled',
87
- schedule: serializeSchedule(schedule)
99
+ schedule: serializeSchedule(schedule.schedule),
100
+ revision: schedule.revision
88
101
  };
89
- });
102
+ }));
90
103
  const listScheduledPublications = createServerFn({
91
104
  method: 'GET'
92
- }).validator((input)=>input).handler(async ({ data })=>{
105
+ }).validator((input)=>input).handler(withDocumentMutationErrors(async ({ data })=>{
93
106
  assertFeatureEnabled();
94
107
  if (data.states?.some((state)=>'armed' !== state && 'needs_reconfirm' !== state) === true) throw ERR_VALIDATION({
95
108
  message: 'state must be armed or needs_reconfirm'
@@ -131,15 +144,12 @@ const listScheduledPublications = createServerFn({
131
144
  }
132
145
  const schedules = await Promise.all(result.schedules.map(async (schedule)=>{
133
146
  const definition = collections.get(schedule.collectionId);
134
- const documentPath = await core.db.queries.documents.getCurrentPath({
135
- collection_id: schedule.collectionId,
136
- document_id: schedule.documentId
137
- });
138
147
  return {
139
148
  ...serializeSchedule(schedule),
140
149
  collectionPath: definition?.path ?? schedule.collectionId,
141
150
  collectionLabel: null == definition ? schedule.collectionId : isSingleton(definition) ? definition.label : definition.labels.plural,
142
- documentPath,
151
+ documentPath: schedule.documentPath,
152
+ revision: schedule.revision,
143
153
  lastAuthorizedByName: null == schedule.lastAuthorizedBy ? null : authorizerNames.get(schedule.lastAuthorizedBy) ?? null
144
154
  };
145
155
  }));
@@ -153,5 +163,5 @@ const listScheduledPublications = createServerFn({
153
163
  },
154
164
  runtime: await scheduledPublicationRuntime()
155
165
  };
156
- });
166
+ }));
157
167
  export { cancelCollectionDocumentScheduledPublish, confirmCollectionDocumentScheduledPublish, getScheduledPublicationRuntime, listScheduledPublications, scheduleCollectionDocumentPublish };
@@ -1,30 +1,31 @@
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
1
  export declare const updateDocumentStatus: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
2
+ expectedRevision: number;
9
3
  collection: string;
10
4
  id: string;
11
5
  status: string;
12
6
  }) => {
7
+ expectedRevision: number;
13
8
  collection: string;
14
9
  id: string;
15
10
  status: string;
16
11
  }, Promise<{
17
12
  status: 'ok';
13
+ documentId: string;
14
+ revision: number;
18
15
  previousStatus: string;
19
16
  newStatus: string;
20
17
  }>>;
21
18
  export declare const unpublishDocument: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
19
+ expectedRevision: number;
22
20
  collection: string;
23
21
  id: string;
24
22
  }) => {
23
+ expectedRevision: number;
25
24
  collection: string;
26
25
  id: string;
27
26
  }, Promise<{
28
27
  status: 'ok';
28
+ documentId: string;
29
+ revision: number;
29
30
  archivedCount: number;
30
31
  }>>;