@forumone/throughline-workflows 0.2.5 → 0.2.7
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/CHANGELOG.md +14 -0
- package/README.md +30 -3
- package/dist/execute-scheduled-publishes.d.ts +8 -12
- package/dist/execute-scheduled-publishes.d.ts.map +1 -1
- package/dist/execute-scheduled-publishes.js +33 -67
- package/dist/execute-scheduled-publishes.js.map +1 -1
- package/dist/revalidate-on-publish.js +18 -1
- package/dist/revalidate-on-publish.js.map +1 -1
- package/dist/types.d.ts +43 -11
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @forumone/throughline-workflows
|
|
2
2
|
|
|
3
|
+
## 0.2.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [3140ea0]
|
|
8
|
+
- @forumone/throughline-core@0.7.0
|
|
9
|
+
|
|
10
|
+
## 0.2.6
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [9131065]
|
|
15
|
+
- @forumone/throughline-core@0.6.0
|
|
16
|
+
|
|
3
17
|
## 0.2.5
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -93,11 +93,38 @@ createRevalidateOnPublishFunction({
|
|
|
93
93
|
|
|
94
94
|
`next` is declared as an optional peer (`peerDependenciesMeta.next.optional = true`) so non-Next consumers don't see a missing-peer warning.
|
|
95
95
|
|
|
96
|
-
## Why scheduled publishes
|
|
96
|
+
## Why scheduled publishes go through the pipeline
|
|
97
|
+
|
|
98
|
+
`createExecuteScheduledPublishesFunction` never writes to Payload. It finds what is
|
|
99
|
+
due and calls the `publish` callback you give it, which must be wired to the
|
|
100
|
+
publishing service — so a scheduled publish runs the same composition /
|
|
101
|
+
accessibility / approval pipeline as an interactive one. A composition error fails
|
|
102
|
+
it loudly (audit log + `lastError`) instead of silently writing through, and a
|
|
103
|
+
`payload.update` here would skip every gate.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { getPublishingService } from '@forumone/throughline-publishing'
|
|
107
|
+
|
|
108
|
+
publish: async ({ collection, id, reasoning }) => {
|
|
109
|
+
const outcome = await getPublishingService(payload).publish({
|
|
110
|
+
collection,
|
|
111
|
+
id,
|
|
112
|
+
actor: { apiKeyName: 'scheduled-publish', channel: 'mcp' },
|
|
113
|
+
meta: { reasoning },
|
|
114
|
+
})
|
|
115
|
+
return { published: outcome.published, reason: outcome.reason }
|
|
116
|
+
}
|
|
117
|
+
```
|
|
97
118
|
|
|
98
|
-
|
|
119
|
+
Injected rather than built in because this package depends on `core` alone, and the
|
|
120
|
+
service lives in the publishing package.
|
|
99
121
|
|
|
100
|
-
|
|
122
|
+
It used to `fetch` `POST /api/publishing/mcp` with a bearer key from
|
|
123
|
+
`PUBLISHING_SYSTEM_API_KEY`. That endpoint is gone — one `/api/mcp` replaced the six
|
|
124
|
+
per-server ones — and the self-call was the wrong shape regardless: a function
|
|
125
|
+
invocation per document, a base URL and a key that both had to be right, and a 401
|
|
126
|
+
rather than a publish if the deployment URL sat behind access protection. Neither
|
|
127
|
+
option exists any more; wire `publish`.
|
|
101
128
|
|
|
102
129
|
## Customizing audit fan-out
|
|
103
130
|
|
|
@@ -4,20 +4,16 @@ import type { ExecuteScheduledPublishesOptions } from './types.js';
|
|
|
4
4
|
* Cron-driven scheduled publish executor. Every tick (default: every 5
|
|
5
5
|
* minutes) the function looks for documents in any of the configured
|
|
6
6
|
* collections whose `_status` is still `draft` and whose
|
|
7
|
-
* `scheduledPublishAt` has passed
|
|
8
|
-
* server's MCP `publish` tool — going through the full publishing pipeline
|
|
9
|
-
* means scheduled publishes get the same composition / accessibility /
|
|
10
|
-
* approval checks as interactive publishes.
|
|
7
|
+
* `scheduledPublishAt` has passed, and calls `options.publish` for each.
|
|
11
8
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* `publish` must go through the publishing pipeline — see the option's own
|
|
10
|
+
* documentation for the wiring. That is what makes a scheduled publish get the
|
|
11
|
+
* same composition / accessibility / approval checks as an interactive one.
|
|
15
12
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* for cron-style work.
|
|
13
|
+
* A refusal is logged and does not throw; the document stays at
|
|
14
|
+
* `_status: draft` until an admin intervenes or a later tick succeeds.
|
|
15
|
+
* Throwing would retry indefinitely on a permanent error (a composition
|
|
16
|
+
* failure, say), which is wrong for cron-style work.
|
|
21
17
|
*/
|
|
22
18
|
export declare function createExecuteScheduledPublishesFunction(options: ExecuteScheduledPublishesOptions): InngestFunction.Any;
|
|
23
19
|
//# sourceMappingURL=execute-scheduled-publishes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-scheduled-publishes.d.ts","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"execute-scheduled-publishes.d.ts","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAA;AAWlE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,gCAAgC,GACxC,eAAe,CAAC,GAAG,CA4ErB"}
|
|
@@ -1,30 +1,22 @@
|
|
|
1
1
|
const DEFAULT_SCHEDULE = '*/5 * * * *';
|
|
2
|
+
const REASONING = 'Scheduled publish executed by workflow cron';
|
|
2
3
|
/**
|
|
3
4
|
* Cron-driven scheduled publish executor. Every tick (default: every 5
|
|
4
5
|
* minutes) the function looks for documents in any of the configured
|
|
5
6
|
* collections whose `_status` is still `draft` and whose
|
|
6
|
-
* `scheduledPublishAt` has passed
|
|
7
|
-
* server's MCP `publish` tool — going through the full publishing pipeline
|
|
8
|
-
* means scheduled publishes get the same composition / accessibility /
|
|
9
|
-
* approval checks as interactive publishes.
|
|
7
|
+
* `scheduledPublishAt` has passed, and calls `options.publish` for each.
|
|
10
8
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* `publish` must go through the publishing pipeline — see the option's own
|
|
10
|
+
* documentation for the wiring. That is what makes a scheduled publish get the
|
|
11
|
+
* same composition / accessibility / approval checks as an interactive one.
|
|
14
12
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* for cron-style work.
|
|
13
|
+
* A refusal is logged and does not throw; the document stays at
|
|
14
|
+
* `_status: draft` until an admin intervenes or a later tick succeeds.
|
|
15
|
+
* Throwing would retry indefinitely on a permanent error (a composition
|
|
16
|
+
* failure, say), which is wrong for cron-style work.
|
|
20
17
|
*/
|
|
21
18
|
export function createExecuteScheduledPublishesFunction(options) {
|
|
22
|
-
const apiKey = options.publishingApiKey ?? process.env['PUBLISHING_SYSTEM_API_KEY'];
|
|
23
|
-
if (!apiKey) {
|
|
24
|
-
throw new Error('createExecuteScheduledPublishesFunction requires options.publishingApiKey or the PUBLISHING_SYSTEM_API_KEY env var.');
|
|
25
|
-
}
|
|
26
19
|
const schedule = options.schedule ?? DEFAULT_SCHEDULE;
|
|
27
|
-
const baseUrl = options.publishingServerUrl.replace(/\/$/, '');
|
|
28
20
|
return options.inngest.createFunction({
|
|
29
21
|
id: options.id ?? 'execute-scheduled-publishes',
|
|
30
22
|
triggers: [{ cron: schedule }],
|
|
@@ -55,7 +47,30 @@ export function createExecuteScheduledPublishesFunction(options) {
|
|
|
55
47
|
});
|
|
56
48
|
for (const doc of due) {
|
|
57
49
|
const outcome = await step.run(`publish-${config.slug}-${doc.id}`, async () => {
|
|
58
|
-
|
|
50
|
+
let result;
|
|
51
|
+
try {
|
|
52
|
+
result = await options.publish({
|
|
53
|
+
collection: doc.collection,
|
|
54
|
+
id: doc.id,
|
|
55
|
+
reasoning: REASONING,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
logger.error('Scheduled publish threw', {
|
|
60
|
+
document: doc.title,
|
|
61
|
+
error: error instanceof Error ? error.message : String(error),
|
|
62
|
+
});
|
|
63
|
+
return 'error';
|
|
64
|
+
}
|
|
65
|
+
if (!result.published) {
|
|
66
|
+
logger.warn('Scheduled publish blocked by policy', {
|
|
67
|
+
document: doc.title,
|
|
68
|
+
reason: result.reason,
|
|
69
|
+
});
|
|
70
|
+
return 'blocked';
|
|
71
|
+
}
|
|
72
|
+
logger.info('Scheduled publish succeeded', { document: doc.title });
|
|
73
|
+
return 'published';
|
|
59
74
|
});
|
|
60
75
|
if (outcome === 'published')
|
|
61
76
|
publishedCount += 1;
|
|
@@ -67,53 +82,4 @@ export function createExecuteScheduledPublishesFunction(options) {
|
|
|
67
82
|
return { publishedCount, blockedCount };
|
|
68
83
|
});
|
|
69
84
|
}
|
|
70
|
-
async function executePublish({ doc, baseUrl, apiKey, logger, }) {
|
|
71
|
-
let response;
|
|
72
|
-
try {
|
|
73
|
-
response = await fetch(`${baseUrl}/api/publishing/mcp`, {
|
|
74
|
-
method: 'POST',
|
|
75
|
-
headers: {
|
|
76
|
-
authorization: `Bearer ${apiKey}`,
|
|
77
|
-
'content-type': 'application/json',
|
|
78
|
-
},
|
|
79
|
-
body: JSON.stringify({
|
|
80
|
-
jsonrpc: '2.0',
|
|
81
|
-
id: 1,
|
|
82
|
-
method: 'tools/call',
|
|
83
|
-
params: {
|
|
84
|
-
name: 'publish',
|
|
85
|
-
arguments: {
|
|
86
|
-
collection: doc.collection,
|
|
87
|
-
id: doc.id,
|
|
88
|
-
_meta: { reasoning: 'Scheduled publish executed by workflow cron' },
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
}),
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
logger.error('Scheduled publish HTTP error', {
|
|
96
|
-
document: doc.title,
|
|
97
|
-
error: error instanceof Error ? error.message : String(error),
|
|
98
|
-
});
|
|
99
|
-
return 'error';
|
|
100
|
-
}
|
|
101
|
-
if (!response.ok) {
|
|
102
|
-
logger.error('Scheduled publish HTTP non-2xx', {
|
|
103
|
-
document: doc.title,
|
|
104
|
-
status: response.status,
|
|
105
|
-
});
|
|
106
|
-
return 'error';
|
|
107
|
-
}
|
|
108
|
-
const body = (await response.json());
|
|
109
|
-
if (body.error) {
|
|
110
|
-
logger.warn('Scheduled publish blocked by policy', {
|
|
111
|
-
document: doc.title,
|
|
112
|
-
reason: body.error.message,
|
|
113
|
-
});
|
|
114
|
-
return 'blocked';
|
|
115
|
-
}
|
|
116
|
-
logger.info('Scheduled publish succeeded', { document: doc.title });
|
|
117
|
-
return 'published';
|
|
118
|
-
}
|
|
119
85
|
//# sourceMappingURL=execute-scheduled-publishes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-scheduled-publishes.js","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"AAGA,MAAM,gBAAgB,GAAG,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"execute-scheduled-publishes.js","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,6 +43,23 @@ export function createRevalidateOnPublishFunction(options) {
|
|
|
43
43
|
return { collection, slug, revalidated: true };
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* How stale a caller may find a tag after this runs: not at all.
|
|
48
|
+
*
|
|
49
|
+
* Next 16 made `revalidateTag`'s second argument required — it is a cache-life
|
|
50
|
+
* profile — and one-argument calls log a deprecation warning on every publish.
|
|
51
|
+
* `{ expire: 0 }` is the immediate expiry the one-argument form used to mean,
|
|
52
|
+
* and it is what an editor pressing Publish expects.
|
|
53
|
+
*
|
|
54
|
+
* Passed unconditionally rather than behind a version check. The peer range is
|
|
55
|
+
* `next >= 15`, and Next 15's `revalidateTag` takes one parameter and ignores a
|
|
56
|
+
* second, so the two-argument call is correct on both.
|
|
57
|
+
*
|
|
58
|
+
* `updateTag`, which Next offers as the other way out of the deprecation, is
|
|
59
|
+
* not usable here: it throws outside a Server Action, and this runs in an
|
|
60
|
+
* Inngest step behind a route handler.
|
|
61
|
+
*/
|
|
62
|
+
const IMMEDIATE = { expire: 0 };
|
|
46
63
|
/**
|
|
47
64
|
* Default revalidator: dynamic-imports `next/cache` so the package can be
|
|
48
65
|
* imported in environments without Next.js (e.g. test runners that don't
|
|
@@ -54,6 +71,6 @@ const defaultRevalidate = async ({ path, tags }) => {
|
|
|
54
71
|
if (path)
|
|
55
72
|
revalidatePath(path);
|
|
56
73
|
for (const tag of tags)
|
|
57
|
-
revalidateTag(tag);
|
|
74
|
+
revalidateTag(tag, IMMEDIATE);
|
|
58
75
|
};
|
|
59
76
|
//# sourceMappingURL=revalidate-on-publish.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revalidate-on-publish.js","sourceRoot":"","sources":["../src/revalidate-on-publish.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"revalidate-on-publish.js","sourceRoot":"","sources":["../src/revalidate-on-publish.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -56,24 +56,56 @@ export interface ScheduledCollectionConfig {
|
|
|
56
56
|
*/
|
|
57
57
|
scheduledField?: string;
|
|
58
58
|
}
|
|
59
|
+
/** One document the cron found due, handed to `publish`. */
|
|
60
|
+
export interface ScheduledPublishRequest {
|
|
61
|
+
collection: string;
|
|
62
|
+
id: string;
|
|
63
|
+
/** Recorded on the audit event, so a scheduled publish is distinguishable. */
|
|
64
|
+
reasoning: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* What `publish` reports back. `published: false` is a policy refusal — a
|
|
68
|
+
* composition error, a missing approval — and is expected traffic, not a fault.
|
|
69
|
+
*/
|
|
70
|
+
export interface ScheduledPublishResult {
|
|
71
|
+
published: boolean;
|
|
72
|
+
reason?: string | undefined;
|
|
73
|
+
}
|
|
59
74
|
export interface ExecuteScheduledPublishesOptions extends BaseWorkflowOptions {
|
|
60
75
|
/** Collections that participate in scheduled publishing. */
|
|
61
76
|
collections: ScheduledCollectionConfig[];
|
|
62
77
|
/** Cron schedule. Default: `*\/5 * * * *` (every 5 minutes). */
|
|
63
78
|
schedule?: string;
|
|
64
79
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
80
|
+
* How to publish one document. **Wire this to the publishing service**, not to
|
|
81
|
+
* `payload.update` — the service is the seven-stage pipeline, and a direct
|
|
82
|
+
* write skips composition, accessibility and approval gating:
|
|
83
|
+
*
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { getPublishingService } from '@forumone/throughline-publishing'
|
|
86
|
+
*
|
|
87
|
+
* publish: async ({ collection, id, reasoning }) => {
|
|
88
|
+
* const outcome = await getPublishingService(payload).publish({
|
|
89
|
+
* collection,
|
|
90
|
+
* id,
|
|
91
|
+
* actor: { apiKeyName: 'scheduled-publish', channel: 'mcp' },
|
|
92
|
+
* meta: { reasoning },
|
|
93
|
+
* })
|
|
94
|
+
* return { published: outcome.published, reason: outcome.reason }
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* Injected rather than built in because this package is a leaf — it depends on
|
|
99
|
+
* `core` alone, and reaching the publishing service means depending on the
|
|
100
|
+
* publishing package or duplicating its symbol string.
|
|
101
|
+
*
|
|
102
|
+
* It used to be a `fetch` to `POST /api/publishing/mcp` with a bearer key, and
|
|
103
|
+
* that endpoint no longer exists. The self-call was also the wrong shape: it
|
|
104
|
+
* cost a function invocation per document, needed a key and a base URL to be
|
|
105
|
+
* right, and returned 401 rather than publishing anything if the deployment
|
|
106
|
+
* URL sat behind access protection.
|
|
75
107
|
*/
|
|
76
|
-
|
|
108
|
+
publish: (request: ScheduledPublishRequest) => Promise<ScheduledPublishResult>;
|
|
77
109
|
/** Override the function id. Default: `execute-scheduled-publishes`. */
|
|
78
110
|
id?: string;
|
|
79
111
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEzE,MAAM,WAAW,0BAA2B,SAAQ,mBAAmB;IACrE;;;;;OAKG;IACH,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,CAAA;IACtD;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,gCAAiC,SAAQ,mBAAmB;IAC3E,4DAA4D;IAC5D,WAAW,EAAE,yBAAyB,EAAE,CAAA;IACxC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forumone/throughline-workflows",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Composable Inngest function factories for the Throughline framework — revalidation, scheduled publishing, approval expiration, audit fan-out, healthcheck.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@forumone/throughline-core": "0.
|
|
49
|
+
"@forumone/throughline-core": "0.7.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^20.17.0",
|