@ryusenkei/maezae 0.2.0 → 0.3.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.
Files changed (94) hide show
  1. package/README.md +2 -0
  2. package/dist/analytics.d.ts +1 -0
  3. package/dist/analytics.js +33 -0
  4. package/dist/body.d.ts +1 -24
  5. package/dist/body.js +1 -333
  6. package/dist/declared-9_jI3JXH.js +336 -0
  7. package/dist/delivery.d.ts +1 -211
  8. package/dist/integrations.d.ts +1 -72
  9. package/dist/integrations.js +12 -2
  10. package/dist/model.d.ts +1 -82
  11. package/dist/model.js +338 -1
  12. package/dist/preview.d.ts +1 -2
  13. package/dist/preview.js +1 -1
  14. package/dist/{src-CA_67dWy.js → src-Baj-EC2G.js} +105 -3
  15. package/dist/trace.d.ts +1 -0
  16. package/dist/trace.js +1 -0
  17. package/dist/types/access/src/index.d.ts +5 -0
  18. package/dist/types/access/src/jwt.d.ts +42 -0
  19. package/dist/types/access/src/oidc.d.ts +47 -0
  20. package/dist/types/access/src/signed.d.ts +47 -0
  21. package/dist/types/access/src/span.d.ts +23 -0
  22. package/dist/types/access/src/traceparent.d.ts +21 -0
  23. package/dist/types/analytics/src/day.d.ts +2 -0
  24. package/dist/types/analytics/src/index.d.ts +4 -0
  25. package/dist/types/analytics/src/record.d.ts +22 -0
  26. package/dist/types/analytics/src/schedule.d.ts +2 -0
  27. package/dist/types/analytics/src/source.d.ts +33 -0
  28. package/dist/types/analytics/src/store.d.ts +24 -0
  29. package/dist/types/body/src/components.d.ts +25 -0
  30. package/dist/types/body/src/declared.d.ts +34 -0
  31. package/dist/types/body/src/derive.d.ts +13 -0
  32. package/dist/types/body/src/description.d.ts +8 -0
  33. package/dist/types/body/src/href.d.ts +4 -0
  34. package/dist/types/body/src/index.d.ts +11 -0
  35. package/dist/types/body/src/library.d.ts +94 -0
  36. package/dist/types/body/src/markdown.d.ts +14 -0
  37. package/dist/types/body/src/normalize.d.ts +7 -0
  38. package/dist/types/body/src/profile.d.ts +48 -0
  39. package/dist/types/body/src/schema.d.ts +6 -0
  40. package/dist/types/body/src/standard.d.ts +20 -0
  41. package/dist/types/body/src/types.d.ts +91 -0
  42. package/dist/types/cms-contract/src/apiKeys.d.ts +13 -0
  43. package/dist/types/cms-contract/src/assets.d.ts +10 -0
  44. package/dist/types/cms-contract/src/builtins.d.ts +17 -0
  45. package/dist/types/cms-contract/src/embeds.d.ts +56 -0
  46. package/dist/types/cms-contract/src/errorLabels.d.ts +22 -0
  47. package/dist/types/cms-contract/src/errors.d.ts +97 -0
  48. package/dist/types/cms-contract/src/extensions.d.ts +75 -0
  49. package/dist/types/cms-contract/src/fieldRules.d.ts +37 -0
  50. package/dist/types/cms-contract/src/functions.d.ts +71 -0
  51. package/dist/types/cms-contract/src/index.d.ts +19 -0
  52. package/dist/types/cms-contract/src/labels.d.ts +6 -0
  53. package/dist/types/cms-contract/src/modules.d.ts +144 -0
  54. package/dist/types/cms-contract/src/paths.d.ts +6 -0
  55. package/dist/types/cms-contract/src/pending.d.ts +4 -0
  56. package/dist/types/cms-contract/src/permissions.d.ts +69 -0
  57. package/dist/types/cms-contract/src/roles.d.ts +35 -0
  58. package/dist/types/cms-contract/src/settings.d.ts +19 -0
  59. package/dist/types/cms-contract/src/transfer.d.ts +48 -0
  60. package/dist/types/cms-contract/src/views.d.ts +21 -0
  61. package/dist/types/cms-contract/src/webhooks.d.ts +45 -0
  62. package/dist/types/delivery-client/src/client.d.ts +62 -0
  63. package/dist/types/delivery-client/src/index.d.ts +5 -0
  64. package/dist/types/delivery-client/src/media.d.ts +12 -0
  65. package/dist/types/delivery-client/src/query.d.ts +68 -0
  66. package/dist/types/delivery-client/src/schema.d.ts +19 -0
  67. package/dist/types/delivery-client/src/values.d.ts +63 -0
  68. package/dist/types/model/src/asset.d.ts +89 -0
  69. package/dist/types/model/src/capabilities.d.ts +20 -0
  70. package/dist/types/model/src/changes.d.ts +23 -0
  71. package/dist/types/model/src/check.d.ts +10 -0
  72. package/dist/types/model/src/image.d.ts +38 -0
  73. package/dist/types/model/src/index.d.ts +14 -0
  74. package/dist/types/model/src/input.d.ts +26 -0
  75. package/dist/types/model/src/media.d.ts +5 -0
  76. package/dist/types/model/src/model.d.ts +190 -0
  77. package/dist/types/model/src/page.d.ts +47 -0
  78. package/dist/types/model/src/rules.d.ts +15 -0
  79. package/dist/types/model/src/schema.d.ts +3 -0
  80. package/dist/types/model/src/screens.d.ts +72 -0
  81. package/dist/types/model/src/time.d.ts +25 -0
  82. package/dist/types/model/src/values.d.ts +24 -0
  83. package/dist/types/sdk/src/analytics.d.ts +2 -0
  84. package/dist/types/sdk/src/body.d.ts +2 -0
  85. package/dist/types/sdk/src/defaults.d.ts +5 -0
  86. package/dist/types/sdk/src/delivery.d.ts +2 -0
  87. package/dist/types/sdk/src/integrations.d.ts +4 -0
  88. package/dist/types/sdk/src/model.d.ts +5 -0
  89. package/dist/types/sdk/src/preview.d.ts +2 -0
  90. package/dist/types/sdk/src/trace.d.ts +2 -0
  91. package/package.json +10 -2
  92. package/dist/index-C8duwjns.d.ts +0 -157
  93. package/dist/index-CLDe_wBc.d.ts +0 -340
  94. package/dist/signed-B_58gV21.d.ts +0 -44
@@ -0,0 +1,19 @@
1
+ import { type User } from './roles.js';
2
+ /**
3
+ * 設定の領域
4
+ * - general: 一般、content: コンテンツタイプ・メニュー・画像サイズ、extensions: 拡張機能
5
+ * - integrations: 連携・プレビューとデプロイ、data: インポート・エクスポート
6
+ */
7
+ export declare const SETTINGS_AREAS: readonly ["general", "content", "extensions", "integrations", "data"];
8
+ /** 設定の領域 */
9
+ export type SettingsArea = (typeof SETTINGS_AREAS)[number];
10
+ /** 権限の表での設定の領域の id */
11
+ export declare const settingsTarget: (area: SettingsArea) => string;
12
+ /** 権限の表の対象が設定の領域か */
13
+ export declare const isSettingsTarget: (id: string) => boolean;
14
+ /** 設定の領域を扱えるか(管理者は常に可、ほかは対象の更新が可のときだけ) */
15
+ export declare const canManageSettings: (user: Pick<User, "role" | "permissions">, area: SettingsArea) => boolean;
16
+ /** 扱える設定の領域(空は設定の層を開けない) */
17
+ export declare const managedAreasOf: (user: Pick<User, "role" | "permissions">) => readonly SettingsArea[];
18
+ /** 設定の領域の表示名 */
19
+ export declare const SETTINGS_AREA_LABELS: Readonly<Record<SettingsArea, string>>;
@@ -0,0 +1,48 @@
1
+ import type { Permissions } from './permissions.js';
2
+ import type { ViewDefinition } from './views.js';
3
+ /** スキーマと設定の形式の名前 */
4
+ export declare const CONFIG_FORMAT = "cms-config";
5
+ /** スキーマと設定(schema はコンテンツスキーマ ContentModel・screens は画面設定 ScreenSettings の形、roles は管理者以外、views はチームのビュー) */
6
+ export type ConfigBundle = Readonly<{
7
+ format: typeof CONFIG_FORMAT;
8
+ version: 1;
9
+ exported_at: string;
10
+ schema: unknown;
11
+ screens: unknown;
12
+ roles: readonly Readonly<{
13
+ id: string;
14
+ label: string;
15
+ permissions: Permissions;
16
+ }>[];
17
+ views: readonly Readonly<{
18
+ id: string;
19
+ type: string;
20
+ label: string;
21
+ definition: ViewDefinition;
22
+ roles: readonly string[];
23
+ }>[];
24
+ extensions: readonly Readonly<{
25
+ id: string;
26
+ enabled: boolean;
27
+ settings: Readonly<Record<string, unknown>>;
28
+ }>[];
29
+ }>;
30
+ /** スキーマと設定の読み込みの確認(schema はスキーマの変更、ほかは追加と更新の件数) */
31
+ export type ConfigPreview = Readonly<{
32
+ schema: readonly Readonly<{
33
+ id: string;
34
+ level: 'safe' | 'confirm' | 'forbidden';
35
+ message: string;
36
+ count: number | null;
37
+ }>[];
38
+ roles: Readonly<{
39
+ added: number;
40
+ updated: number;
41
+ }>;
42
+ views: Readonly<{
43
+ added: number;
44
+ updated: number;
45
+ }>;
46
+ extensions: number;
47
+ screens: boolean;
48
+ }>;
@@ -0,0 +1,21 @@
1
+ /** ビューで許可できる一括操作(assign: 担当者の割り当て、publish: 公開) */
2
+ export declare const VIEW_ACTIONS: readonly ["assign", "publish"];
3
+ /** ビューで許可できる一括操作 */
4
+ export type ViewAction = (typeof VIEW_ACTIONS)[number];
5
+ /** ビューの内容(filters は列の id ごとの絞り込みの値、query は検索の文、columns は表示する列、editable は一覧で編集する列) */
6
+ export type ViewDefinition = Readonly<{
7
+ filters: Readonly<Record<string, string>>;
8
+ query: string;
9
+ columns: readonly string[];
10
+ editable: readonly string[];
11
+ actions: readonly ViewAction[];
12
+ }>;
13
+ /** 保存したビュー(owner がなければチームのビュー、roles は見られるロールの ID で空はすべて) */
14
+ export type SavedView = Readonly<{
15
+ id: string;
16
+ owner: string | null;
17
+ type: string;
18
+ label: string;
19
+ definition: ViewDefinition;
20
+ roles: readonly string[];
21
+ }>;
@@ -0,0 +1,45 @@
1
+ /** 送れる操作(レビューの依頼・公開・非公開・差し戻し) */
2
+ export declare const WEBHOOK_ACTIONS: readonly ["submitted", "published", "unpublished", "rejected"];
3
+ /** 送れる操作 */
4
+ export type WebhookAction = (typeof WEBHOOK_ACTIONS)[number];
5
+ /** 送れる出来事(編集機能を持つ型の <型の id>.<操作> と、拡張機能が宣言した出来事) */
6
+ export type WebhookEvent = `${string}.${string}`;
7
+ /** 操作の表示名(画面の選択肢と、Slack の文) */
8
+ export declare const WEBHOOK_ACTION_LABELS: Readonly<Record<WebhookAction, string>>;
9
+ /** 型と操作の出来事 */
10
+ export declare const webhookEventOf: (type: string, action: WebhookAction) => WebhookEvent;
11
+ /** 出来事の型と操作(形が不正なら null) */
12
+ export declare function parseWebhookEvent(event: string): Readonly<{
13
+ type: string;
14
+ action: WebhookAction;
15
+ }> | null;
16
+ /** 出来事の表示名(types は型の id と表示名で型の表示名と操作の表示名、moduleEvents は拡張機能の出来事の表示名) */
17
+ export declare function webhookEventLabel(event: string, types: Readonly<Record<string, string>>, moduleEvents?: Readonly<Record<string, string>>): string;
18
+ /** Webhook の形式 */
19
+ export type WebhookKind = 'json' | 'slack';
20
+ /** Webhook(url・secret は末尾だけを伏せずに返す、secret の null は署名なし、lastStatus は最新の送信で返った HTTP の状態、送れなかったときは0) */
21
+ export type Webhook = Readonly<{
22
+ id: string;
23
+ label: string;
24
+ kind: WebhookKind;
25
+ url: string;
26
+ secret: string | null;
27
+ events: readonly WebhookEvent[];
28
+ enabled: boolean;
29
+ lastStatus: number | null;
30
+ lastAt: string | null;
31
+ }>;
32
+ /**
33
+ * json の形式の本文(編集機能を持つ型の出来事、署名はヘッダー x-cms-signature で登録ごとの鍵)
34
+ * - item: 行の ID と題、by: 操作した人の表示名、at: 送信の日時(ISO 8601)
35
+ */
36
+ export type WebhookBody = Readonly<{
37
+ event: WebhookEvent;
38
+ type: string;
39
+ item: Readonly<{
40
+ id: string;
41
+ title: string;
42
+ }>;
43
+ by: string;
44
+ at: string;
45
+ }>;
@@ -0,0 +1,62 @@
1
+ import type { ContentType } from '../../model/src/index.js';
2
+ import { type ListQuery, type Page } from './query.js';
3
+ /** 配信 API のパスの前半 */
4
+ export declare const DELIVERY_PATH = "/content/v1";
5
+ /** 配信 API への接続(path は /content/v1 から始まるパスとクエリ) */
6
+ export type Delivery = (path: string, init?: RequestInit) => Promise<Response>;
7
+ /** 一式の経路ごとの結果(body は経路の応答の JSON) */
8
+ export type BundleResult = Readonly<{
9
+ status: number;
10
+ body: unknown;
11
+ }>;
12
+ /**
13
+ * 一式の取得の結果
14
+ * - notModified: ETag が一致、etag: 応答の ETag、stale: 失敗のため最後に成功した値
15
+ * - partial: 一部の経路が 5xx の一式 x-partial(最後に成功した値や描画の結果として保存しない)
16
+ */
17
+ export type Prefetched = Readonly<{
18
+ notModified: boolean;
19
+ etag: string | null;
20
+ stale: boolean;
21
+ partial: boolean;
22
+ }>;
23
+ /** 配信 API の取得の失敗(call: 失敗した経路、status: 応答のステータス) */
24
+ export declare class DeliveryError extends Error {
25
+ readonly call: string;
26
+ readonly status: number;
27
+ constructor(call: string, status: number, body: string);
28
+ }
29
+ /** 配信 API の中のパスとクエリ(一式の path と結果のキー) */
30
+ export declare const subPath: (path: string, params?: Readonly<Record<string, string>>) => string;
31
+ /**
32
+ * 配信 API の読み取り
33
+ * - drafts: 下書き・予約なども含める(プレビュー用、署名は接続の側で付与)
34
+ * - at: 公開の基準の日時(なしは今)
35
+ */
36
+ export declare function createDeliveryClient(delivery: Delivery, { drafts, at }?: {
37
+ drafts?: boolean;
38
+ at?: string;
39
+ }): {
40
+ find: <T>(path: string, params?: Readonly<Record<string, string>>) => Promise<T | undefined>;
41
+ get: <T>(path: string, params?: Readonly<Record<string, string>>) => Promise<T>;
42
+ page: <I = Readonly<Record<string, unknown>>, T extends ContentType = Readonly<{
43
+ id: string;
44
+ label: string;
45
+ description?: string;
46
+ format?: import("../../model/src/index.js").ContentFormat;
47
+ publishing?: import("../../model/src/index.js").Publishing;
48
+ table?: string;
49
+ core?: readonly import("../../model/src/index.js").FieldDef[];
50
+ fields: readonly import("../../model/src/index.js").FieldDef[];
51
+ pages?: readonly import("../../model/src/index.js").PageDef[];
52
+ counts?: readonly import("../../model/src/index.js").CountDef[];
53
+ og?: string;
54
+ }>>(path: string, query: ListQuery<T> & Readonly<{
55
+ limit: number;
56
+ }>) => Promise<Page<I>>;
57
+ prefetch: (paths: readonly string[], { ifNoneMatch }?: {
58
+ ifNoneMatch?: string;
59
+ }) => Promise<Prefetched>;
60
+ };
61
+ /** 配信 API の読み取り(createDeliveryClient の戻り値) */
62
+ export type DeliveryClient = ReturnType<typeof createDeliveryClient>;
@@ -0,0 +1,5 @@
1
+ export { createDeliveryClient, DELIVERY_PATH, DeliveryError, subPath, type BundleResult, type Delivery, type DeliveryClient, type Prefetched } from './client.js';
2
+ export { mediaOf, type ImageUrl, type MediaOf } from './media.js';
3
+ export { listParams, type ListFilter, type ListQuery, type Page } from './query.js';
4
+ export { createDeliveryClock, fieldOf, limitOf, optionLabels, pagePath, type DeliveryClock } from './schema.js';
5
+ export type { DeliveredAsset, FieldValue, Item, ItemOf } from './values.js';
@@ -0,0 +1,12 @@
1
+ import { type CropRect, type Media } from '../../model/src/index.js';
2
+ /** 配信する画像の URL(元の URL と、元画像の画素での切り抜きの範囲から、配信の側で変換する URL) */
3
+ export type ImageUrl = (src: string, rect?: CropRect) => string;
4
+ /** 実体から表示の素材(見つからない実体はなし) */
5
+ export type MediaOf = (asset: unknown) => Media | undefined;
6
+ /**
7
+ * 実体から表示の素材への変換(動画は代わりの画像も)
8
+ * - base: 実体の URL の前半(URL は base/<ID>)
9
+ * - 画像の変換: imageUrl があれば画像(動画の実体は除く)を変換の URL に、切り抜きは切り抜いた画像の URL・寸法・見せたい点
10
+ * - imageUrl なし: 元の画像のまま(手元の開発)
11
+ */
12
+ export declare function mediaOf(base: string, imageUrl?: ImageUrl): MediaOf;
@@ -0,0 +1,68 @@
1
+ import type { ContentType, FieldDef } from '../../model/src/index.js';
2
+ import type { FieldsOf, Item, SingleValue } from './values.js';
3
+ /** 範囲の指定(両端を含む) */
4
+ type Range<V> = Readonly<{
5
+ gte?: V;
6
+ lte?: V;
7
+ }>;
8
+ type Scalar<F extends FieldDef> = NonNullable<SingleValue<F>>;
9
+ /** 項目の種類ごとの絞り込みの値(選択肢・参照は一致か in、チェックボックスは一致、数値・日付は一致か範囲、日時は範囲) */
10
+ type FilterValue<F extends FieldDef> = F extends {
11
+ private: true;
12
+ } ? never : F extends {
13
+ type: 'select' | 'reference';
14
+ } ? Scalar<F> | Readonly<{
15
+ in: readonly Scalar<F>[];
16
+ }> : F extends {
17
+ type: 'checkbox';
18
+ } ? boolean : F extends {
19
+ type: 'number' | 'date';
20
+ } ? Scalar<F> | Range<Scalar<F>> : F extends {
21
+ type: 'datetime';
22
+ } ? Range<string> : never;
23
+ /** 並べ替えできる項目の key(単数の文字・数値・日付・日時・選択肢・チェックボックス) */
24
+ type SortableKey<T extends ContentType> = FieldsOf<T> extends infer F ? (F extends {
25
+ private: true;
26
+ } | {
27
+ multiple: true;
28
+ } ? never : F extends {
29
+ type: 'text' | 'number' | 'date' | 'datetime' | 'select' | 'checkbox';
30
+ key: infer K extends string;
31
+ } ? K : never) : never;
32
+ /** 並べ替えの key(項目・公開日時・更新日時・id) */
33
+ type OrderKey<T extends ContentType> = SortableKey<T> | 'published_at' | 'updated_at' | 'id';
34
+ /** 絞り込みの指定(項目の key ごと、公開日時・更新日時は範囲) */
35
+ export type ListFilter<T extends ContentType = ContentType> = Readonly<{
36
+ [F in FieldsOf<T> as [FilterValue<F>] extends [never] ? never : F['key']]?: FilterValue<F>;
37
+ } & {
38
+ published_at?: Range<string>;
39
+ updated_at?: Range<string>;
40
+ }>;
41
+ /**
42
+ * 型の一覧の指定
43
+ * - limit: 1ページの件数(サーバーの上限は100)
44
+ * - cursor: 前のページの next
45
+ * - order: 並べ替えの key の配列(`-` の接頭辞で降順、最後に id を自動で追加)
46
+ * - filter: 項目の key ごとの絞り込み(複数の値の項目は値を含む行)
47
+ */
48
+ export type ListQuery<T extends ContentType = ContentType> = Readonly<{
49
+ limit?: number;
50
+ cursor?: string | null;
51
+ order?: readonly (OrderKey<T> | `-${OrderKey<T>}`)[];
52
+ filter?: ListFilter<T>;
53
+ }>;
54
+ /** ページ送りの応答(next は次のページの cursor、最後のページは null) */
55
+ export type Page<I = Item> = Readonly<{
56
+ items: readonly I[];
57
+ next: string | null;
58
+ }>;
59
+ /** どの型の一覧の指定も受け取る形(型の検査は ListQuery の側) */
60
+ type QueryShape = Readonly<{
61
+ limit?: number;
62
+ cursor?: string | null;
63
+ order?: readonly string[];
64
+ filter?: Readonly<Record<string, unknown>>;
65
+ }>;
66
+ /** 一覧の指定をクエリの組に(find・get・subPath の params、一式の path に使用) */
67
+ export declare function listParams(query: QueryShape): Record<string, string>;
68
+ export {};
@@ -0,0 +1,19 @@
1
+ import { type Clock, type ContentModel, type DateString, type FieldDef, type PageEntry } from '../../model/src/index.js';
2
+ /** 選択肢の項目から表示名の表(値 → 表示名、key はまとまりの中なら `links.kind` の形、選択肢の項目でなければ空) */
3
+ export declare const optionLabels: <K extends string = string>(schema: ContentModel, type: string, key: string) => Readonly<Record<K, string>>;
4
+ /** 型の項目(コアの項目と追加の項目から、なければ例外: 導入先の設定の誤り) */
5
+ export declare function fieldOf(schema: ContentModel, type: string, key: string): FieldDef;
6
+ /** 項目の宣言の上限(宣言がなければ例外) */
7
+ export declare function limitOf(field: FieldDef, name: 'maxItems' | 'maxLength'): number;
8
+ /** ページのパス(型の宣言 pages から、ページのない型は例外) */
9
+ export declare function pagePath(schema: ContentModel, type: string, entry: PageEntry): string;
10
+ /** 媒体のタイムゾーンでの日時の変換(表示用の日付と日時の組 dated を含む) */
11
+ export type DeliveryClock = Clock & Readonly<{
12
+ /** 日時の項目から、表示用のタイムゾーンの日付と `ISO 8601` の日時(日時の形でない値はそのまま) */
13
+ dated: (value: string) => Readonly<{
14
+ date: DateString;
15
+ at: string;
16
+ }>;
17
+ }>;
18
+ /** 日時の変換を作成(timeZone は媒体の設定にある IANA の名前) */
19
+ export declare function createDeliveryClock(timeZone: string): DeliveryClock;
@@ -0,0 +1,63 @@
1
+ import type { Body } from '../../body/src/index.js';
2
+ import type { ContentType, Crop, DateString, FieldDef, Hotspot } from '../../model/src/index.js';
3
+ /** 配信 API の1件の値(項目の key と id・updated_at) */
4
+ export type Item = Readonly<Record<string, unknown>>;
5
+ /** 配信 API が解決した実体(hotspot・crop は元の画像に対する割合) */
6
+ export type DeliveredAsset = Readonly<{
7
+ id: string;
8
+ kind: 'image' | 'video';
9
+ width: number;
10
+ height: number;
11
+ alt: string;
12
+ hotspot?: Hotspot;
13
+ crop?: Crop;
14
+ poster?: DeliveredAsset | null;
15
+ }>;
16
+ /** 項目の1つ分の値(複数の値を持つ項目は FieldValue が配列に、query.ts の絞り込みの値と共通) */
17
+ export type SingleValue<F extends FieldDef> = F extends {
18
+ type: 'text' | 'textarea';
19
+ } ? string : F extends {
20
+ type: 'number';
21
+ } ? number : F extends {
22
+ type: 'checkbox';
23
+ } ? boolean : F extends {
24
+ type: 'date';
25
+ } ? DateString : F extends {
26
+ type: 'datetime';
27
+ } ? string : F extends {
28
+ type: 'select';
29
+ options: readonly (infer O extends {
30
+ value: string;
31
+ })[];
32
+ } ? O['value'] : F extends {
33
+ type: 'reference';
34
+ } ? string : F extends {
35
+ type: 'media';
36
+ } ? DeliveredAsset | null : F extends {
37
+ type: 'body';
38
+ } ? Body<DeliveredAsset | null> : F extends {
39
+ type: 'group';
40
+ fields: readonly (infer G extends FieldDef)[];
41
+ } ? GroupValue<G> : unknown;
42
+ /** まとまりの値(中の項目の key ごと) */
43
+ type GroupValue<G extends FieldDef> = {
44
+ readonly [K in G as K['key']]: FieldValue<K>;
45
+ };
46
+ /**
47
+ * 項目の値(種類ごと: 文字は string、日付は YYYY-MM-DD、日時は `ISO 8601` の UTC、参照は参照先の id、メディアは実体、本文は標準のブロック)
48
+ * - multiple の項目: 値の配列
49
+ * - 値なし: null
50
+ */
51
+ export type FieldValue<F extends FieldDef> = (F extends {
52
+ multiple: true;
53
+ } ? readonly SingleValue<F>[] : SingleValue<F>) | null;
54
+ /** 型の項目(コアの項目と追加の項目) */
55
+ export type FieldsOf<T extends ContentType> = (T['core'] extends readonly (infer C extends FieldDef)[] ? C : never) | T['fields'][number];
56
+ /** 型の宣言から導く1件の値(id・更新日時と、項目の key ごとの値) */
57
+ export type ItemOf<T extends ContentType> = Readonly<{
58
+ id: string;
59
+ updated_at: string;
60
+ } & {
61
+ [F in FieldsOf<T> as F['key']]: FieldValue<F>;
62
+ }>;
63
+ export {};
@@ -0,0 +1,89 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * 見せたい点(Sanity の hotspot、値はすべて画像に対する割合の0〜1、左上が0,0)
4
+ * - x・y: 中心(枠に合わせて切り抜くときの中心、なしは中央)
5
+ * - width・height: 範囲の大きさ(今の表示は中心だけを使用)
6
+ * - 切り抜き crop がある画像: CMS で保存する値は元の画像に対する割合、表示の Media では切り抜いた後の画像に対する割合
7
+ */
8
+ export type Hotspot = Readonly<{
9
+ x: number;
10
+ y: number;
11
+ width?: number;
12
+ height?: number;
13
+ }>;
14
+ /** 切り抜き(Sanity の crop、上下左右の各辺から削る量を画像に対する割合の0〜1で) */
15
+ export type Crop = Readonly<{
16
+ top: number;
17
+ bottom: number;
18
+ left: number;
19
+ right: number;
20
+ }>;
21
+ /** サイトのビルドで読み込んだ画像(Astro の ImageMetadata と同じ形、画像の最適化の対象) */
22
+ export type LocalImage = Readonly<{
23
+ src: string;
24
+ width: number;
25
+ height: number;
26
+ format: string;
27
+ }>;
28
+ /** 実体の共通の項目(ID は UUID で R2 のキーと同じ、sha256 は内容のハッシュで同じ画像の重複を防止、ファイル名は保存しない) */
29
+ type AssetBase = Readonly<{
30
+ id: string;
31
+ mimeType: string;
32
+ size: number;
33
+ sha256: string | null;
34
+ width: number;
35
+ height: number;
36
+ alt: string;
37
+ hotspot?: Hotspot;
38
+ crop?: Crop;
39
+ createdAt: string;
40
+ }>;
41
+ /** 画像の実体(Sanity の sanity.imageAsset、代替テキストと hotspot は画像ごとに1つ) */
42
+ export type ImageAsset = AssetBase & Readonly<{
43
+ kind: 'image';
44
+ }>;
45
+ /** 動画の実体(poster は代わりに表示する画像の実体の ID、配信と再生は最初に使用する場所が決まったときに実装) */
46
+ export type VideoAsset = AssetBase & Readonly<{
47
+ kind: 'video';
48
+ duration?: number;
49
+ poster?: string;
50
+ }>;
51
+ /** 実体(CMS のメディアにある1件) */
52
+ export type Asset = ImageAsset | VideoAsset;
53
+ /** 使用する側が保存する実体の参照(Sanity の image の asset、表示のときに実体の寸法・代替テキスト・hotspot を合わせて Media に解決) */
54
+ export type AssetRef = Readonly<{
55
+ asset: string;
56
+ }>;
57
+ /**
58
+ * 表示する素材の共通の項目
59
+ * - src: URL(CMS の実体)か、ビルドで読み込んだ画像
60
+ * - width・height: 元の寸法(表示の比と、読み込み前の場所の確保)
61
+ * - alt: 代替テキスト(飾りの画像は空文字)
62
+ */
63
+ type MediaBase = Readonly<{
64
+ src: string | LocalImage;
65
+ width: number;
66
+ height: number;
67
+ alt: string;
68
+ hotspot?: Hotspot;
69
+ }>;
70
+ /**
71
+ * 表示の素材(使用する側の型で共通、実体の参照 AssetRef を解決した値)
72
+ * - `image`: 画像
73
+ * - `video`: 動画(poster は読み込み前・動きを抑える設定・OG で代わりに表示する画像、再生の仕方は使用する場所で決定)
74
+ */
75
+ export type Media = MediaBase & Readonly<{
76
+ kind: 'image';
77
+ } | {
78
+ kind: 'video';
79
+ poster: MediaBase;
80
+ }>;
81
+ /** 見せたい点の検査 */
82
+ export declare const hotspotSchema: z.ZodType<Hotspot>;
83
+ /** 切り抜きの検査(残る幅と高さが画像の1割以上) */
84
+ export declare const cropSchema: z.ZodType<Crop>;
85
+ /** 解決後の素材の検査(src は URL、ビルドで読み込んだ画像は JSON に含めないため対象外) */
86
+ export declare const mediaSchema: z.ZodType<Media>;
87
+ /** 使用する側が保存する実体の参照の検査 */
88
+ export declare const assetRefSchema: z.ZodType<AssetRef>;
89
+ export {};
@@ -0,0 +1,20 @@
1
+ import type { ContentModel, ContentType } from './model.js';
2
+ /**
3
+ * コアの表の性質
4
+ * - editorial: 編集の機能の列 status・published_at・version・review_note・assignee
5
+ * - derived: 本文から保存時に作成する列 excerpt・read_min・links
6
+ * - sources: 共有の行(出典)を付属の表 article_sources で結び付ける
7
+ * - shared: 共有の行を持つ表(複数の行から結び付ける)
8
+ */
9
+ export type TableTraits = Readonly<{
10
+ editorial: boolean;
11
+ derived: boolean;
12
+ sources: boolean;
13
+ shared: boolean;
14
+ }>;
15
+ /** 表の性質(コアの表にない表はすべてなし) */
16
+ export declare const tableTraitsOf: (table: string | null | undefined) => TableTraits;
17
+ /** 表の性質を持つ型(スキーマの順で先頭、なければ null: コアの表は1つの型だけが保存) */
18
+ export declare const typeWithTrait: (model: ContentModel, trait: keyof TableTraits) => ContentType | null;
19
+ /** 表の性質を持つ型(なければ例外: その型を前提にする画面・処理だけが使用) */
20
+ export declare function requiredTypeWithTrait(model: ContentModel, trait: keyof TableTraits): ContentType;
@@ -0,0 +1,23 @@
1
+ import type { ContentModel } from './model.js';
2
+ /** 変更の扱い */
3
+ export type ChangeLevel = 'safe' | 'confirm' | 'forbidden';
4
+ /** 変更の種類 */
5
+ export type ChangeKind = 'type-added' | 'type-removed' | 'type-changed' | 'format-changed' | 'publishing-changed' | 'publishing-removed' | 'fixed-changed' | 'field-added' | 'field-removed' | 'field-changed' | 'field-type-changed' | 'field-key-reused' | 'required-added' | 'constraint-tightened' | 'option-added' | 'option-removed' | 'component-added' | 'component-changed' | 'component-removed';
6
+ /** スキーマの1つの変更(id は確認と置き換え先の指定で使用する識別子、path は項目の key を `.` で連結、value は削除した選択肢の値) */
7
+ export type SchemaChange = Readonly<{
8
+ id: string;
9
+ level: ChangeLevel;
10
+ kind: ChangeKind;
11
+ type: string;
12
+ path?: string;
13
+ value?: string;
14
+ message: string;
15
+ }>;
16
+ /** 差分の条件(fixed はコードで固定の定義、history は保存済みの版より古い過去の版) */
17
+ export type DiffOptions = Readonly<{
18
+ fixed?: ContentModel;
19
+ history?: readonly ContentModel[];
20
+ }>;
21
+ /** 保存済みの版 prev から新しい定義 next への変更(型の順、項目の順) */
22
+ export declare function diffSchema(prev: ContentModel, next: ContentModel, options?: DiffOptions): SchemaChange[];
23
+ export declare function withFixed(fixed: ContentModel, stored: ContentModel): ContentModel;
@@ -0,0 +1,10 @@
1
+ import type { DeclaredComponent } from '../../body/src/index.js';
2
+ import type { ContentType, FieldDef, FieldProblem } from './model.js';
3
+ /** 項目が値の組に当てはまるか(条件なしは常に当てはまる、values は同じ階層の値) */
4
+ export declare const appliesTo: (field: FieldDef, values: Readonly<Record<string, unknown>>) => boolean;
5
+ /** 値の組に当てはまる項目だけ */
6
+ export declare const fieldsFor: <F extends FieldDef>(fields: readonly F[], values: Readonly<Record<string, unknown>>) => F[];
7
+ /** 値を型の定義で検査(stage は保存か提出、提出は保存の必須も含む、まとまりの中は path を key・行の番号で連結、components はスキーマで宣言した本文の部品) */
8
+ export declare const checkFields: (type: ContentType, values: Readonly<Record<string, unknown>>, stage: "save" | "submit", components?: readonly DeclaredComponent[]) => FieldProblem[];
9
+ /** 配列でないオブジェクトか */
10
+ export declare const isRecord: (v: unknown) => v is Readonly<Record<string, unknown>>;
@@ -0,0 +1,38 @@
1
+ import type { Crop, Hotspot, Media } from './asset.js';
2
+ /** 静止画として表示する画像(動画は代わりの画像 poster) */
3
+ export declare const stillOf: (media: Media) => Readonly<{
4
+ src: string | import("./asset.js").LocalImage;
5
+ width: number;
6
+ height: number;
7
+ alt: string;
8
+ hotspot?: Hotspot;
9
+ }>;
10
+ /** 見せたい点を CSS の object-position に(なしは undefined で中央、枠の比が分からない表示の代わり) */
11
+ export declare const objectPosition: (hotspot?: Hotspot) => string | undefined;
12
+ /**
13
+ * 枠を覆う表示で、枠に見える範囲(窓)の始まりの位置: 1次元、画像に対する割合で0〜1 - window
14
+ * - 見せたい範囲の中心を窓の中央に寄せ、画像の端を越えるときは端と同じ位置
15
+ * - 範囲が窓に収まる大きさなら、この位置で範囲は必ず窓に入る(範囲が窓より大きいときは範囲の中央を表示)
16
+ * - center なしは中央、CMS のプレビュー(apps/admin の crop.ts)とサイトの表示で共通
17
+ */
18
+ export declare function coverStart(center: number | undefined, window: number): number;
19
+ /**
20
+ * 枠を覆う表示(object-fit: cover)の object-position: 見せたい範囲が枠に入る位置
21
+ * - size: 画像の幅と高さ、frame: 枠の幅 / 高さ(なしは見せたい点の百分率で代用)
22
+ * - 帯や余白はなし、枠いっぱいに画像を敷いたまま位置だけを合わせる
23
+ */
24
+ export declare function coverPosition(hotspot: Hotspot | undefined, size: Readonly<{
25
+ width: number;
26
+ height: number;
27
+ }>, frame?: number): string | undefined;
28
+ /** 切り抜いた範囲(元の画像の画素、左上と大きさ、1画素以上) */
29
+ export type CropRect = Readonly<{
30
+ left: number;
31
+ top: number;
32
+ width: number;
33
+ height: number;
34
+ }>;
35
+ /** 切り抜きの割合から、元画像での画素の範囲 */
36
+ export declare function cropRect(width: number, height: number, crop: Crop): CropRect;
37
+ /** 元の画像に対する見せたい点を、切り抜いた後の画像に対する割合に変換(範囲の外は端に寄せる) */
38
+ export declare function croppedHotspot(hotspot: Hotspot, crop: Crop): Hotspot;
@@ -0,0 +1,14 @@
1
+ export { fieldZod, jsonSchemaOf, normalizeValues, zodOf, type ValueOptions } from './input.js';
2
+ export { assetRefSchema, cropSchema, hotspotSchema, mediaSchema, type Asset, type AssetRef, type Crop, type Hotspot, type LocalImage, type Media } from './asset.js';
3
+ export { coverPosition, coverStart, cropRect, croppedHotspot, objectPosition, stillOf, type CropRect } from './image.js';
4
+ export { IMAGE_TYPE, VIDEO_TYPE } from './media.js';
5
+ export { diffSchema, withFixed, type ChangeKind, type ChangeLevel, type DiffOptions, type SchemaChange } from './changes.js';
6
+ export { requiredTypeWithTrait, tableTraitsOf, typeWithTrait, type TableTraits } from './capabilities.js';
7
+ export { appliesTo, checkFields, fieldsFor } from './check.js';
8
+ export { deliveredFields, emptyValues, pickValues, referencedIds, referencesOf, valueFieldsOf } from './values.js';
9
+ export { imageFieldOf, initialValueOf, isEditorial, isEntryType, isListType, isSingleton, optionLabelOf, optionsOf, publishingOf, requestReferencesOf, tableOf, titleFieldOf, toneOf, typeOf, type ContentFormat, type ContentModel, type ContentType, type FieldCondition, type FieldDef, type FieldDerive, type FieldFixedBy, type CountDef, type FieldProblem, type MediaKind, type OptionTone, type Publishing, type ReferenceRules, type SelectOption } from './model.js';
10
+ export { hasPublicPage, imageFrameOf, pagePathOf, publicPathOf, type ImageFrame, type ImageFrameDef, type PageDef, type PageEntry, type PageRule } from './page.js';
11
+ export { schemaRulesOf, type SchemaRule } from './rules.js';
12
+ export { parseModel } from './schema.js';
13
+ export { menuItemsOf, parseScreens, placedItemsOf, resolveLayout, resolveMenu, typeItem, typeOfItem, viewItem, viewOfItem, type EditorLayout, type EditorSection, type MenuEntry, type MenuGroup, type ResolvedMenuEntry, type ScreenSettings } from './screens.js';
14
+ export { createClock, isDateOnly, isDateTimeText, type Clock, type DateString } from './time.js';
@@ -0,0 +1,26 @@
1
+ import { type DeclaredComponent } from '../../body/src/index.js';
2
+ import { z } from 'zod';
3
+ import type { FieldDef } from './model.js';
4
+ /** 検査の時点(保存か提出、提出は保存の必須も含む) */
5
+ type Stage = 'save' | 'submit';
6
+ /** 値の検査の設定(toDateTime は日時の変換で、媒体のタイムゾーンを持つ側が指定、components はスキーマで宣言した本文の部品) */
7
+ export type ValueOptions = Readonly<{
8
+ toDateTime?: (value: string) => string | null;
9
+ components?: readonly DeclaredComponent[];
10
+ }>;
11
+ /** MCP のツールで入力する1項目の JSON Schema */
12
+ type JsonSchema = Readonly<Record<string, unknown>>;
13
+ /** 1項目の定義から入力の検査を作成(stage が save なら提出の必須は任意、options は日時の変換) */
14
+ export declare function fieldZod(field: FieldDef, stage: Stage, options?: ValueOptions): z.ZodType;
15
+ /** 項目の一覧から入力の検査を作成(key ごとに fieldZod を持つ object) */
16
+ export declare const zodOf: (fields: readonly FieldDef[], stage: Stage, options?: ValueOptions) => z.ZodObject<Record<string, z.ZodType>>;
17
+ /**
18
+ * 値を保存の形に整形(すべての格納先で共通、まとまりの中も)
19
+ * - 日時: `ISO 8601` の UTC(options の toDateTime)、本文: 注の記法の変換と未知のキーの除去、メディア: { asset } だけ
20
+ * - 形の誤りのある値: そのまま(checkFields が検出)
21
+ * - 定義にないキー・項目を定義しないまとまり: そのまま
22
+ */
23
+ export declare function normalizeValues(fields: readonly FieldDef[], values: Readonly<Record<string, unknown>>, options: ValueOptions): Record<string, unknown>;
24
+ /** 項目の定義から MCP のツールで入力する JSON Schema を作成(説明は表示名・説明・必須の時点、参照は ID の文字列) */
25
+ export declare function jsonSchemaOf(field: FieldDef): JsonSchema;
26
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { ContentType } from './model.js';
2
+ /** 画像の型 */
3
+ export declare const IMAGE_TYPE: ContentType;
4
+ /** 動画の型(配信と再生は最初に使用する場所が決まったときに実装) */
5
+ export declare const VIDEO_TYPE: ContentType;