Skip to content

Commit

Permalink
chore: externalize transform utils
Browse files Browse the repository at this point in the history
  • Loading branch information
davidenke committed Nov 12, 2024
1 parent b294d75 commit d16e8a0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 21 deletions.
32 changes: 11 additions & 21 deletions src/transformers/field.transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 };
};
48 changes: 48 additions & 0 deletions src/utils/transform.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,54 @@ export type TransformResult<R = Zod.ZodType> = {
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.
*/
Expand Down

0 comments on commit d16e8a0

Please sign in to comment.