Skip to content

Commit 12671b0

Browse files
committed
Generate all routes
1 parent daed45c commit 12671b0

20 files changed

+531
-48
lines changed

generate-routes.ts

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
11
import { writeFile } from 'node:fs/promises'
22
import { resolve } from 'node:path'
33

4-
import { camelCase, pascalCase, snakeCase } from 'change-case'
4+
import { openapi } from '@seamapi/types/connect'
5+
import { camelCase, paramCase, pascalCase, snakeCase } from 'change-case'
56
import { ESLint } from 'eslint'
67
import { format, resolveConfig } from 'prettier'
78

9+
const routeOutputPath = resolve('src', 'lib', 'seam', 'connect', 'routes')
10+
11+
const routePaths: string[] = [
12+
'/access_codes',
13+
'/access_codes/unmanaged',
14+
'/acs/access_groups',
15+
'/acs/credentials',
16+
'/acs/systems',
17+
'/acs/users',
18+
'/action_attempts',
19+
'/client_sessions',
20+
'/connect_webviews',
21+
'/connected_accounts',
22+
'/devices',
23+
'/devices/unmanaged',
24+
'/events',
25+
'/locks',
26+
'/noise_sensors/noise_thresholds',
27+
'/thermostats/climate_setting_schedules',
28+
'/thermostats',
29+
'/webhooks',
30+
'/workspaces',
31+
]
32+
33+
const ignoredEndpointPaths = [
34+
'/access_codes/simulate/create_unmanaged_access_code',
35+
'/health',
36+
'/health/get_health',
37+
'/health/get_service_health',
38+
'/health/service/[service_name]',
39+
'/noise_sensors/simulate/trigger_noise_threshold',
40+
]
41+
842
interface Route {
943
namespace: string
1044
endpoints: Endpoint[]
@@ -19,6 +53,58 @@ interface Endpoint {
1953
requestFormat: 'params' | 'body'
2054
}
2155

56+
const exampleRoute: Route = {
57+
namespace: 'workspaces',
58+
endpoints: [
59+
{
60+
name: 'get',
61+
namespace: 'workspaces',
62+
path: '/workspaces/get',
63+
method: 'GET',
64+
resource: 'workspace',
65+
requestFormat: ['GET', 'DELETE'].includes('GET') ? 'params' : 'body',
66+
},
67+
],
68+
}
69+
70+
const isEndpointUnderRoute = (
71+
endpointPath: string,
72+
routePath: string,
73+
): boolean =>
74+
endpointPath.startsWith(routePath) &&
75+
endpointPath.split('/').length - 1 === routePath.split('/').length
76+
77+
const createRoutes = (): Route[] => {
78+
const paths = Object.keys(openapi.paths)
79+
80+
const unmatchedEndpointPaths = paths
81+
.filter(
82+
(path) =>
83+
!routePaths.some((routePath) => isEndpointUnderRoute(path, routePath)),
84+
)
85+
.filter((path) => !ignoredEndpointPaths.includes(path))
86+
87+
if (unmatchedEndpointPaths.length > 0) {
88+
// eslint-disable-next-line no-console
89+
console.warn(
90+
`The following endpoints will not be generated:\n${unmatchedEndpointPaths.join(
91+
'\n',
92+
)}`,
93+
)
94+
}
95+
96+
return routePaths.map(createRoute)
97+
}
98+
99+
const createRoute = (routePath: string): Route => {
100+
return {
101+
namespace: routePath.split('/').join('_').slice(1),
102+
endpoints: [],
103+
}
104+
}
105+
106+
const routes = createRoutes()
107+
22108
const renderRoute = (route: Route): string => `
23109
/*
24110
* Automatically generated by generate-routes.ts.
@@ -43,9 +129,9 @@ import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
43129
import { parseOptions } from 'lib/seam/connect/parse-options.js'
44130
`
45131

46-
const renderClass = ({ endpoints }: Route): string =>
132+
const renderClass = ({ namespace, endpoints }: Route): string =>
47133
`
48-
export class SeamHttpWorkspaces {
134+
export class SeamHttp${pascalCase(namespace)} {
49135
client: Axios
50136
51137
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
@@ -112,11 +198,6 @@ type ${renderResponseType({ name, namespace })}= SetNonNullable<
112198
>
113199
`
114200

115-
const getRequestFormat = (
116-
method: Endpoint['method'],
117-
): Endpoint['requestFormat'] =>
118-
['GET', 'DELETE'].includes(method) ? 'params' : 'body'
119-
120201
const renderRequestType = ({
121202
name,
122203
namespace,
@@ -130,22 +211,12 @@ const renderResponseType = ({
130211
}: Pick<Endpoint, 'name' | 'namespace'>): string =>
131212
[pascalCase(namespace), pascalCase(name), 'Response'].join('')
132213

133-
const exampleRoute: Route = {
134-
namespace: 'workspaces',
135-
endpoints: [
136-
{
137-
name: 'get',
138-
namespace: 'workspaces',
139-
path: '/workspaces/get',
140-
method: 'GET',
141-
resource: 'workspace',
142-
requestFormat: getRequestFormat('GET'),
143-
},
144-
],
145-
}
146-
147214
const write = async (data: string, ...path: string[]): Promise<void> => {
148215
const filePath = resolve(...path)
216+
await writeFile(
217+
filePath,
218+
'// Generated empty file to allow ESLint parsing by filename',
219+
)
149220
const fixedOutput = await eslintFixOutput(data, filePath)
150221
const prettyOutput = await prettierOutput(fixedOutput, filePath)
151222
await writeFile(filePath, prettyOutput)
@@ -187,11 +258,12 @@ const eslintFixOutput = async (
187258
return linted.output ?? linted.source ?? data
188259
}
189260

190-
const routeRootPath = resolve('src', 'lib', 'seam', 'connect', 'routes')
191261
const writeRoute = async (route: Route): Promise<void> => {
192-
await write(renderRoute(route), routeRootPath, `${route.namespace}.ts`)
262+
await write(
263+
renderRoute(route),
264+
routeOutputPath,
265+
`${paramCase(route.namespace)}.ts`,
266+
)
193267
}
194268

195-
const routes = [exampleRoute]
196-
197269
await Promise.all(routes.map(writeRoute))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpAccessCodesUnmanaged {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpAccessCodes {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpAcsAccessGroups {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpAcsCredentials {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpAcsSystems {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpAcsUsers {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpActionAttempts {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpClientSessions {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Automatically generated by generate-routes.ts.
3+
* Do not edit this file or add other files to this directory.
4+
*/
5+
6+
import { Axios } from 'axios'
7+
8+
import { createAxiosClient } from 'lib/seam/connect/axios.js'
9+
import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js'
10+
import { parseOptions } from 'lib/seam/connect/parse-options.js'
11+
12+
export class SeamHttpConnectWebviews {
13+
client: Axios
14+
15+
constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) {
16+
if (apiKeyOrOptionsOrClient instanceof Axios) {
17+
this.client = apiKeyOrOptionsOrClient
18+
return
19+
}
20+
21+
const options = parseOptions(apiKeyOrOptionsOrClient)
22+
this.client = createAxiosClient(options)
23+
}
24+
}

0 commit comments

Comments
 (0)