UNPKG

@7nohe/openapi-react-query-codegen

Version:
138 lines (137 loc) 4.56 kB
import { stat } from "node:fs/promises"; import path from "node:path"; import ts from "typescript"; import { queriesOutputPath, requestsOutputPath } from "./constants.mjs"; export const TData = ts.factory.createIdentifier("TData"); export const TError = ts.factory.createIdentifier("TError"); export const TContext = ts.factory.createIdentifier("TContext"); export const EqualsOrGreaterThanToken = ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken); export const QuestionToken = ts.factory.createToken(ts.SyntaxKind.QuestionToken); export const queryKeyGenericType = ts.factory.createTypeReferenceNode("TQueryKey"); export const queryKeyConstraint = ts.factory.createTypeReferenceNode("Array", [ ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword), ]); export const capitalizeFirstLetter = (str) => { return str.charAt(0).toUpperCase() + str.slice(1); }; export const lowercaseFirstLetter = (str) => { return str.charAt(0).toLowerCase() + str.slice(1); }; export const getNameFromMethod = (method) => { const methodName = method.getName(); if (!methodName) { throw new Error("Method name not found"); } return methodName; }; export async function exists(f) { try { await stat(f); return true; } catch { return false; } } const Common = "Common"; /** * Build a common type name by prepending the Common namespace. */ export function BuildCommonTypeName(name) { if (typeof name === "string") { return ts.factory.createIdentifier(`${Common}.${name}`); } return ts.factory.createIdentifier(`${Common}.${name.text}`); } /** * Safely parse a value into a number. Checks for NaN and Infinity. * Returns NaN if the string is not a valid number. * @param value The value to parse. * @returns The parsed number or NaN if the value is not a valid number. */ export function safeParseNumber(value) { const parsed = Number(value); if (!Number.isNaN(parsed) && Number.isFinite(parsed)) { return parsed; } return Number.NaN; } export function extractPropertiesFromObjectParam(param) { const referenced = param.findReferences()[0]; const def = referenced.getDefinition(); const paramNodes = def .getNode() .getType() .getProperties() .map((prop) => ({ name: prop.getName(), optional: prop.isOptional(), type: prop.getValueDeclaration()?.getType(), })); return paramNodes; } /** * Replace the import("...") surrounding the type if there is one. * This can happen when the type is imported from another file, but * we are already importing all the types from that file. * * https://regex101.com/r/3DyHaQ/1 * * TODO: Replace with a more robust solution. */ export function getShortType(type) { return type.replaceAll(/import\(".*?"\)\./g, ""); } export function getClassesFromService(node) { const klasses = node.getClasses(); if (!klasses.length) { throw new Error("No classes found"); } return klasses.map((klass) => { const className = klass.getName(); if (!className) { throw new Error("Class name not found"); } return { className, klass, }; }); } export function getClassNameFromClassNode(klass) { const className = klass.getName(); if (!className) { throw new Error("Class name not found"); } return className; } export function formatOptions(options) { // loop through properties on the options object // if the property is a string of number then convert it to a number // if the property is a string of boolean then convert it to a boolean const formattedOptions = Object.entries(options).reduce((acc, [key, value]) => { const typedKey = key; const typedValue = value; const parsedNumber = safeParseNumber(typedValue); if (value === "true" || value === true) { acc[typedKey] = true; } else if (value === "false" || value === false) { acc[typedKey] = false; } else if (!Number.isNaN(parsedNumber)) { acc[typedKey] = parsedNumber; } else { acc[typedKey] = typedValue; } return acc; }, options); return formattedOptions; } export function buildRequestsOutputPath(outputPath) { return path.join(outputPath, requestsOutputPath); } export function buildQueriesOutputPath(outputPath) { return path.join(outputPath, queriesOutputPath); }