1+ import path from 'node:path' ;
2+ import { toUnixPath } from '@code-pushup/utils' ;
13import type {
24 ConfigFileFormat ,
35 ImportDeclarationStructure ,
@@ -32,6 +34,60 @@ class CodeBuilder {
3234 }
3335}
3436
37+ export function generateConfigSource (
38+ plugins : PluginCodegenResult [ ] ,
39+ format : ConfigFileFormat ,
40+ ) : string {
41+ const builder = new CodeBuilder ( ) ;
42+ addImports ( builder , collectImports ( plugins , format ) ) ;
43+ if ( format === 'ts' ) {
44+ builder . addLine ( 'export default {' ) ;
45+ addPlugins ( builder , plugins ) ;
46+ builder . addLine ( '} satisfies CoreConfig;' ) ;
47+ } else {
48+ builder . addLine ( "/** @type {import('@code-pushup/models').CoreConfig} */" ) ;
49+ builder . addLine ( 'export default {' ) ;
50+ addPlugins ( builder , plugins ) ;
51+ builder . addLine ( '};' ) ;
52+ }
53+ return builder . toString ( ) ;
54+ }
55+
56+ export function generatePresetSource (
57+ plugins : PluginCodegenResult [ ] ,
58+ format : ConfigFileFormat ,
59+ ) : string {
60+ const builder = new CodeBuilder ( ) ;
61+ addImports ( builder , collectImports ( plugins , format ) ) ;
62+ addPresetExport ( builder , plugins , format ) ;
63+ return builder . toString ( ) ;
64+ }
65+
66+ export function generateProjectSource (
67+ projectName : string ,
68+ presetImportPath : string ,
69+ ) : string {
70+ const builder = new CodeBuilder ( ) ;
71+ builder . addLine (
72+ formatImport ( {
73+ moduleSpecifier : presetImportPath ,
74+ namedImports : [ 'createConfig' ] ,
75+ } ) ,
76+ ) ;
77+ builder . addEmptyLine ( ) ;
78+ builder . addLine ( `export default await createConfig('${ projectName } ');` ) ;
79+ return builder . toString ( ) ;
80+ }
81+
82+ export function computeRelativePresetImport (
83+ projectRelativeDir : string ,
84+ presetFilename : string ,
85+ ) : string {
86+ const relativePath = path . relative ( projectRelativeDir , presetFilename ) ;
87+ const importPath = toUnixPath ( relativePath ) . replace ( / \. t s $ / , '.js' ) ;
88+ return importPath . startsWith ( '.' ) ? importPath : `./${ importPath } ` ;
89+ }
90+
3591function formatImport ( {
3692 moduleSpecifier,
3793 defaultImport,
@@ -45,76 +101,77 @@ function formatImport({
45101 return `import ${ type } ${ from } '${ moduleSpecifier } ';` ;
46102}
47103
48- function collectTsImports (
49- plugins : PluginCodegenResult [ ] ,
104+ function sortImports (
105+ imports : ImportDeclarationStructure [ ] ,
50106) : ImportDeclarationStructure [ ] {
51- return [
52- CORE_CONFIG_IMPORT ,
53- ...plugins . flatMap ( ( { imports } ) => imports ) ,
54- ] . toSorted ( ( a , b ) => a . moduleSpecifier . localeCompare ( b . moduleSpecifier ) ) ;
107+ return imports . toSorted ( ( a , b ) =>
108+ a . moduleSpecifier . localeCompare ( b . moduleSpecifier ) ,
109+ ) ;
55110}
56111
57- function collectJsImports (
112+ function collectImports (
58113 plugins : PluginCodegenResult [ ] ,
114+ format : ConfigFileFormat ,
59115) : ImportDeclarationStructure [ ] {
60- return plugins
61- . flatMap ( ( { imports } ) => imports )
62- . map ( ( { isTypeOnly : _ , ...rest } ) => rest )
63- . toSorted ( ( a , b ) => a . moduleSpecifier . localeCompare ( b . moduleSpecifier ) ) ;
116+ const pluginImports = plugins . flatMap ( ( { imports } ) => imports ) ;
117+ if ( format === 'ts' ) {
118+ return sortImports ( [ CORE_CONFIG_IMPORT , ...pluginImports ] ) ;
119+ }
120+ return sortImports ( pluginImports . map ( ( { isTypeOnly : _ , ...rest } ) => rest ) ) ;
121+ }
122+
123+ function addImports (
124+ builder : CodeBuilder ,
125+ imports : ImportDeclarationStructure [ ] ,
126+ ) : void {
127+ if ( imports . length > 0 ) {
128+ builder . addLines ( imports . map ( formatImport ) ) ;
129+ builder . addEmptyLine ( ) ;
130+ }
64131}
65132
66133function addPlugins (
67134 builder : CodeBuilder ,
68135 plugins : PluginCodegenResult [ ] ,
136+ depth = 1 ,
69137) : void {
138+ builder . addLine ( 'plugins: [' , depth ) ;
70139 if ( plugins . length === 0 ) {
71- builder . addLine ( 'plugins: [' , 1 ) ;
72- builder . addLine ( '// TODO: register some plugins' , 2 ) ;
73- builder . addLine ( '],' , 1 ) ;
140+ builder . addLine ( '// TODO: register some plugins' , depth + 1 ) ;
74141 } else {
75- builder . addLine ( 'plugins: [' , 1 ) ;
76142 builder . addLines (
77143 plugins . map ( ( { pluginInit } ) => `${ pluginInit } ,` ) ,
78- 2 ,
144+ depth + 1 ,
79145 ) ;
80- builder . addLine ( '],' , 1 ) ;
81146 }
147+ builder . addLine ( '],' , depth ) ;
82148}
83149
84- export function generateConfigSource (
150+ function addPresetExport (
151+ builder : CodeBuilder ,
85152 plugins : PluginCodegenResult [ ] ,
86153 format : ConfigFileFormat ,
87- ) : string {
88- return format === 'ts'
89- ? generateTsConfig ( plugins )
90- : generateJsConfig ( plugins ) ;
91- }
92-
93- function generateTsConfig ( plugins : PluginCodegenResult [ ] ) : string {
94- const builder = new CodeBuilder ( ) ;
95-
96- builder . addLines ( collectTsImports ( plugins ) . map ( formatImport ) ) ;
97- builder . addEmptyLine ( ) ;
98- builder . addLine ( 'export default {' ) ;
99- addPlugins ( builder , plugins ) ;
100- builder . addLine ( '} satisfies CoreConfig;' ) ;
101-
102- return builder . toString ( ) ;
103- }
104-
105- function generateJsConfig ( plugins : PluginCodegenResult [ ] ) : string {
106- const builder = new CodeBuilder ( ) ;
107-
108- const pluginImports = collectJsImports ( plugins ) ;
109- if ( pluginImports . length > 0 ) {
110- builder . addLines ( pluginImports . map ( formatImport ) ) ;
111- builder . addEmptyLine ( ) ;
154+ ) : void {
155+ if ( format === 'ts' ) {
156+ builder . addLines ( [
157+ '/**' ,
158+ ' * Creates a Code PushUp config for a project.' ,
159+ ' * @param project Project name' ,
160+ ' */' ,
161+ 'export async function createConfig(project: string): Promise<CoreConfig> {' ,
162+ ] ) ;
163+ } else {
164+ builder . addLines ( [
165+ '/**' ,
166+ ' * Creates a Code PushUp config for a project.' ,
167+ ' * @param {string} project Project name' ,
168+ " * @returns {Promise<import('@code-pushup/models').CoreConfig>}" ,
169+ ' */' ,
170+ 'export async function createConfig(project) {' ,
171+ ] ) ;
112172 }
113-
114- builder . addLine ( "/** @type {import('@code-pushup/models').CoreConfig} */" ) ;
115- builder . addLine ( 'export default {' ) ;
116- addPlugins ( builder , plugins ) ;
117- builder . addLine ( '};' ) ;
118-
119- return builder . toString ( ) ;
173+ builder . addLine ( 'return {' , 1 ) ;
174+ addPlugins ( builder , plugins , 2 ) ;
175+ builder . addLine ( '};' , 1 ) ;
176+ builder . addLine ( '}' ) ;
120177}
0 commit comments