@researchdatabox/redbox-core 5.0.4-beta.12498 → 5.1.0-beta.12568
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/DatastreamService.d.ts +2 -0
- package/dist/DatastreamService.d.ts.map +1 -1
- package/dist/QueueService.d.ts +1 -1
- package/dist/QueueService.d.ts.map +1 -1
- package/dist/RecordStorageConcurrency.d.ts +2 -1
- package/dist/RecordStorageConcurrency.d.ts.map +1 -1
- package/dist/RecordStorageConcurrency.js +1 -1
- package/dist/RecordWriteOptions.d.ts +21 -0
- package/dist/RecordWriteOptions.d.ts.map +1 -0
- package/dist/RecordWriteOptions.js +17 -0
- package/dist/RecordsService.d.ts +5 -0
- package/dist/RecordsService.d.ts.map +1 -1
- package/dist/RecordsService.js +1 -1
- package/dist/StorageService.d.ts +12 -0
- package/dist/StorageService.d.ts.map +1 -1
- package/dist/StorageService.js +1 -1
- package/dist/api-routes/schemas/responses.d.ts +1 -1
- package/dist/config/agendaQueue.config.d.ts.map +1 -1
- package/dist/config/agendaQueue.config.js +10 -1
- package/dist/config/i18n.config.d.ts +4 -0
- package/dist/config/i18n.config.d.ts.map +1 -1
- package/dist/config/i18n.config.js +1 -1
- package/dist/configmodels/FigsharePublishing.d.ts +103 -0
- package/dist/configmodels/FigsharePublishing.d.ts.map +1 -1
- package/dist/configmodels/FigsharePublishing.js +36 -2
- package/dist/controllers/RecordAuditController.d.ts.map +1 -1
- package/dist/controllers/RecordAuditController.js +24 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/model/storage/FigshareSyncModel.d.ts +126 -0
- package/dist/model/storage/FigshareSyncModel.d.ts.map +1 -0
- package/dist/model/storage/FigshareSyncModel.js +3 -0
- package/dist/model/storage/RecordAuditModel.d.ts +3 -0
- package/dist/model/storage/RecordAuditModel.d.ts.map +1 -1
- package/dist/model/storage/RecordAuditModel.js +29 -1
- package/dist/model/storage/RecordModel.d.ts +3 -0
- package/dist/model/storage/RecordModel.d.ts.map +1 -1
- package/dist/services/AgendaQueueService.d.ts +1 -1
- package/dist/services/AgendaQueueService.d.ts.map +1 -1
- package/dist/services/AgendaQueueService.js +7 -4
- package/dist/services/FigshareService.d.ts +15 -10
- package/dist/services/FigshareService.d.ts.map +1 -1
- package/dist/services/FigshareService.js +76 -576
- package/dist/services/I18nEntriesService.d.ts +13 -12
- package/dist/services/I18nEntriesService.d.ts.map +1 -1
- package/dist/services/I18nEntriesService.js +103 -65
- package/dist/services/RecordsService.d.ts +5 -1
- package/dist/services/RecordsService.d.ts.map +1 -1
- package/dist/services/RecordsService.js +77 -23
- package/dist/services/StandardDatastreamService.d.ts +5 -0
- package/dist/services/StandardDatastreamService.d.ts.map +1 -1
- package/dist/services/StandardDatastreamService.js +18 -1
- package/dist/services/figshare-v2/admin.d.ts +16 -0
- package/dist/services/figshare-v2/admin.d.ts.map +1 -0
- package/dist/services/figshare-v2/admin.js +283 -0
- package/dist/services/figshare-v2/assets.d.ts +20 -1
- package/dist/services/figshare-v2/assets.d.ts.map +1 -1
- package/dist/services/figshare-v2/assets.js +16 -1
- package/dist/services/figshare-v2/config.d.ts +8 -2
- package/dist/services/figshare-v2/config.d.ts.map +1 -1
- package/dist/services/figshare-v2/config.js +31 -3
- package/dist/services/figshare-v2/execution.d.ts +25 -0
- package/dist/services/figshare-v2/execution.d.ts.map +1 -0
- package/dist/services/figshare-v2/execution.js +49 -0
- package/dist/services/figshare-v2/http.d.ts +6 -1
- package/dist/services/figshare-v2/http.d.ts.map +1 -1
- package/dist/services/figshare-v2/http.js +69 -12
- package/dist/services/figshare-v2/identity.d.ts +12 -0
- package/dist/services/figshare-v2/identity.d.ts.map +1 -0
- package/dist/services/figshare-v2/identity.js +78 -0
- package/dist/services/figshare-v2/managed-assets.d.ts +9 -0
- package/dist/services/figshare-v2/managed-assets.d.ts.map +1 -0
- package/dist/services/figshare-v2/managed-assets.js +229 -0
- package/dist/services/figshare-v2/plan.d.ts.map +1 -1
- package/dist/services/figshare-v2/plan.js +2 -9
- package/dist/services/figshare-v2/source-intent.d.ts +9 -0
- package/dist/services/figshare-v2/source-intent.d.ts.map +1 -0
- package/dist/services/figshare-v2/source-intent.js +93 -0
- package/dist/services/figshare-v2/status.d.ts +4 -0
- package/dist/services/figshare-v2/status.d.ts.map +1 -0
- package/dist/services/figshare-v2/status.js +29 -0
- package/dist/services/figshare-v2/sync-store.d.ts +27 -0
- package/dist/services/figshare-v2/sync-store.d.ts.map +1 -0
- package/dist/services/figshare-v2/sync-store.js +139 -0
- package/dist/services/figshare-v2/types.d.ts +3 -0
- package/dist/services/figshare-v2/types.d.ts.map +1 -1
- package/dist/services/figshare-v2/types.js +1 -1
- package/dist/services/figshare-v2/worker.d.ts +16 -0
- package/dist/services/figshare-v2/worker.d.ts.map +1 -0
- package/dist/services/figshare-v2/worker.js +752 -0
- package/dist/utilities/TranslationHtml.d.ts +3 -0
- package/dist/utilities/TranslationHtml.d.ts.map +1 -0
- package/dist/utilities/TranslationHtml.js +46 -0
- package/dist/waterline-models/FigshareSync.d.ts +41 -0
- package/dist/waterline-models/FigshareSync.d.ts.map +1 -0
- package/dist/waterline-models/FigshareSync.js +168 -0
- package/dist/waterline-models/index.d.ts +2 -0
- package/dist/waterline-models/index.d.ts.map +1 -1
- package/dist/waterline-models/index.js +4 -1
- package/package.json +9 -8
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.contentHash = void 0;
|
|
7
|
+
exports.getSyncStore = getSyncStore;
|
|
8
|
+
exports.projectionPaths = projectionPaths;
|
|
9
|
+
exports.importRecordIntent = importRecordIntent;
|
|
10
|
+
exports.dispatchFigshare = dispatchFigshare;
|
|
11
|
+
exports.runFigshareWorker = runFigshareWorker;
|
|
12
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
13
|
+
const node_crypto_1 = require("node:crypto");
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
const FigsharePublishing_1 = require("../../configmodels/FigsharePublishing");
|
|
16
|
+
const config_1 = require("./config");
|
|
17
|
+
const sync_store_1 = require("./sync-store");
|
|
18
|
+
const execution_1 = require("./execution");
|
|
19
|
+
const identity_1 = require("./identity");
|
|
20
|
+
const source_intent_1 = require("./source-intent");
|
|
21
|
+
const http_1 = require("./http");
|
|
22
|
+
const runtime_1 = require("./runtime");
|
|
23
|
+
const embargo_1 = require("./embargo");
|
|
24
|
+
const managed_assets_1 = require("./managed-assets");
|
|
25
|
+
const audit_1 = require("./audit");
|
|
26
|
+
const context_1 = require("./context");
|
|
27
|
+
const IntegrationAuditModel_1 = require("../../model/storage/IntegrationAuditModel");
|
|
28
|
+
const RecordWriteOptions_1 = require("../../RecordWriteOptions");
|
|
29
|
+
const contentHash = (value) => {
|
|
30
|
+
const canonical = (v) => Array.isArray(v)
|
|
31
|
+
? v.map(canonical)
|
|
32
|
+
: v && typeof v === 'object'
|
|
33
|
+
? Object.fromEntries(Object.entries(v)
|
|
34
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
35
|
+
.map(([k, x]) => [k, canonical(x)]))
|
|
36
|
+
: v;
|
|
37
|
+
return (0, node_crypto_1.createHash)('sha256')
|
|
38
|
+
.update(JSON.stringify(canonical(value)))
|
|
39
|
+
.digest('hex');
|
|
40
|
+
};
|
|
41
|
+
exports.contentHash = contentHash;
|
|
42
|
+
function getSyncStore() {
|
|
43
|
+
const manager = FigshareSync.getDatastore().manager;
|
|
44
|
+
return new sync_store_1.FigshareSyncStore(manager);
|
|
45
|
+
}
|
|
46
|
+
function projectionPaths(config) {
|
|
47
|
+
return [
|
|
48
|
+
...new Set([
|
|
49
|
+
config.record.articleIdPath,
|
|
50
|
+
config.record.statusPath,
|
|
51
|
+
config.record.errorPath,
|
|
52
|
+
config.record.syncStatePath,
|
|
53
|
+
config.record.dataLocationsPath,
|
|
54
|
+
config.record.allFilesUploadedPath,
|
|
55
|
+
config.writeBack.articleId,
|
|
56
|
+
...config.writeBack.articleUrls,
|
|
57
|
+
...config.writeBack.extraFields.map(f => f.targetPath),
|
|
58
|
+
].filter((p) => !!p)),
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
/** Source import never acknowledges before durable state exists. Queue delivery is disposable. */
|
|
62
|
+
async function importRecordIntent(store, record) {
|
|
63
|
+
const intent = record.figshareSyncIntent;
|
|
64
|
+
if (!intent?.pending || intent.readiness !== 'ready')
|
|
65
|
+
return;
|
|
66
|
+
const storage = RecordsService.getFigshareIntentStorage();
|
|
67
|
+
if (!storage.acknowledgeFigshareIntent)
|
|
68
|
+
throw new Error('Storage adapter cannot acknowledge Figshare intent');
|
|
69
|
+
await store.importSource(record.redboxOid, record.metaMetadata.brandId, intent);
|
|
70
|
+
await storage.acknowledgeFigshareIntent(record.redboxOid, intent.generation);
|
|
71
|
+
}
|
|
72
|
+
const PAUSED_DISPATCH_BACKOFF_MS = 5 * 60 * 1000;
|
|
73
|
+
// Failed saves abandon their intent explicitly, so only saves interrupted by a process stop reach this
|
|
74
|
+
// threshold. It is set well beyond any synchronous post-save hook, so live saves are never promoted early.
|
|
75
|
+
const STALE_INITIALISING_MS = 60 * 60 * 1000;
|
|
76
|
+
async function dispatchFigshare() {
|
|
77
|
+
const storage = RecordsService.getFigshareIntentStorage();
|
|
78
|
+
if (!storage.pendingFigshareIntents)
|
|
79
|
+
return;
|
|
80
|
+
const store = getSyncStore();
|
|
81
|
+
await store.ensureIndexes();
|
|
82
|
+
if (storage.recoverStaleFigshareIntents) {
|
|
83
|
+
const recovered = await storage.recoverStaleFigshareIntents(new Date(Date.now() - STALE_INITIALISING_MS).toISOString());
|
|
84
|
+
if (recovered)
|
|
85
|
+
sails.log.warn(`Recovered ${recovered} Figshare intent(s) left initialising by an interrupted save`);
|
|
86
|
+
}
|
|
87
|
+
let afterOid = '';
|
|
88
|
+
while (true) {
|
|
89
|
+
const page = await storage.pendingFigshareIntents(100, afterOid);
|
|
90
|
+
for (const record of page) {
|
|
91
|
+
try {
|
|
92
|
+
const config = (0, config_1.resolveFigsharePublishingConfig)(record, { requireToken: false });
|
|
93
|
+
if (config?.processing?.enabled && !config.processingError)
|
|
94
|
+
await importRecordIntent(store, record);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
sails.log.error(`Figshare intent import failed for ${record.redboxOid}; pending work is retained`, error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (page.length < 100)
|
|
101
|
+
break;
|
|
102
|
+
afterOid = page[page.length - 1].redboxOid;
|
|
103
|
+
}
|
|
104
|
+
// Exclude rows already visited this run before the page limit, so paging continues past paused records
|
|
105
|
+
// even if a dispatch cooldown expires mid-run.
|
|
106
|
+
const seen = new Set();
|
|
107
|
+
while (true) {
|
|
108
|
+
const page = await store.due(100, seen);
|
|
109
|
+
if (!page.length)
|
|
110
|
+
break;
|
|
111
|
+
for (const due of page) {
|
|
112
|
+
seen.add(due.oid);
|
|
113
|
+
if (!(await store.dispatchClaim(due.oid)))
|
|
114
|
+
continue;
|
|
115
|
+
try {
|
|
116
|
+
const fresh = await RecordsService.getMeta(due.oid);
|
|
117
|
+
const freshConfig = fresh && (0, config_1.resolveFigsharePublishingConfig)(fresh, { requireToken: false });
|
|
118
|
+
// Paused or misconfigured brands back off: the worker would return without consuming the due work.
|
|
119
|
+
if (fresh && (!freshConfig?.processing?.enabled || freshConfig.processingError)) {
|
|
120
|
+
await store.dispatchClaim(due.oid, PAUSED_DISPATCH_BACKOFF_MS, true);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
await AgendaQueueService.now('Figshare-SyncRecord', { oid: due.oid, brandId: due.brandId });
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
sails.log.error('Figshare delivery failed; durable work remains due', error);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function runFigshareWorker(service, job, store = getSyncStore()) {
|
|
132
|
+
const { oid, brandId } = job.attrs?.data ?? {};
|
|
133
|
+
if (!oid || !brandId)
|
|
134
|
+
return;
|
|
135
|
+
let record = await RecordsService.getMeta(oid);
|
|
136
|
+
if (!record) {
|
|
137
|
+
const existing = await store.get(oid);
|
|
138
|
+
if (existing)
|
|
139
|
+
await store.change(oid, s => {
|
|
140
|
+
s.status = 'cancelled';
|
|
141
|
+
for (const work of Object.values(s.work))
|
|
142
|
+
work.dueAt = null;
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (record.metaMetadata.brandId !== brandId)
|
|
147
|
+
throw new execution_1.FigshareRepairRequired('Queue brand does not match the fresh record');
|
|
148
|
+
const config = (0, config_1.resolveFigsharePublishingConfig)(record, { requireToken: false });
|
|
149
|
+
if (!config?.processing?.enabled || config.processingError)
|
|
150
|
+
return;
|
|
151
|
+
const settings = { ...FigsharePublishing_1.DEFAULT_FIGSHARE_PROCESSING, ...config.processing };
|
|
152
|
+
if (settings.heartbeatMs <= 0 || settings.leaseMs < settings.heartbeatMs * 3)
|
|
153
|
+
throw new Error('Figshare lease must cover at least three heartbeat intervals');
|
|
154
|
+
await store.ensureIndexes();
|
|
155
|
+
await importRecordIntent(store, record);
|
|
156
|
+
const owner = (0, node_crypto_1.randomUUID)();
|
|
157
|
+
const claimed = await store.claim(oid, brandId, owner, settings.leaseMs);
|
|
158
|
+
if (!claimed)
|
|
159
|
+
return;
|
|
160
|
+
let state = claimed;
|
|
161
|
+
const startedWork = lodash_1.default.cloneDeep(state.work);
|
|
162
|
+
const due = (k) => startedWork[k].dueAt != null && startedWork[k].dueAt <= Date.now();
|
|
163
|
+
// Attribute errors in the initial account/article reads to the work being polled.
|
|
164
|
+
let kind = due('sync') ? 'sync' : due('cleanup') ? 'cleanup' : 'observe';
|
|
165
|
+
const abort = new AbortController();
|
|
166
|
+
let heartbeatBusy = false;
|
|
167
|
+
const heartbeat = setInterval(() => {
|
|
168
|
+
if (heartbeatBusy)
|
|
169
|
+
return;
|
|
170
|
+
heartbeatBusy = true;
|
|
171
|
+
void (async () => {
|
|
172
|
+
await store.renew(oid, owner, settings.leaseMs);
|
|
173
|
+
if (job.touch)
|
|
174
|
+
await job.touch();
|
|
175
|
+
})()
|
|
176
|
+
.catch(() => abort.abort())
|
|
177
|
+
.finally(() => {
|
|
178
|
+
heartbeatBusy = false;
|
|
179
|
+
});
|
|
180
|
+
}, settings.heartbeatMs);
|
|
181
|
+
heartbeat.unref();
|
|
182
|
+
const checkpoint = async (fn) => {
|
|
183
|
+
if (abort.signal.aborted)
|
|
184
|
+
throw new sync_store_1.FigshareLeaseLost();
|
|
185
|
+
state = await store.change(oid, fn, owner);
|
|
186
|
+
return state;
|
|
187
|
+
};
|
|
188
|
+
const finish = async (k) => checkpoint(s => {
|
|
189
|
+
const w = s.work[k];
|
|
190
|
+
w.processed = Math.max(w.processed, startedWork[k].requested);
|
|
191
|
+
if (w.requested === startedWork[k].requested)
|
|
192
|
+
w.dueAt = null;
|
|
193
|
+
});
|
|
194
|
+
const wait = async (reason) => checkpoint(s => {
|
|
195
|
+
s.status = 'waiting';
|
|
196
|
+
s.waitingReason = reason;
|
|
197
|
+
// Readiness is an expected wait, not a failed attempt. Clear recovered polling
|
|
198
|
+
// errors, while retaining a genuine terminal failure of unfinished source sync.
|
|
199
|
+
const unresolvedSyncFailure = s.error?.terminal &&
|
|
200
|
+
(!s.error.kind || s.error.kind === 'sync') &&
|
|
201
|
+
s.work.sync.requested > s.work.sync.processed;
|
|
202
|
+
if (!unresolvedSyncFailure && (!s.error?.kind || s.error.kind === kind))
|
|
203
|
+
delete s.error;
|
|
204
|
+
if (s.work[kind].requested === startedWork[kind].requested)
|
|
205
|
+
s.work[kind].dueAt = Date.now() + settings.observationMs;
|
|
206
|
+
});
|
|
207
|
+
const rawClient = config.runtime.mode === 'fixture'
|
|
208
|
+
? (0, http_1.makeFixtureClient)(config)
|
|
209
|
+
: (0, http_1.makeLiveClient)(config, (0, context_1.createRunContext)(record, config, owner, 'worker'));
|
|
210
|
+
let article;
|
|
211
|
+
let metadataChanged = false;
|
|
212
|
+
const sourceGeneration = record.figshareSyncIntent?.generation ?? 0;
|
|
213
|
+
const eligible = async (policies, current) => {
|
|
214
|
+
const brand = BrandingService.getBrandById(brandId);
|
|
215
|
+
if (!brand)
|
|
216
|
+
return false;
|
|
217
|
+
const recordType = await RecordTypesService.get(brand, current.metaMetadata.type).toPromise();
|
|
218
|
+
return (0, source_intent_1.currentExecutionEligible)(recordType, policies, oid, current);
|
|
219
|
+
};
|
|
220
|
+
const assertCurrent = async () => {
|
|
221
|
+
await store.assertOwner(oid, owner);
|
|
222
|
+
if (abort.signal.aborted)
|
|
223
|
+
throw new sync_store_1.FigshareLeaseLost();
|
|
224
|
+
const fresh = await RecordsService.getMeta(oid);
|
|
225
|
+
if (!fresh || fresh.metaMetadata.brandId !== brandId)
|
|
226
|
+
throw new execution_1.FigshareWaiting('record_changed');
|
|
227
|
+
const latestConfig = (0, config_1.resolveFigsharePublishingConfig)(fresh, { requireToken: false });
|
|
228
|
+
if (!latestConfig?.processing?.enabled ||
|
|
229
|
+
latestConfig.processingError ||
|
|
230
|
+
(0, exports.contentHash)(latestConfig) !== (0, exports.contentHash)(config))
|
|
231
|
+
throw new execution_1.FigshareWaiting('configuration_changed');
|
|
232
|
+
if (fresh.figshareSyncIntent?.readiness === 'initialising' ||
|
|
233
|
+
(fresh.figshareSyncIntent?.generation ?? 0) !== sourceGeneration)
|
|
234
|
+
throw new execution_1.FigshareWaiting('newer_save');
|
|
235
|
+
if (kind === 'sync' && !(await eligible(startedWork.sync.policies, fresh)))
|
|
236
|
+
throw new execution_1.FigshareWaiting('eligibility');
|
|
237
|
+
return fresh;
|
|
238
|
+
};
|
|
239
|
+
const execution = {
|
|
240
|
+
signal: abort.signal,
|
|
241
|
+
async guard(operation) {
|
|
242
|
+
await assertCurrent();
|
|
243
|
+
if (kind !== 'sync' && operation !== 'read')
|
|
244
|
+
throw new Error('Observation or cleanup intent cannot authorise remote mutation');
|
|
245
|
+
if (state.binding?.articleId) {
|
|
246
|
+
const current = await rawClient.getArticle(state.binding.articleId);
|
|
247
|
+
if ((0, runtime_1.isCurationLocked)(config, current))
|
|
248
|
+
throw new execution_1.FigshareWaiting('curation');
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
async metadata(id, payload, send) {
|
|
252
|
+
const current = await rawClient.getArticle(id);
|
|
253
|
+
const hash = (0, exports.contentHash)(payload);
|
|
254
|
+
// Compare only managed fields, preserving remote fields not mapped by ReDBox.
|
|
255
|
+
const remoteFields = {};
|
|
256
|
+
for (const key of Object.keys(payload)) {
|
|
257
|
+
if (key === 'custom_fields') {
|
|
258
|
+
const remote = Array.isArray(current.custom_fields)
|
|
259
|
+
? Object.fromEntries(current.custom_fields.map(f => [f.name, f.value]))
|
|
260
|
+
: (current.custom_fields ?? {});
|
|
261
|
+
remoteFields[key] = Object.fromEntries(Object.keys(payload.custom_fields ?? {}).map(k => [k, remote[k]]));
|
|
262
|
+
}
|
|
263
|
+
else if (key === 'defined_type' && typeof payload[key] === 'string')
|
|
264
|
+
remoteFields[key] = current.defined_type_name ?? current[key];
|
|
265
|
+
else if (key === 'categories' && Array.isArray(current[key]))
|
|
266
|
+
remoteFields[key] = current[key].map(value => (typeof value === 'object' && value ? value.id : value));
|
|
267
|
+
else if (key === 'authors' && Array.isArray(current[key]))
|
|
268
|
+
remoteFields[key] = current[key].map(value => typeof value === 'object' && value ? { id: value.id } : value);
|
|
269
|
+
else
|
|
270
|
+
remoteFields[key] = current[key];
|
|
271
|
+
}
|
|
272
|
+
if ((0, exports.contentHash)(remoteFields) === hash) {
|
|
273
|
+
await checkpoint(s => {
|
|
274
|
+
s.checkpoints.metadata = hash;
|
|
275
|
+
});
|
|
276
|
+
return current;
|
|
277
|
+
}
|
|
278
|
+
metadataChanged = true;
|
|
279
|
+
const outgoing = { ...payload };
|
|
280
|
+
if (payload.custom_fields) {
|
|
281
|
+
const remote = Array.isArray(current.custom_fields)
|
|
282
|
+
? Object.fromEntries(current.custom_fields.map(f => [f.name, f.value]))
|
|
283
|
+
: (current.custom_fields ?? {});
|
|
284
|
+
outgoing.custom_fields = { ...remote, ...payload.custom_fields };
|
|
285
|
+
}
|
|
286
|
+
const result = await send(outgoing);
|
|
287
|
+
await checkpoint(s => {
|
|
288
|
+
s.checkpoints.metadata = hash;
|
|
289
|
+
});
|
|
290
|
+
return { ...result, id };
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
const recovery = (fn) => execution_1.figshareExecution.run({ ...execution, binding: state.create?.binding ?? state.binding, recovery: true }, fn);
|
|
294
|
+
try {
|
|
295
|
+
await execution_1.figshareExecution.run(execution, async () => {
|
|
296
|
+
if (config.runtime.mode !== 'fixture' && !config.connection.token)
|
|
297
|
+
throw new execution_1.FigshareRepairRequired('Configure a Figshare API token before enabling processing');
|
|
298
|
+
const brand = BrandingService.getBrandById(brandId);
|
|
299
|
+
if (!brand)
|
|
300
|
+
throw new execution_1.FigshareRepairRequired('Record brand cannot be resolved');
|
|
301
|
+
const username = settings.serviceUsername || config.workflow.transitionJob.username;
|
|
302
|
+
const userType = settings.serviceUserType || config.workflow.transitionJob.userType;
|
|
303
|
+
if (!username || !userType)
|
|
304
|
+
throw new execution_1.FigshareRepairRequired('Configure a per-brand Figshare local service identity');
|
|
305
|
+
const user = await UsersService.getUserWithUsername(username).toPromise();
|
|
306
|
+
if (!user || user.type !== userType || user.disabled === true)
|
|
307
|
+
throw new execution_1.FigshareRepairRequired('Configured Figshare local service user is unavailable');
|
|
308
|
+
if (!(await RecordsService.hasEditAccess(brand, user, (user.roles ?? []).map(role => ({ ...role })), record)))
|
|
309
|
+
throw new execution_1.FigshareRepairRequired('Figshare service user does not have record edit access');
|
|
310
|
+
if (!rawClient.getAccount)
|
|
311
|
+
throw new execution_1.FigshareRepairRequired('Figshare client cannot verify authenticated account');
|
|
312
|
+
const account = await rawClient.getAccount();
|
|
313
|
+
const accountId = String(account.id);
|
|
314
|
+
if (!/^\d+$/.test(accountId))
|
|
315
|
+
throw new execution_1.FigshareRepairRequired('Authenticated account response has no valid account ID');
|
|
316
|
+
if (state.binding && (state.binding.namespace !== (0, identity_1.apiNamespace)(config) || state.binding.accountId !== accountId))
|
|
317
|
+
throw new execution_1.FigshareRepairRequired('Figshare API environment or token account changed');
|
|
318
|
+
execution.binding = state.binding;
|
|
319
|
+
if (state.binding?.articleId) {
|
|
320
|
+
article = await rawClient.getArticle(state.binding.articleId);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
const legacyId = String((0, types_1.getRecordField)(record, config.record.articleIdPath) ?? '');
|
|
324
|
+
if (legacyId) {
|
|
325
|
+
const lookup = RecordsService.getFigshareIntentStorage().findFigshareArticleRecords;
|
|
326
|
+
if (!lookup)
|
|
327
|
+
throw new execution_1.FigshareRepairRequired('Storage adapter cannot verify legacy binding uniqueness');
|
|
328
|
+
const matching = await lookup.call(RecordsService.getFigshareIntentStorage(), config.record.articleIdPath, legacyId);
|
|
329
|
+
if (matching.some(other => other.redboxOid !== oid &&
|
|
330
|
+
(0, config_1.resolveFigsharePublishingConfig)(other)?.connection.baseUrl.replace(/\/+$/, '') === (0, identity_1.apiNamespace)(config)))
|
|
331
|
+
throw new execution_1.FigshareRepairRequired('Duplicate legacy article bindings require repair before mutation');
|
|
332
|
+
article = await rawClient.getArticle(legacyId);
|
|
333
|
+
const binding = {
|
|
334
|
+
namespace: (0, identity_1.apiNamespace)(config),
|
|
335
|
+
accountId,
|
|
336
|
+
ownerId: String(article.account_id ?? accountId),
|
|
337
|
+
articleId: String(article.id),
|
|
338
|
+
};
|
|
339
|
+
await checkpoint(s => {
|
|
340
|
+
s.binding = binding;
|
|
341
|
+
s.namespace = binding.namespace;
|
|
342
|
+
s.articleId = binding.articleId;
|
|
343
|
+
});
|
|
344
|
+
execution.binding = binding;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const project = async () => {
|
|
348
|
+
if (!state.binding?.articleId)
|
|
349
|
+
return;
|
|
350
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
351
|
+
const fresh = await RecordsService.getMeta(oid);
|
|
352
|
+
const fields = {
|
|
353
|
+
[config.record.articleIdPath]: state.binding.articleId,
|
|
354
|
+
[config.writeBack.articleId]: state.binding.articleId,
|
|
355
|
+
[config.record.statusPath]: state.status,
|
|
356
|
+
[config.record.errorPath]: state.error?.message ?? '',
|
|
357
|
+
};
|
|
358
|
+
for (const path of config.writeBack.articleUrls)
|
|
359
|
+
fields[path] =
|
|
360
|
+
article?.url_public_html ??
|
|
361
|
+
article?.url_private_html ??
|
|
362
|
+
`${config.connection.frontEndUrl}/articles/${state.binding.articleId}`;
|
|
363
|
+
for (const binding of config.writeBack.extraFields) {
|
|
364
|
+
const source = binding.from === 'article' ? article : binding.from === 'publishResult' ? state.publish : undefined;
|
|
365
|
+
const value = lodash_1.default.get(source, binding.sourcePath);
|
|
366
|
+
if (value !== undefined)
|
|
367
|
+
fields[binding.targetPath] = value;
|
|
368
|
+
}
|
|
369
|
+
await store.assertOwner(oid, owner);
|
|
370
|
+
if ((await RecordsService.setRecordFields(oid, fields, fresh.recordVersion ?? 0, projectionPaths(config), user))
|
|
371
|
+
.updated)
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
throw new execution_1.FigshareWaiting('record_changed');
|
|
375
|
+
};
|
|
376
|
+
if (due('sync')) {
|
|
377
|
+
kind = 'sync';
|
|
378
|
+
await assertCurrent();
|
|
379
|
+
if (!state.audit || state.auditClosed) {
|
|
380
|
+
const audit = (0, audit_1.startFigshareAudit)(oid, IntegrationAuditModel_1.IntegrationAuditAction.syncRecordWithFigshare, (0, context_1.createRunContext)(record, config, owner, 'worker'), {
|
|
381
|
+
sourceGeneration,
|
|
382
|
+
requestedBy: startedWork.sync.requestedBy,
|
|
383
|
+
requests: startedWork.sync.requested - startedWork.sync.processed,
|
|
384
|
+
});
|
|
385
|
+
await checkpoint(s => {
|
|
386
|
+
s.audit = audit;
|
|
387
|
+
s.auditClosed = false;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
if (!state.binding?.articleId) {
|
|
391
|
+
if (state.create) {
|
|
392
|
+
const recovered = await recovery(() => (0, identity_1.recoverCreate)(rawClient, state.create));
|
|
393
|
+
if (!recovered)
|
|
394
|
+
throw new execution_1.FigshareRepairRequired('Uncertain create has no unique visible token match; do not create again. Reconcile, then run abandon-create if no article exists');
|
|
395
|
+
const binding = { ...state.create.binding, articleId: String(recovered.id) };
|
|
396
|
+
await checkpoint(s => {
|
|
397
|
+
s.binding = binding;
|
|
398
|
+
s.namespace = binding.namespace;
|
|
399
|
+
s.articleId = binding.articleId;
|
|
400
|
+
s.create.verifiedId = binding.articleId;
|
|
401
|
+
});
|
|
402
|
+
execution.binding = binding;
|
|
403
|
+
article = recovered;
|
|
404
|
+
if (state.create.error && startedWork.sync.requested <= (state.createRequest ?? startedWork.sync.requested))
|
|
405
|
+
throw new Error(state.create.error);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
if ((state.waitingReason === 'uncertain_legacy_create' ||
|
|
409
|
+
(0, types_1.getRecordField)(record, config.record.syncStatePath)) &&
|
|
410
|
+
!state.create)
|
|
411
|
+
throw new execution_1.FigshareRepairRequired('Legacy synchronisation evidence without an article ID requires migration review');
|
|
412
|
+
const ownerId = config.impersonation?.operations.create === 'owner'
|
|
413
|
+
? await (0, identity_1.resolveCreationOwner)(rawClient, config, record, accountId)
|
|
414
|
+
: accountId;
|
|
415
|
+
const binding = { namespace: (0, identity_1.apiNamespace)(config), accountId, ownerId };
|
|
416
|
+
const operation = (0, identity_1.newCreateOperation)(binding);
|
|
417
|
+
await checkpoint(s => {
|
|
418
|
+
s.binding = binding;
|
|
419
|
+
s.create = operation;
|
|
420
|
+
s.createGeneration = sourceGeneration;
|
|
421
|
+
s.createRequest = startedWork.sync.requested;
|
|
422
|
+
});
|
|
423
|
+
execution.binding = binding;
|
|
424
|
+
try {
|
|
425
|
+
const response = await (0, execution_1.workerClient)(rawClient).createArticle({
|
|
426
|
+
title: (0, identity_1.provisionalTitle)(operation.token),
|
|
427
|
+
});
|
|
428
|
+
if (response.id == null)
|
|
429
|
+
throw new Error('Create response did not contain an article identity');
|
|
430
|
+
article = await recovery(() => rawClient.getArticle(String(response.id)));
|
|
431
|
+
if (article.title !== (0, identity_1.provisionalTitle)(operation.token))
|
|
432
|
+
throw new execution_1.FigshareRepairRequired('Create response did not verify the operation token');
|
|
433
|
+
const id = String(article.id);
|
|
434
|
+
await checkpoint(s => {
|
|
435
|
+
s.binding.articleId = id;
|
|
436
|
+
s.namespace = binding.namespace;
|
|
437
|
+
s.articleId = id;
|
|
438
|
+
s.create.verifiedId = id;
|
|
439
|
+
s.create.outcome = 'confirmed';
|
|
440
|
+
});
|
|
441
|
+
execution.binding = state.binding;
|
|
442
|
+
}
|
|
443
|
+
catch (error) {
|
|
444
|
+
// Only the transport guard raises a wait here, and it refuses before sending, so nothing was created.
|
|
445
|
+
if (error instanceof execution_1.FigshareWaiting) {
|
|
446
|
+
await checkpoint(s => {
|
|
447
|
+
delete s.create;
|
|
448
|
+
delete s.createGeneration;
|
|
449
|
+
delete s.createRequest;
|
|
450
|
+
delete s.binding;
|
|
451
|
+
});
|
|
452
|
+
throw error;
|
|
453
|
+
}
|
|
454
|
+
await checkpoint(s => {
|
|
455
|
+
s.create.outcome = error instanceof http_1.FigshareHttpError && error.statusCode ? 'failed' : 'uncertain';
|
|
456
|
+
s.create.error = error instanceof Error ? error.message : String(error);
|
|
457
|
+
});
|
|
458
|
+
const recovered = await recovery(() => (0, identity_1.recoverCreate)(rawClient, state.create));
|
|
459
|
+
if (recovered) {
|
|
460
|
+
const id = String(recovered.id);
|
|
461
|
+
await checkpoint(s => {
|
|
462
|
+
s.binding.articleId = id;
|
|
463
|
+
s.namespace = binding.namespace;
|
|
464
|
+
s.articleId = id;
|
|
465
|
+
s.create.verifiedId = id;
|
|
466
|
+
});
|
|
467
|
+
article = recovered;
|
|
468
|
+
await project();
|
|
469
|
+
}
|
|
470
|
+
throw error;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
await project(); // durable identity precedes replacement of the provisional title
|
|
474
|
+
}
|
|
475
|
+
const id = state.binding.articleId;
|
|
476
|
+
article = await rawClient.getArticle(id);
|
|
477
|
+
if (state.publish && state.publish.outcome !== 'observed') {
|
|
478
|
+
if ((0, identity_1.observedPublished)(article) && Number(article.version ?? 0) > state.publish.previousVersion) {
|
|
479
|
+
await checkpoint(s => {
|
|
480
|
+
s.publish.outcome = 'observed';
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
else if ((0, runtime_1.isCurationLocked)(config, article)) {
|
|
484
|
+
throw new execution_1.FigshareWaiting('curation');
|
|
485
|
+
}
|
|
486
|
+
else if (startedWork.sync.sourceGeneration > state.publish.generation) {
|
|
487
|
+
// The read confirms the earlier request did not publish. A newer eligible source save supersedes it,
|
|
488
|
+
// e.g. after a curator returns the article for changes, so its content syncs and publication is requested again.
|
|
489
|
+
await checkpoint(s => {
|
|
490
|
+
delete s.publish;
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
else if (state.publish.outcome === 'submitted' || state.publish.outcome === 'uncertain') {
|
|
494
|
+
throw new execution_1.FigshareRepairRequired('Publication outcome is uncertain; confirm the article in Figshare, then run reset-publish');
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
throw new execution_1.FigshareWaiting('publication_confirmation');
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if ((0, runtime_1.isCurationLocked)(config, article))
|
|
501
|
+
throw new execution_1.FigshareWaiting('curation');
|
|
502
|
+
const pendingFiles = (await (0, runtime_1.listArticleFiles)(rawClient, id)).filter(f => String(f.status).toLowerCase() === 'created');
|
|
503
|
+
if (pendingFiles.length) {
|
|
504
|
+
if (!pendingFiles.every(file => state.receipts.some(r => r.fileId === String(file.id) && r.resumeApproved))) {
|
|
505
|
+
// An interrupted managed upload needs an operator decision; any other pending file belongs to another uploader.
|
|
506
|
+
if (state.receipts.some(r => ['initialising', 'uploading'].includes(r.state) && !r.resumeApproved)) {
|
|
507
|
+
throw new execution_1.FigshareRepairRequired('Interrupted Figshare upload requires bind-file or resume-upload');
|
|
508
|
+
}
|
|
509
|
+
throw new execution_1.FigshareWaiting('uploads');
|
|
510
|
+
}
|
|
511
|
+
await (0, managed_assets_1.mirrorManagedAssets)(service.makeClient(config, record, owner, 'resume-upload'), config, record, id, state, checkpoint);
|
|
512
|
+
}
|
|
513
|
+
(0, types_1.setRecordField)(record, config.record.articleIdPath, id);
|
|
514
|
+
const previousAssets = state.checkpoints.assets;
|
|
515
|
+
await service.syncMetadata(record, {
|
|
516
|
+
action: 'update',
|
|
517
|
+
articleId: id,
|
|
518
|
+
sameJob: true,
|
|
519
|
+
syncState: { status: 'syncing', correlationId: owner },
|
|
520
|
+
});
|
|
521
|
+
const client = service.makeClient(config, record, owner, 'worker');
|
|
522
|
+
await (0, managed_assets_1.mirrorManagedAssets)(client, config, record, id, state, checkpoint);
|
|
523
|
+
const assetsChanged = previousAssets !== state.checkpoints.assets;
|
|
524
|
+
await (0, embargo_1.syncEmbargoPhase)(client, config, record, id);
|
|
525
|
+
await checkpoint(s => {
|
|
526
|
+
s.checkpoints.embargo = (0, exports.contentHash)(config.embargo.mode === 'none' ? null : record.metadata);
|
|
527
|
+
});
|
|
528
|
+
await assertCurrent();
|
|
529
|
+
article = await rawClient.getArticle(id);
|
|
530
|
+
const publishHash = (0, exports.contentHash)(state.checkpoints);
|
|
531
|
+
const needsPublish = !(0, identity_1.observedPublished)(article) ||
|
|
532
|
+
(metadataChanged && config.article.republishOnMetadataChange) ||
|
|
533
|
+
(assetsChanged && config.article.republishOnAssetChange);
|
|
534
|
+
if (needsPublish && state.publish?.hash !== publishHash && config.article.publishMode !== 'manual') {
|
|
535
|
+
await checkpoint(s => {
|
|
536
|
+
s.publish = {
|
|
537
|
+
generation: sourceGeneration,
|
|
538
|
+
hash: publishHash,
|
|
539
|
+
previousVersion: Number(article.version ?? 0),
|
|
540
|
+
outcome: 'submitted',
|
|
541
|
+
submittedAt: new Date().toISOString(),
|
|
542
|
+
};
|
|
543
|
+
});
|
|
544
|
+
try {
|
|
545
|
+
await client.publishArticle(id);
|
|
546
|
+
await checkpoint(s => {
|
|
547
|
+
s.publish.outcome = 'accepted';
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
catch (error) {
|
|
551
|
+
const body = error instanceof http_1.FigshareHttpError
|
|
552
|
+
? error.responseBody
|
|
553
|
+
: undefined;
|
|
554
|
+
const rejected = error instanceof http_1.FigshareHttpError &&
|
|
555
|
+
error.statusCode === 400 &&
|
|
556
|
+
body?.code === 'BadRequest' &&
|
|
557
|
+
typeof body.message === 'string' &&
|
|
558
|
+
body.message.startsWith('Missing mandatory value:');
|
|
559
|
+
await checkpoint(s => {
|
|
560
|
+
s.publish.outcome = rejected ? 'rejected' : 'uncertain';
|
|
561
|
+
});
|
|
562
|
+
throw error;
|
|
563
|
+
}
|
|
564
|
+
// Immediate publication is visible now; a curated article still reads private and waits for review.
|
|
565
|
+
article = await rawClient.getArticle(id);
|
|
566
|
+
}
|
|
567
|
+
await finish('sync');
|
|
568
|
+
await checkpoint(s => {
|
|
569
|
+
s.status = (0, identity_1.observedPublished)(article) ? 'synced' : 'waiting';
|
|
570
|
+
delete s.error;
|
|
571
|
+
s.waitingReason = (0, identity_1.observedPublished)(article)
|
|
572
|
+
? undefined
|
|
573
|
+
: config.article.publishMode === 'manual'
|
|
574
|
+
? 'manual_publication'
|
|
575
|
+
: 'review';
|
|
576
|
+
s.work.observe.requested++;
|
|
577
|
+
s.work.observe.dueAt = Date.now() + settings.observationMs;
|
|
578
|
+
if (s.receipts.some(r => r.kind === 'hosted' && r.desired)) {
|
|
579
|
+
s.work.cleanup.requested++;
|
|
580
|
+
s.work.cleanup.dueAt = s.work.cleanup.dueAt ?? Date.now() + settings.cleanupMs;
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
if (!state.auditClosed) {
|
|
584
|
+
(0, audit_1.completeFigshareAudit)(state.audit, {
|
|
585
|
+
message: 'Figshare content synchronised; publication is observed separately.',
|
|
586
|
+
responseSummary: { articleId: id, sourceGeneration, requests: startedWork.sync.requested },
|
|
587
|
+
});
|
|
588
|
+
await checkpoint(s => {
|
|
589
|
+
s.auditClosed = true;
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
await project();
|
|
593
|
+
}
|
|
594
|
+
if (!state.binding?.articleId) {
|
|
595
|
+
if (due('cleanup'))
|
|
596
|
+
await finish('cleanup');
|
|
597
|
+
if (due('observe'))
|
|
598
|
+
await finish('observe');
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const id = state.binding.articleId;
|
|
602
|
+
article = await rawClient.getArticle(id);
|
|
603
|
+
await checkpoint(s => {
|
|
604
|
+
s.publication = (0, identity_1.observedPublished)(article) ? 'published' : s.publish ? 'pending' : 'private';
|
|
605
|
+
s.embargoed = article.is_embargoed === true;
|
|
606
|
+
s.observedAt = new Date().toISOString();
|
|
607
|
+
});
|
|
608
|
+
if (due('cleanup')) {
|
|
609
|
+
kind = 'cleanup';
|
|
610
|
+
if (startedWork.cleanup.policies.length && !(await eligible(startedWork.cleanup.policies, record)))
|
|
611
|
+
throw new execution_1.FigshareWaiting('cleanup_eligibility');
|
|
612
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
613
|
+
record = await RecordsService.getMeta(oid);
|
|
614
|
+
const entries = await (0, managed_assets_1.cleanupProjection)(rawClient, config, record, article, state);
|
|
615
|
+
await store.assertOwner(oid, owner);
|
|
616
|
+
const fields = { [config.record.dataLocationsPath]: entries };
|
|
617
|
+
if (config.record.allFilesUploadedPath)
|
|
618
|
+
fields[config.record.allFilesUploadedPath] = 'yes';
|
|
619
|
+
if ((await RecordsService.setRecordFields(oid, fields, record.recordVersion ?? 0, projectionPaths(config), user)).updated) {
|
|
620
|
+
await finish('cleanup');
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
if (attempt === 2)
|
|
624
|
+
throw new execution_1.FigshareWaiting('record_changed');
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (due('observe')) {
|
|
628
|
+
kind = 'observe';
|
|
629
|
+
if (!(0, identity_1.observedPublished)(article))
|
|
630
|
+
throw new execution_1.FigshareWaiting(config.article.publishMode === 'manual' ? 'manual_publication' : 'review');
|
|
631
|
+
if (state.publish && state.publish.outcome !== 'observed') {
|
|
632
|
+
if (Number(article.version ?? 0) <= state.publish.previousVersion)
|
|
633
|
+
throw new execution_1.FigshareWaiting('publication_confirmation');
|
|
634
|
+
await checkpoint(s => {
|
|
635
|
+
s.publish.outcome = 'observed';
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
const publicationKey = `${id}:${article.version ?? article.published_date}`;
|
|
639
|
+
if (state.publicationAuditKey !== publicationKey) {
|
|
640
|
+
// Persist the marker first: recurring observation must not produce another event.
|
|
641
|
+
await checkpoint(s => {
|
|
642
|
+
s.publicationAuditKey = publicationKey;
|
|
643
|
+
});
|
|
644
|
+
const publicationAudit = (0, audit_1.startFigshareAudit)(oid, IntegrationAuditModel_1.IntegrationAuditAction.publishAfterUploadFilesJob, (0, context_1.createRunContext)(record, config, owner, 'observation'), { articleId: id });
|
|
645
|
+
(0, audit_1.completeFigshareAudit)(publicationAudit, {
|
|
646
|
+
message: 'Figshare publication confirmed.',
|
|
647
|
+
responseSummary: { articleId: id, version: article.version, publication: 'published' },
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
record = await RecordsService.getMeta(oid);
|
|
651
|
+
// An abandoned intent carries no work; only an unimported live save is newer content.
|
|
652
|
+
const newerSource = record.figshareSyncIntent?.pending && record.figshareSyncIntent.readiness !== 'abandoned';
|
|
653
|
+
if (newerSource || state.work.sync.requested > state.work.sync.processed)
|
|
654
|
+
throw new execution_1.FigshareWaiting('newer_sync');
|
|
655
|
+
if (state.receipts.some(r => !['available', 'removed'].includes(r.state)))
|
|
656
|
+
throw new execution_1.FigshareWaiting('uploads');
|
|
657
|
+
const transition = config.workflow.transitionJob;
|
|
658
|
+
if (transition.enabled &&
|
|
659
|
+
record.workflow.stage !== transition.targetStep &&
|
|
660
|
+
article[transition.figshareTargetFieldKey] === transition.figshareTargetFieldValue) {
|
|
661
|
+
// Current business eligibility is still required even though the source actor is not used again.
|
|
662
|
+
if (!(await eligible(state.work.sync.policies, record)))
|
|
663
|
+
throw new execution_1.FigshareWaiting('workflow_eligibility');
|
|
664
|
+
const recordType = await RecordTypesService.get(brand, record.metaMetadata.type).toPromise();
|
|
665
|
+
if (!recordType)
|
|
666
|
+
throw new execution_1.FigshareRepairRequired('Workflow record type is missing');
|
|
667
|
+
const step = await WorkflowStepsService.get(recordType, transition.targetStep).toPromise();
|
|
668
|
+
await store.assertOwner(oid, owner);
|
|
669
|
+
const result = await RecordsService.updateMetaInternal({
|
|
670
|
+
actor: { kind: 'service', id: 'FigshareService.observeWorkflow' },
|
|
671
|
+
authorization: { kind: 'record-edit' },
|
|
672
|
+
mutationClass: 'transition',
|
|
673
|
+
maintenance: true,
|
|
674
|
+
oid,
|
|
675
|
+
record,
|
|
676
|
+
brand,
|
|
677
|
+
user,
|
|
678
|
+
targetStep: step,
|
|
679
|
+
operation: 'transition',
|
|
680
|
+
});
|
|
681
|
+
if (result.problems.some(problem => problem.issues.some(issue => issue.code === 'record-revision-stale')))
|
|
682
|
+
throw new execution_1.FigshareWaiting('record_changed');
|
|
683
|
+
if (!result.isComplete())
|
|
684
|
+
throw new execution_1.FigshareRepairRequired('Workflow hooks failed; inspect partial transition before resuming');
|
|
685
|
+
}
|
|
686
|
+
await finish('observe');
|
|
687
|
+
await checkpoint(s => {
|
|
688
|
+
s.status = 'synced';
|
|
689
|
+
delete s.waitingReason;
|
|
690
|
+
});
|
|
691
|
+
await project();
|
|
692
|
+
}
|
|
693
|
+
if (state.status === 'running')
|
|
694
|
+
await checkpoint(s => {
|
|
695
|
+
s.status = s.nextActionAt == null ? 'synced' : 'waiting';
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
catch (error) {
|
|
700
|
+
if (error instanceof sync_store_1.FigshareLeaseLost || abort.signal.aborted)
|
|
701
|
+
return;
|
|
702
|
+
if (error instanceof execution_1.FigshareWaiting || error instanceof RecordWriteOptions_1.RecordWriteConflict) {
|
|
703
|
+
await wait(error instanceof execution_1.FigshareWaiting ? error.reason : 'record_changed');
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
707
|
+
const category = error instanceof execution_1.FigshareRepairRequired
|
|
708
|
+
? 'repair'
|
|
709
|
+
: error instanceof http_1.FigshareHttpError
|
|
710
|
+
? `http:${error.statusCode ?? 'transport'}`
|
|
711
|
+
: 'configuration_or_operation';
|
|
712
|
+
await checkpoint(s => {
|
|
713
|
+
const previous = s.error?.category === category && (!s.error.kind || s.error.kind === kind) ? s.error : undefined;
|
|
714
|
+
const count = (previous?.count ?? 0) + 1;
|
|
715
|
+
const terminal = category === 'repair' ||
|
|
716
|
+
(error instanceof http_1.FigshareHttpError &&
|
|
717
|
+
error.statusCode != null &&
|
|
718
|
+
error.statusCode >= 400 &&
|
|
719
|
+
error.statusCode < 500 &&
|
|
720
|
+
![408, 429].includes(error.statusCode)) ||
|
|
721
|
+
count >= settings.maxAttempts;
|
|
722
|
+
s.error = {
|
|
723
|
+
kind,
|
|
724
|
+
category,
|
|
725
|
+
message,
|
|
726
|
+
count,
|
|
727
|
+
firstAt: previous?.firstAt ?? new Date().toISOString(),
|
|
728
|
+
lastAt: new Date().toISOString(),
|
|
729
|
+
terminal,
|
|
730
|
+
};
|
|
731
|
+
s.status = terminal ? (category === 'repair' ? 'repair_required' : 'failed') : 'retrying';
|
|
732
|
+
if (s.work[kind].requested === startedWork[kind].requested)
|
|
733
|
+
s.work[kind].dueAt = terminal ? null : Date.now() + settings.retryBaseMs * 2 ** (count - 1);
|
|
734
|
+
});
|
|
735
|
+
if (state.error?.terminal && !state.auditClosed && state.audit) {
|
|
736
|
+
(0, audit_1.failFigshareAudit)(state.audit, new Error(message), {
|
|
737
|
+
message,
|
|
738
|
+
responseSummary: { articleId: state.binding?.articleId, attempts: state.error.count, category },
|
|
739
|
+
});
|
|
740
|
+
await checkpoint(s => {
|
|
741
|
+
s.auditClosed = true;
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
finally {
|
|
747
|
+
clearInterval(heartbeat);
|
|
748
|
+
abort.abort();
|
|
749
|
+
await store.release(oid, owner);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2VzL2ZpZ3NoYXJlLXYyL3dvcmtlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFnRUEsb0NBR0M7QUFDRCwwQ0FnQkM7QUFHRCxnREFPQztBQU9ELDRDQWdEQztBQUVELDhDQXdwQkM7QUEveUJELG9EQUF1QjtBQUN2Qiw2Q0FBcUQ7QUFVckQsbUNBQXlEO0FBQ3pELDhFQUE0RztBQUM1RyxxQ0FBc0c7QUFDdEcsNkNBQW9FO0FBQ3BFLDJDQU1xQjtBQUNyQix5Q0FPb0I7QUFDcEIsbURBQTJEO0FBQzNELGlDQUFtRztBQUNuRyx1Q0FBK0Q7QUFDL0QsdUNBQTZDO0FBQzdDLHFEQUEwRTtBQUMxRSxtQ0FBdUY7QUFDdkYsdUNBQTZDO0FBQzdDLHFGQUFtRjtBQUNuRixpRUFBK0Q7QUFXeEQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxLQUFjLEVBQVUsRUFBRTtJQUNwRCxNQUFNLFNBQVMsR0FBRyxDQUFDLENBQVUsRUFBVyxFQUFFLENBQ3hDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUTtZQUMxQixDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FDaEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7aUJBQ2QsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUN0QyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFD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
|