@notion-headless-cms/core 0.1.1 → 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.
- package/README.md +145 -47
- package/dist/cache/memory.d.ts +54 -0
- package/dist/cache/memory.js +15 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/noop.d.ts +9 -0
- package/dist/cache/noop.js +9 -0
- package/dist/cache/noop.js.map +1 -0
- package/dist/cache-DvbyemBK.d.ts +33 -0
- package/dist/chunk-4KGKWKKI.js +80 -0
- package/dist/chunk-4KGKWKKI.js.map +1 -0
- package/dist/chunk-6DG63XUF.js +42 -0
- package/dist/chunk-6DG63XUF.js.map +1 -0
- package/dist/chunk-6LHROEPI.js +104 -0
- package/dist/chunk-6LHROEPI.js.map +1 -0
- package/dist/chunk-V6ML4QE5.js +26 -0
- package/dist/chunk-V6ML4QE5.js.map +1 -0
- package/dist/content-Biqf0l_o.d.ts +51 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/hooks-B83RUclt.d.ts +41 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +9 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +57 -253
- package/dist/index.js +176 -344
- package/dist/index.js.map +1 -0
- package/package.json +29 -11
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var CMSError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
cause;
|
|
5
|
+
context;
|
|
6
|
+
constructor(params) {
|
|
7
|
+
super(params.message, { cause: params.cause });
|
|
8
|
+
this.name = "CMSError";
|
|
9
|
+
this.code = params.code;
|
|
10
|
+
this.cause = params.cause;
|
|
11
|
+
this.context = params.context;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function isCMSError(error) {
|
|
15
|
+
return error instanceof CMSError;
|
|
16
|
+
}
|
|
17
|
+
function isCMSErrorInNamespace(error, namespace) {
|
|
18
|
+
return isCMSError(error) && error.code.startsWith(namespace);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
CMSError,
|
|
23
|
+
isCMSError,
|
|
24
|
+
isCMSErrorInNamespace
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=chunk-V6ML4QE5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["type BuiltInCMSErrorCode =\n\t| \"core/config_invalid\"\n\t| \"core/schema_invalid\"\n\t| \"source/fetch_items_failed\"\n\t| \"source/fetch_item_failed\"\n\t| \"source/load_markdown_failed\"\n\t| \"cache/io_failed\"\n\t| \"cache/image_fetch_failed\"\n\t| \"renderer/failed\";\n\n/**\n * CMS エラーコード。\n * `BuiltInCMSErrorCode` のリテラル補完を維持しつつ、\n * サードパーティアダプタが独自コードを定義できるよう `string & {}` で拡張可能にする。\n */\nexport type CMSErrorCode = BuiltInCMSErrorCode | (string & {});\n\nexport interface CMSErrorContext {\n\toperation: string;\n\tslug?: string;\n\tdataSourceId?: string;\n\tpageId?: string;\n\t[key: string]: string | number | boolean | null | undefined;\n}\n\nexport class CMSError extends Error {\n\treadonly code: CMSErrorCode;\n\toverride readonly cause?: unknown;\n\treadonly context: CMSErrorContext;\n\n\tconstructor(params: {\n\t\tcode: CMSErrorCode;\n\t\tmessage: string;\n\t\tcause?: unknown;\n\t\tcontext: CMSErrorContext;\n\t}) {\n\t\tsuper(params.message, { cause: params.cause });\n\t\tthis.name = \"CMSError\";\n\t\tthis.code = params.code;\n\t\tthis.cause = params.cause;\n\t\tthis.context = params.context;\n\t}\n}\n\nexport function isCMSError(error: unknown): error is CMSError {\n\treturn error instanceof CMSError;\n}\n\n/** エラーコードが特定の名前空間に属するかを判定する(例: \"source/\")。 */\nexport function isCMSErrorInNamespace(\n\terror: unknown,\n\tnamespace: string,\n): error is CMSError {\n\treturn isCMSError(error) && error.code.startsWith(namespace);\n}\n"],"mappings":";AAyBO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAC1B;AAAA,EACS;AAAA,EACT;AAAA,EAET,YAAY,QAKT;AACF,UAAM,OAAO,SAAS,EAAE,OAAO,OAAO,MAAM,CAAC;AAC7C,SAAK,OAAO;AACZ,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO;AACpB,SAAK,UAAU,OAAO;AAAA,EACvB;AACD;AAEO,SAAS,WAAW,OAAmC;AAC7D,SAAO,iBAAiB;AACzB;AAGO,SAAS,sBACf,OACA,WACoB;AACpB,SAAO,WAAW,KAAK,KAAK,MAAM,KAAK,WAAW,SAAS;AAC5D;","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ライブラリが動作するために必須なフィールド。
|
|
3
|
+
* 利用者はこのインターフェースを拡張して独自のコンテンツ型を定義する。
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* interface Post extends BaseContentItem {
|
|
7
|
+
* title: string;
|
|
8
|
+
* author: string;
|
|
9
|
+
* }
|
|
10
|
+
* createCMS<Post>({ source: notionAdapter({ ... }) })
|
|
11
|
+
*/
|
|
12
|
+
interface BaseContentItem {
|
|
13
|
+
/** Notion ページ ID(変更検知に必須)。 */
|
|
14
|
+
id: string;
|
|
15
|
+
/** URL キー(必須)。 */
|
|
16
|
+
slug: string;
|
|
17
|
+
/** 最終更新タイムスタンプ(変更検知に必須)。 */
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
/** コンテンツのステータス。ステータスのない DB では省略可能。 */
|
|
20
|
+
status?: string;
|
|
21
|
+
/** 公開日時。日付プロパティのない DB では省略可能。 */
|
|
22
|
+
publishedAt?: string;
|
|
23
|
+
}
|
|
24
|
+
/** ストレージにキャッシュされたレンダリング済みコンテンツ。 */
|
|
25
|
+
interface CachedItem<T extends BaseContentItem = BaseContentItem> {
|
|
26
|
+
html: string;
|
|
27
|
+
item: T;
|
|
28
|
+
notionUpdatedAt: string;
|
|
29
|
+
cachedAt: number;
|
|
30
|
+
}
|
|
31
|
+
/** ストレージにキャッシュされたコンテンツ一覧。 */
|
|
32
|
+
interface CachedItemList<T extends BaseContentItem = BaseContentItem> {
|
|
33
|
+
items: T[];
|
|
34
|
+
cachedAt: number;
|
|
35
|
+
}
|
|
36
|
+
/** ストレージから取得したバイナリオブジェクト。 */
|
|
37
|
+
interface StorageBinary {
|
|
38
|
+
data: ArrayBuffer;
|
|
39
|
+
contentType?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Notionのプロパティ名マッピング(すべてオプション)。 */
|
|
42
|
+
interface CMSSchemaProperties {
|
|
43
|
+
/** Notionのスラッグプロパティ名。デフォルト: 'Slug' */
|
|
44
|
+
slug?: string;
|
|
45
|
+
/** Notionのステータスプロパティ名。デフォルト: 'Status' */
|
|
46
|
+
status?: string;
|
|
47
|
+
/** Notionの公開日プロパティ名。デフォルト: 'CreatedAt' */
|
|
48
|
+
date?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type { BaseContentItem as B, CMSSchemaProperties as C, StorageBinary as S, CachedItem as a, CachedItemList as b };
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type BuiltInCMSErrorCode = "core/config_invalid" | "core/schema_invalid" | "source/fetch_items_failed" | "source/fetch_item_failed" | "source/load_markdown_failed" | "cache/io_failed" | "cache/image_fetch_failed" | "renderer/failed";
|
|
2
|
+
/**
|
|
3
|
+
* CMS エラーコード。
|
|
4
|
+
* `BuiltInCMSErrorCode` のリテラル補完を維持しつつ、
|
|
5
|
+
* サードパーティアダプタが独自コードを定義できるよう `string & {}` で拡張可能にする。
|
|
6
|
+
*/
|
|
7
|
+
type CMSErrorCode = BuiltInCMSErrorCode | (string & {});
|
|
8
|
+
interface CMSErrorContext {
|
|
9
|
+
operation: string;
|
|
10
|
+
slug?: string;
|
|
11
|
+
dataSourceId?: string;
|
|
12
|
+
pageId?: string;
|
|
13
|
+
[key: string]: string | number | boolean | null | undefined;
|
|
14
|
+
}
|
|
15
|
+
declare class CMSError extends Error {
|
|
16
|
+
readonly code: CMSErrorCode;
|
|
17
|
+
readonly cause?: unknown;
|
|
18
|
+
readonly context: CMSErrorContext;
|
|
19
|
+
constructor(params: {
|
|
20
|
+
code: CMSErrorCode;
|
|
21
|
+
message: string;
|
|
22
|
+
cause?: unknown;
|
|
23
|
+
context: CMSErrorContext;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
declare function isCMSError(error: unknown): error is CMSError;
|
|
27
|
+
/** エラーコードが特定の名前空間に属するかを判定する(例: "source/")。 */
|
|
28
|
+
declare function isCMSErrorInNamespace(error: unknown, namespace: string): error is CMSError;
|
|
29
|
+
|
|
30
|
+
export { CMSError, type CMSErrorCode, type CMSErrorContext, isCMSError, isCMSErrorInNamespace };
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { B as BaseContentItem, a as CachedItem } from './content-Biqf0l_o.js';
|
|
2
|
+
|
|
3
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
4
|
+
interface CMSHooks<T extends BaseContentItem = BaseContentItem> {
|
|
5
|
+
beforeCache?: (item: CachedItem<T>) => MaybePromise<CachedItem<T>>;
|
|
6
|
+
afterRender?: (html: string, item: T) => MaybePromise<string>;
|
|
7
|
+
onCacheHit?: (slug: string, item: CachedItem<T>) => void;
|
|
8
|
+
onCacheMiss?: (slug: string) => void;
|
|
9
|
+
onListCacheHit?: (items: T[], cachedAt: number) => void;
|
|
10
|
+
onListCacheMiss?: () => void;
|
|
11
|
+
onError?: (error: Error) => void;
|
|
12
|
+
onRenderStart?: (slug: string) => void;
|
|
13
|
+
onRenderEnd?: (slug: string, durationMs: number) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Logger {
|
|
17
|
+
debug?: (message: string, context?: Record<string, unknown>) => void;
|
|
18
|
+
info?: (message: string, context?: Record<string, unknown>) => void;
|
|
19
|
+
warn?: (message: string, context?: Record<string, unknown>) => void;
|
|
20
|
+
error?: (message: string, context?: Record<string, unknown>) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface CMSPlugin<T extends BaseContentItem = BaseContentItem> {
|
|
24
|
+
name: string;
|
|
25
|
+
hooks?: CMSHooks<T>;
|
|
26
|
+
logger?: Partial<Logger>;
|
|
27
|
+
}
|
|
28
|
+
declare function definePlugin<T extends BaseContentItem>(plugin: CMSPlugin<T>): CMSPlugin<T>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* プラグイン配列とダイレクトフックを合成して単一の CMSHooks を返す。
|
|
32
|
+
* beforeCache / afterRender はパイプライン(前の出力が次の入力)。
|
|
33
|
+
* onCacheHit などオブザーバー系は全員に同じ値を渡し、例外は logger に流して握りつぶす。
|
|
34
|
+
*/
|
|
35
|
+
declare function mergeHooks<T extends BaseContentItem>(plugins: CMSPlugin<T>[], directHooks?: CMSHooks<T>, logger?: Logger): CMSHooks<T>;
|
|
36
|
+
/** プラグイン配列とダイレクトロガーを合成して単一の Logger を返す。 */
|
|
37
|
+
declare function mergeLoggers(plugins: Array<{
|
|
38
|
+
logger?: Partial<Logger>;
|
|
39
|
+
}>, directLogger?: Logger): Logger | undefined;
|
|
40
|
+
|
|
41
|
+
export { type CMSHooks as C, type Logger as L, type MaybePromise as M, type CMSPlugin as a, mergeLoggers as b, definePlugin as d, mergeHooks as m };
|
package/dist/hooks.d.ts
ADDED
package/dist/hooks.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
export { MemoryDocumentCacheOptions, MemoryImageCacheOptions, memoryCache, memoryDocumentCache, memoryImageCache } from './cache/memory.js';
|
|
2
|
+
export { noopDocumentCache, noopImageCache } from './cache/noop.js';
|
|
3
|
+
import { B as BaseContentItem, C as CMSSchemaProperties, a as CachedItem, S as StorageBinary } from './content-Biqf0l_o.js';
|
|
4
|
+
export { b as CachedItemList } from './content-Biqf0l_o.js';
|
|
5
|
+
import { PluggableList } from '@notion-headless-cms/renderer';
|
|
6
|
+
import { C as CacheConfig } from './cache-DvbyemBK.js';
|
|
7
|
+
export { D as DocumentCacheAdapter, I as ImageCacheAdapter } from './cache-DvbyemBK.js';
|
|
8
|
+
import { C as CMSHooks, a as CMSPlugin, L as Logger } from './hooks-B83RUclt.js';
|
|
9
|
+
export { M as MaybePromise, d as definePlugin, m as mergeHooks, b as mergeLoggers } from './hooks-B83RUclt.js';
|
|
10
|
+
export { CMSError, CMSErrorCode, CMSErrorContext, isCMSError, isCMSErrorInNamespace } from './errors.js';
|
|
5
11
|
|
|
6
12
|
/** 文字列をSHA-256でハッシュ化し、16進数文字列として返す。画像キーの生成に使用。 */
|
|
7
13
|
declare function sha256Hex(input: string): Promise<string>;
|
|
@@ -11,103 +17,6 @@ declare function sha256Hex(input: string): Promise<string>;
|
|
|
11
17
|
*/
|
|
12
18
|
declare function isStale(cachedAt: number, ttlMs?: number): boolean;
|
|
13
19
|
|
|
14
|
-
/**
|
|
15
|
-
* ライブラリが動作するために必須なフィールド。
|
|
16
|
-
* 利用者はこのインターフェースを拡張して独自のコンテンツ型を定義する。
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* interface Post extends BaseContentItem {
|
|
20
|
-
* title: string;
|
|
21
|
-
* author: string;
|
|
22
|
-
* }
|
|
23
|
-
* createCMS<Post>({ source: notionAdapter({ ... }) })
|
|
24
|
-
*/
|
|
25
|
-
interface BaseContentItem {
|
|
26
|
-
id: string;
|
|
27
|
-
slug: string;
|
|
28
|
-
status: string;
|
|
29
|
-
publishedAt: string;
|
|
30
|
-
updatedAt: string;
|
|
31
|
-
}
|
|
32
|
-
/** ストレージにキャッシュされたレンダリング済みコンテンツ。 */
|
|
33
|
-
interface CachedItem<T extends BaseContentItem = BaseContentItem> {
|
|
34
|
-
html: string;
|
|
35
|
-
item: T;
|
|
36
|
-
notionUpdatedAt: string;
|
|
37
|
-
cachedAt: number;
|
|
38
|
-
}
|
|
39
|
-
/** ストレージにキャッシュされたコンテンツ一覧。 */
|
|
40
|
-
interface CachedItemList<T extends BaseContentItem = BaseContentItem> {
|
|
41
|
-
items: T[];
|
|
42
|
-
cachedAt: number;
|
|
43
|
-
}
|
|
44
|
-
/** ストレージから取得したバイナリオブジェクト。 */
|
|
45
|
-
interface StorageBinary {
|
|
46
|
-
data: ArrayBuffer;
|
|
47
|
-
contentType?: string;
|
|
48
|
-
}
|
|
49
|
-
/** Notionのプロパティ名マッピング(すべてオプション)。 */
|
|
50
|
-
interface CMSSchemaProperties {
|
|
51
|
-
/** Notionのスラッグプロパティ名。デフォルト: 'Slug' */
|
|
52
|
-
slug?: string;
|
|
53
|
-
/** Notionのステータスプロパティ名。デフォルト: 'Status' */
|
|
54
|
-
status?: string;
|
|
55
|
-
/** Notionの公開日プロパティ名。デフォルト: 'CreatedAt' */
|
|
56
|
-
date?: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** ドキュメントキャッシュを抽象化するインターフェース。 */
|
|
60
|
-
interface DocumentCacheAdapter<T extends BaseContentItem = BaseContentItem> {
|
|
61
|
-
readonly name: string;
|
|
62
|
-
getList(): Promise<CachedItemList<T> | null>;
|
|
63
|
-
setList(data: CachedItemList<T>): Promise<void>;
|
|
64
|
-
getItem(slug: string): Promise<CachedItem<T> | null>;
|
|
65
|
-
setItem(slug: string, data: CachedItem<T>): Promise<void>;
|
|
66
|
-
invalidate?(scope: "all" | {
|
|
67
|
-
slug: string;
|
|
68
|
-
} | {
|
|
69
|
-
tag: string;
|
|
70
|
-
}): Promise<void>;
|
|
71
|
-
}
|
|
72
|
-
/** 画像キャッシュを抽象化するインターフェース。 */
|
|
73
|
-
interface ImageCacheAdapter {
|
|
74
|
-
readonly name: string;
|
|
75
|
-
get(hash: string): Promise<StorageBinary | null>;
|
|
76
|
-
set(hash: string, data: ArrayBuffer, contentType: string): Promise<void>;
|
|
77
|
-
}
|
|
78
|
-
/** キャッシュ設定オブジェクト。document / image それぞれ独立したアダプタを差し込める。 */
|
|
79
|
-
interface CacheConfig<T extends BaseContentItem = BaseContentItem> {
|
|
80
|
-
document?: DocumentCacheAdapter<T> | false;
|
|
81
|
-
image?: ImageCacheAdapter | false;
|
|
82
|
-
/** キャッシュの有効期間(ミリ秒)。未設定の場合はTTLなし。 */
|
|
83
|
-
ttlMs?: number;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
87
|
-
interface CMSHooks<T extends BaseContentItem = BaseContentItem> {
|
|
88
|
-
beforeCache?: (item: CachedItem<T>) => MaybePromise<CachedItem<T>>;
|
|
89
|
-
afterRender?: (html: string, item: T) => MaybePromise<string>;
|
|
90
|
-
onCacheHit?: (slug: string, item: CachedItem<T>) => void;
|
|
91
|
-
onCacheMiss?: (slug: string) => void;
|
|
92
|
-
onListCacheHit?: (items: T[], cachedAt: number) => void;
|
|
93
|
-
onListCacheMiss?: () => void;
|
|
94
|
-
onError?: (error: Error) => void;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
interface Logger {
|
|
98
|
-
debug?: (message: string, context?: Record<string, unknown>) => void;
|
|
99
|
-
info?: (message: string, context?: Record<string, unknown>) => void;
|
|
100
|
-
warn?: (message: string, context?: Record<string, unknown>) => void;
|
|
101
|
-
error?: (message: string, context?: Record<string, unknown>) => void;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
interface CMSPlugin<T extends BaseContentItem = BaseContentItem> {
|
|
105
|
-
name: string;
|
|
106
|
-
hooks?: CMSHooks<T>;
|
|
107
|
-
logger?: Partial<Logger>;
|
|
108
|
-
}
|
|
109
|
-
declare function definePlugin<T extends BaseContentItem>(plugin: CMSPlugin<T>): CMSPlugin<T>;
|
|
110
|
-
|
|
111
20
|
/** ソース側クエリのフィルタ・ソート条件。 */
|
|
112
21
|
interface SourceQueryOptions {
|
|
113
22
|
filter?: {
|
|
@@ -145,19 +54,26 @@ interface DataSourceAdapter<T extends BaseContentItem = BaseContentItem> {
|
|
|
145
54
|
query?(opts: SourceQueryOptions): Promise<SourceQueryResult<T>>;
|
|
146
55
|
}
|
|
147
56
|
|
|
57
|
+
/**
|
|
58
|
+
* render() オプション。core は renderer の実装を知らず、この型だけを扱う。
|
|
59
|
+
* @notion-headless-cms/renderer の renderMarkdown() はこのシグネチャと構造的に互換。
|
|
60
|
+
*/
|
|
61
|
+
interface RenderOptions {
|
|
62
|
+
imageProxyBase?: string;
|
|
63
|
+
cacheImage?: (url: string) => Promise<string>;
|
|
64
|
+
remarkPlugins?: PluggableList;
|
|
65
|
+
rehypePlugins?: PluggableList;
|
|
66
|
+
}
|
|
67
|
+
/** カスタムレンダラー関数の型。デフォルトは @notion-headless-cms/renderer の renderMarkdown。 */
|
|
68
|
+
type RendererFn = (markdown: string, opts?: RenderOptions) => Promise<string>;
|
|
148
69
|
/** スキーマ設定。公開ステータスのフィルタやプロパティ名マッピングを制御する。 */
|
|
149
70
|
interface SchemaConfig<T extends BaseContentItem = BaseContentItem> {
|
|
150
|
-
/**
|
|
151
|
-
* Notionページをコンテンツ型 T にマッピングするカスタム関数。
|
|
152
|
-
* 指定した場合 properties の設定は無視される(slug プロパティ名のみ例外)。
|
|
153
|
-
*/
|
|
154
|
-
mapItem?: (page: PageObjectResponse) => T;
|
|
155
|
-
/** mapItem 未使用時のプロパティ名マッピング。 */
|
|
156
|
-
properties?: CMSSchemaProperties;
|
|
157
71
|
/** list() で返す「公開済み」ステータス値の配列。デフォルト: [] (全件返す) */
|
|
158
72
|
publishedStatuses?: string[];
|
|
159
73
|
/** findBySlug() でアクセス可能なステータス値の配列。デフォルト: [] (全件許可) */
|
|
160
74
|
accessibleStatuses?: string[];
|
|
75
|
+
/** mapItem 未使用時のプロパティ名マッピング。source-notion 経由で渡す場合は不要。 */
|
|
76
|
+
properties?: CMSSchemaProperties;
|
|
161
77
|
}
|
|
162
78
|
/** レンダリング・コンテンツ処理設定。 */
|
|
163
79
|
interface ContentConfig {
|
|
@@ -167,10 +83,6 @@ interface ContentConfig {
|
|
|
167
83
|
remarkPlugins?: PluggableList;
|
|
168
84
|
/** 追加する rehype プラグイン。 */
|
|
169
85
|
rehypePlugins?: PluggableList;
|
|
170
|
-
/** デフォルトのパイプラインを置き換えるカスタムレンダラー。 */
|
|
171
|
-
render?: RendererFn;
|
|
172
|
-
/** カスタムブロックハンドラーのマップ。Notionブロックタイプをキーとする。 */
|
|
173
|
-
blocks?: Record<string, BlockHandler>;
|
|
174
86
|
}
|
|
175
87
|
/** レートリミット・リトライ設定。 */
|
|
176
88
|
interface RateLimiterConfig {
|
|
@@ -190,6 +102,8 @@ interface RateLimiterConfig {
|
|
|
190
102
|
interface CreateCMSOptions<T extends BaseContentItem = BaseContentItem> {
|
|
191
103
|
/** データソースアダプタ(Notion など)。 */
|
|
192
104
|
source: DataSourceAdapter<T>;
|
|
105
|
+
/** レンダラー関数。未指定時は @notion-headless-cms/renderer の renderMarkdown を使用。 */
|
|
106
|
+
renderer?: RendererFn;
|
|
193
107
|
/** キャッシュ設定。未設定時はキャッシュなし。 */
|
|
194
108
|
cache?: CacheConfig<T>;
|
|
195
109
|
/** スキーマ・ステータス設定。 */
|
|
@@ -208,21 +122,6 @@ interface CreateCMSOptions<T extends BaseContentItem = BaseContentItem> {
|
|
|
208
122
|
rateLimiter?: RateLimiterConfig;
|
|
209
123
|
}
|
|
210
124
|
|
|
211
|
-
/** インメモリキャッシュ(ドキュメント用)を生成する。 */
|
|
212
|
-
declare function memoryDocumentCache<T extends BaseContentItem = BaseContentItem>(): DocumentCacheAdapter<T>;
|
|
213
|
-
/** インメモリキャッシュ(画像用)を生成する。 */
|
|
214
|
-
declare function memoryImageCache(): ImageCacheAdapter;
|
|
215
|
-
/**
|
|
216
|
-
* ドキュメントと画像の両方にインメモリキャッシュを返す便利関数。
|
|
217
|
-
* memoryCache() はドキュメントキャッシュを返す(後方互換)。
|
|
218
|
-
*/
|
|
219
|
-
declare function memoryCache<T extends BaseContentItem = BaseContentItem>(): DocumentCacheAdapter<T>;
|
|
220
|
-
|
|
221
|
-
/** 何もしないドキュメントキャッシュを返す(シングルトン)。 */
|
|
222
|
-
declare function noopDocumentCache<T extends BaseContentItem = BaseContentItem>(): DocumentCacheAdapter<T>;
|
|
223
|
-
/** 何もしない画像キャッシュを返す(シングルトン)。 */
|
|
224
|
-
declare function noopImageCache(): ImageCacheAdapter;
|
|
225
|
-
|
|
226
125
|
interface QueryResult<T> {
|
|
227
126
|
items: T[];
|
|
228
127
|
total: number;
|
|
@@ -252,23 +151,26 @@ declare class QueryBuilder<T extends BaseContentItem> {
|
|
|
252
151
|
}): this;
|
|
253
152
|
execute(): Promise<QueryResult<T>>;
|
|
254
153
|
executeOne(): Promise<T | null>;
|
|
154
|
+
/** 前後アイテムを返す。sortBy() で指定したソート順を適用する。 */
|
|
255
155
|
adjacent(slug: string): Promise<{
|
|
256
156
|
prev: T | null;
|
|
257
157
|
next: T | null;
|
|
258
158
|
}>;
|
|
159
|
+
/** 最初の 1 件を返す。`.paginate({ page: 1, perPage: 1 }).executeOne()` の短縮形。 */
|
|
160
|
+
first(): Promise<T | null>;
|
|
259
161
|
}
|
|
260
162
|
|
|
261
|
-
/**
|
|
262
|
-
interface
|
|
263
|
-
|
|
163
|
+
/** キャッシュ系の公開名前空間。SWR 読み取りとキャッシュ管理を統合する。 */
|
|
164
|
+
interface CacheAccessor<T extends BaseContentItem> {
|
|
165
|
+
/** キャッシュ優先でコンテンツ一覧を返す(SWR)。 */
|
|
166
|
+
getList(): Promise<{
|
|
264
167
|
items: T[];
|
|
265
168
|
isStale: boolean;
|
|
266
169
|
cachedAt: number;
|
|
267
170
|
}>;
|
|
171
|
+
/** キャッシュ優先で単一コンテンツを返す(SWR)。HTML 付きの CachedItem を返す。 */
|
|
268
172
|
get(slug: string): Promise<CachedItem<T> | null>;
|
|
269
|
-
|
|
270
|
-
/** キャッシュ管理オペレーション。 */
|
|
271
|
-
interface CacheManager<T extends BaseContentItem> {
|
|
173
|
+
/** 全コンテンツを事前レンダリングしてキャッシュに保存する。 */
|
|
272
174
|
prefetchAll(opts?: {
|
|
273
175
|
concurrency?: number;
|
|
274
176
|
onProgress?: (done: number, total: number) => void;
|
|
@@ -276,20 +178,24 @@ interface CacheManager<T extends BaseContentItem> {
|
|
|
276
178
|
ok: number;
|
|
277
179
|
failed: number;
|
|
278
180
|
}>;
|
|
181
|
+
/** 指定スコープのキャッシュを無効化する。 */
|
|
279
182
|
revalidate(scope?: "all" | {
|
|
280
183
|
slug: string;
|
|
281
184
|
}): Promise<void>;
|
|
185
|
+
/** Webhook ペイロードを元にキャッシュを同期する。 */
|
|
282
186
|
sync(payload?: {
|
|
283
187
|
slug?: string;
|
|
284
188
|
}): Promise<{
|
|
285
189
|
updated: string[];
|
|
286
190
|
}>;
|
|
191
|
+
/** リスト全体の変更を検知する。version はリスト取得時の buildListVersion の値。 */
|
|
287
192
|
checkList(version: string): Promise<{
|
|
288
193
|
changed: false;
|
|
289
194
|
} | {
|
|
290
195
|
changed: true;
|
|
291
196
|
items: T[];
|
|
292
197
|
}>;
|
|
198
|
+
/** 単一アイテムの変更を検知し、変更があれば再レンダリングしてキャッシュを更新する。 */
|
|
293
199
|
checkItem(slug: string, lastEdited: string): Promise<{
|
|
294
200
|
changed: false;
|
|
295
201
|
} | {
|
|
@@ -307,6 +213,7 @@ interface CacheManager<T extends BaseContentItem> {
|
|
|
307
213
|
* source: notionAdapter({ token: '...', dataSourceId: '...' }),
|
|
308
214
|
* });
|
|
309
215
|
* const items = await cms.list();
|
|
216
|
+
* const entry = await cms.cache.get('my-post');
|
|
310
217
|
*/
|
|
311
218
|
declare class CMS<T extends BaseContentItem = BaseContentItem> {
|
|
312
219
|
private readonly source;
|
|
@@ -318,157 +225,54 @@ declare class CMS<T extends BaseContentItem = BaseContentItem> {
|
|
|
318
225
|
private readonly accessibleStatuses;
|
|
319
226
|
private readonly imageProxyBase;
|
|
320
227
|
private readonly contentConfig;
|
|
228
|
+
private readonly rendererFn;
|
|
321
229
|
private readonly waitUntil;
|
|
322
230
|
private readonly hooks;
|
|
323
231
|
private readonly logger;
|
|
324
232
|
private readonly retryConfig;
|
|
325
|
-
readonly
|
|
326
|
-
readonly cache:
|
|
233
|
+
private readonly maxConcurrent;
|
|
234
|
+
readonly cache: CacheAccessor<T>;
|
|
327
235
|
constructor(opts: CreateCMSOptions<T>);
|
|
328
236
|
/** 公開済みコンテンツ一覧をソースから直接取得する。 */
|
|
329
237
|
list(): Promise<T[]>;
|
|
330
238
|
/** スラッグでコンテンツをソースから直接取得する。 */
|
|
331
239
|
find(slug: string): Promise<T | null>;
|
|
332
|
-
/**
|
|
333
|
-
|
|
240
|
+
/** 複数スラッグをまとめてソースから直接取得する。accessibleStatuses フィルタを適用する。 */
|
|
241
|
+
findMany(slugs: string[]): Promise<Map<string, T>>;
|
|
334
242
|
/** アイテムが publishedStatuses に含まれるステータスかどうかを返す。 */
|
|
335
243
|
isPublished(item: T): boolean;
|
|
336
|
-
/** コンテンツを Markdown → HTML にレンダリングし、CachedItem
|
|
244
|
+
/** コンテンツを Markdown → HTML にレンダリングし、CachedItem として返す。キャッシュには保存しない。 */
|
|
337
245
|
render(item: T): Promise<CachedItem<T>>;
|
|
338
246
|
/** QueryBuilder を返す。ステータス・タグ・ページネーションなどを連鎖で指定できる。 */
|
|
339
247
|
query(): QueryBuilder<T>;
|
|
340
|
-
/** 全コンテンツを事前レンダリングしてキャッシュに保存する。 */
|
|
341
|
-
prefetchAll(opts?: {
|
|
342
|
-
concurrency?: number;
|
|
343
|
-
onProgress?: (done: number, total: number) => void;
|
|
344
|
-
}): Promise<{
|
|
345
|
-
ok: number;
|
|
346
|
-
failed: number;
|
|
347
|
-
}>;
|
|
348
248
|
/** 静的生成用のスラッグ一覧を返す。 */
|
|
349
249
|
getStaticSlugs(): Promise<string[]>;
|
|
350
|
-
/** 指定スコープのキャッシュを無効化する。 */
|
|
351
|
-
revalidate(scope?: "all" | {
|
|
352
|
-
slug: string;
|
|
353
|
-
}): Promise<void>;
|
|
354
|
-
/** Webhook ペイロードを元にキャッシュを同期する。 */
|
|
355
|
-
syncFromWebhook(payload?: {
|
|
356
|
-
slug?: string;
|
|
357
|
-
}): Promise<{
|
|
358
|
-
updated: string[];
|
|
359
|
-
}>;
|
|
360
|
-
/** キャッシュ優先でコンテンツ一覧を返す(SWR)。 */
|
|
361
|
-
private cachedList;
|
|
362
|
-
/** キャッシュ優先で単一コンテンツを返す(SWR)。 */
|
|
363
|
-
private cachedGet;
|
|
364
|
-
checkListUpdate(version: string): Promise<{
|
|
365
|
-
changed: false;
|
|
366
|
-
} | {
|
|
367
|
-
changed: true;
|
|
368
|
-
items: T[];
|
|
369
|
-
}>;
|
|
370
|
-
checkItemUpdate(slug: string, lastEdited: string): Promise<{
|
|
371
|
-
changed: false;
|
|
372
|
-
} | {
|
|
373
|
-
changed: true;
|
|
374
|
-
html: string;
|
|
375
|
-
item: T;
|
|
376
|
-
notionUpdatedAt: string;
|
|
377
|
-
}>;
|
|
378
|
-
/** @deprecated cached.list() を使用してください。 */
|
|
379
|
-
getList(): Promise<{
|
|
380
|
-
items: T[];
|
|
381
|
-
listVersion: string;
|
|
382
|
-
}>;
|
|
383
|
-
/** @deprecated cached.get() を使用してください。 */
|
|
384
|
-
getItem(slug: string): Promise<CachedItem<T> | null>;
|
|
385
|
-
/** @deprecated cache.prefetchAll() を使用してください。 */
|
|
386
|
-
prefetchAllLegacy(opts?: {
|
|
387
|
-
concurrency?: number;
|
|
388
|
-
onProgress?: (done: number, total: number) => void;
|
|
389
|
-
}): Promise<{
|
|
390
|
-
ok: number;
|
|
391
|
-
failed: number;
|
|
392
|
-
}>;
|
|
393
|
-
/** @deprecated query().status(s).execute() を使用してください。 */
|
|
394
|
-
listByStatus(status: string | readonly string[]): Promise<T[]>;
|
|
395
|
-
/** @deprecated query().where(pred).execute() を使用してください。 */
|
|
396
|
-
where(predicate: (item: T) => boolean): Promise<T[]>;
|
|
397
|
-
/** @deprecated query().paginate(opts).execute() を使用してください。 */
|
|
398
|
-
paginate(opts: {
|
|
399
|
-
page: number;
|
|
400
|
-
perPage: number;
|
|
401
|
-
}): Promise<{
|
|
402
|
-
items: T[];
|
|
403
|
-
total: number;
|
|
404
|
-
page: number;
|
|
405
|
-
perPage: number;
|
|
406
|
-
hasNext: boolean;
|
|
407
|
-
}>;
|
|
408
|
-
/** @deprecated query().adjacent(slug) を使用してください。 */
|
|
409
|
-
getAdjacent(slug: string): Promise<{
|
|
410
|
-
prev: T | null;
|
|
411
|
-
next: T | null;
|
|
412
|
-
}>;
|
|
413
250
|
/** ハッシュキーでキャッシュ画像を取得する。 */
|
|
414
251
|
getCachedImage(hash: string): Promise<StorageBinary | null>;
|
|
415
252
|
/** ハッシュキーでキャッシュ画像を Response として返す。 */
|
|
416
253
|
createCachedImageResponse(hash: string): Promise<Response | null>;
|
|
254
|
+
private cachedList;
|
|
255
|
+
private cachedGet;
|
|
256
|
+
private prefetchAll;
|
|
257
|
+
private revalidate;
|
|
258
|
+
private syncFromWebhook;
|
|
259
|
+
private checkListUpdate;
|
|
260
|
+
private checkItemUpdate;
|
|
417
261
|
private buildCachedItem;
|
|
418
262
|
}
|
|
419
263
|
/** 設定済みの CMS インスタンスを生成するファクトリ関数。 */
|
|
420
264
|
declare function createCMS<T extends BaseContentItem = BaseContentItem>(opts: CreateCMSOptions<T>): CMS<T>;
|
|
421
265
|
|
|
422
|
-
type CMSErrorCode = "CONFIG_INVALID" | "NOTION_ITEM_SCHEMA_INVALID" | "NOTION_FETCH_ITEMS_FAILED" | "NOTION_FETCH_ITEM_BY_SLUG_FAILED" | "NOTION_GET_BLOCKS_FAILED" | "NOTION_MARKDOWN_FETCH_FAILED" | "IMAGE_CACHE_FAILED" | "RENDERER_FAILED";
|
|
423
|
-
interface CMSErrorContext {
|
|
424
|
-
operation: string;
|
|
425
|
-
slug?: string;
|
|
426
|
-
dataSourceId?: string;
|
|
427
|
-
pageId?: string;
|
|
428
|
-
[key: string]: string | number | boolean | null | undefined;
|
|
429
|
-
}
|
|
430
|
-
declare class CMSError extends Error {
|
|
431
|
-
readonly code: CMSErrorCode;
|
|
432
|
-
readonly cause?: unknown;
|
|
433
|
-
readonly context: CMSErrorContext;
|
|
434
|
-
constructor(params: {
|
|
435
|
-
code: CMSErrorCode;
|
|
436
|
-
message: string;
|
|
437
|
-
cause?: unknown;
|
|
438
|
-
context: CMSErrorContext;
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
declare function isCMSError(error: unknown): error is CMSError;
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* プラグイン配列とダイレクトフックを合成して単一の CMSHooks を返す。
|
|
445
|
-
* beforeCache / afterRender はパイプライン(前の出力が次の入力)。
|
|
446
|
-
* onCacheHit などオブザーバー系は全員に同じ値を渡す。
|
|
447
|
-
*/
|
|
448
|
-
declare function mergeHooks<T extends BaseContentItem>(plugins: CMSPlugin<T>[], directHooks?: CMSHooks<T>): CMSHooks<T>;
|
|
449
|
-
/** プラグイン配列とダイレクトロガーを合成して単一の Logger を返す。 */
|
|
450
|
-
declare function mergeLoggers(plugins: Array<{
|
|
451
|
-
logger?: Partial<Logger>;
|
|
452
|
-
}>, directLogger?: Logger): Logger | undefined;
|
|
453
|
-
|
|
454
|
-
/** Notionリッチテキスト配列をプレーンテキストに結合する。 */
|
|
455
|
-
declare function getPlainText(items: RichTextItemResponse[] | undefined): string;
|
|
456
|
-
/**
|
|
457
|
-
* NotionのPageObjectResponseをデフォルトの BaseContentItem に変換する。
|
|
458
|
-
* 独自の拡張型(title などを含む)が必要な場合は、本関数の戻り値に
|
|
459
|
-
* 追加フィールドを足してカスタム mapItem を実装する。
|
|
460
|
-
*/
|
|
461
|
-
declare function mapItem(page: PageObjectResponse, props: Required<CMSSchemaProperties>): BaseContentItem;
|
|
462
|
-
|
|
463
266
|
interface RetryConfig {
|
|
464
|
-
maxConcurrent: number;
|
|
465
267
|
retryOn: number[];
|
|
466
268
|
maxRetries: number;
|
|
467
269
|
baseDelayMs: number;
|
|
270
|
+
/** true のとき指数バックオフにランダムジッターを加える(Thundering Herd 対策)。デフォルト: true */
|
|
271
|
+
jitter?: boolean;
|
|
468
272
|
onRetry?: (attempt: number, status: number) => void;
|
|
469
273
|
}
|
|
470
274
|
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
471
|
-
/**
|
|
275
|
+
/** 指数バックオフ(オプションでジッター付き)でリトライする。retryOn に含まれる HTTP エラーのみ対象。 */
|
|
472
276
|
declare function withRetry<T>(fn: () => Promise<T>, config: RetryConfig): Promise<T>;
|
|
473
277
|
|
|
474
|
-
export {
|
|
278
|
+
export { BaseContentItem, CMS, CMSHooks, CMSPlugin, CMSSchemaProperties, type CacheAccessor, CacheConfig, CachedItem, type ContentConfig, type CreateCMSOptions, DEFAULT_RETRY_CONFIG, type DataSourceAdapter, Logger, QueryBuilder, type QueryResult, type RateLimiterConfig, type RenderOptions, type RendererFn, type RetryConfig, type SchemaConfig, type SourceQueryOptions, type SourceQueryResult, StorageBinary, createCMS, isStale, sha256Hex, withRetry };
|