Skip to content

Commit 6f96c7b

Browse files
committed
Build all domains, not just person.
1 parent 69e58dd commit 6f96c7b

File tree

4 files changed

+63
-54
lines changed

4 files changed

+63
-54
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "safety-net-openapi",
33
"version": "1.0.0",
44
"private": true,
5-
"description": "Generate Mock API server, Swagger UI, and Zodios API clients from OpenApi specifications",
5+
"description": "Generate Mock API server, Swagger UI, and typed API clients from OpenAPI specifications",
66
"type": "module",
77
"engines": {
88
"node": ">=18.0.0"

packages/clients/generated/.gitkeep

Lines changed: 0 additions & 9 deletions
This file was deleted.

packages/clients/scripts/build-state-package.js

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ async function main() {
117117
const srcDir = join(outputDir, 'src');
118118
const templatesDir = join(clientsRoot, 'templates');
119119
const resolvedDir = join(repoRoot, 'packages', 'schemas', 'openapi', 'resolved');
120-
const bundledSpec = join(outputDir, 'openapi-bundled.yaml');
121-
const configPath = join(outputDir, 'openapi-ts.config.js');
122120

123121
console.log(`\nBuilding package for ${stateTitle}...`);
124122
console.log(` State: ${state}`);
@@ -136,43 +134,63 @@ async function main() {
136134
console.log('\n1. Resolving state overlay...');
137135
await exec('npm', ['run', 'overlay:resolve', '-w', '@safety-net/schemas', '--', `--state=${state}`]);
138136

139-
// Step 2: Find and bundle all resolved spec files
140-
console.log('\n2. Bundling OpenAPI specs...');
137+
// Step 2: Generate client for each domain spec
138+
console.log('\n2. Generating domain clients...');
141139
const specFiles = readdirSync(resolvedDir).filter(f => f.endsWith('.yaml') && !f.startsWith('.'));
142140

143141
if (specFiles.length === 0) {
144142
throw new Error('No resolved spec files found');
145143
}
146144

147-
// For now, bundle each spec separately and use persons as the main one
148-
// In the future, we could merge all specs into one
149-
const mainSpec = join(resolvedDir, 'persons.yaml');
150-
await exec('npx', [
151-
'@apidevtools/swagger-cli', 'bundle',
152-
mainSpec,
153-
'-o', bundledSpec,
154-
'--dereference'
155-
]);
156-
console.log(` Bundled: ${bundledSpec}`);
157-
158-
// Step 3: Generate client using openapi-ts
159-
console.log('\n3. Generating API client with openapi-ts...');
160-
const configContent = createOpenApiTsConfig(bundledSpec, srcDir);
161-
writeFileSync(configPath, configContent);
162-
163-
await exec('npx', ['@hey-api/openapi-ts', '-f', configPath], { cwd: outputDir });
164-
console.log(' Client generated successfully');
165-
166-
// Post-process: Remove unused @ts-expect-error directives from generated code
167-
// (openapi-ts generates these for compatibility but they cause TS2578 errors)
168-
const clientGenPath = join(srcDir, 'client', 'client.gen.ts');
169-
if (existsSync(clientGenPath)) {
170-
let content = readFileSync(clientGenPath, 'utf8');
171-
content = content.replace(/^\s*\/\/\s*@ts-expect-error\s*$/gm, '');
172-
writeFileSync(clientGenPath, content);
173-
console.log(' Cleaned up @ts-expect-error directives');
145+
console.log(` Found specs: ${specFiles.join(', ')}`);
146+
const domains = [];
147+
148+
for (const file of specFiles) {
149+
const domain = file.replace('.yaml', '');
150+
domains.push(domain);
151+
const specPath = join(resolvedDir, file);
152+
const domainBundled = join(outputDir, `${domain}-bundled.yaml`);
153+
const domainSrcDir = join(srcDir, domain);
154+
const domainConfigPath = join(outputDir, `${domain}.config.js`);
155+
156+
console.log(`\n Processing ${domain}...`);
157+
158+
// Bundle spec (dereference $refs)
159+
await exec('npx', [
160+
'@apidevtools/swagger-cli', 'bundle',
161+
specPath,
162+
'-o', domainBundled,
163+
'--dereference'
164+
]);
165+
166+
// Generate client for this domain
167+
mkdirSync(domainSrcDir, { recursive: true });
168+
const configContent = createOpenApiTsConfig(domainBundled, domainSrcDir);
169+
writeFileSync(domainConfigPath, configContent);
170+
171+
await exec('npx', ['@hey-api/openapi-ts', '-f', domainConfigPath], { cwd: outputDir });
172+
173+
// Post-process: Remove unused @ts-expect-error directives
174+
const clientGenPath = join(domainSrcDir, 'client', 'client.gen.ts');
175+
if (existsSync(clientGenPath)) {
176+
let content = readFileSync(clientGenPath, 'utf8');
177+
content = content.replace(/^\s*\/\/\s*@ts-expect-error\s*$/gm, '');
178+
writeFileSync(clientGenPath, content);
179+
}
180+
181+
// Clean up temp files
182+
rmSync(domainBundled, { force: true });
183+
rmSync(domainConfigPath, { force: true });
184+
185+
console.log(` Generated: ${domain}`);
174186
}
175187

188+
// Step 3: Create index.ts that re-exports all domains
189+
console.log('\n3. Creating index exports...');
190+
const indexContent = domains.map(d => `export * as ${d} from './${d}/index.js';`).join('\n') + '\n';
191+
writeFileSync(join(srcDir, 'index.ts'), indexContent);
192+
console.log(' Created index.ts')
193+
176194
// Step 4: Generate package.json from template
177195
console.log('\n4. Generating package.json...');
178196
const packageTemplate = readFileSync(join(templatesDir, 'package.template.json'), 'utf8');
@@ -222,10 +240,6 @@ async function main() {
222240
}
223241
console.log(' Compilation complete');
224242

225-
// Clean up temporary files
226-
rmSync(bundledSpec, { force: true });
227-
rmSync(configPath, { force: true });
228-
229243
// Summary
230244
console.log('\n========================================');
231245
console.log(`Package built successfully!`);

packages/clients/templates/package.template.json

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@
1111
"import": "./dist/index.js",
1212
"types": "./dist/index.d.ts"
1313
},
14-
"./sdk": {
15-
"import": "./dist/sdk.gen.js",
16-
"types": "./dist/sdk.gen.d.ts"
14+
"./persons": {
15+
"import": "./dist/persons/index.js",
16+
"types": "./dist/persons/index.d.ts"
1717
},
18-
"./types": {
19-
"import": "./dist/types.gen.js",
20-
"types": "./dist/types.gen.d.ts"
18+
"./applications": {
19+
"import": "./dist/applications/index.js",
20+
"types": "./dist/applications/index.d.ts"
2121
},
22-
"./zod": {
23-
"import": "./dist/zod.gen.js",
24-
"types": "./dist/zod.gen.d.ts"
22+
"./households": {
23+
"import": "./dist/households/index.js",
24+
"types": "./dist/households/index.d.ts"
25+
},
26+
"./incomes": {
27+
"import": "./dist/incomes/index.js",
28+
"types": "./dist/incomes/index.d.ts"
2529
}
2630
},
2731
"peerDependencies": {

0 commit comments

Comments
 (0)