From d16e8a00afc43f7365acc9e3f9d62d627bba3153 Mon Sep 17 00:00:00 2001 From: David Enke Date: Tue, 12 Nov 2024 16:14:49 +0100 Subject: [PATCH] chore: externalize transform utils --- src/transformers/field.transform.ts | 32 +++++++------------ src/utils/transform.utils.ts | 48 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/transformers/field.transform.ts b/src/transformers/field.transform.ts index 523120c..23e2536 100644 --- a/src/transformers/field.transform.ts +++ b/src/transformers/field.transform.ts @@ -2,7 +2,13 @@ import type * as Decap from 'decap-cms-core'; import type * as Zod from 'zod'; import type { DecapWidgetType } from '../utils/decap.utils.js'; -import type { Transformer, TransformResult } from '../utils/transform.utils.js'; +import { + applyDefaultValue, + applyDescription, + applyOptional, + type Transformer, + type TransformResult, +} from '../utils/transform.utils.js'; import { transformBooleanField } from './field-boolean.transform.js'; import { transformCodeField } from './field-code.transform.js'; import { transformDateTimeField } from './field-date-time.transform.js'; @@ -88,26 +94,10 @@ export const transformField: Transformer = (field, z) => { break; } - // flag field as optional - it should be explicitly `optional()` or `nullable()`, - // but for me it's not quite clear right now what is specified on the Decap side - // fyi: https://gist.github.com/ciiqr/ee19e9ff3bb603f8c42b00f5ad8c551e - if (field.required === false) { - runtime = runtime.nullish(); - cptime = `${cptime}.nullish()`; - } - - // set a default value - const { default: def } = field as { default?: any }; - // cannot set null as default value on mandatory fields - if (def !== undefined || (def === null && !field.required)) { - runtime = runtime.default(def); - cptime = `${cptime}.default(${JSON.stringify(def)})`; - } - - // add a description - const description = field.hint ?? field.label ?? field.name; - runtime = runtime.describe(description); - cptime = `${cptime}.describe('${description}')`; + // flag field as optional, set a default value and add a description if available + ({ cptime, runtime } = applyOptional(field, { cptime, runtime })); + ({ cptime, runtime } = applyDefaultValue(field, { cptime, runtime })); + ({ cptime, runtime } = applyDescription(field, { cptime, runtime })); return { runtime, cptime }; }; diff --git a/src/utils/transform.utils.ts b/src/utils/transform.utils.ts index c61119a..c22c4f7 100644 --- a/src/utils/transform.utils.ts +++ b/src/utils/transform.utils.ts @@ -28,6 +28,54 @@ export type TransformResult = { cptime: string; }; +/** + * Flags a field as optional if it is not required. + */ +export function applyOptional(field: Decap.CmsField, result: TransformResult): TransformResult { + // it should be explicitly `optional()` or `nullable()`, + // but for me it's not quite clear right now what is specified on the Decap side + // fyi: https://gist.github.com/ciiqr/ee19e9ff3bb603f8c42b00f5ad8c551e + if (field.required === false) { + return { + runtime: result.runtime.nullish(), + cptime: `${result.cptime}.nullish()`, + }; + } + return result; +} + +/** + * Sets a default value if reasonable. + */ +export function applyDefaultValue(field: Decap.CmsField, result: TransformResult): TransformResult { + const { default: def } = field as { default?: any }; + // cannot set null as default value on mandatory fields + if (def === undefined || (def === null && field.required)) { + return result; + } + + // set default value + return { + runtime: result.runtime.default(def), + cptime: `${result.cptime}.default(${JSON.stringify(def)})`, + }; +} + +/** + * Derives and sets a description if available. + */ +export function applyDescription(field: Decap.CmsField, result: TransformResult): TransformResult { + // derive potential description + const description = field.hint ?? field.label ?? field.name; + if (description === undefined) return result; + + // set a description + return { + runtime: result.runtime.describe(description), + cptime: `${result.cptime}.describe('${description}')`, + }; +} + /** * Transforms a Decap CMS collection config into an Astro collection schema. */