@@ -39,6 +39,26 @@ interface PlatformConfig {
3939 generatedDir : string ;
4040 generatedExtension : string ;
4141 generate : ( definitionPath : string , outFile : string ) => Promise < void > ;
42+ /**
43+ * Optional follow-up generation passes. Used by TypeScript to additionally
44+ * emit code against alternative SDK targets (e.g. the web SDK) so that
45+ * cross-target features like the `bytes` primitive can be round-tripped
46+ * with each target's native representation.
47+ */
48+ extraGenerations ?: {
49+ /**
50+ * Subdirectory under `generatedDir` that the extra pass writes to. The
51+ * platform's `tsconfig.json` / `Package.swift` etc. must already include
52+ * files in this directory.
53+ */
54+ subdir : string ;
55+ /**
56+ * Restricts the pass to a subset of fixtures (matched by basename, e.g.
57+ * `'secrets'`). Omit to apply to every fixture.
58+ */
59+ onlyFixtures ?: string [ ] ;
60+ generate : ( definitionPath : string , outFile : string ) => Promise < void > ;
61+ } [ ] ;
4262 runs : { description : string ; cwd : string ; cmd : string ; args : string [ ] ; underEmulator : boolean } [ ] ;
4363}
4464
@@ -94,6 +114,30 @@ const PLATFORMS: Record<Platform, PlatformConfig> = {
94114 objectTypeFormat : 'interface' ,
95115 } ) ;
96116 } ,
117+ // The `bytes` scenario is the only place where the wire-level
118+ // representation differs across TS targets (Buffer vs firestore.Bytes
119+ // vs firestore.Blob), so we emit it against the web SDK in addition
120+ // to the admin SDK. The admin pass above writes `generated/secrets.ts`;
121+ // this pass writes `generated/web/secrets.ts`, which is imported by
122+ // the dedicated `secrets.web.test.ts` round-trip suite. The
123+ // react-native-firebase target is verified by the unit/snapshot tests
124+ // under `src/renderers/ts/__tests__/`; we don't run it here because
125+ // `@react-native-firebase/firestore` is RN-runtime-only and cannot
126+ // execute under Node.
127+ extraGenerations : [
128+ {
129+ subdir : 'web' ,
130+ onlyFixtures : [ 'secrets' ] ,
131+ async generate ( definition , outFile ) {
132+ await typesync . generateTs ( {
133+ definition,
134+ outFile,
135+ target : 'firebase@10' ,
136+ objectTypeFormat : 'interface' ,
137+ } ) ;
138+ } ,
139+ } ,
140+ ] ,
97141 runs : [
98142 {
99143 description : 'tsc --noEmit (compile-time check)' ,
@@ -129,21 +173,35 @@ function listSchemaFixtures(): { path: string; name: string }[] {
129173
130174function clearGeneratedDir ( generatedDir : string , extension : string ) : void {
131175 if ( ! existsSync ( generatedDir ) ) return ;
132- for ( const entry of readdirSync ( generatedDir ) ) {
133- if ( entry . endsWith ( extension ) ) {
134- rmSync ( resolve ( generatedDir , entry ) ) ;
176+ for ( const entry of readdirSync ( generatedDir , { withFileTypes : true } ) ) {
177+ const entryPath = resolve ( generatedDir , entry . name ) ;
178+ if ( entry . isDirectory ( ) ) {
179+ clearGeneratedDir ( entryPath , extension ) ;
180+ continue ;
181+ }
182+ if ( entry . name . endsWith ( extension ) ) {
183+ rmSync ( entryPath ) ;
135184 }
136185 }
137186}
138187
139188async function generateAll ( platform : Platform , config : PlatformConfig ) : Promise < void > {
140189 console . log ( `\n[${ platform } ] generating fixtures…` ) ;
141190 clearGeneratedDir ( config . generatedDir , config . generatedExtension ) ;
142- for ( const fixture of listSchemaFixtures ( ) ) {
191+ const fixtures = listSchemaFixtures ( ) ;
192+ for ( const fixture of fixtures ) {
143193 const outFile = resolve ( config . generatedDir , `${ fixture . name } ${ config . generatedExtension } ` ) ;
144194 await config . generate ( fixture . path , outFile ) ;
145195 console . log ( ` → ${ fixture . name } -> ${ outFile } ` ) ;
146196 }
197+ for ( const extra of config . extraGenerations ?? [ ] ) {
198+ const targets = extra . onlyFixtures ? fixtures . filter ( f => extra . onlyFixtures ! . includes ( f . name ) ) : fixtures ;
199+ for ( const fixture of targets ) {
200+ const outFile = resolve ( config . generatedDir , extra . subdir , `${ fixture . name } ${ config . generatedExtension } ` ) ;
201+ await extra . generate ( fixture . path , outFile ) ;
202+ console . log ( ` → [${ extra . subdir } ] ${ fixture . name } -> ${ outFile } ` ) ;
203+ }
204+ }
147205}
148206
149207const FIREBASE_BIN = resolve ( REPO_ROOT , 'node_modules/.bin/firebase' ) ;
0 commit comments