@tk_wfl/o2n-core 0.1.2

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.
Files changed (53) hide show
  1. package/dist/converter.d.ts +48 -0
  2. package/dist/converter.d.ts.map +1 -0
  3. package/dist/converter.js +264 -0
  4. package/dist/converter.js.map +1 -0
  5. package/dist/credentials.d.ts +13 -0
  6. package/dist/credentials.d.ts.map +1 -0
  7. package/dist/credentials.js +33 -0
  8. package/dist/credentials.js.map +1 -0
  9. package/dist/index.d.ts +13 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +13 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/migrator.d.ts +16 -0
  14. package/dist/migrator.d.ts.map +1 -0
  15. package/dist/migrator.js +402 -0
  16. package/dist/migrator.js.map +1 -0
  17. package/dist/notion-blocks.d.ts +23 -0
  18. package/dist/notion-blocks.d.ts.map +1 -0
  19. package/dist/notion-blocks.js +91 -0
  20. package/dist/notion-blocks.js.map +1 -0
  21. package/dist/notion-client.d.ts +161 -0
  22. package/dist/notion-client.d.ts.map +1 -0
  23. package/dist/notion-client.js +187 -0
  24. package/dist/notion-client.js.map +1 -0
  25. package/dist/notion-db.d.ts +15 -0
  26. package/dist/notion-db.d.ts.map +1 -0
  27. package/dist/notion-db.js +88 -0
  28. package/dist/notion-db.js.map +1 -0
  29. package/dist/planner.d.ts +16 -0
  30. package/dist/planner.d.ts.map +1 -0
  31. package/dist/planner.js +60 -0
  32. package/dist/planner.js.map +1 -0
  33. package/dist/property-mapping.d.ts +17 -0
  34. package/dist/property-mapping.d.ts.map +1 -0
  35. package/dist/property-mapping.js +68 -0
  36. package/dist/property-mapping.js.map +1 -0
  37. package/dist/report.d.ts +6 -0
  38. package/dist/report.d.ts.map +1 -0
  39. package/dist/report.js +51 -0
  40. package/dist/report.js.map +1 -0
  41. package/dist/scanner.d.ts +14 -0
  42. package/dist/scanner.d.ts.map +1 -0
  43. package/dist/scanner.js +202 -0
  44. package/dist/scanner.js.map +1 -0
  45. package/dist/state.d.ts +39 -0
  46. package/dist/state.d.ts.map +1 -0
  47. package/dist/state.js +99 -0
  48. package/dist/state.js.map +1 -0
  49. package/dist/types.d.ts +126 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +3 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +48 -0
@@ -0,0 +1,161 @@
1
+ export declare const NOTION_VERSION = "2026-03-11";
2
+ export interface RetryOptions {
3
+ maxRetries: number;
4
+ initialDelayMs: number;
5
+ maxDelayMs: number;
6
+ }
7
+ export declare class NotionApiError extends Error {
8
+ status: number;
9
+ code: string | undefined;
10
+ raw?: unknown | undefined;
11
+ constructor(status: number, code: string | undefined, message: string, raw?: unknown | undefined);
12
+ }
13
+ export interface RateLimitOptions {
14
+ concurrency: number;
15
+ interval: number;
16
+ intervalCap: number;
17
+ }
18
+ export interface NotionClientOptions {
19
+ token: string;
20
+ dryRun?: boolean;
21
+ fetchImpl?: typeof fetch;
22
+ notionVersion?: string;
23
+ retry?: Partial<RetryOptions>;
24
+ /** テスト等でレート制御を無効化・調整したい場合に指定 */
25
+ rateLimit?: Partial<RateLimitOptions>;
26
+ }
27
+ export interface JsonRequestInit {
28
+ method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
29
+ path: string;
30
+ body?: unknown;
31
+ /** クエリパラメータ */
32
+ query?: Record<string, string | undefined>;
33
+ }
34
+ export interface RawRequestInit {
35
+ method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
36
+ path: string;
37
+ body: FormData | string | Buffer;
38
+ headers?: Record<string, string>;
39
+ }
40
+ /**
41
+ * §4・§10準拠のNotion APIクライアント。
42
+ * - 並列2・実効2.5req/s以下に制御
43
+ * - 429: Retry-After優先、なければ指数バックオフ(初期1s・最大60s・ジッター)、最大5回
44
+ * - 5xx: 同様にリトライ
45
+ * - dry-run時は一切fetchを呼ばず、callCountのみ加算する(テストで検証可能)
46
+ */
47
+ export declare class NotionClient {
48
+ readonly dryRun: boolean;
49
+ callCount: number;
50
+ private readonly queue;
51
+ private readonly token;
52
+ private readonly fetchImpl;
53
+ private readonly notionVersion;
54
+ private readonly retry;
55
+ constructor(opts: NotionClientOptions);
56
+ request<T = unknown>(init: JsonRequestInit): Promise<T>;
57
+ /** バイナリ送信(File Upload の send エンドポイント)用 */
58
+ requestRaw<T = unknown>(init: RawRequestInit): Promise<T>;
59
+ private executeWithRetry;
60
+ }
61
+ export interface CreatePageMarkdownParams {
62
+ parent: {
63
+ page_id: string;
64
+ } | {
65
+ type: 'data_source_id';
66
+ data_source_id: string;
67
+ };
68
+ markdown?: string;
69
+ properties?: Record<string, unknown>;
70
+ }
71
+ export interface UpdateContentItem {
72
+ old_str: string;
73
+ new_str: string;
74
+ replace_all_matches?: boolean;
75
+ }
76
+ /**
77
+ * §16-3検証済み(2026-07-19、実ワークスペース): PATCH .../markdown のボディは
78
+ * トップレベルに操作全体の `type` を持ち、対応するキー(update_content /
79
+ * insert_content / replace_content)の中に詳細を入れるネスト構造。
80
+ * 1回のPATCHで送れる操作は単一の種類のみ(配列で複数種類を混在できない)。
81
+ */
82
+ export type MarkdownUpdateBody = {
83
+ type: 'update_content';
84
+ update_content: {
85
+ content_updates: UpdateContentItem[];
86
+ };
87
+ } | {
88
+ type: 'insert_content';
89
+ insert_content: {
90
+ content: string;
91
+ position?: {
92
+ type: 'start' | 'end';
93
+ };
94
+ after?: string;
95
+ };
96
+ } | {
97
+ type: 'replace_content';
98
+ replace_content: {
99
+ new_str: string;
100
+ allow_deleting_content?: boolean;
101
+ };
102
+ };
103
+ /** §4.1のエンドポイントに対応する高レベルAPI */
104
+ export declare class NotionApi {
105
+ private readonly client;
106
+ constructor(client: NotionClient);
107
+ get callCount(): number;
108
+ getMe(): Promise<{
109
+ bot?: {
110
+ workspace_limits?: {
111
+ max_file_upload_size_in_bytes: number;
112
+ };
113
+ };
114
+ }>;
115
+ createPageMarkdown(params: CreatePageMarkdownParams): Promise<{
116
+ id: string;
117
+ url: string;
118
+ }>;
119
+ getPageMarkdown(pageId: string): Promise<{
120
+ markdown: string;
121
+ unknown_block_ids?: string[];
122
+ }>;
123
+ updatePageMarkdown(pageId: string, body: MarkdownUpdateBody, allowAsync?: boolean): Promise<{
124
+ task_id?: string;
125
+ poll_after_seconds?: number;
126
+ }>;
127
+ createDatabase(params: Record<string, unknown>): Promise<{
128
+ id: string;
129
+ }>;
130
+ createFileUpload(params: {
131
+ filename: string;
132
+ content_type?: string;
133
+ mode?: 'single_part' | 'multi_part';
134
+ number_of_parts?: number;
135
+ }): Promise<{
136
+ id: string;
137
+ upload_url: string;
138
+ }>;
139
+ sendFileUpload(fileUploadId: string, formData: FormData): Promise<{
140
+ id: string;
141
+ status: string;
142
+ }>;
143
+ /**
144
+ * §16検証済み(2026-07-19): `after`パラメータは廃止済みで指定すると400になる。
145
+ * 代わりに `position: { type: 'after_block', after_block: { id } }` を使う。
146
+ */
147
+ appendBlockChildren(blockId: string, children: unknown[], afterBlockId?: string): Promise<{
148
+ results: Array<{
149
+ id: string;
150
+ }>;
151
+ }>;
152
+ deleteBlock(blockId: string): Promise<void>;
153
+ getBlockChildren(blockId: string): Promise<{
154
+ results: Array<{
155
+ id: string;
156
+ type: string;
157
+ [k: string]: unknown;
158
+ }>;
159
+ }>;
160
+ }
161
+ //# sourceMappingURL=notion-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion-client.d.ts","sourceRoot":"","sources":["../src/notion-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,187 @@
1
+ import PQueue from 'p-queue';
2
+ export const NOTION_VERSION = '2026-03-11';
3
+ const API_BASE = 'https://api.notion.com/v1';
4
+ const DEFAULT_RETRY = {
5
+ maxRetries: 5,
6
+ initialDelayMs: 1000,
7
+ maxDelayMs: 60_000,
8
+ };
9
+ export class NotionApiError extends Error {
10
+ status;
11
+ code;
12
+ raw;
13
+ constructor(status, code, message, raw) {
14
+ super(message);
15
+ this.status = status;
16
+ this.code = code;
17
+ this.raw = raw;
18
+ this.name = 'NotionApiError';
19
+ }
20
+ }
21
+ function sleep(ms) {
22
+ return new Promise((resolve) => setTimeout(resolve, ms));
23
+ }
24
+ async function safeJson(res) {
25
+ try {
26
+ return await res.json();
27
+ }
28
+ catch {
29
+ return {};
30
+ }
31
+ }
32
+ const DEFAULT_RATE_LIMIT = {
33
+ // 3req/s制限に対しマージンを取り、実効2.5req/s以下にする
34
+ concurrency: 2,
35
+ interval: 1000,
36
+ intervalCap: 2,
37
+ };
38
+ /**
39
+ * §4・§10準拠のNotion APIクライアント。
40
+ * - 並列2・実効2.5req/s以下に制御
41
+ * - 429: Retry-After優先、なければ指数バックオフ(初期1s・最大60s・ジッター)、最大5回
42
+ * - 5xx: 同様にリトライ
43
+ * - dry-run時は一切fetchを呼ばず、callCountのみ加算する(テストで検証可能)
44
+ */
45
+ export class NotionClient {
46
+ dryRun;
47
+ callCount = 0;
48
+ queue;
49
+ token;
50
+ fetchImpl;
51
+ notionVersion;
52
+ retry;
53
+ constructor(opts) {
54
+ this.token = opts.token;
55
+ this.dryRun = opts.dryRun ?? false;
56
+ this.fetchImpl = opts.fetchImpl ?? fetch;
57
+ this.notionVersion = opts.notionVersion ?? NOTION_VERSION;
58
+ this.retry = { ...DEFAULT_RETRY, ...opts.retry };
59
+ const rateLimit = { ...DEFAULT_RATE_LIMIT, ...opts.rateLimit };
60
+ this.queue = new PQueue({
61
+ concurrency: rateLimit.concurrency,
62
+ interval: rateLimit.interval,
63
+ intervalCap: rateLimit.intervalCap,
64
+ });
65
+ }
66
+ async request(init) {
67
+ if (this.dryRun) {
68
+ this.callCount += 1;
69
+ return {};
70
+ }
71
+ const qs = init.query
72
+ ? '?' + new URLSearchParams(Object.entries(init.query).filter(([, v]) => v !== undefined)).toString()
73
+ : '';
74
+ return this.queue.add(() => this.executeWithRetry({
75
+ method: init.method,
76
+ url: `${API_BASE}${init.path}${qs}`,
77
+ headers: { 'Content-Type': 'application/json' },
78
+ body: init.body !== undefined ? JSON.stringify(init.body) : undefined,
79
+ }));
80
+ }
81
+ /** バイナリ送信(File Upload の send エンドポイント)用 */
82
+ async requestRaw(init) {
83
+ if (this.dryRun) {
84
+ this.callCount += 1;
85
+ return {};
86
+ }
87
+ return this.queue.add(() => this.executeWithRetry({
88
+ method: init.method,
89
+ url: `${API_BASE}${init.path}`,
90
+ headers: init.headers ?? {},
91
+ body: init.body,
92
+ }));
93
+ }
94
+ async executeWithRetry(req, attempt = 0) {
95
+ this.callCount += 1;
96
+ const res = await this.fetchImpl(req.url, {
97
+ method: req.method,
98
+ headers: {
99
+ Authorization: `Bearer ${this.token}`,
100
+ 'Notion-Version': this.notionVersion,
101
+ ...req.headers,
102
+ },
103
+ body: req.body,
104
+ });
105
+ if (res.status === 429 || res.status >= 500) {
106
+ if (attempt >= this.retry.maxRetries) {
107
+ const body = await safeJson(res);
108
+ throw new NotionApiError(res.status, body?.code, `retry exhausted: ${res.status}`, body);
109
+ }
110
+ const retryAfterHeader = res.headers.get('Retry-After');
111
+ const delay = retryAfterHeader
112
+ ? Number(retryAfterHeader) * 1000
113
+ : Math.min(this.retry.maxDelayMs, this.retry.initialDelayMs * 2 ** attempt) + Math.random() * 250;
114
+ await sleep(delay);
115
+ return this.executeWithRetry(req, attempt + 1);
116
+ }
117
+ if (!res.ok) {
118
+ const body = await safeJson(res);
119
+ const b = body;
120
+ throw new NotionApiError(res.status, b?.code, `Notion API error ${res.status}: ${b?.message ?? res.statusText}`, body);
121
+ }
122
+ if (res.status === 204)
123
+ return undefined;
124
+ return (await res.json());
125
+ }
126
+ }
127
+ /** §4.1のエンドポイントに対応する高レベルAPI */
128
+ export class NotionApi {
129
+ client;
130
+ constructor(client) {
131
+ this.client = client;
132
+ }
133
+ get callCount() {
134
+ return this.client.callCount;
135
+ }
136
+ async getMe() {
137
+ return this.client.request({ method: 'GET', path: '/users/me' });
138
+ }
139
+ async createPageMarkdown(params) {
140
+ return this.client.request({ method: 'POST', path: '/pages', body: params });
141
+ }
142
+ async getPageMarkdown(pageId) {
143
+ return this.client.request({ method: 'GET', path: `/pages/${pageId}/markdown` });
144
+ }
145
+ async updatePageMarkdown(pageId, body, allowAsync = false) {
146
+ return this.client.request({
147
+ method: 'PATCH',
148
+ path: `/pages/${pageId}/markdown`,
149
+ query: allowAsync ? { allow_async: 'true' } : undefined,
150
+ body,
151
+ });
152
+ }
153
+ async createDatabase(params) {
154
+ return this.client.request({ method: 'POST', path: '/databases', body: params });
155
+ }
156
+ async createFileUpload(params) {
157
+ return this.client.request({ method: 'POST', path: '/file_uploads', body: params });
158
+ }
159
+ async sendFileUpload(fileUploadId, formData) {
160
+ return this.client.requestRaw({
161
+ method: 'POST',
162
+ path: `/file_uploads/${fileUploadId}/send`,
163
+ body: formData,
164
+ });
165
+ }
166
+ /**
167
+ * §16検証済み(2026-07-19): `after`パラメータは廃止済みで指定すると400になる。
168
+ * 代わりに `position: { type: 'after_block', after_block: { id } }` を使う。
169
+ */
170
+ async appendBlockChildren(blockId, children, afterBlockId) {
171
+ return this.client.request({
172
+ method: 'PATCH',
173
+ path: `/blocks/${blockId}/children`,
174
+ body: {
175
+ children,
176
+ ...(afterBlockId ? { position: { type: 'after_block', after_block: { id: afterBlockId } } } : {}),
177
+ },
178
+ });
179
+ }
180
+ async deleteBlock(blockId) {
181
+ await this.client.request({ method: 'DELETE', path: `/blocks/${blockId}` });
182
+ }
183
+ async getBlockChildren(blockId) {
184
+ return this.client.request({ method: 'GET', path: `/blocks/${blockId}/children` });
185
+ }
186
+ }
187
+ //# sourceMappingURL=notion-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion-client.js","sourceRoot":"","sources":["../src/notion-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { FrontmatterMapping } from './types.js';
2
+ import type { NotionApi } from './notion-client.js';
3
+ /**
4
+ * §7.2 databaseモード: フォルダをDBとして作成する。
5
+ * §16-4は実ワークスペースで検証済み(2026-07-19):
6
+ * - parentは `{ type: 'page_id', page_id }` と明示的な type が必須(省略すると400)
7
+ * - properties は `initial_data_source.properties` 配下に置く必要がある(トップレベル不可)
8
+ * - レスポンスの data source id は `data_sources[0].id` を使う
9
+ */
10
+ export declare function createDatabaseForFolder(api: NotionApi, parentPageId: string, folderTitle: string, mappings: FrontmatterMapping[]): Promise<{
11
+ databaseId: string;
12
+ dataSourceId: string;
13
+ }>;
14
+ export declare function buildRowProperties(frontmatter: Record<string, unknown>, mappings: FrontmatterMapping[], fallbackTitle: string): Record<string, unknown>;
15
+ //# sourceMappingURL=notion-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion-db.d.ts","sourceRoot":"","sources":["../src/notion-db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAuBpD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,SAAS,EACd,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,kBAAkB,EAAE,GAC7B,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBvD;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,EAAE,kBAAkB,EAAE,EAC9B,aAAa,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezB"}
@@ -0,0 +1,88 @@
1
+ function propertySchema(type) {
2
+ switch (type) {
3
+ case 'title':
4
+ return { title: {} };
5
+ case 'rich_text':
6
+ return { rich_text: {} };
7
+ case 'number':
8
+ return { number: {} };
9
+ case 'checkbox':
10
+ return { checkbox: {} };
11
+ case 'date':
12
+ return { date: {} };
13
+ case 'multi_select':
14
+ return { multi_select: {} };
15
+ case 'url':
16
+ return { url: {} };
17
+ default:
18
+ return { rich_text: {} };
19
+ }
20
+ }
21
+ /**
22
+ * §7.2 databaseモード: フォルダをDBとして作成する。
23
+ * §16-4は実ワークスペースで検証済み(2026-07-19):
24
+ * - parentは `{ type: 'page_id', page_id }` と明示的な type が必須(省略すると400)
25
+ * - properties は `initial_data_source.properties` 配下に置く必要がある(トップレベル不可)
26
+ * - レスポンスの data source id は `data_sources[0].id` を使う
27
+ */
28
+ export async function createDatabaseForFolder(api, parentPageId, folderTitle, mappings) {
29
+ const properties = {};
30
+ let hasTitle = false;
31
+ for (const m of mappings) {
32
+ properties[m.key] = propertySchema(m.notionPropertyType);
33
+ if (m.notionPropertyType === 'title')
34
+ hasTitle = true;
35
+ }
36
+ if (!hasTitle) {
37
+ properties.Name = propertySchema('title');
38
+ }
39
+ const res = await api.createDatabase({
40
+ parent: { type: 'page_id', page_id: parentPageId },
41
+ title: [{ type: 'text', text: { content: folderTitle } }],
42
+ initial_data_source: { properties },
43
+ });
44
+ const withDataSources = res;
45
+ const dataSourceId = withDataSources.data_sources?.[0]?.id ?? withDataSources.id;
46
+ return { databaseId: withDataSources.id, dataSourceId };
47
+ }
48
+ export function buildRowProperties(frontmatter, mappings, fallbackTitle) {
49
+ const properties = {};
50
+ let hasTitle = false;
51
+ for (const m of mappings) {
52
+ const value = frontmatter[m.key];
53
+ if (value === undefined)
54
+ continue;
55
+ properties[m.key] = renderPropertyValue(m.notionPropertyType, value);
56
+ if (m.notionPropertyType === 'title')
57
+ hasTitle = true;
58
+ }
59
+ if (!hasTitle) {
60
+ properties.Name = { title: [{ text: { content: fallbackTitle } }] };
61
+ }
62
+ return properties;
63
+ }
64
+ function renderPropertyValue(type, value) {
65
+ switch (type) {
66
+ case 'title':
67
+ return { title: [{ text: { content: String(value) } }] };
68
+ case 'rich_text':
69
+ return {
70
+ rich_text: [{ text: { content: typeof value === 'object' ? JSON.stringify(value) : String(value) } }],
71
+ };
72
+ case 'number':
73
+ return { number: typeof value === 'number' ? value : Number(value) };
74
+ case 'checkbox':
75
+ return { checkbox: Boolean(value) };
76
+ case 'date':
77
+ return { date: { start: value instanceof Date ? value.toISOString().slice(0, 10) : String(value) } };
78
+ case 'multi_select':
79
+ return {
80
+ multi_select: (Array.isArray(value) ? value : [value]).map((v) => ({ name: String(v) })),
81
+ };
82
+ case 'url':
83
+ return { url: String(value) };
84
+ default:
85
+ return { rich_text: [{ text: { content: String(value) } }] };
86
+ }
87
+ }
88
+ //# sourceMappingURL=notion-db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion-db.js","sourceRoot":"","sources":["../src/notion-db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { FolderPlan, MigrationPlan, VaultInventory } from './types.js';
2
+ export interface PlannerOptions {
3
+ parentPageId: string;
4
+ /** フォルダ直下ノートのうち共通キーを持つ割合の閾値(デフォルト0.6) */
5
+ dbSuggestionRatio?: number;
6
+ /** database提案に必要な共通frontmatterキー数(デフォルト3) */
7
+ dbSuggestionMinKeys?: number;
8
+ skipList?: string[];
9
+ }
10
+ /**
11
+ * F2 DB化自動提案: フォルダ直下ノートの60%以上が共通のfrontmatterキーを3つ以上持つ場合、
12
+ * database モードを提案する。最終決定は必ずユーザー(ここでは提案のみ行う)。
13
+ */
14
+ export declare function suggestFolderModes(inventory: VaultInventory, opts?: PlannerOptions): FolderPlan[];
15
+ export declare function buildPlan(inventory: VaultInventory, opts: PlannerOptions): MigrationPlan;
16
+ //# sourceMappingURL=planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5E,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6CAA6C;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,cAAc,EAAE,IAAI,GAAE,cAAqC,GAAG,UAAU,EAAE,CAiCvH;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,GAAG,aAAa,CAoBxF"}
@@ -0,0 +1,60 @@
1
+ import { buildFrontmatterMappingsForFolder } from './property-mapping.js';
2
+ /**
3
+ * F2 DB化自動提案: フォルダ直下ノートの60%以上が共通のfrontmatterキーを3つ以上持つ場合、
4
+ * database モードを提案する。最終決定は必ずユーザー(ここでは提案のみ行う)。
5
+ */
6
+ export function suggestFolderModes(inventory, opts = { parentPageId: '' }) {
7
+ const ratio = opts.dbSuggestionRatio ?? 0.6;
8
+ const minKeys = opts.dbSuggestionMinKeys ?? 3;
9
+ const folders = [];
10
+ for (const [folderPath, notePaths] of Object.entries(inventory.folderTree)) {
11
+ if (notePaths.length === 0) {
12
+ folders.push({ folderPath, mode: 'page_tree' });
13
+ continue;
14
+ }
15
+ const notesByPath = new Map(inventory.notes.map((n) => [n.path, n]));
16
+ const keyCounts = new Map();
17
+ for (const p of notePaths) {
18
+ const note = notesByPath.get(p);
19
+ if (!note)
20
+ continue;
21
+ for (const key of Object.keys(note.frontmatter)) {
22
+ keyCounts.set(key, (keyCounts.get(key) ?? 0) + 1);
23
+ }
24
+ }
25
+ const threshold = notePaths.length * ratio;
26
+ const commonKeys = [...keyCounts.entries()].filter(([, count]) => count >= threshold);
27
+ if (commonKeys.length >= minKeys) {
28
+ folders.push({
29
+ folderPath,
30
+ mode: 'database',
31
+ suggestionReason: `直下${notePaths.length}ノート中${Math.max(...commonKeys.map(([, c]) => c))}以上が共通キー[${commonKeys.map(([k]) => k).join(', ')}]を保持`,
32
+ });
33
+ }
34
+ else {
35
+ folders.push({ folderPath, mode: 'page_tree' });
36
+ }
37
+ }
38
+ return folders.sort((a, b) => a.folderPath.localeCompare(b.folderPath));
39
+ }
40
+ export function buildPlan(inventory, opts) {
41
+ const folders = suggestFolderModes(inventory, opts);
42
+ const notesByPath = new Map(inventory.notes.map((n) => [n.path, n]));
43
+ const frontmatterMappings = {};
44
+ for (const folder of folders) {
45
+ if (folder.mode !== 'database')
46
+ continue;
47
+ const notePaths = inventory.folderTree[folder.folderPath] ?? [];
48
+ const fms = notePaths.map((p) => notesByPath.get(p)?.frontmatter ?? {});
49
+ frontmatterMappings[folder.folderPath] = buildFrontmatterMappingsForFolder(fms);
50
+ }
51
+ return {
52
+ version: 1,
53
+ vaultPath: inventory.vaultPath,
54
+ parentPageId: opts.parentPageId,
55
+ folders,
56
+ frontmatterMappings,
57
+ skipList: opts.skipList ?? inventory.skipped.map((s) => s.path),
58
+ };
59
+ }
60
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FrontmatterMapping } from './types.js';
2
+ /**
3
+ * §7.2 型推論規則: YAML値 → Notionプロパティ型
4
+ */
5
+ export declare function inferPropertyType(key: string, sampleValues: unknown[]): FrontmatterMapping['notionPropertyType'];
6
+ export declare function buildFrontmatterMappingsForFolder(notesFrontmatter: Record<string, unknown>[]): FrontmatterMapping[];
7
+ /** rich_text値が2000文字を超える場合の切り詰め。全文は本文冒頭メタcalloutへ退避+レポート対象 */
8
+ export declare function truncateRichText(value: string, maxLen?: number): {
9
+ text: string;
10
+ truncated: boolean;
11
+ };
12
+ /** multi_selectの選択肢が100を超える場合、超過分をrich_textに退避 */
13
+ export declare function splitMultiSelectOverflow(values: string[], maxOptions?: number): {
14
+ kept: string[];
15
+ overflow: string[];
16
+ };
17
+ //# sourceMappingURL=property-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"property-mapping.d.ts","sourceRoot":"","sources":["../src/property-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKrD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,oBAAoB,CAAC,CAgChH;AAED,wBAAgB,iCAAiC,CAC/C,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAC1C,kBAAkB,EAAE,CAatB;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAGnG;AAED,kDAAkD;AAClD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,SAAM,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAGnH"}