-
-
Notifications
You must be signed in to change notification settings - Fork 391
parseKey is not a function #1146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Labels
bug
Something isn't working
Comments
Are you using a custom template? |
Yes, that's how I call it generateApi({
name: file.name,
input: path.resolve(file.path),
output: path.resolve(process.cwd(), getPath(file.name)),
modular: true,
silent: true,
templates: path.resolve(process.cwd(), './templates'),
unwrapResponseData: true,
cleanOutput: true,
codeGenConstructs: constructs => {
return {
...constructs,
Keyword: {
...constructs.Keyword,
File: 'Record<string, any>',
csv: 'string',
},
}
},
hooks: {
onCreateRoute: routeData => {
if (
routeData.request.method === 'get' &&
'payload' in routeData.request &&
routeData.request.payload
) {
console.warn(
`Removing endpoint: ${routeData.raw.route} | Reason: GET endpoint with body is not supported by fetch`
)
return false
}
return routeData
},
onFormatTypeName: typeName => {
if (typeName === 'Record') {
return 'RecordType'
}
},
},
}) The templates are api.ejs <%
const { utils, route, config, modelTypes } = it;
const { _, pascalCase, require } = utils;
const apiClassName = pascalCase(route.moduleName);
const routes = route.routes;
const dataContracts = _.map(modelTypes, "name");
%>
import { HttpClient, FullRequestParams, RequestParams, ContentType, HttpResponse, QueryParamsType } from "./<%~ config.fileNames.httpClient %>";
<% if (dataContracts.length) { %>
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"
<% } %>
export class <%= apiClassName %><SecurityDataType = unknown> {
// See templates/api.ejs we need this in order to send as parameter to request call
serviceName = "<%~ config.fileName %>"
/**
* @deprecated Internal use only.
*/
httpClient: HttpClient<SecurityDataType>
constructor(config?: ConstructorParameters<typeof HttpClient<SecurityDataType>>[0]) {
this.httpClient = new HttpClient(config)
}
/**
* @deprecated Internal use only.
* See src/http-client we need this so we can send service name to http-client so it knows
* which service is calling it
*/
request = <T = any, E = any>(params: FullRequestParams): Promise<T> => {
return this.httpClient.clientRequest<T, E>({ ...params, serviceName: this.serviceName})
}
/**
* @deprecated Internal use only.
* See src/http-client we need this so we can send service name to http-client so it knows
* which service is calling it
*/
getServicePath = <Q extends QueryParamsType>(path: string, query?: Q): string => {
const servicePath = this.httpClient.clientGetPath({ path, serviceName: this.serviceName });
if (!query) return servicePath;
const queryParams = this.httpClient.encodeQueryParams(query);
return `${servicePath}?${queryParams}`;
};
<% routes.forEach((route) => { %>
<%~ includeFile('./procedure-call.ejs', { ...it, route }) %>
<%~ includeFile('./procedure-call-path.ejs', { ...it, route }) %>
<% }) %>
} data-contracts.ejs <%
const { modelTypes, utils, config } = it;
const { formatDescription, require, _, Ts } = utils;
const camelCase = require('camelcase')
const parseKey = require('../utils/parseEnumKeys.cjs')
// Replaces enums with typescript map + union type
const enumTemplate = (contract) => {
return `
export const ${contract.name} = {
${contract.$content.map(content => `
/**
* @deprecated Discriminator consts are deprecated. Please use raw string instead
*/
${content.key}: ${content.value}`).join(',\n ')}
} as const
export type ${contract.name} = ${contract.$content.map(content => content.value).join(' | ')};\n\n`;
}
const interfaceTemplate = (contract) => {
// x-discriminator values comes from injectDiscriminatorConstant
// defined under plugins/plugins.js
if (contract['x-discriminator-parent']) {
const discriminatedInterface = contract['x-discriminator-parent']
const discriminatorProperty = contract['x-discriminator-property']
const discriminatorValue = contract['x-discriminator-value']
const discriminatorName = `${discriminatedInterface}Discriminator`
const discriminatorKey = parseKey(discriminatorValue)
const discriminatorAccess = `${camelCase(discriminatorName, {pascalCase: true, preserveConsecutiveUppercase: true})}.${discriminatorKey}`
const oldDiscriminatorPiece = `${discriminatorProperty}: "${discriminatorValue}"`
const newDiscriminatorPiece = `/** @see {@link ${discriminatorAccess}} */
${discriminatorProperty}: typeof ${discriminatorAccess}\n\n`
// Replaces string with discriminator enum usage and add @see tsdoc
const newContent = contract.content.replace(
oldDiscriminatorPiece,
newDiscriminatorPiece
)
return `/** @see {@link ${discriminatorAccess}} */
export interface ${contract.name} {\r\n${newContent}};\n\n`;
}
return `export interface ${contract.name} {\r\n${contract.content}};\n\n`;
}
const typeTemplate = (contract) => {
if (contract.discriminator) {
const discriminatorName = `${contract.name}Discriminator`
const content = Object.keys(contract.discriminator.mapping)
.map(mapping => ({ key: parseKey(mapping), value: `'${mapping}'` }))
// For each union schema containing a discriminator, creates the discriminator enum
return `${dataContractTemplates.enum({ name: discriminatorName, $content: content })}
/** @see {@link ${discriminatorName}} */
export type ${contract.name} = ${contract.content};\n\n`;
}
return `export type ${contract.name} = ${contract.content};\n\n`;
}
const dataContractTemplates = {
enum: enumTemplate,
interface: interfaceTemplate,
type: typeTemplate,
}
%>
<% if (config.internalTemplateOptions.addUtilRequiredKeysType) { %>
type <%~ config.Ts.CodeGenKeyword.UtilRequiredKeys %><T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>
<% } %>
<% modelTypes.forEach((contract) => { %>
<%~ includeFile('@base/data-contract-jsdoc.ejs', { ...it, data: { ...contract, ...contract.typeData } }) %>
<%~ (dataContractTemplates[contract.typeIdentifier] || dataContractTemplates.type)(contract) %>
<% }) %> procedure-call-path.ejs <%
const { utils, route, config } = it;
const { specificArgNameResolver } = route;
const { _, getInlineParseContent } = utils;
const { parameters, path, query, requestParams } = route.request;
const { type } = route.response;
const { RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants;
const queryName = (query && query.name) || "query";
const pathParams = _.values(parameters);
const pathParamsNames = _.map(pathParams, "name");
const requestConfigParam = {
name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),
optional: true,
type: "RequestParams",
defaultValue: "{}",
}
const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue && optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`;
const rawWrapperArgs = _
.compact([
...pathParams,
query,
])
const wrapperArgs = _
// Sort by optionality
.sortBy(rawWrapperArgs, [o => o.optional])
.map(argToTmpl)
.join(', ')
let getServicePathArgs = `\`${path}\``
if (query) {
getServicePathArgs = `${getServicePathArgs}, query`
}
%>
/**
* @description Returns string containing request path for <%~ route.routeName.usage %>
*/
<%~ route.routeName.usage %>PathGetter = (<%~ wrapperArgs %>) => this.getServicePath(<%~ getServicePathArgs %>)
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After updating from 13.0.3 to 13.0.28 I'm getting this error when running
generateApi
fromswagger-typescript-api
The text was updated successfully, but these errors were encountered: