@@ -20,7 +20,6 @@ import { cwd } from 'node:process'
2020import type { ParseArgsConfig } from 'node:util'
2121import { parseArgs } from 'node:util'
2222import { snakeToSlug } from './helpers'
23- import type { PackageJSON } from './types.js'
2423
2524type Scope = '@scaleway' | '@scaleway-internal'
2625
@@ -48,6 +47,21 @@ interface Product {
4847 hasPackageJson: boolean
4948}
5049
50+ const REQUIRED_PRODUCT_FILES = [
51+ 'package.json' ,
52+ 'tsconfig.json' ,
53+ 'tsconfig.build.json' ,
54+ 'vite.config.ts' ,
55+ 'README.md' ,
56+ ] as const
57+
58+ const OPTIONAL_PRODUCT_FILES : Record <
59+ string ,
60+ Set < ( typeof REQUIRED_PRODUCT_FILES ) [ number ] >
61+ > = {
62+ std : new Set ( [ 'README.md' ] ) ,
63+ }
64+
5165const log = ( ...args : unknown [ ] ) => {
5266 if ( VERBOSE ) console . log ( ...args )
5367}
@@ -64,7 +78,7 @@ function safeReadJson(path: string): unknown {
6478}
6579
6680function writeJsonIfChanged ( path : string , data : unknown ) {
67- const newContent = ` ${ JSON . stringify ( data , null , 2 ) } \n`
81+ const newContent = JSON . stringify ( data , null , 2 ) + '\n'
6882 const oldContent = existsSync ( path ) ? readFileSync ( path , 'utf8' ) : ''
6983 if ( oldContent !== newContent ) {
7084 if ( DRY_RUN ) {
@@ -82,8 +96,7 @@ function walkHasGenFiles(root: string): boolean {
8296 if ( ! existsSync ( root ) ) return false
8397 const stack = [ root ]
8498 while ( stack . length ) {
85- const p = stack . pop ( )
86- if ( ! p ) break
99+ const p = stack . pop ( ) !
87100 const st = statSync ( p )
88101 if ( st . isDirectory ( ) ) {
89102 for ( const name of readdirSync ( p ) ) stack . push ( join ( p , name ) )
@@ -113,6 +126,33 @@ function detectNewProducts(products: Product[]): Product[] {
113126 return products . filter ( p => p . hasGenFiles && ! p . hasPackageJson )
114127}
115128
129+ function ensureProductFiles ( products : Product [ ] ) {
130+ const missingFilesByProduct : string [ ] = [ ]
131+
132+ for ( const product of products ) {
133+ const optionalFiles = OPTIONAL_PRODUCT_FILES [ product . name ] ?? new Set ( )
134+
135+ for ( const fileName of REQUIRED_PRODUCT_FILES ) {
136+ if ( optionalFiles . has ( fileName ) ) continue
137+
138+ const filePath = join ( product . path , fileName )
139+ if ( ! existsSync ( filePath ) ) {
140+ missingFilesByProduct . push ( `${ product . name } /${ fileName } ` )
141+ }
142+ }
143+ }
144+
145+ if ( missingFilesByProduct . length > 0 ) {
146+ throw new Error (
147+ [
148+ 'Missing required configuration files for new products:' ,
149+ ...missingFilesByProduct . map ( f => ` • ${ f } ` ) ,
150+ 'Please re-run `pnpm run generatePackages` and `pnpm run generateAlias` locally to regenerate the missing files before committing.' ,
151+ ] . join ( '\n' ) ,
152+ )
153+ }
154+ }
155+
116156function detectPackageScope ( sdkPackageJsonPath : string ) : Scope {
117157 if ( values . scope ) {
118158 const s = String ( values . scope ) as Scope
@@ -122,7 +162,7 @@ function detectPackageScope(sdkPackageJsonPath: string): Scope {
122162 warn ( '⚠️ SDK package.json not found, using @scaleway scope' )
123163 return '@scaleway'
124164 }
125- const sdkPackage = safeReadJson ( sdkPackageJsonPath ) as PackageJSON
165+ const sdkPackage = safeReadJson ( sdkPackageJsonPath ) as any
126166 const deps : Record < string , string > = sdkPackage ?. dependencies ?? { }
127167 const hasInternal = Object . keys ( deps ) . some ( k =>
128168 k . startsWith ( '@scaleway-internal/sdk-' ) ,
@@ -140,7 +180,7 @@ function updateSdkPackageJson(
140180 return { added : [ ] }
141181 }
142182
143- const sdkPackage = safeReadJson ( sdkPackageJsonPath ) as PackageJSON
183+ const sdkPackage = safeReadJson ( sdkPackageJsonPath ) as any
144184 sdkPackage . dependencies = sdkPackage . dependencies ?? { }
145185 sdkPackage . devDependencies = sdkPackage . devDependencies ?? { }
146186
@@ -226,6 +266,8 @@ async function main(): Promise<number> {
226266 updateSdkPackageJson ( SDK_PACKAGE_JSON , newProducts , scope )
227267 info ( '' )
228268
269+ ensureProductFiles ( newProducts )
270+
229271 // 4) alias
230272 info ( '📝 Step 4: Generating SDK exports…' )
231273 runCommand ( 'pnpm run generateAlias' , 'Generate SDK exports' )
0 commit comments