fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 81 lines 2.0 kB view raw
1import type { FromRef, FromRefs, Ref, Refs } from './types'; 2 3/** 4 * Wraps a single value in a Ref object. 5 * 6 * If the value is already a Ref, returns it as-is (idempotent). 7 * 8 * @example 9 * ```ts 10 * const r = ref(123); // { '~ref': 123 } 11 * console.log(r['~ref']); // 123 12 * 13 * const r2 = ref(r); // { '~ref': 123 } (not double-wrapped) 14 * ``` 15 */ 16export const ref = <T>(value: T): Ref<T> => { 17 if (isRef(value)) { 18 return value as Ref<T>; 19 } 20 return { '~ref': value } as Ref<T>; 21}; 22 23/** 24 * Converts a plain object to an object of Refs (deep, per property). 25 * 26 * @example 27 * ```ts 28 * const obj = { a: 1, b: "x" }; 29 * const refs = refs(obj); // { a: { '~ref': 1 }, b: { '~ref': "x" } } 30 * ``` 31 */ 32export const refs = <T extends Record<string, unknown>>(obj: T): Refs<T> => { 33 const result = {} as Refs<T>; 34 for (const key in obj) { 35 if (Object.prototype.hasOwnProperty.call(obj, key)) { 36 result[key] = ref(obj[key]); 37 } 38 } 39 return result; 40}; 41 42/** 43 * Unwraps a single Ref object to its value. 44 * 45 * @example 46 * ```ts 47 * const r = { '~ref': 42 }; 48 * const n = fromRef(r); // 42 49 * console.log(n); // 42 50 * ``` 51 */ 52export const fromRef = <T extends Ref<unknown> | undefined>(ref: T): FromRef<T> => 53 ref?.['~ref'] as FromRef<T>; 54 55/** 56 * Converts an object of Refs back to a plain object (unwraps all refs). 57 * 58 * @example 59 * ```ts 60 * const refs = { a: { '~ref': 1 }, b: { '~ref': "x" } }; 61 * const plain = fromRefs(refs); // { a: 1, b: "x" } 62 * ``` 63 */ 64export const fromRefs = <T extends Refs<Record<string, unknown>>>(obj: T): FromRefs<T> => { 65 const result = {} as FromRefs<T>; 66 for (const key in obj) { 67 if (Object.prototype.hasOwnProperty.call(obj, key)) { 68 result[key] = fromRef(obj[key]!) as (typeof result)[typeof key]; 69 } 70 } 71 return result; 72}; 73 74/** 75 * Checks whether a value is a Ref object. 76 * 77 * @param value Value to check 78 * @returns True if the value is a Ref object. 79 */ 80export const isRef = <T>(value: unknown): value is Ref<T> => 81 typeof value === 'object' && value !== null && '~ref' in value;