typespec-rust-emitter 0.10.3 → 0.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +65 -0
- package/CHANGELOG.md +15 -0
- package/dist/src/emitter.js +32 -6
- package/dist/src/emitter.js.map +1 -1
- package/dist/test/hello.test.js +37 -0
- package/dist/test/hello.test.js.map +1 -1
- package/dist/test/test-host.js +6 -1
- package/dist/test/test-host.js.map +1 -1
- package/example/lib/learning/models.tsp +38 -0
- package/example/lib/learning/operations.tsp +14 -0
- package/example/output-rust/Cargo.lock +29 -0
- package/example/output-rust/Cargo.toml +1 -0
- package/example/output-rust/src/generated/server.rs +51 -0
- package/example/output-rust/src/generated/types.rs +86 -0
- package/example/package-lock.json +170 -127
- package/example/package.json +3 -1
- package/example/tspconfig.yaml +1 -1
- package/package.json +3 -1
- package/src/emitter.ts +39 -7
- package/test/hello.test.ts +48 -0
- package/test/test-host.ts +6 -1
|
@@ -52,7 +52,10 @@ pub trait Server: Send + Sync {
|
|
|
52
52
|
/// The server closes the current Timelog if it is running, and updates Log.stoppedAt.
|
|
53
53
|
/// Returns 409 if the session is already Stopped.
|
|
54
54
|
async fn sessions_stop(&self, claims: Self::Claims, account_id: uuid::Uuid, subject_id: i64, log_id: i64, body: SessionNoteBody) -> Result<SessionsStopResponse>;
|
|
55
|
+
/// Server-Sent Events stream for learning data changes.
|
|
56
|
+
async fn accounts_events(&self, account_id: uuid::Uuid) -> Result<AccountsEventsResponse>;
|
|
55
57
|
}
|
|
58
|
+
#[allow(clippy::type_complexity)]
|
|
56
59
|
pub enum GroupsListResponse {
|
|
57
60
|
Ok(Json<Vec<GroupStatistics>>),
|
|
58
61
|
Unauthorized(Json<ApiError>),
|
|
@@ -68,6 +71,7 @@ impl IntoResponse for GroupsListResponse {
|
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
#[allow(clippy::type_complexity)]
|
|
71
75
|
pub enum GroupsCalendarResponse {
|
|
72
76
|
Ok(Json<Vec<CalendarHeatmapItem>>),
|
|
73
77
|
Unauthorized(Json<ApiError>),
|
|
@@ -83,6 +87,7 @@ impl IntoResponse for GroupsCalendarResponse {
|
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
#[allow(clippy::type_complexity)]
|
|
86
91
|
pub enum GroupsCreateResponse {
|
|
87
92
|
Created(Json<Group>),
|
|
88
93
|
BadRequest(Json<ValidationError>),
|
|
@@ -100,6 +105,7 @@ impl IntoResponse for GroupsCreateResponse {
|
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
|
|
108
|
+
#[allow(clippy::type_complexity)]
|
|
103
109
|
pub enum GroupsGetByIdResponse {
|
|
104
110
|
Ok(Json<GroupStatistics>),
|
|
105
111
|
Unauthorized(Json<ApiError>),
|
|
@@ -117,6 +123,7 @@ impl IntoResponse for GroupsGetByIdResponse {
|
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
125
|
|
|
126
|
+
#[allow(clippy::type_complexity)]
|
|
120
127
|
pub enum GroupsUpdateResponse {
|
|
121
128
|
Ok(Json<Group>),
|
|
122
129
|
BadRequest(Json<ValidationError>),
|
|
@@ -136,6 +143,7 @@ impl IntoResponse for GroupsUpdateResponse {
|
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
|
|
146
|
+
#[allow(clippy::type_complexity)]
|
|
139
147
|
pub enum GroupsDeleteResponse {
|
|
140
148
|
NoContent,
|
|
141
149
|
Unauthorized(Json<ApiError>),
|
|
@@ -153,6 +161,7 @@ impl IntoResponse for GroupsDeleteResponse {
|
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
|
|
164
|
+
#[allow(clippy::type_complexity)]
|
|
156
165
|
pub enum SubjectsListResponse {
|
|
157
166
|
Ok(Json<Vec<SubjectStatistics>>),
|
|
158
167
|
Unauthorized(Json<ApiError>),
|
|
@@ -170,6 +179,7 @@ impl IntoResponse for SubjectsListResponse {
|
|
|
170
179
|
}
|
|
171
180
|
}
|
|
172
181
|
|
|
182
|
+
#[allow(clippy::type_complexity)]
|
|
173
183
|
pub enum SubjectsCreateResponse {
|
|
174
184
|
Created(Json<Subject>),
|
|
175
185
|
BadRequest(Json<ValidationError>),
|
|
@@ -189,6 +199,7 @@ impl IntoResponse for SubjectsCreateResponse {
|
|
|
189
199
|
}
|
|
190
200
|
}
|
|
191
201
|
|
|
202
|
+
#[allow(clippy::type_complexity)]
|
|
192
203
|
pub enum SubjectsGetByIdResponse {
|
|
193
204
|
Ok(Json<SubjectStatistics>),
|
|
194
205
|
Unauthorized(Json<ApiError>),
|
|
@@ -206,6 +217,7 @@ impl IntoResponse for SubjectsGetByIdResponse {
|
|
|
206
217
|
}
|
|
207
218
|
}
|
|
208
219
|
|
|
220
|
+
#[allow(clippy::type_complexity)]
|
|
209
221
|
pub enum SubjectsUpdateResponse {
|
|
210
222
|
Ok(Json<Subject>),
|
|
211
223
|
BadRequest(Json<ValidationError>),
|
|
@@ -225,6 +237,7 @@ impl IntoResponse for SubjectsUpdateResponse {
|
|
|
225
237
|
}
|
|
226
238
|
}
|
|
227
239
|
|
|
240
|
+
#[allow(clippy::type_complexity)]
|
|
228
241
|
pub enum SubjectsDeleteResponse {
|
|
229
242
|
NoContent,
|
|
230
243
|
Unauthorized(Json<ApiError>),
|
|
@@ -242,6 +255,7 @@ impl IntoResponse for SubjectsDeleteResponse {
|
|
|
242
255
|
}
|
|
243
256
|
}
|
|
244
257
|
|
|
258
|
+
#[allow(clippy::type_complexity)]
|
|
245
259
|
pub enum SessionsStartResponse {
|
|
246
260
|
Created(Json<SessionOpenedResponse>),
|
|
247
261
|
Unauthorized(Json<ApiError>),
|
|
@@ -261,6 +275,7 @@ impl IntoResponse for SessionsStartResponse {
|
|
|
261
275
|
}
|
|
262
276
|
}
|
|
263
277
|
|
|
278
|
+
#[allow(clippy::type_complexity)]
|
|
264
279
|
pub enum SessionsPauseResponse {
|
|
265
280
|
Ok(Json<SessionClosedResponse>),
|
|
266
281
|
Unauthorized(Json<ApiError>),
|
|
@@ -280,6 +295,7 @@ impl IntoResponse for SessionsPauseResponse {
|
|
|
280
295
|
}
|
|
281
296
|
}
|
|
282
297
|
|
|
298
|
+
#[allow(clippy::type_complexity)]
|
|
283
299
|
pub enum SessionsResumeResponse {
|
|
284
300
|
Ok(Json<SessionOpenedResponse>),
|
|
285
301
|
Unauthorized(Json<ApiError>),
|
|
@@ -299,6 +315,7 @@ impl IntoResponse for SessionsResumeResponse {
|
|
|
299
315
|
}
|
|
300
316
|
}
|
|
301
317
|
|
|
318
|
+
#[allow(clippy::type_complexity)]
|
|
302
319
|
pub enum SessionsStopResponse {
|
|
303
320
|
Ok(Json<SessionClosedResponse>),
|
|
304
321
|
Unauthorized(Json<ApiError>),
|
|
@@ -318,6 +335,20 @@ impl IntoResponse for SessionsStopResponse {
|
|
|
318
335
|
}
|
|
319
336
|
}
|
|
320
337
|
|
|
338
|
+
#[allow(clippy::type_complexity)]
|
|
339
|
+
pub enum AccountsEventsResponse {
|
|
340
|
+
Ok(axum::response::sse::Sse<std::pin::Pin<Box<dyn futures::stream::Stream<Item = Result<axum::response::sse::Event, std::convert::Infallible>> + Send>>>),
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
impl IntoResponse for AccountsEventsResponse {
|
|
344
|
+
fn into_response(self) -> axum::response::Response {
|
|
345
|
+
match self {
|
|
346
|
+
|
|
347
|
+
AccountsEventsResponse::Ok(body) => body.into_response(),
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
321
352
|
use axum::extract::Query;
|
|
322
353
|
use axum::routing::{delete, get, patch, post};
|
|
323
354
|
use axum::Router;
|
|
@@ -634,6 +665,25 @@ where
|
|
|
634
665
|
}
|
|
635
666
|
}
|
|
636
667
|
|
|
668
|
+
pub async fn accounts_events_handler<S>(
|
|
669
|
+
axum::extract::State(service): axum::extract::State<S>,
|
|
670
|
+
Path(account_id): Path<uuid::Uuid>,
|
|
671
|
+
) -> impl axum::response::IntoResponse
|
|
672
|
+
where
|
|
673
|
+
S: Server + Clone + Send + Sync + 'static,
|
|
674
|
+
S::Claims: Send + Sync + Clone + 'static,
|
|
675
|
+
{
|
|
676
|
+
let result = service.accounts_events(account_id).await;
|
|
677
|
+
match result {
|
|
678
|
+
Ok(response) => response.into_response(),
|
|
679
|
+
Err(e) => (
|
|
680
|
+
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
|
|
681
|
+
format!("Internal error: {e}"),
|
|
682
|
+
)
|
|
683
|
+
.into_response(),
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
637
687
|
pub fn create_router<S, M>(service: S, middleware: M) -> Router
|
|
638
688
|
where
|
|
639
689
|
S: Server + Clone + Send + Sync + 'static,
|
|
@@ -647,6 +697,7 @@ where
|
|
|
647
697
|
.route("/accounts/{accountId}/learning/groups/{id}", get(groups_get_by_id_handler::<S>))
|
|
648
698
|
.route("/accounts/{accountId}/learning/groups/{groupId}/subjects", get(subjects_list_handler::<S>))
|
|
649
699
|
.route("/accounts/{accountId}/learning/groups/{groupId}/subjects/{id}", get(subjects_get_by_id_handler::<S>))
|
|
700
|
+
.route("/accounts/{accountId}/learning/accounts/{accountId}/events", get(accounts_events_handler::<S>))
|
|
650
701
|
;
|
|
651
702
|
router = router.merge(public);
|
|
652
703
|
let protected = Router::new()
|
|
@@ -225,6 +225,44 @@ pub struct Timelog {
|
|
|
225
225
|
pub duration_in_seconds: i64,
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
229
|
+
pub struct LogWithTimelogs {
|
|
230
|
+
pub id: i64,
|
|
231
|
+
#[serde(rename = "accountId")]
|
|
232
|
+
pub account_id: uuid::Uuid,
|
|
233
|
+
#[serde(rename = "subjectId")]
|
|
234
|
+
pub subject_id: i64,
|
|
235
|
+
#[serde(rename = "startedAt")]
|
|
236
|
+
pub started_at: chrono::DateTime<chrono::Utc>,
|
|
237
|
+
#[serde(rename = "stoppedAt")]
|
|
238
|
+
pub stopped_at: Option<chrono::DateTime<chrono::Utc>>,
|
|
239
|
+
#[serde(rename = "logContent")]
|
|
240
|
+
pub log_content: Option<String>,
|
|
241
|
+
pub status: StudyStatus,
|
|
242
|
+
pub timelogs: Vec<Timelog>,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
246
|
+
pub struct SessionEvent {
|
|
247
|
+
#[serde(rename = "eventType")]
|
|
248
|
+
pub event_type: EnumSessionSessionpause4,
|
|
249
|
+
pub session: LogWithTimelogs,
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
253
|
+
pub struct GroupEvent {
|
|
254
|
+
#[serde(rename = "eventType")]
|
|
255
|
+
pub event_type: EnumGroupcreatedGroupupdated3,
|
|
256
|
+
pub group: Group,
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
260
|
+
pub struct SubjectEvent {
|
|
261
|
+
#[serde(rename = "eventType")]
|
|
262
|
+
pub event_type: EnumSubjectcreatedSubjectupdated4,
|
|
263
|
+
pub subject: Subject,
|
|
264
|
+
}
|
|
265
|
+
|
|
228
266
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
229
267
|
pub struct SessionOpenedResponse {
|
|
230
268
|
pub log: Log,
|
|
@@ -244,6 +282,46 @@ pub struct SessionNoteBody {
|
|
|
244
282
|
pub log_content: Option<String>,
|
|
245
283
|
}
|
|
246
284
|
|
|
285
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize)]
|
|
286
|
+
#[allow(clippy::enum_variant_names)]
|
|
287
|
+
pub enum EnumSessionSessionpause4 {
|
|
288
|
+
#[default]
|
|
289
|
+
#[serde(rename = "session")]
|
|
290
|
+
Session,
|
|
291
|
+
#[serde(rename = "session_pause")]
|
|
292
|
+
SessionPause,
|
|
293
|
+
#[serde(rename = "session_resume")]
|
|
294
|
+
SessionResume,
|
|
295
|
+
#[serde(rename = "session_stop")]
|
|
296
|
+
SessionStop,
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize)]
|
|
300
|
+
#[allow(clippy::enum_variant_names)]
|
|
301
|
+
pub enum EnumGroupcreatedGroupupdated3 {
|
|
302
|
+
#[default]
|
|
303
|
+
#[serde(rename = "group_created")]
|
|
304
|
+
GroupCreated,
|
|
305
|
+
#[serde(rename = "group_updated")]
|
|
306
|
+
GroupUpdated,
|
|
307
|
+
#[serde(rename = "group_deleted")]
|
|
308
|
+
GroupDeleted,
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize)]
|
|
312
|
+
#[allow(clippy::enum_variant_names)]
|
|
313
|
+
pub enum EnumSubjectcreatedSubjectupdated4 {
|
|
314
|
+
#[default]
|
|
315
|
+
#[serde(rename = "subject_created")]
|
|
316
|
+
SubjectCreated,
|
|
317
|
+
#[serde(rename = "subject_updated")]
|
|
318
|
+
SubjectUpdated,
|
|
319
|
+
#[serde(rename = "subject_deleted")]
|
|
320
|
+
SubjectDeleted,
|
|
321
|
+
#[serde(rename = "subject_moved")]
|
|
322
|
+
SubjectMoved,
|
|
323
|
+
}
|
|
324
|
+
|
|
247
325
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize, sqlx::Type)]
|
|
248
326
|
#[sqlx(type_name = "study_status")]
|
|
249
327
|
pub enum StudyStatus {
|
|
@@ -269,6 +347,14 @@ pub enum ChartGranularity {
|
|
|
269
347
|
Year,
|
|
270
348
|
}
|
|
271
349
|
|
|
350
|
+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
|
351
|
+
#[serde(untagged)]
|
|
352
|
+
pub enum LearningEvents {
|
|
353
|
+
Variant1(SessionEvent),
|
|
354
|
+
Variant2(GroupEvent),
|
|
355
|
+
Variant3(SubjectEvent),
|
|
356
|
+
}
|
|
357
|
+
|
|
272
358
|
pub type Uuid = uuid::Uuid;
|
|
273
359
|
|
|
274
360
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize)]
|