@@ -31,8 +31,11 @@ async function main(): Promise<void> {
3131 ] )
3232}
3333
34+ const openapiResponseKeyProp = 'x-fern-sdk-return-value'
35+
3436const routePaths = [
3537 '/access_codes' ,
38+ '/access_codes/simulate' ,
3639 '/access_codes/unmanaged' ,
3740 '/acs' ,
3841 '/acs/access_groups' ,
@@ -54,6 +57,7 @@ const routePaths = [
5457 '/networks' ,
5558 '/noise_sensors' ,
5659 '/noise_sensors/noise_thresholds' ,
60+ '/noise_sensors/simulate' ,
5761 '/phones' ,
5862 '/phones/simulate' ,
5963 '/thermostats' ,
@@ -67,7 +71,7 @@ const routePaths = [
6771const routePathSubresources : Partial <
6872 Record < ( typeof routePaths ) [ number ] , string [ ] >
6973> = {
70- '/access_codes' : [ 'unmanaged' ] ,
74+ '/access_codes' : [ 'unmanaged' , 'simulate' ] ,
7175 '/acs' : [
7276 'access_groups' ,
7377 'credential_pools' ,
@@ -79,41 +83,11 @@ const routePathSubresources: Partial<
7983 ] ,
8084 '/phones' : [ 'simulate' ] ,
8185 '/devices' : [ 'unmanaged' , 'simulate' ] ,
82- '/noise_sensors' : [ 'noise_thresholds' ] ,
86+ '/noise_sensors' : [ 'noise_thresholds' , 'simulate' ] ,
8387 '/thermostats' : [ 'climate_setting_schedules' ] ,
8488 '/user_identities' : [ 'enrollment_automations' ] ,
8589}
8690
87- const ignoredEndpointPaths = [
88- '/access_codes/simulate/create_unmanaged_access_code' ,
89- '/connect_webviews/view' ,
90- '/health' ,
91- '/health/get_health' ,
92- '/health/get_service_health' ,
93- '/health/service/[service_name]' ,
94- '/noise_sensors/simulate/trigger_noise_threshold' ,
95- '/workspaces/reset_sandbox' ,
96- ] as const
97-
98- const endpointResources : Partial <
99- Record <
100- keyof typeof openapi . paths ,
101- null | 'action_attempt' | 'noise_threshold'
102- >
103- > = {
104- // Set all ignored endpoints null to simplify code generation.
105- ...ignoredEndpointPaths . reduce ( ( acc , cur ) => ( { ...acc , [ cur ] : null } ) , { } ) ,
106-
107- // These endpoints return a deprecated action attempt or resource.
108- '/access_codes/delete' : null ,
109- '/access_codes/unmanaged/delete' : null ,
110- '/access_codes/update' : null ,
111- '/noise_sensors/noise_thresholds/create' : 'noise_threshold' ,
112- '/noise_sensors/noise_thresholds/delete' : null ,
113- '/noise_sensors/noise_thresholds/update' : null ,
114- '/thermostats/climate_setting_schedules/update' : null ,
115- } as const
116-
11791interface Route {
11892 namespace : string
11993 endpoints : Endpoint [ ]
@@ -139,14 +113,10 @@ interface ClassMeta {
139113const createRoutes = ( ) : Route [ ] => {
140114 const paths = Object . keys ( openapi . paths )
141115
142- const unmatchedEndpointPaths = paths
143- . filter (
144- ( path ) =>
145- ! routePaths . some ( ( routePath ) => isEndpointUnderRoute ( path , routePath ) ) ,
146- )
147- . filter (
148- ( path ) => ! ( ignoredEndpointPaths as unknown as string [ ] ) . includes ( path ) ,
149- )
116+ const unmatchedEndpointPaths = paths . filter (
117+ ( path ) =>
118+ ! routePaths . some ( ( routePath ) => isEndpointUnderRoute ( path , routePath ) ) ,
119+ )
150120
151121 if ( unmatchedEndpointPaths . length > 0 ) {
152122 throw new Error (
@@ -206,28 +176,28 @@ const deriveResource = (
206176 endpointPath : string ,
207177 method : Method ,
208178) : string | null => {
209- if ( isEndpointResource ( endpointPath ) ) {
210- return endpointResources [ endpointPath ] ?? null
211- }
212-
213179 if ( isOpenapiPath ( endpointPath ) ) {
214180 const spec = openapi . paths [ endpointPath ]
215181 const methodKey = method . toLowerCase ( )
216182
217183 if ( methodKey === 'post' && 'post' in spec ) {
218- const response = spec . post . responses [ 200 ]
219- if ( ! ( 'content' in response ) ) return null
220- return deriveResourceFromSchema (
221- response . content [ 'application/json' ] ?. schema ?. properties ?? { } ,
222- )
184+ const postSpec = spec . post
185+ const openapiEndpointResource =
186+ openapiResponseKeyProp in postSpec
187+ ? postSpec [ openapiResponseKeyProp ]
188+ : null
189+
190+ return openapiEndpointResource
223191 }
224192
225193 if ( methodKey === 'get' && 'get' in spec ) {
226194 const response = spec . get . responses [ 200 ]
195+
227196 if ( ! ( 'content' in response ) ) {
228197 throw new Error ( `Missing resource for ${ method } ${ endpointPath } ` )
229198 }
230- return deriveResourceFromSchema (
199+
200+ return deriveResourceFromSchemaForGetRequest (
231201 response . content [ 'application/json' ] ?. schema ?. properties ?? { } ,
232202 )
233203 }
@@ -236,7 +206,9 @@ const deriveResource = (
236206 throw new Error ( `Could not derive resource for ${ method } ${ endpointPath } ` )
237207}
238208
239- const deriveResourceFromSchema = ( properties : object ) : string | null =>
209+ const deriveResourceFromSchemaForGetRequest = (
210+ properties : object ,
211+ ) : string | null =>
240212 Object . keys ( properties ) . filter ( ( key ) => key !== 'ok' ) [ 0 ] ?? null
241213
242214const deriveSemanticMethod = ( methods : string [ ] ) : Method => {
@@ -248,10 +220,6 @@ const deriveSemanticMethod = (methods: string[]): Method => {
248220 throw new Error ( `Could not find valid method in ${ methods . join ( ', ' ) } ` )
249221}
250222
251- const isEndpointResource = (
252- key : string ,
253- ) : key is keyof typeof endpointResources => key in endpointResources
254-
255223const isOpenapiPath = ( key : string ) : key is keyof typeof openapi . paths =>
256224 key in openapi . paths
257225
0 commit comments