UNPKG

kintone-effect-schema

Version:

Type-safe kintone field schema definitions with Effect-TS. Normalize empty values, validate writes, and ensure runtime type safety for kintone API responses.

99 lines (85 loc) 2.98 kB
import { Schema } from 'effect' import { KintoneFieldSchema } from './schemas/fields.js' import type { KintoneFieldType } from './types/kintone.js' /** * フィールドタイプごとの空値正規化ルール * kintoneのAPIは取得時と更新時で空値の扱いが異なるため、 * 一貫性のある形に正規化する */ export const normalizeFieldValue = (field: unknown): unknown => { if (!field || typeof field !== 'object') { return field } const fieldObj = field as Record<string, unknown> const type = fieldObj['type'] as KintoneFieldType const value = fieldObj['value'] switch (type) { // 文字列系: undefined → "" case 'SINGLE_LINE_TEXT': case 'MULTI_LINE_TEXT': case 'LINK': case 'LOOKUP': return { ...fieldObj, value: value === undefined ? '' : value } // リッチテキスト: 変換不要 case 'RICH_TEXT': return fieldObj // 数値・日時系: undefined/"" → null case 'NUMBER': case 'DATETIME': return { ...fieldObj, value: (value === undefined || value === '') ? null : value } // 日付・時刻: undefined → null case 'DATE': case 'TIME': return { ...fieldObj, value: value === undefined ? null : value } // ドロップダウン: undefined/"" → null case 'DROP_DOWN': return { ...fieldObj, value: (value === undefined || value === '') ? null : value } // ラジオボタン: undefined/"" → null case 'RADIO_BUTTON': return { ...fieldObj, value: (value === undefined || value === '') ? null : value } // 配列系: undefined/null → [] case 'CHECK_BOX': case 'MULTI_SELECT': case 'USER_SELECT': case 'ORGANIZATION_SELECT': case 'GROUP_SELECT': case 'FILE': case 'CATEGORY': case 'STATUS_ASSIGNEE': return { ...fieldObj, value: value === undefined || value === null ? [] : value } // その他のフィールド(CALC, STATUS, CREATOR等): 変換不要 default: return fieldObj } } /** * kintoneフィールドをデコードし、空値を正規化する */ export const decodeKintoneField = (data: unknown): unknown => { const normalized = normalizeFieldValue(data) return Schema.decodeUnknownSync(KintoneFieldSchema)(normalized) } /** * kintoneレコード全体をデコードし、各フィールドの空値を正規化する */ export const decodeKintoneRecord = (record: Record<string, unknown>): Record<string, unknown> => { const normalizedRecord: Record<string, unknown> = {} for (const [fieldCode, field] of Object.entries(record)) { // SubtableやRecordの場合は再帰的に処理が必要だが、 // ここでは単純化のため基本フィールドのみ対応 normalizedRecord[fieldCode] = normalizeFieldValue(field) } return normalizedRecord }