Skip to content

Commit

Permalink
wip - config introduction
Browse files Browse the repository at this point in the history
  • Loading branch information
mironbalcerzak committed Nov 24, 2024
1 parent 71e74f6 commit 91101bf
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 10 deletions.
1 change: 1 addition & 0 deletions packages/core/src/generators/component-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const generateComponentDefinition = (
if (modelName !== type) {
acc.push({
name: modelName,
factoryMethod: '',
model,
imports,
});
Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/generators/imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
GeneratorMutator,
GeneratorVerbOptions,
GetterPropType,
OutputModelFactoryMethodsMode,
} from '../types';
import { camel, upath } from '../utils';

Expand All @@ -14,12 +15,16 @@ export const generateImports = ({
isRootKey,
specsName,
specKey: currentSpecKey,
factoryMethodOutput,
factoryMethodPrefix
}: {
imports: GeneratorImport[];
target: string;
isRootKey: boolean;
specsName: Record<string, string>;
specKey: string;
factoryMethodOutput?: (typeof OutputModelFactoryMethodsMode)[keyof typeof OutputModelFactoryMethodsMode];
factoryMethodPrefix?: string;
}) => {
if (!imports.length) {
return '';
Expand Down Expand Up @@ -47,9 +52,14 @@ export const generateImports = ({
} } from \'./${upath.join(path, camel(name))}\';`;
}

return `import { create${name}, ${name}${
let mainImport = `import ${!values ? 'type ' : ''}{ ${name}${
alias ? ` as ${alias}` : ''
} } from \'./${camel(name)}\';`;
}${factoryMethodOutput == OutputModelFactoryMethodsMode.SINGLE ? `${factoryMethodPrefix}${name}` : ''} } from \'./${camel(name)}\';`;
if (factoryMethodOutput == OutputModelFactoryMethodsMode.SPLIT) {
let factoryMethodImport = `import { ${factoryMethodPrefix}${name} } from \'./${camel(name)}.factory\';`;
mainImport += '\n' + factoryMethodImport;
}
return mainImport;
})
.join('\n');
};
Expand Down
15 changes: 12 additions & 3 deletions packages/core/src/generators/interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SchemaObject } from 'openapi3-ts/oas30';
import { getScalar } from '../getters';
import { ContextSpecs } from '../types';
import { ContextSpecs, OutputModelFactoryMethodsMode } from '../types';
import { jsDoc } from '../utils';

/**
Expand Down Expand Up @@ -53,18 +53,27 @@ export const generateInterface = ({
} else {
model += `export type ${name} = ${scalar.value};\n`;
}
model += `export function create${name}(): ${name} ${scalar.factoryMethodValue}\n`;

// Filter out imports that refer to the type defined in current file (OpenAPI recursive schema definitions)
const externalModulesImportsOnly = scalar.imports.filter(
(importName) => importName.name !== name,
);

let factoryMethod: string = '';
if (context?.output.modelFactoryMethods) {
let factoryMethodPrefix = context?.output.override?.modelFactoryMethods?.factoryMethodPrefix!;
factoryMethod = `export function ${factoryMethodPrefix}${name}(): ${name} ${scalar.factoryMethodValue}\n`;
if (context?.output.override?.modelFactoryMethods?.outputMode == OutputModelFactoryMethodsMode.SINGLE) {
model += factoryMethod;
factoryMethod = '';
}
}

return [
...scalar.schemas,
{
name,
model,
factoryMethod,
imports: externalModulesImportsOnly,
},
];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/generators/parameter-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const generateParameterDefinition = (
if (!schema.schema || imports.length) {
acc.push({
name: modelName,
factoryMethod: '',
imports: imports.length
? [
{
Expand Down Expand Up @@ -63,6 +64,7 @@ export const generateParameterDefinition = (
if (modelName !== resolvedObject.value) {
acc.push({
name: modelName,
factoryMethod: '',
model,
imports: resolvedObject.imports,
});
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/generators/schema-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const generateSchemasDefinition = (

acc.push(...resolvedValue.schemas, {
name: schemaName,
factoryMethod: '',
model: output,
imports,
});
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/getters/combine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export const combineSchemas = ({
})),
],
model: newEnum,
factoryMethod: '',
name: name,
},
],
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/getters/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const getProps = ({
required: true,
schema: {
name: parameterTypeName,
factoryMethod: '',
model: namedParametersTypeDefinition,
imports: params.flatMap((property) => property.imports),
},
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/getters/query-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const getQueryParamsTypes = (
imports: [{ name: enumName }],
schemas: [
...resolvedValue.schemas,
{ name: enumName, model: enumValue, imports: resolvedValue.imports },
{ name: enumName, model: enumValue, factoryMethod: '', imports: resolvedValue.imports },
],
originalSchema: resolvedValue.originalSchema,
};
Expand Down Expand Up @@ -125,6 +125,7 @@ export const getQueryParams = ({

const schema = {
name,
factoryMethod: '',
model: `export type ${name} = {\n${type}\n};\n`,
imports,
};
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/resolvers/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const resolveObjectOriginal = ({
...resolvedValue.schemas,
{
name: propName,
factoryMethod: `export function ${context.output.override.modelFactoryMethods?.factoryMethodPrefix}${propName}(): ${propName}${resolvedValue.factoryMethodValue}`,
model: `${doc}export type ${propName} = ${resolvedValue.value};\n`,
imports: resolvedValue.imports,
},
Expand All @@ -55,14 +56,19 @@ const resolveObjectOriginal = ({
resolvedValue.originalSchema?.['x-enumNames'],
context.output.override.useNativeEnums,
);
const factoryMethodValue = context?.output.override?.useTypeOverInterfaces
? `${propName}[${resolvedValue.value.split(' | ')[0]}]`
: `${resolvedValue.value.split(' | ')[0]}`;


return {
value: propName,
factoryMethodValue: `${propName}[${resolvedValue.value.split(' | ')[0]}]`,
factoryMethodValue,
imports: [{ name: propName }],
schemas: [
...resolvedValue.schemas,
{
factoryMethod: '',
name: propName,
model: doc + enumValue,
imports: resolvedValue.imports,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/resolvers/value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const resolveValue = ({

return {
value: resolvedImport.name,
factoryMethodValue: `create${resolvedImport.name}()`,
factoryMethodValue: `${context.output.override.modelFactoryMethods?.factoryMethodPrefix}${resolvedImport.name}()`,
imports: [
{
name: resolvedImport.name,
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export type NormalizedOutputOptions = {
override: NormalizedOverrideOutput;
client: OutputClient | OutputClientFunc;
httpClient: OutputHttpClient;
modelFactoryMethods?: boolean;
clean: boolean | string[];
prettier: boolean;
tslint: boolean;
Expand All @@ -68,6 +69,16 @@ export type NormalizedParamsSerializerOptions = {
qs?: Record<string, any>;
};

export const OutputModelFactoryMethodsMode = {
SINGLE: 'single',
SPLIT: 'split',
} as const;

export type NormalizedModelFactoryMethodsOptions = {
factoryMethodPrefix?: string;
outputMode?: (typeof OutputModelFactoryMethodsMode)[keyof typeof OutputModelFactoryMethodsMode];
};

export type NormalizedOverrideOutput = {
title?: (title: string) => string;
transformer?: OutputTransformer;
Expand All @@ -81,6 +92,7 @@ export type NormalizedOverrideOutput = {
formUrlEncoded: boolean | NormalizedMutator;
paramsSerializer?: NormalizedMutator;
paramsSerializerOptions?: NormalizedParamsSerializerOptions;
modelFactoryMethods?: NormalizedModelFactoryMethodsOptions;
components: {
schemas: {
suffix: string;
Expand Down Expand Up @@ -173,6 +185,7 @@ export type OutputOptions = {
override?: OverrideOutput;
client?: OutputClient | OutputClientFunc;
httpClient?: OutputHttpClient;
modelFactoryMethods?: boolean;
clean?: boolean | string[];
prettier?: boolean;
tslint?: boolean;
Expand Down Expand Up @@ -321,6 +334,11 @@ export type ParamsSerializerOptions = {
qs?: Record<string, any>;
};

export type ModelFactoryMethodsOptions = {
factoryMethodPrefix?: string;
outputMode?: (typeof OutputModelFactoryMethodsMode)[keyof typeof OutputModelFactoryMethodsMode];
};

export type OverrideOutput = {
title?: (title: string) => string;
transformer?: OutputTransformer;
Expand All @@ -334,6 +352,7 @@ export type OverrideOutput = {
formUrlEncoded?: boolean | Mutator;
paramsSerializer?: Mutator;
paramsSerializerOptions?: ParamsSerializerOptions;
modelFactoryMethods?: ModelFactoryMethodsOptions;
components?: {
schemas?: {
suffix?: string;
Expand Down Expand Up @@ -596,6 +615,7 @@ export interface GlobalOptions {
mock?: boolean | GlobalMockOptions;
client?: OutputClient;
httpClient?: OutputHttpClient;
modelFactoryMethods?: boolean;
mode?: OutputMode;
tsconfig?: string | Tsconfig;
packageJson?: string;
Expand Down Expand Up @@ -637,6 +657,7 @@ export interface PackageJson {
export type GeneratorSchema = {
name: string;
model: string;
factoryMethod: string;
imports: GeneratorImport[];
};

Expand Down
64 changes: 63 additions & 1 deletion packages/core/src/writers/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs-extra';
import { generateImports } from '../generators';
import { GeneratorSchema } from '../types';
import { GeneratorSchema, OutputModelFactoryMethodsMode } from '../types';
import { camel, upath } from '../utils';

const getSchema = ({
Expand Down Expand Up @@ -35,6 +35,46 @@ const getSchema = ({
return file;
};

const getFactoryMethod = ({
schema: { name, imports, model, factoryMethod },
target,
isRootKey,
specsName,
header,
specKey,
factoryMethodOutput,
factoryMethodPrefix
}: {
schema: GeneratorSchema;
target: string;
isRootKey: boolean;
specsName: Record<string, string>;
header: string;
specKey: string;
factoryMethodOutput?: (typeof OutputModelFactoryMethodsMode)[keyof typeof OutputModelFactoryMethodsMode];
factoryMethodPrefix?: string;
}): string => {
let file = header;
file += generateImports({
imports: imports.filter(
(imp) =>
!model.includes(`type ${imp.alias || imp.name} =`) &&
!model.includes(`interface ${imp.alias || imp.name} {`),
),
target,
isRootKey,
specsName,
specKey,
factoryMethodOutput,
factoryMethodPrefix
});
file += `import { ${name}} from \'./${camel(name)}\';`;
file += '\n\n';

file += factoryMethod;
return file;
};

const getPath = (path: string, name: string, fileExtension: string): string =>
upath.join(path, `/${name}${fileExtension}`);

Expand All @@ -53,6 +93,9 @@ export const writeSchema = async ({
isRootKey,
specsName,
header,
factoryMethodInclude,
factoryMethodOutput,
factoryMethodPrefix
}: {
path: string;
schema: GeneratorSchema;
Expand All @@ -62,6 +105,10 @@ export const writeSchema = async ({
isRootKey: boolean;
specsName: Record<string, string>;
header: string;
factoryMethodInclude: boolean;
factoryMethodOutput?: (typeof OutputModelFactoryMethodsMode)[keyof typeof OutputModelFactoryMethodsMode];
factoryMethodPrefix?: string;

}) => {
const name = camel(schema.name);

Expand All @@ -70,6 +117,12 @@ export const writeSchema = async ({
getPath(path, name, fileExtension),
getSchema({ schema, target, isRootKey, specsName, header, specKey }),
);
if (factoryMethodInclude && schema.factoryMethod.length > 0) {
await fs.outputFile(
getPath(path, name + '.factory', fileExtension),
getFactoryMethod({ schema, target, isRootKey, specsName, header, specKey, factoryMethodOutput, factoryMethodPrefix }),
);
}
} catch (e) {
throw `Oups... 🍻. An Error occurred while writing schema ${name} => ${e}`;
}
Expand All @@ -85,6 +138,9 @@ export const writeSchemas = async ({
specsName,
header,
indexFiles,
factoryMethodInclude,
factoryMethodOutput,
factoryMethodPrefix
}: {
schemaPath: string;
schemas: GeneratorSchema[];
Expand All @@ -95,6 +151,9 @@ export const writeSchemas = async ({
specsName: Record<string, string>;
header: string;
indexFiles: boolean;
factoryMethodInclude: boolean;
factoryMethodOutput?: (typeof OutputModelFactoryMethodsMode)[keyof typeof OutputModelFactoryMethodsMode];
factoryMethodPrefix?: string;
}) => {
await Promise.all(
schemas.map((schema) =>
Expand All @@ -107,6 +166,9 @@ export const writeSchemas = async ({
isRootKey,
specsName,
header,
factoryMethodInclude,
factoryMethodOutput,
factoryMethodPrefix
}),
),
);
Expand Down
Loading

0 comments on commit 91101bf

Please sign in to comment.