Skip to content

Commit ff9e195

Browse files
Generate /action_attempts route, add special handling for AA resource
1 parent 18b10ed commit ff9e195

4 files changed

Lines changed: 113 additions & 8 deletions

File tree

src/data/paths.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,8 @@
8080
title: Enrollment Automations
8181
resources:
8282
- enrollment_automation
83+
84+
/action_attempts:
85+
title: Action Attempts
86+
resources:
87+
- action_attempt
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import type { Blueprint } from '@seamapi/blueprint'
2+
3+
import {
4+
type ApiError,
5+
type ApiRouteEvent,
6+
type ApiRouteProperty,
7+
type ApiRouteResource,
8+
type ApiWarning,
9+
mapBlueprintPropertyToRouteProperty,
10+
type ResourceSampleContext,
11+
} from './api-route.js'
12+
13+
export function processActionAttemptResource(
14+
blueprint: Blueprint,
15+
resources: Array<
16+
ApiRouteResource & {
17+
warnings: ApiWarning[]
18+
errors: ApiError[]
19+
resourceSamples: ResourceSampleContext[]
20+
}
21+
>,
22+
eventsByRoutePath: Map<string, ApiRouteEvent[]>,
23+
): void {
24+
const blueprintActionAttemptDef = blueprint.actionAttempts[0]
25+
if (blueprintActionAttemptDef == null) {
26+
throw new Error(
27+
'Cannot process action attempt resource: blueprint.actionAttempts is empty.',
28+
)
29+
}
30+
31+
const idPropKey = 'action_attempt_id'
32+
const idPropDef = blueprintActionAttemptDef.properties.find(
33+
(p) => p.name === idPropKey,
34+
)
35+
if (idPropDef == null) {
36+
throw new Error(
37+
`Blueprint action attempt is missing "${idPropKey}" property.`,
38+
)
39+
}
40+
41+
const statusPropKey = 'status'
42+
const statusPropDef = blueprintActionAttemptDef.properties.find(
43+
(p) => p.name === statusPropKey,
44+
)
45+
if (statusPropDef == null) {
46+
throw new Error(
47+
`Blueprint action attempt is missing "${statusPropKey}" property.`,
48+
)
49+
}
50+
51+
const actionTypes = blueprint.actionAttempts.map(
52+
(attempt) => attempt.actionAttemptType,
53+
)
54+
55+
const properties: ApiRouteProperty[] = [
56+
mapBlueprintPropertyToRouteProperty(idPropDef),
57+
mapBlueprintPropertyToRouteProperty(statusPropDef),
58+
{
59+
name: 'action_type',
60+
description: 'Type of the action attempt.',
61+
format: 'String',
62+
isDeprecated: false,
63+
deprecationMessage: '',
64+
enumValues: actionTypes,
65+
},
66+
{
67+
name: 'error',
68+
description:
69+
'Errors associated with the action attempt. Null for pending action attempts.',
70+
format: 'Object',
71+
isDeprecated: false,
72+
deprecationMessage: '',
73+
},
74+
{
75+
name: 'result',
76+
description:
77+
'Result of the action attempt. Null for pending action attempts.',
78+
format: 'Object',
79+
isDeprecated: false,
80+
deprecationMessage: '',
81+
},
82+
]
83+
84+
resources.push({
85+
name: 'action_attempt',
86+
description: 'Represents an attempt to perform an action against a device.',
87+
properties,
88+
errors: [],
89+
warnings: [],
90+
events: eventsByRoutePath.get('/action_attempts') ?? [],
91+
resourceSamples: [],
92+
})
93+
}

src/lib/layout/api-route.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import type { ResourceSample } from 'node_modules/@seamapi/blueprint/lib/samples
1515

1616
import type { PathMetadata } from 'lib/path-metadata.js'
1717

18+
import { processActionAttemptResource } from './action-attempt-resource.js'
19+
1820
export interface ApiRouteLayoutContext {
1921
title: string
2022
description: string
@@ -30,19 +32,19 @@ export interface ApiRouteLayoutContext {
3032
events: ApiRouteEvent[]
3133
}
3234

33-
interface ApiRouteEvent {
35+
export interface ApiRouteEvent {
3436
name: string
3537
description: string
3638
properties: ApiRouteProperty[]
3739
}
3840

39-
interface ResourceSampleContext {
41+
export interface ResourceSampleContext {
4042
title: string
4143
resourceData: string
4244
resourceDataSyntax: SyntaxName
4345
}
4446

45-
type ApiRouteProperty = Pick<
47+
export type ApiRouteProperty = Pick<
4648
Property,
4749
'name' | 'description' | 'isDeprecated' | 'deprecationMessage'
4850
> & {
@@ -68,11 +70,12 @@ export interface ApiRouteResource {
6870
events: ApiRouteEvent[]
6971
}
7072

71-
interface ApiWarning {
73+
export interface ApiWarning {
7274
name: string
7375
description: string
7476
}
75-
interface ApiError {
77+
78+
export interface ApiError {
7679
name: string
7780
description: string
7881
}
@@ -108,6 +111,11 @@ export function setApiRouteLayoutContext(
108111

109112
file.resources = []
110113
for (const resourceType of metadata.resources) {
114+
if (resourceType === 'action_attempt') {
115+
processActionAttemptResource(blueprint, file.resources, eventsByRoutePath)
116+
continue
117+
}
118+
111119
const resource = blueprint.resources[resourceType]
112120

113121
if (resource == null) {
@@ -150,8 +158,6 @@ const groupEventsByRoutePath = (
150158
const eventsByRoutePath = new Map<string, ApiRouteEvent[]>()
151159

152160
for (const event of events) {
153-
if (event.routePath == null) continue
154-
155161
const routeEvents = eventsByRoutePath.get(event.routePath) ?? []
156162
routeEvents.push({
157163
name: event.eventType,

src/lib/reference.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ export const reference = (
5757
!route.path.startsWith('/acs') &&
5858
!route.path.startsWith('/thermostats') &&
5959
!route.path.startsWith('/phones') &&
60-
!route.path.startsWith('/user_identities')
60+
!route.path.startsWith('/user_identities') &&
61+
!route.path.startsWith('/action_attempts')
6162
) {
6263
continue
6364
}

0 commit comments

Comments
 (0)