@@ -15,6 +15,7 @@ for await (const tsconfigEntry of Deno.readDir("bases")) {
1515 const templateDir = "./template"
1616 for await ( const templateFile of Deno . readDir ( templateDir ) ) {
1717 if ( ! templateFile . isFile ) continue
18+ if ( templateFile . name === "README-combined.md" ) continue // README-combined.md is only for the combined bases
1819 const templatedFile = path . join ( templateDir , templateFile . name )
1920 Deno . copyFileSync ( templatedFile , path . join ( packagePath , templateFile . name ) )
2021 }
@@ -90,6 +91,8 @@ for await (const tsconfigEntry of Deno.readDir("bases")) {
9091 console . log ( "Built:" , tsconfigEntry . name ) ;
9192}
9293
94+ await buildTsconfigBases ( )
95+
9396function isBumpedVersionHigher ( packageJSONVersion : string , bumpedVersion : string ) {
9497 const semverMarkersPackageJSON = packageJSONVersion . split ( '.' )
9598 const semverMarkersBumped = bumpedVersion . split ( '.' )
@@ -101,3 +104,118 @@ function isBumpedVersionHigher (packageJSONVersion: string, bumpedVersion: strin
101104
102105 return true
103106}
107+
108+ // build @tsconfig /bases catch all package
109+ async function buildTsconfigBases ( ) {
110+ const name = "bases"
111+
112+ // Make the folder
113+ const packagePath = path . join ( "packages" , name )
114+ Deno . mkdirSync ( packagePath , { recursive : true } )
115+
116+ // Copy over the template files
117+ const templateDir = "./template"
118+ for await ( const templateFile of Deno . readDir ( templateDir ) ) {
119+ if ( ! templateFile . isFile ) continue
120+ if ( templateFile . name === "README.md" ) continue
121+ const templatedFile = path . join ( templateDir , templateFile . name )
122+ Deno . copyFileSync (
123+ templatedFile ,
124+ path . join (
125+ packagePath ,
126+ templateFile . name === "README-combined.md" ? "README.md" : templateFile . name ,
127+ ) ,
128+ )
129+ }
130+
131+ const exportsOverride = { }
132+
133+ // Copy the tsconfig.json files from all bases
134+ for await ( const tsconfigEntry of Deno . readDir ( "bases" ) ) {
135+ if ( ! tsconfigEntry . isFile ) continue
136+
137+ // remove extension
138+ const name = tsconfigEntry . name . replace ( / \. j s o n $ / , "" )
139+
140+ const finalTsconfigFile = `${ name } .tsconfig.json`
141+
142+ // add entry to package.json exports
143+ exportsOverride [ `./${ name } ` ] = `./${ finalTsconfigFile } `
144+
145+ const tsconfigFilePath = path . join ( "bases" , tsconfigEntry . name )
146+
147+ const newPackageTSConfigPath = path . join ( packagePath , finalTsconfigFile )
148+
149+ Deno . copyFileSync ( tsconfigFilePath , newPackageTSConfigPath )
150+
151+ const tsconfigText = await Deno . readTextFile ( newPackageTSConfigPath )
152+
153+ // Drop `display` field in tsconfig.json for npm package
154+ await Deno . writeTextFile ( newPackageTSConfigPath , tsconfigText . replace ( / \s * " d i s p l a y .* / , "" ) )
155+ }
156+
157+ const tsconfigJSON = { display : "Bases" }
158+
159+ // Edit the package.json
160+ const packageText = await Deno . readTextFile ( path . join ( packagePath , "package.json" ) )
161+ const packageJSON = JSON . parse ( packageText )
162+ packageJSON . name = `@tsconfig/${ name } `
163+ packageJSON . description = `Combined tsconfig bases.`
164+ packageJSON . keywords = [ "tsconfig" , name , "combined" ]
165+ packageJSON . exports = exportsOverride
166+
167+ // Do some string replacements in the other templated files
168+ const replaceTextIn = [ "README.md" ]
169+ for ( const filenameToEdit of replaceTextIn ) {
170+ const fileToEdit = path . join ( packagePath , filenameToEdit )
171+
172+ const defaultTitle = `A base TSConfig for working with ${ tsconfigJSON . display } `
173+ const title = name !== "recommended" ? defaultTitle : "The recommended base for a TSConfig"
174+
175+ let packageText = await Deno . readTextFile ( fileToEdit )
176+ packageText = packageText . replace ( / \[ f i l e n a m e \] / g, name ) . replace ( / \[ d i s p l a y _ t i t l e \] / g, title )
177+
178+ // Inject readme-extra if any
179+ try {
180+ const readmeExtra = ( await Deno . readTextFile ( path . join ( "readme-extras" , `${ name } .md` ) ) ) . trim ( )
181+
182+ if ( readmeExtra ) {
183+ packageText = packageText . replace ( / \[ r e a d m e - e x t r a \] / g, `\n${ readmeExtra } \n` )
184+ }
185+ } catch ( error ) {
186+ // NOOP, there is no extra readme
187+ // console.log(error)
188+ }
189+
190+ // Remove readme-extra placeholders if any
191+ packageText = packageText . replace ( / \[ r e a d m e - e x t r a \] / g, "" )
192+
193+ await Deno . writeTextFile ( fileToEdit , packageText )
194+ }
195+
196+ // Bump the last version of the number from npm,
197+ // or use the _version in tsconfig if it's higher,
198+ // or default to 1.0.0
199+ let version = tsconfigJSON . _version || "1.0.0"
200+ try {
201+ const npmResponse = await fetch ( `https://registry.npmjs.org/${ packageJSON . name } ` )
202+ const npmPackage = await npmResponse . json ( )
203+
204+ const semverMarkers = npmPackage [ "dist-tags" ] . latest . split ( "." )
205+ const bumpedVersion = `${ semverMarkers [ 0 ] } .${ semverMarkers [ 1 ] } .${ Number ( semverMarkers [ 2 ] ) + 1 } `
206+ if ( isBumpedVersionHigher ( version , bumpedVersion ) ) {
207+ version = bumpedVersion
208+ }
209+ } catch ( error ) {
210+ // NOOP, this is for the first deploy
211+ // console.log(error)
212+ }
213+
214+ packageJSON . version = version
215+ await Deno . writeTextFile (
216+ path . join ( packagePath , "package.json" ) ,
217+ JSON . stringify ( packageJSON , null , " " ) ,
218+ )
219+
220+ console . log ( "Built:" , "bases" )
221+ }
0 commit comments