hubspot-cms-sync 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/adapters/blog.mjs +34 -8
package/package.json
CHANGED
package/src/adapters/blog.mjs
CHANGED
|
@@ -45,12 +45,14 @@ import {
|
|
|
45
45
|
mkdirSync,
|
|
46
46
|
readdirSync,
|
|
47
47
|
existsSync,
|
|
48
|
+
rmSync,
|
|
48
49
|
} from 'node:fs';
|
|
49
50
|
import { join, resolve as resolvePath, basename, extname } from 'node:path';
|
|
50
51
|
import { createHash } from 'node:crypto';
|
|
51
52
|
|
|
52
53
|
import { hub, getAll } from '../lib/hub.mjs';
|
|
53
54
|
import { stableStringify } from '../lib/canonical.mjs';
|
|
55
|
+
import { wireToFile, fileToWire } from '../lib/posts-format.mjs';
|
|
54
56
|
import { resolve as resolveRefs, canonicalize as canonicalizeRefs } from '../lib/refs.mjs';
|
|
55
57
|
import { resolveCtaEmbeds, loadInventory } from '../cta-inventory.mjs';
|
|
56
58
|
|
|
@@ -317,10 +319,13 @@ export async function pull(acct, { contentDir, registry }) {
|
|
|
317
319
|
// (codex #7). It is content here, not a volatile timestamp to strip.
|
|
318
320
|
publishDate: p.publishDate || null,
|
|
319
321
|
};
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
322
|
+
// Canonical post format is frontmatter + HTML body (.md). Reshaping is lossless
|
|
323
|
+
// to the wire object (lib/posts-format.mjs round-trip), so the push payload is
|
|
324
|
+
// byte-identical to the old .json path. Drop any stale sibling .json from the
|
|
325
|
+
// pre-frontmatter format so push never sees the same post twice.
|
|
326
|
+
const base = join(postsOut, postFileFor(p.slug));
|
|
327
|
+
writeFileSync(`${base}.md`, wireToFile(portable));
|
|
328
|
+
if (existsSync(`${base}.json`)) rmSync(`${base}.json`);
|
|
324
329
|
pulled++;
|
|
325
330
|
}
|
|
326
331
|
|
|
@@ -372,6 +377,10 @@ export async function push(
|
|
|
372
377
|
registry,
|
|
373
378
|
publish = false,
|
|
374
379
|
limit,
|
|
380
|
+
// only: restrict the push to specific posts by file base name (no extension),
|
|
381
|
+
// e.g. ['blog__hello']. Enables a scoped sample push without touching the rest
|
|
382
|
+
// of the blog — used by verification harnesses; undefined means "all posts".
|
|
383
|
+
only,
|
|
375
384
|
dryRun = false,
|
|
376
385
|
hubFn = hub,
|
|
377
386
|
// Injectable clock + sleep so the "wait past every scheduled publish" gate
|
|
@@ -393,12 +402,29 @@ export async function push(
|
|
|
393
402
|
// then replaces @asset tokens below. (The old blog-local rehostAssets path is
|
|
394
403
|
// retired: one upload location, no /blog-migrated vs /synced-assets split.)
|
|
395
404
|
|
|
396
|
-
|
|
397
|
-
|
|
405
|
+
// Accept the canonical frontmatter format (.md) and the legacy .json. If both
|
|
406
|
+
// exist for one post, .md wins; dedup by base name so a post is never pushed
|
|
407
|
+
// twice during the transition.
|
|
408
|
+
const byBase = new Map();
|
|
409
|
+
for (const f of readdirSync(postsDir)) {
|
|
410
|
+
const m = /^(.*)\.(md|json)$/.exec(f);
|
|
411
|
+
if (!m) continue;
|
|
412
|
+
const [, base, ext] = m;
|
|
413
|
+
if (ext === 'md' || !byBase.has(base)) byBase.set(base, f);
|
|
414
|
+
}
|
|
415
|
+
let files = [...byBase.values()].sort();
|
|
416
|
+
if (only) {
|
|
417
|
+
const want = new Set(only);
|
|
418
|
+
files = files.filter((f) => want.has(f.replace(/\.(md|json)$/, '')));
|
|
419
|
+
}
|
|
398
420
|
if (limit) files = files.slice(0, limit);
|
|
399
421
|
|
|
400
|
-
// Group posts by their blogSlug and resolve each container exactly once.
|
|
401
|
-
|
|
422
|
+
// Group posts by their blogSlug and resolve each container exactly once. The
|
|
423
|
+
// frontmatter codec yields the same wire object JSON.parse would have.
|
|
424
|
+
const posts = files.map((f) => {
|
|
425
|
+
const raw = readFileSync(join(postsDir, f), 'utf8');
|
|
426
|
+
return f.endsWith('.md') ? fileToWire(raw) : JSON.parse(raw);
|
|
427
|
+
});
|
|
402
428
|
const containerCache = new Map();
|
|
403
429
|
async function containerIdFor(blogSlug) {
|
|
404
430
|
if (containerCache.has(blogSlug)) return containerCache.get(blogSlug);
|