@moxn/kb-migrate 0.5.0 → 0.6.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.
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `--json` output contract + version reporting.
3
+ *
4
+ * - `kb-migrate local --json` printed `Processing: …` progress on STDOUT ahead
5
+ * of the JSON log, so `context import-local --json` was not parseable. In
6
+ * JSON mode stdout carries the log and nothing else; progress goes to stderr.
7
+ * - `--version` was hardcoded `0.1.0`, so a stale npx resolution (a cached
8
+ * 0.4.x exporter, prod 2026-09-25) was undiagnosable. The real package
9
+ * version is reported, and stamped on every JSON log.
10
+ */
11
+ import { describe, it, expect, vi, afterEach } from 'vitest';
12
+ import * as fs from 'fs';
13
+ import { emitJson, packageVersion, withJsonStdout } from './output.js';
14
+ afterEach(() => {
15
+ vi.restoreAllMocks();
16
+ });
17
+ describe('packageVersion', () => {
18
+ it('is the version in package.json, not a hardcoded placeholder', () => {
19
+ const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
20
+ expect(packageVersion()).toBe(pkg.version);
21
+ expect(packageVersion()).not.toBe('0.1.0');
22
+ });
23
+ });
24
+ describe('JSON mode stdout', () => {
25
+ function capture() {
26
+ const stdout = [];
27
+ const stderr = [];
28
+ vi.spyOn(process.stdout, 'write').mockImplementation(((c) => {
29
+ stdout.push(String(c));
30
+ return true;
31
+ }));
32
+ vi.spyOn(process.stderr, 'write').mockImplementation(((c) => {
33
+ stderr.push(String(c));
34
+ return true;
35
+ }));
36
+ return { stdout, stderr };
37
+ }
38
+ it('routes progress (console.log) to stderr while the run is in JSON mode', async () => {
39
+ const { stdout, stderr } = capture();
40
+ await withJsonStdout(true, async () => {
41
+ console.log('Processing: a.md (1/1)');
42
+ });
43
+ emitJson({ summary: { total: 1 } });
44
+ const out = stdout.join('');
45
+ const parsed = JSON.parse(out);
46
+ expect(parsed.summary.total).toBe(1);
47
+ expect(parsed.kbMigrateVersion).toBe(packageVersion());
48
+ expect(out).not.toContain('Processing');
49
+ expect(stderr.join('')).toContain('Processing: a.md');
50
+ });
51
+ it('restores console.log afterwards, and leaves it alone outside JSON mode', async () => {
52
+ const original = console.log;
53
+ await withJsonStdout(true, async () => { });
54
+ expect(console.log).toBe(original);
55
+ await withJsonStdout(false, async () => {
56
+ expect(console.log).toBe(original);
57
+ });
58
+ });
59
+ });
@@ -11,6 +11,7 @@
11
11
  * Conflict detection uses the MoxnClient's notion-mapping API endpoints
12
12
  * (when available) to find existing Notion pages for a KB document.
13
13
  */
14
+ import { moxnFetch } from '../http.js';
14
15
  import { Client } from '@notionhq/client';
15
16
  import { markdownToBlocks } from '@tryfabric/martian';
16
17
  import { ExportTarget, } from './base.js';
@@ -744,7 +745,7 @@ export class NotionExportTarget extends ExportTarget {
744
745
  return cached;
745
746
  // Try notion-mapping API
746
747
  try {
747
- const response = await fetch(`${this.config.apiUrl}/api/v1/kb/notion-mappings/by-document/${kbDocumentId}`, {
748
+ const response = await moxnFetch(`${this.config.apiUrl}/api/v1/kb/notion-mappings/by-document/${kbDocumentId}`, {
748
749
  headers: { 'x-api-key': this.config.apiKey },
749
750
  });
750
751
  if (response.ok) {
@@ -764,7 +765,7 @@ export class NotionExportTarget extends ExportTarget {
764
765
  this.mappingCache.set(kbDocumentId, notionPageId);
765
766
  // Try to save mapping via API (best-effort)
766
767
  try {
767
- await fetch(`${this.config.apiUrl}/api/v1/kb/notion-mappings`, {
768
+ await moxnFetch(`${this.config.apiUrl}/api/v1/kb/notion-mappings`, {
768
769
  method: 'POST',
769
770
  headers: {
770
771
  'Content-Type': 'application/json',
package/dist/types.d.ts CHANGED
@@ -146,6 +146,8 @@ export interface MigrationResult {
146
146
  /** Source page ID (e.g. Notion page ID) for building cross-ref mappings */
147
147
  sourcePageId?: string;
148
148
  error?: string;
149
+ /** Non-fatal: the document landed, but not everything asked for applied. */
150
+ warning?: string;
149
151
  duration?: number;
150
152
  }
151
153
  /**
@@ -276,8 +278,10 @@ export interface ListResponse {
276
278
  export interface ExportResult {
277
279
  documentId: string;
278
280
  documentPath: string;
281
+ /** Directory-relative output file; empty when nothing was written. */
279
282
  outputFile: string;
280
- status: 'exported' | 'failed';
283
+ /** 'skipped': a kind with no local export format (nothing written). */
284
+ status: 'exported' | 'failed' | 'skipped';
281
285
  sectionsCount: number;
282
286
  mediaFiles: string[];
283
287
  error?: string;
@@ -302,6 +306,7 @@ export interface ExportLog {
302
306
  total: number;
303
307
  exported: number;
304
308
  failed: number;
309
+ skipped: number;
305
310
  mediaDownloaded: number;
306
311
  duration: number;
307
312
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moxn/kb-migrate",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Migration tool for importing documents into Moxn Knowledge Base from local files, Notion, Google Docs, and more",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -112,6 +112,7 @@
112
112
  "dependencies": {
113
113
  "@azure/msal-node": "^3.8.10",
114
114
  "@microsoft/microsoft-graph-client": "^3.0.7",
115
+ "@moxn/auth": "^0.1.0",
115
116
  "@moxn/kb-migrate": "^0.4.14",
116
117
  "@notionhq/client": "^5.9.0",
117
118
  "@tryfabric/martian": "^1.2.4",