graphql-request
Version:
Minimal GraphQL client supporting Node and browsers for scripts or simple apps.
53 lines (51 loc) • 2.8 kB
text/typescript
export namespace Code {
export const propertyAccess = (object: string, name: string) => `${object}.${name}`
export const quote = (str: string) => `"${str}"`
export const nullable = (type: string) => `${type} | null`
export const union = (name: string, types: string[]) => `type ${name} =\n| ${Code.unionItems(types)}`
export const unionItems = (types: string[]) => types.join(`\n| `)
export const tuple = (types: string[]) => `[${types.join(`, `)}]`
export const list = (type: string) => `Array<${type}>`
export const field = (name: string, type: string, options?: { optional?: boolean }) => {
if (options?.optional) return `${name}?: ${type}`
return `${name}: ${type}`
}
export const optionalField = (name: string, type: string) => Code.field(name, type, { optional: true })
export const fields = (fieldTypes: string[]) => fieldTypes.join(`\n`)
export const intersection = (a: string, b: string) => `${a} & ${b}`
export const object = (fields: string) => `{\n${fields}\n}`
export const objectFromEntries = (entries: [string, string][]) =>
Code.objectFrom(Object.fromEntries(entries.map(([name, type]) => [name, { type }])))
export const objectFrom = (
object: Record<
string,
null | string | boolean | number | { type: null | string | boolean | number; optional?: boolean; tsdoc?: string }
>,
) => {
return Code.object(
Code.fields(
Object.entries(object).map(([name, spec]) =>
[name, spec && typeof spec === `object` ? spec : { type: spec }] as const
)
.map((
[name, spec],
) => Code.field(name, String(spec.type), { optional: spec.optional })),
),
)
}
export const type = (name: string, type: string) => `type ${name} = ${type}`
export const interface$ = (name: string, object: string) => `interface ${name} ${object}`
export const export$ = (thing: string) => `export ${thing}`
export const TSDoc = (content: string | null, block: string) =>
content === null ? block : `/**\n${prependLines(`* `, content) || `*`}\n*/\n${block}`
export const namespace = (name: string, content: string) => `namespace ${name} ${Code.object(content)}`
export const group = (...content: string[]) => content.join(`\n`)
export const commentSectionTitle = (title: string) => {
const lineSize = 60
const line = `-`.repeat(lineSize)
const titlePrefixSpace = ` `.repeat(Math.round(lineSize / 2) - Math.round(title.length / 2))
const titleSuffixSpace = ` `.repeat(lineSize - (titlePrefixSpace.length + title.length))
return `\n\n// ${line} //\n// ${titlePrefixSpace + title + titleSuffixSpace} //\n// ${line} //\n\n`
}
}
const prependLines = (prepend: string, str: string) => str.split(`\n`).map((line) => `${prepend}${line}`).join(`\n`)