backend-manager 5.9.16 → 5.9.18
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/docs/ghostii.md +63 -5
- package/package.json +1 -1
- package/src/manager/events/cron/daily/blog-auto-publisher.js +23 -398
- package/src/manager/libraries/content/ghostii.js +2 -1
- package/src/manager/libraries/content/source-resolver.js +397 -0
- package/src/manager/libraries/email/generators/newsletter.js +18 -46
- package/src/manager/routes/admin/post/post.js +1 -0
- package/src/manager/routes/admin/post/templates/post.html +1 -0
- package/src/manager/routes/content/post/get.js +1 -0
- package/src/test/fixtures/firebase-project/.temp/test-mode.json +1 -1
- package/src/test/fixtures/firebase-project/database-debug.log +8 -8
- package/src/test/fixtures/firebase-project/firestore-debug.log +56 -56
- package/src/test/fixtures/firebase-project/pubsub-debug.log +3 -3
- package/test/email/newsletter-generate.js +65 -50
|
@@ -2,7 +2,7 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
|
|
|
2
2
|
WARNING: sun.misc.Unsafe::allocateMemory has been called by io.netty.util.internal.PlatformDependent0$2 (file:/Users/ian/.cache/firebase/emulators/cloud-firestore-emulator-v1.21.0.jar)
|
|
3
3
|
WARNING: Please consider reporting this to the maintainers of class io.netty.util.internal.PlatformDependent0$2
|
|
4
4
|
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
|
|
5
|
-
Jun
|
|
5
|
+
Jun 26, 2026 5:05:47 PM com.google.cloud.datastore.emulator.firestore.websocket.WebSocketServer start
|
|
6
6
|
INFO: Started WebSocket server on ws://127.0.0.1:9150
|
|
7
7
|
|
|
8
8
|
API endpoint: http://127.0.0.1:8080
|
|
@@ -20,115 +20,115 @@ If you are running a Firestore in Datastore Mode project, run:
|
|
|
20
20
|
Note: Support for Datastore Mode is in preview. If you encounter any bugs please file at https://github.com/firebase/firebase-tools/issues.
|
|
21
21
|
Dev App Server is now running.
|
|
22
22
|
|
|
23
|
-
Jun
|
|
23
|
+
Jun 26, 2026 5:05:57 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
24
24
|
INFO: Detected non-HTTP/2 connection.
|
|
25
|
-
Jun
|
|
25
|
+
Jun 26, 2026 5:05:57 PM io.grpc.netty.TcpMetrics loadEpollInfo
|
|
26
26
|
INFO: Epoll available during static init of TcpMetrics:false
|
|
27
|
-
Jun
|
|
27
|
+
Jun 26, 2026 5:05:57 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
28
28
|
INFO: Detected HTTP/2 connection.
|
|
29
|
-
Jun
|
|
29
|
+
Jun 26, 2026 5:05:59 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
30
30
|
INFO: Detected HTTP/2 connection.
|
|
31
|
-
Jun
|
|
31
|
+
Jun 26, 2026 5:05:59 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
32
32
|
INFO: Detected HTTP/2 connection.
|
|
33
|
-
Jun
|
|
33
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
34
34
|
INFO: Detected HTTP/2 connection.
|
|
35
|
-
Jun
|
|
35
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
36
36
|
INFO: Detected HTTP/2 connection.
|
|
37
|
-
Jun
|
|
37
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
38
38
|
INFO: Detected HTTP/2 connection.
|
|
39
|
-
Jun
|
|
39
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
40
40
|
INFO: Detected HTTP/2 connection.
|
|
41
|
-
Jun
|
|
41
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
42
42
|
INFO: Detected HTTP/2 connection.
|
|
43
|
-
Jun
|
|
43
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
44
44
|
INFO: Detected HTTP/2 connection.
|
|
45
|
-
Jun
|
|
45
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
46
46
|
INFO: Detected HTTP/2 connection.
|
|
47
|
-
Jun
|
|
47
|
+
Jun 26, 2026 5:06:08 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
48
48
|
INFO: Detected HTTP/2 connection.
|
|
49
|
-
Jun
|
|
49
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
50
50
|
INFO: Detected HTTP/2 connection.
|
|
51
|
-
Jun
|
|
51
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
52
52
|
INFO: Detected HTTP/2 connection.
|
|
53
|
-
Jun
|
|
53
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
54
54
|
INFO: Detected HTTP/2 connection.
|
|
55
|
-
Jun
|
|
55
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
56
56
|
INFO: Detected HTTP/2 connection.
|
|
57
|
-
Jun
|
|
57
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
58
58
|
INFO: Detected HTTP/2 connection.
|
|
59
|
-
Jun
|
|
59
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
60
60
|
INFO: Detected HTTP/2 connection.
|
|
61
|
-
Jun
|
|
61
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
62
62
|
INFO: Detected HTTP/2 connection.
|
|
63
|
-
Jun
|
|
63
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
64
64
|
INFO: Detected HTTP/2 connection.
|
|
65
|
-
Jun
|
|
65
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
66
66
|
INFO: Detected HTTP/2 connection.
|
|
67
|
-
Jun
|
|
67
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
68
68
|
INFO: Detected HTTP/2 connection.
|
|
69
|
-
Jun
|
|
69
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
70
70
|
INFO: Detected HTTP/2 connection.
|
|
71
|
-
Jun
|
|
71
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
72
72
|
INFO: Detected HTTP/2 connection.
|
|
73
|
-
Jun
|
|
73
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
74
74
|
INFO: Detected HTTP/2 connection.
|
|
75
|
-
Jun
|
|
75
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
76
76
|
INFO: Detected HTTP/2 connection.
|
|
77
|
-
Jun
|
|
77
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
78
78
|
INFO: Detected HTTP/2 connection.
|
|
79
|
-
Jun
|
|
79
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
80
80
|
INFO: Detected HTTP/2 connection.
|
|
81
|
-
Jun
|
|
81
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
82
82
|
INFO: Detected HTTP/2 connection.
|
|
83
|
-
Jun
|
|
83
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
84
84
|
INFO: Detected HTTP/2 connection.
|
|
85
|
-
Jun
|
|
85
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
86
86
|
INFO: Detected HTTP/2 connection.
|
|
87
|
-
Jun
|
|
87
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
88
88
|
INFO: Detected HTTP/2 connection.
|
|
89
|
-
Jun
|
|
89
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
90
90
|
INFO: Detected HTTP/2 connection.
|
|
91
|
-
Jun
|
|
91
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
92
92
|
INFO: Detected HTTP/2 connection.
|
|
93
|
-
Jun
|
|
93
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
94
94
|
INFO: Detected HTTP/2 connection.
|
|
95
|
-
Jun
|
|
95
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
96
96
|
INFO: Detected HTTP/2 connection.
|
|
97
|
-
Jun
|
|
97
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
98
98
|
INFO: Detected HTTP/2 connection.
|
|
99
|
-
Jun
|
|
99
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
100
100
|
INFO: Detected HTTP/2 connection.
|
|
101
|
-
Jun
|
|
101
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
102
102
|
INFO: Detected HTTP/2 connection.
|
|
103
|
-
Jun
|
|
103
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
104
104
|
INFO: Detected HTTP/2 connection.
|
|
105
|
-
Jun
|
|
105
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
106
106
|
INFO: Detected HTTP/2 connection.
|
|
107
|
-
Jun
|
|
107
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
108
108
|
INFO: Detected HTTP/2 connection.
|
|
109
|
-
Jun
|
|
109
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
110
110
|
INFO: Detected HTTP/2 connection.
|
|
111
|
-
Jun
|
|
111
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
112
112
|
INFO: Detected HTTP/2 connection.
|
|
113
|
-
Jun
|
|
113
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
114
114
|
INFO: Detected HTTP/2 connection.
|
|
115
|
-
Jun
|
|
115
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
116
116
|
INFO: Detected HTTP/2 connection.
|
|
117
|
-
Jun
|
|
117
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
118
118
|
INFO: Detected HTTP/2 connection.
|
|
119
|
-
Jun
|
|
119
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
120
120
|
INFO: Detected HTTP/2 connection.
|
|
121
|
-
Jun
|
|
121
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
122
122
|
INFO: Detected HTTP/2 connection.
|
|
123
|
-
Jun
|
|
123
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
124
124
|
INFO: Detected HTTP/2 connection.
|
|
125
|
-
Jun
|
|
125
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
126
126
|
INFO: Detected HTTP/2 connection.
|
|
127
|
-
Jun
|
|
127
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
128
128
|
INFO: Detected HTTP/2 connection.
|
|
129
|
-
Jun
|
|
129
|
+
Jun 26, 2026 5:06:09 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
130
130
|
INFO: Detected HTTP/2 connection.
|
|
131
|
-
Jun
|
|
131
|
+
Jun 26, 2026 5:06:10 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
132
132
|
INFO: Detected HTTP/2 connection.
|
|
133
133
|
*** shutting down gRPC server since JVM is shutting down
|
|
134
134
|
*** server shut down
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
This is the Google Pub/Sub fake.
|
|
2
2
|
Implementation may be incomplete or differ from the real system.
|
|
3
|
-
Jun
|
|
3
|
+
Jun 26, 2026 5:05:51 PM com.google.cloud.pubsub.testing.v1.Main main
|
|
4
4
|
INFO: IAM integration is disabled. IAM policy methods and ACL checks are not supported
|
|
5
5
|
SLF4J(W): No SLF4J providers were found.
|
|
6
6
|
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
|
|
@@ -9,9 +9,9 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
|
|
|
9
9
|
WARNING: sun.misc.Unsafe::allocateMemory has been called by io.netty.util.internal.PlatformDependent0$2 (file:/Users/ian/.cache/firebase/emulators/pubsub-emulator-0.8.33/pubsub-emulator/lib/cloud-pubsub-emulator-0.8.33-all.jar)
|
|
10
10
|
WARNING: Please consider reporting this to the maintainers of class io.netty.util.internal.PlatformDependent0$2
|
|
11
11
|
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
|
|
12
|
-
Jun
|
|
12
|
+
Jun 26, 2026 5:05:52 PM com.google.cloud.pubsub.testing.v1.Main main
|
|
13
13
|
INFO: Server started, listening on 8085
|
|
14
|
-
Jun
|
|
14
|
+
Jun 26, 2026 5:05:58 PM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
15
15
|
INFO: Detected HTTP/2 connection.
|
|
16
16
|
*** shutting down gRPC server since JVM is shutting down
|
|
17
17
|
*** server shut down
|
|
@@ -41,6 +41,11 @@
|
|
|
41
41
|
* NEWSLETTER_OPEN=1 Auto-open the rendered preview in the default browser (macOS only).
|
|
42
42
|
*
|
|
43
43
|
* --- AI-mode-only env vars (require TEST_EXTENDED_MODE=1) ---
|
|
44
|
+
* NEWSLETTER_SOURCE=<type> Override the source type for this run. Bypasses parent-server
|
|
45
|
+
* fetch and lets the generator's built-in resolver run.
|
|
46
|
+
* Values: '$feed:<url>', '$parent'. When set, sources[] in the
|
|
47
|
+
* config is replaced with this single source.
|
|
48
|
+
* Example: NEWSLETTER_SOURCE='$feed:https://feeds.arstechnica.com/arstechnica/index'
|
|
44
49
|
* NEWSLETTER_PEEK=1 Fetch + list ready sources, do not claim, exit.
|
|
45
50
|
* NEWSLETTER_SOURCE_ID=<id> Generate from one specific source WITHOUT claiming it.
|
|
46
51
|
* NEWSLETTER_LIMIT=10 Sources per category for PEEK (default 10).
|
|
@@ -325,60 +330,57 @@ module.exports = {
|
|
|
325
330
|
// `api.` subdomain (e.g. 'https://itwcreativeworks.com'); the helper
|
|
326
331
|
// inserts `api.` at call time. PARENT_API_URL env override is honored
|
|
327
332
|
// verbatim for one-off testing against a different parent.
|
|
328
|
-
|
|
329
|
-
|
|
333
|
+
// When NEWSLETTER_SOURCE is set, skip parent URL checks and source fetching —
|
|
334
|
+
// the generator's built-in resolver (resolveNewsletterSources) handles everything.
|
|
335
|
+
let sources = [];
|
|
336
|
+
|
|
337
|
+
if (!env.NEWSLETTER_SOURCE) {
|
|
338
|
+
const parentUrl = env.PARENT_API_URL || Manager.getParentApiUrl();
|
|
339
|
+
assert.ok(parentUrl, 'PARENT_API_URL (env) or parent (config) must be set for the AI pipeline. Set TEST_EXTENDED_MODE=1 to run it, or omit TEST_EXTENDED_MODE for the fast fixture preview.');
|
|
340
|
+
|
|
341
|
+
// --- Peek mode (early return) ---
|
|
342
|
+
if (env.NEWSLETTER_PEEK) {
|
|
343
|
+
const peeked = await peekSources({
|
|
344
|
+
parentUrl,
|
|
345
|
+
categories: newsletterConfig.categories || [],
|
|
346
|
+
limit: parseInt(env.NEWSLETTER_LIMIT, 10) || 10,
|
|
347
|
+
key: env.BACKEND_MANAGER_KEY,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
console.log(`\nPeek mode — ${peeked.length} ready source(s):\n`);
|
|
351
|
+
peeked.forEach((s, i) => {
|
|
352
|
+
const raw = s.source || {};
|
|
353
|
+
const cats = (s.categories || []).join(', ') || s.category || '(none)';
|
|
354
|
+
console.log(`[${i + 1}] ${s.id}`);
|
|
355
|
+
console.log(` Categories: ${cats}`);
|
|
356
|
+
console.log(` From: ${raw.from || s.from || '(unknown)'}`);
|
|
357
|
+
console.log(` Subject: ${raw.subject || s.subject || '(none)'}`);
|
|
358
|
+
console.log(` Headline: ${s.ai?.headline || '(none — not yet AI-processed)'}`);
|
|
359
|
+
console.log('');
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
assert.ok(true, `Peeked ${peeked.length} sources`);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
330
365
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
366
|
+
// --- Fetch sources ---
|
|
367
|
+
const claim = !!env.NEWSLETTER_CLAIM;
|
|
368
|
+
sources = await fetchSourcesForRun({
|
|
334
369
|
parentUrl,
|
|
335
|
-
|
|
336
|
-
|
|
370
|
+
newsletterConfig,
|
|
371
|
+
brandId: config.brand?.id,
|
|
372
|
+
sourceId: env.NEWSLETTER_SOURCE_ID,
|
|
337
373
|
key: env.BACKEND_MANAGER_KEY,
|
|
374
|
+
claim,
|
|
338
375
|
});
|
|
339
376
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const cats = (s.categories || []).join(', ') || s.category || '(none)';
|
|
344
|
-
console.log(`[${i + 1}] ${s.id}`);
|
|
345
|
-
console.log(` Categories: ${cats}`);
|
|
346
|
-
console.log(` From: ${raw.from || s.from || '(unknown)'}`);
|
|
347
|
-
console.log(` Subject: ${raw.subject || s.subject || '(none)'}`);
|
|
348
|
-
console.log(` Headline: ${s.ai?.headline || '(none — not yet AI-processed)'}`);
|
|
349
|
-
console.log('');
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
assert.ok(true, `Peeked ${sources.length} sources`);
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// --- Fetch sources ---
|
|
357
|
-
// By DEFAULT the test does NOT claim sources — it fetches them without
|
|
358
|
-
// claimFor, so they stay 'ready' and available for the real newsletter.
|
|
359
|
-
// This keeps test runs repeatable and non-destructive (a test should never
|
|
360
|
-
// silently consume production resources). Set NEWSLETTER_CLAIM=1 to exercise
|
|
361
|
-
// the real claim/consume path (then use NEWSLETTER_RELEASE=1 to put them back).
|
|
362
|
-
const claim = !!env.NEWSLETTER_CLAIM;
|
|
363
|
-
const sources = await fetchSourcesForRun({
|
|
364
|
-
parentUrl,
|
|
365
|
-
newsletterConfig,
|
|
366
|
-
brandId: config.brand?.id,
|
|
367
|
-
sourceId: env.NEWSLETTER_SOURCE_ID,
|
|
368
|
-
key: env.BACKEND_MANAGER_KEY,
|
|
369
|
-
claim,
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
// Environmental precondition: the parent server must have ready sources in
|
|
373
|
-
// at least one configured category. Skip cleanly when the pool is empty
|
|
374
|
-
// (transient state — no point hard-failing CI on an external queue).
|
|
375
|
-
if (sources.length === 0) {
|
|
376
|
-
return skip('No ready newsletter sources available on parent server (environmental)');
|
|
377
|
-
}
|
|
377
|
+
if (sources.length === 0) {
|
|
378
|
+
return skip('No ready newsletter sources available on parent server (environmental)');
|
|
379
|
+
}
|
|
378
380
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
381
|
+
if (claim && !env.NEWSLETTER_SOURCE_ID) {
|
|
382
|
+
appendClaimed(claimedFile, sources.map((s) => s.id));
|
|
383
|
+
}
|
|
382
384
|
}
|
|
383
385
|
|
|
384
386
|
// Force `newsletter.enabled: true` and inject the per-run newsletter config
|
|
@@ -432,12 +434,25 @@ module.exports = {
|
|
|
432
434
|
|
|
433
435
|
console.log(`[extended] uploading to itw-creative-works/newsletter-assets/${config.brand?.id}/${campaignId || '<auto-id>'}/ + Beehiiv draft`);
|
|
434
436
|
|
|
437
|
+
// NEWSLETTER_SOURCE overrides the configured sources[] and lets the
|
|
438
|
+
// generator's built-in resolver run (resolveNewsletterSources). Without
|
|
439
|
+
// this, the test always passes pre-fetched parent sources via opts.sources,
|
|
440
|
+
// bypassing feed resolution entirely.
|
|
441
|
+
// NEWSLETTER_SOURCE='$feed:https://feeds.arstechnica.com/arstechnica/index'
|
|
442
|
+
// NEWSLETTER_SOURCE='$parent' (default behavior, explicit)
|
|
443
|
+
const useResolverSources = !!env.NEWSLETTER_SOURCE;
|
|
444
|
+
|
|
445
|
+
if (useResolverSources) {
|
|
446
|
+
newsletterConfig.sources = [env.NEWSLETTER_SOURCE];
|
|
447
|
+
Manager.config.marketing.newsletter.content = newsletterConfig;
|
|
448
|
+
}
|
|
449
|
+
|
|
435
450
|
const result = await generator.generate(
|
|
436
451
|
Manager,
|
|
437
452
|
assistant,
|
|
438
|
-
{ name:
|
|
453
|
+
{ name: `${config.brand?.name || 'Brand'} Newsletter — Iteration ${stamp}` },
|
|
439
454
|
{
|
|
440
|
-
sources,
|
|
455
|
+
sources: useResolverSources ? undefined : sources,
|
|
441
456
|
skipClaim: true, // We manage the claim/release lifecycle ourselves
|
|
442
457
|
skipImages: !!env.NEWSLETTER_NO_IMAGES,
|
|
443
458
|
// The article is GENERATED whenever the brand's config.article.enabled is on
|