@ryusenkei/maezae 0.11.0 → 0.12.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/README.md CHANGED
@@ -57,40 +57,37 @@ const body = (await request.json()) as PublishCheckRequest;
57
57
 
58
58
  ## Webhook の本文と契約の版
59
59
 
60
- 本文の形は Webhook の登録ごとの契約の版(`version`)で決まる。非互換の変更はバージョン(版)を上げて行い、旧い版は受け手の移行の期間だけ残す(#495)
60
+ 本文の `version` は契約の版(今は1だけ)。非互換の変更はバージョン(版)を上げて行う(#495)
61
61
 
62
- | 版 | 対象の登録 | 編集の出来事の本文 |
63
- | --- | --- | --- |
64
- | 2(今の版) | 2026-11-12より後に作成した登録と、管理画面で版2に切り替えた登録 | `{ "version": 2, "id": "evt_…", "event": "published", "type": "column", "item": { "id": "…", "title": "…" }, "by": "…", "at": "…" }` |
65
- | 1(旧い版) | 2026-11-12より前に作成した登録(移し替えの後も版1のまま) | `{ "version": 1, "id": "evt_…", "event": "column.published", "type": "column", "item": {…}, "by": "…", "at": "…" }` |
62
+ ```json
63
+ { "version": 1, "id": "evt_…", "event": "published", "type": "column", "item": { "id": "…", "title": "…" }, "by": "…", "at": "2026-11-12T00:00:00.000Z" }
64
+ ```
66
65
 
67
- - `event`: `submitted`(レビューの依頼)・`published`(公開)・`unpublished`(非公開)・`rejected`(差し戻し)。型は `type` で判断する(型の ID を変えても受け手の分岐が切れない)
68
- - 拡張機能の出来事(例: お問い合わせの `contact.received`): 版を問わず `{ version, id, event: "contact.received", data, at }`(接頭辞はモジュールの ID で型の ID ではないため、名前は変えない)
66
+ - `event`: `submitted`(レビューの依頼)・`published`(公開)・`unpublished`(非公開)・`rejected`(差し戻し)。型は `type`(型の ID)で判断する(型の ID を変えても `event` は変わらない)
67
+ - `id`: イベントの ID(再送しても同じ値、重複の除去に使用)、`item`: 行の ID と題、`by`: 操作した人の表示名、`at`: 出来事の日時
68
+ - 拡張機能の出来事(例: お問い合わせの `contact.received`): `{ version: 1, id, event: "contact.received", data, at }`(接頭辞はモジュールの ID で型の ID ではない)
69
69
  - 購読: 管理画面の「設定 → 連携」で、送る出来事と対象の型を別々に選ぶ。編集の出来事は「選んだ出来事 × 選んだ型」で届く
70
- - 版1の廃止: 本番のすべての登録が版2になり、最後の切り替えから再送の期間(約55時間半)が過ぎた後。期限の目安は2027-01-31(延ばすときは #495に書く)
71
- - 版1の登録のまま型の ID を変えると、版1の `event`(`<型の ID>.<出来事>`)も変わる。型の ID の変更(#465)は受け手を版2に移してから行う
72
-
73
- ### 受け手の移行(版1 → 版2)
74
-
75
- 1. 受け手を両方の形で動くように直してデプロイ(下の例)。SDK を 0.11.0 以上にすると `WebhookBody` が2つの版の型になる
76
- 2. 管理画面の「設定 → 連携」で Webhook を開き、「契約の版」を版2にして保存し、「テストの送信」で受け手の成功を確かめる
77
- 3. 「送信の記録」で、切り替えの後の本物の出来事が成功していることを確かめる
78
- 4. 3日(再送の期間の約55時間半を過ぎる)待ってから、受け手の版1の処理を消す。切り替えの前に失敗した送信の再送は、版1の形のまま届く
79
70
 
80
71
  ```ts
81
72
  import type { WebhookBody } from '@ryusenkei/maezae/integrations';
82
73
 
83
74
  const body = (await request.json()) as WebhookBody;
84
- // 版2は event と type、版1は event の <型の ID>.<出来事> を分けて同じ形に
85
- const [type, event] = body.version === 2 ? [body.type, body.event] : [body.type, body.event.slice(body.event.lastIndexOf('.') + 1)];
86
- if (type === 'part' && event === 'published') await revalidatePart(body.item.id);
75
+ if (body.type === 'part' && body.event === 'published') await revalidatePart(body.item.id);
87
76
  ```
88
77
 
78
+ ### 受け手の移行(0.11.0 以前の形から)
79
+
80
+ 0.12.0 で旧い形(`event` が `<型の ID>.<出来事>`、0.11.0 の版1)と版2を廃止し、`event` と `type` を分けた形だけを版1とした(まだ導入先がないため移行の期間なし)
81
+
82
+ 1. SDK を 0.12.0 にする。`WebhookBodyV1`・`WebhookBodyV2` は廃止、`WebhookBody` が唯一の形(`event` は `WebhookAction`)
83
+ 2. 受け手の分岐を `body.type` と `body.event`(`published` など)に直してデプロイ。`event` の `.` を分ける処理は消す
84
+ 3. 管理画面の「設定 → 連携」の「テストの送信」と「送信の記録」で受け手の成功を確かめる。CMS の更新の前に失敗した送信の再送も、新しい形で届く(migration で本文を揃えた)
85
+
89
86
  ### microCMS の Webhook との対応
90
87
 
91
88
  キーの名前は maezae の語彙のまま(`type` を2つの意味で使わない)
92
89
 
93
- | microCMS | maezae(版2) | 備考 |
90
+ | microCMS | maezae | 備考 |
94
91
  | --- | --- | --- |
95
92
  | `service` | (なし) | 送信先の URL と署名の鍵が媒体ごと |
96
93
  | `api`(API のエンドポイント名) | `type`(型の ID) | |
@@ -15,7 +15,7 @@ export { CONFIG_FORMAT, type ConfigBundle, type ConfigPreview } from './transfer
15
15
  export { IMPORT_ITEMS_MAX, IMPORT_PROBLEM_LABELS, IMPORT_PROBLEMS, type ImportIdChange, type ImportIdConflict, importIdOf, type ImportIdPlan, type ImportImage, type ImportItem, type ImportItemReport, type ImportProblem, type ImportProblemCode, type ImportReport, importReportOf, mergeImportReports, planImportIds, sourceOf } from './import.js';
16
16
  export { EMBED_CONTEXT_NEXT_PARAM, EMBED_CONTEXT_PARAM, EMBED_CONTEXT_TTL_SEC, EMBED_MESSAGES, EMBED_PLACEMENTS, type EmbedContext, type EmbedEntry, type EmbedMessage, type EmbedPlacement, type ExternalScreen } from './embeds.js';
17
17
  export { type ExternalFunction, FUNCTION_HOOK_LABELS, FUNCTION_HOOKS, functionEventLabel, functionEventOf, type FunctionHook, type FunctionOnError, type FunctionRequest, type PublishCheckRequest, type PublishCheckResponse, type SaveCheckRequest, type SaveCheckResponse } from './functions.js';
18
- export { isWebhookAction, parseWebhookEvent, type Webhook, WEBHOOK_ACTION_LABELS, type WebhookBody, type WebhookBodyV1, type WebhookBodyV2, WEBHOOK_ACTIONS, type WebhookAction, type WebhookDelivery, type WebhookEvent, webhookEventLabel, webhookEventOf, type WebhookKind, type WebhookModuleBody, type WebhookSubscription, webhookSubscriptionLabel, WEBHOOK_VERSION, WEBHOOK_VERSIONS, type WebhookVersion } from './webhooks.js';
18
+ export { isWebhookAction, parseWebhookEvent, type Webhook, WEBHOOK_ACTION_LABELS, type WebhookBody, WEBHOOK_ACTIONS, type WebhookAction, type WebhookDelivery, type WebhookEvent, webhookEventLabel, webhookEventOf, type WebhookKind, type WebhookModuleBody, type WebhookSubscription, webhookSubscriptionLabel, WEBHOOK_VERSION, type WebhookVersion } from './webhooks.js';
19
19
  export { CONTRACT_VERSION_HEADER, DELIVERY_VERSION } from './versions.js';
20
20
  export { type SavedView, VIEW_ACTIONS, type ViewAction, type ViewDefinition } from './views.js';
21
21
  export { canManageSettings, isSettingsTarget, managedAreasOf, SETTINGS_AREA_LABELS, SETTINGS_AREAS, type SettingsArea, settingsTarget } from './settings.js';
@@ -2,12 +2,10 @@
2
2
  export declare const WEBHOOK_ACTIONS: readonly ["submitted", "published", "unpublished", "rejected"];
3
3
  /** 送れる操作 */
4
4
  export type WebhookAction = (typeof WEBHOOK_ACTIONS)[number];
5
- /** Webhook の契約の版(1は旧い形、2は今の形) */
6
- export declare const WEBHOOK_VERSIONS: readonly [1, 2];
5
+ /** Webhook の契約の版(本文の version) */
6
+ export declare const WEBHOOK_VERSION = 1;
7
7
  /** Webhook の契約の版 */
8
- export type WebhookVersion = (typeof WEBHOOK_VERSIONS)[number];
9
- /** 新しい登録の版(今の版) */
10
- export declare const WEBHOOK_VERSION: WebhookVersion;
8
+ export type WebhookVersion = typeof WEBHOOK_VERSION;
11
9
  /** サーバーの内側の出来事のキー(編集の出来事は <型の id>.<操作>、拡張機能の出来事は宣言の名前) */
12
10
  export type WebhookEvent = `${string}.${string}`;
13
11
  /** 購読する出来事(操作か拡張機能の出来事の名前) */
@@ -31,7 +29,6 @@ export declare const webhookSubscriptionLabel: (subscription: string, moduleEven
31
29
  export type WebhookKind = 'json' | 'slack';
32
30
  /**
33
31
  * Webhook(url・secret は末尾だけを伏せずに返す、secret の null は署名なし)
34
- * - version: 契約の版(本文の形)
35
32
  * - events: 購読する出来事(操作と拡張機能の出来事)、types: 購読する型の id(編集の出来事は events の操作 × types)
36
33
  * - previousSecret: 鍵の移行の期間の古い鍵の末尾、期間の外は null
37
34
  * - lastStatus: 最新の送信で返った HTTP の状態、送れなかったときは0
@@ -43,7 +40,6 @@ export type Webhook = Readonly<{
43
40
  url: string;
44
41
  secret: string | null;
45
42
  previousSecret: string | null;
46
- version: WebhookVersion;
47
43
  events: readonly WebhookSubscription[];
48
44
  types: readonly string[];
49
45
  enabled: boolean;
@@ -51,13 +47,14 @@ export type Webhook = Readonly<{
51
47
  lastAt: string | null;
52
48
  }>;
53
49
  /**
54
- * json の形式の本文の版2(編集機能を持つ型の出来事、署名はヘッダー x-cms-signature で登録ごとの鍵)
50
+ * json の形式の本文(編集機能を持つ型の出来事、署名はヘッダー x-cms-signature で登録ごとの鍵)
51
+ * - version: 契約の版(1)
55
52
  * - id: イベントの ID(再送しても同じ値、受け手は処理済みの id を捨てて重複を除く)
56
53
  * - event: 操作、type: 型の id
57
54
  * - item: 行の ID と題、by: 操作した人の表示名、at: 出来事の日時(ISO 8601、再送しても同じ値)
58
55
  */
59
- export type WebhookBodyV2 = Readonly<{
60
- version: 2;
56
+ export type WebhookBody = Readonly<{
57
+ version: WebhookVersion;
61
58
  id: string;
62
59
  event: WebhookAction;
63
60
  type: string;
@@ -68,22 +65,7 @@ export type WebhookBodyV2 = Readonly<{
68
65
  by: string;
69
66
  at: string;
70
67
  }>;
71
- /** json の形式の本文の版1(event は <型の id>.<操作>、ほかは版2と同じ。版1の登録だけに送る) */
72
- export type WebhookBodyV1 = Readonly<{
73
- version: 1;
74
- id: string;
75
- event: WebhookEvent;
76
- type: string;
77
- item: Readonly<{
78
- id: string;
79
- title: string;
80
- }>;
81
- by: string;
82
- at: string;
83
- }>;
84
- /** json の形式の本文(編集機能を持つ型の出来事、version で形を判別) */
85
- export type WebhookBody = WebhookBodyV2 | WebhookBodyV1;
86
- /** json の形式の拡張機能の出来事の本文(event は宣言の名前、data はモジュールの値、形は版1と版2で同じ) */
68
+ /** json の形式の拡張機能の出来事の本文(event は宣言の名前、data はモジュールの値) */
87
69
  export type WebhookModuleBody = Readonly<{
88
70
  version: WebhookVersion;
89
71
  id: string;
@@ -3,6 +3,6 @@ import { type EmbedContext } from '../../cms-contract/src/index.js';
3
3
  export { openValue, SIGNED_HEADERS, verifyRequest } from '../../access/src/index.js';
4
4
  export type { SigningSecrets, VerifyRequestOptions } from '../../access/src/index.js';
5
5
  export { EMBED_CONTEXT_NEXT_PARAM, EMBED_CONTEXT_PARAM, EMBED_MESSAGES, FUNCTION_HOOKS } from '../../cms-contract/src/index.js';
6
- export type { EmbedContext, EmbedMessage, FunctionHook, FunctionRequest, PublishCheckRequest, PublishCheckResponse, SaveCheckRequest, SaveCheckResponse, WebhookAction, WebhookBody, WebhookBodyV1, WebhookBodyV2, WebhookEvent, WebhookModuleBody, WebhookVersion } from '../../cms-contract/src/index.js';
6
+ export type { EmbedContext, EmbedMessage, FunctionHook, FunctionRequest, PublishCheckRequest, PublishCheckResponse, SaveCheckRequest, SaveCheckResponse, WebhookAction, WebhookBody, WebhookEvent, WebhookModuleBody, WebhookVersion } from '../../cms-contract/src/index.js';
7
7
  /** 外の画面の URL の文脈(クエリ ctx と、鍵の移行の期間の ctx_next のどちらかが鍵で開けば文脈、なければ null) */
8
8
  export declare function openEmbedContext(secret: SigningSecrets, url: string | URL, now?: number): Promise<EmbedContext | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryusenkei/maezae",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "maezae の導入先のサイト向けの SDK(配信 API の取得・本文の型・プレビューの署名・手元の開発の配信 API)",
5
5
  "license": "UNLICENSED",
6
6
  "author": "RYUSENKEI",