import fs from "fs" ; import { CampaignServiceClient } from "google-ads-node" ; import { toCamelCase , capitaliseFirstLetter } from "../src/utils" ; import { FILES } from "./path" ; export interface PathTemplate { path : string ; bindings : { [ index ] : string | number ; } ; data : string ; } export interface Parts { resource : string ; typeName : string ; functionName : string ; arguments : string ; returnType : string ; returnValue : string ; } export interface Comments { params : string ; return : string ; example : string ; } interface Bindings { arguments : string [ ] ; params : string [ ] ; exampleArgs : string [ ] ; } export interface Text { comment : string ; type : string ; functionComments : string ; function : string ; } export function generateTextParts ( pathTemplate ) { const resource = pathTemplate . path . replace ( /PathTemplate/g , "" ) ; const parts = { resource : capitaliseFirstLetter ( resource ) , typeName : capitaliseFirstLetter ( `${ resource }ResourceName` ) , functionName : resource , arguments : "" , returnType : pathTemplate . data , returnValue : pathTemplate . data , } ; const comments = { params : "" , return : `\n* @returns \`${ parts . typeName }\`\n` , example : `* @example const ${ resource }: ResourceNames.${ parts . typeName } = ResourceNames.${ parts . functionName }(` , } ; const bindings = { arguments : [ ] , params : [ ] , exampleArgs : [ ] } ; let exampleId = 10987417 ; Object . keys ( pathTemplate . bindings ) . forEach ( ( snakeArg ) => { const camelArg = toCamelCase ( snakeArg ) ; const re = new RegExp ( `{${ snakeArg }}` , "g" ) ; parts . returnType = parts . returnType . replace ( re , `\${StrNum}` ) ; parts . returnValue = parts . returnValue . replace ( re , `\${${ camelArg }}` ) ; bindings . arguments . push ( `${ camelArg }: string | number` ) ; bindings . params . push ( `* @param {string | number} ${ camelArg }` ) ; bindings . exampleArgs . push ( `${ exampleId }` ) ; exampleId = exampleId * 2 ; } ) ; parts . arguments = bindings . arguments . join ( `, ` ) ; comments . params = bindings . params . join ( `\n` ) ; comments . example = comments . example . concat ( `${ bindings . exampleArgs . join ( `, ` ) })\n` ) ; return { parts , comments } ; } export function generateText ( parts , comments ) { return { comment : `/* ${ parts . resource } */\n` , type : `export type ${ parts . typeName } = \`${ parts . returnType }\`\n` , functionComments : `/**\n${ comments . params }${ comments . return }${ comments . example }*/\n` , function : `export function ${ parts . functionName }(${ parts . arguments }): ${ parts . typeName } { return \`${ parts . returnValue }\` as const }\n\n` , } ; } function buildResourceNameBuilder ( stream , text ) { stream . write ( text . comment ) ; stream . write ( text . type ) ; stream . write ( text . functionComments ) ; stream . write ( text . function ) ; } export async function compileResourceNameFunctions ( ) { const service = new CampaignServiceClient ( ) ; const pathTemplatesRaw = service . pathTemplates ; const pathTemplates = Object . entries ( pathTemplatesRaw ) . map ( ( [ path , template ] ) => { return { path , ... template } ; } ) ; const stream = fs . createWriteStream ( FILES . resourceNames ) ; stream . write ( `/* Autogenerated File! Do Not Edit */\n\n` ) ; stream . write ( `type StrNum = string | number\n\n` ) ; pathTemplates . forEach ( ( pathTemplate ) => { const { parts , comments } = generateTextParts ( pathTemplate ) ; const text = generateText ( parts , comments ) ; buildResourceNameBuilder ( stream , text ) ; } ) ; }