@workos/oagen-emitters 0.4.0 → 0.5.0

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.
Files changed (105) hide show
  1. package/.github/workflows/ci.yml +1 -1
  2. package/.github/workflows/lint.yml +1 -1
  3. package/.github/workflows/release-please.yml +2 -2
  4. package/.github/workflows/release.yml +1 -1
  5. package/.husky/pre-push +11 -0
  6. package/.node-version +1 -1
  7. package/.release-please-manifest.json +1 -1
  8. package/CHANGELOG.md +8 -0
  9. package/README.md +35 -224
  10. package/dist/index.d.mts +9 -1
  11. package/dist/index.d.mts.map +1 -1
  12. package/dist/index.mjs +2 -15234
  13. package/dist/plugin-BSop9f9z.mjs +21471 -0
  14. package/dist/plugin-BSop9f9z.mjs.map +1 -0
  15. package/dist/plugin.d.mts +7 -0
  16. package/dist/plugin.d.mts.map +1 -0
  17. package/dist/plugin.mjs +2 -0
  18. package/docs/sdk-architecture/dotnet.md +5 -5
  19. package/oagen.config.ts +5 -373
  20. package/package.json +10 -34
  21. package/src/dotnet/index.ts +6 -4
  22. package/src/dotnet/models.ts +58 -82
  23. package/src/dotnet/naming.ts +44 -6
  24. package/src/dotnet/resources.ts +350 -29
  25. package/src/dotnet/tests.ts +44 -24
  26. package/src/dotnet/type-map.ts +44 -17
  27. package/src/dotnet/wrappers.ts +21 -10
  28. package/src/go/client.ts +35 -3
  29. package/src/go/enums.ts +4 -0
  30. package/src/go/index.ts +10 -5
  31. package/src/go/models.ts +6 -1
  32. package/src/go/resources.ts +534 -73
  33. package/src/go/tests.ts +39 -3
  34. package/src/go/type-map.ts +8 -3
  35. package/src/go/wrappers.ts +79 -21
  36. package/src/index.ts +14 -0
  37. package/src/kotlin/client.ts +7 -2
  38. package/src/kotlin/enums.ts +30 -3
  39. package/src/kotlin/models.ts +97 -6
  40. package/src/kotlin/naming.ts +7 -1
  41. package/src/kotlin/resources.ts +370 -39
  42. package/src/kotlin/tests.ts +120 -6
  43. package/src/node/client.ts +38 -11
  44. package/src/node/field-plan.ts +12 -14
  45. package/src/node/fixtures.ts +39 -3
  46. package/src/node/models.ts +281 -37
  47. package/src/node/resources.ts +156 -52
  48. package/src/node/tests.ts +76 -27
  49. package/src/node/type-map.ts +1 -31
  50. package/src/node/utils.ts +96 -6
  51. package/src/node/wrappers.ts +31 -1
  52. package/src/php/models.ts +0 -33
  53. package/src/php/resources.ts +199 -18
  54. package/src/php/tests.ts +26 -2
  55. package/src/php/type-map.ts +16 -2
  56. package/src/php/wrappers.ts +6 -2
  57. package/src/plugin.ts +50 -0
  58. package/src/python/client.ts +13 -3
  59. package/src/python/enums.ts +28 -3
  60. package/src/python/index.ts +35 -27
  61. package/src/python/models.ts +138 -1
  62. package/src/python/resources.ts +234 -17
  63. package/src/python/tests.ts +260 -16
  64. package/src/python/type-map.ts +16 -2
  65. package/src/ruby/client.ts +238 -0
  66. package/src/ruby/enums.ts +149 -0
  67. package/src/ruby/index.ts +93 -0
  68. package/src/ruby/manifest.ts +35 -0
  69. package/src/ruby/models.ts +360 -0
  70. package/src/ruby/naming.ts +187 -0
  71. package/src/ruby/rbi.ts +313 -0
  72. package/src/ruby/resources.ts +799 -0
  73. package/src/ruby/tests.ts +459 -0
  74. package/src/ruby/type-map.ts +97 -0
  75. package/src/ruby/wrappers.ts +161 -0
  76. package/src/shared/model-utils.ts +131 -7
  77. package/src/shared/naming-utils.ts +36 -0
  78. package/src/shared/non-spec-services.ts +13 -0
  79. package/src/shared/resolved-ops.ts +75 -1
  80. package/test/dotnet/client.test.ts +2 -2
  81. package/test/dotnet/models.test.ts +7 -9
  82. package/test/dotnet/resources.test.ts +135 -3
  83. package/test/dotnet/tests.test.ts +5 -5
  84. package/test/entrypoint.test.ts +89 -0
  85. package/test/go/client.test.ts +6 -6
  86. package/test/go/resources.test.ts +156 -7
  87. package/test/kotlin/models.test.ts +1 -1
  88. package/test/kotlin/resources.test.ts +210 -0
  89. package/test/node/models.test.ts +134 -1
  90. package/test/node/resources.test.ts +134 -26
  91. package/test/node/utils.test.ts +140 -0
  92. package/test/php/models.test.ts +5 -4
  93. package/test/php/resources.test.ts +66 -1
  94. package/test/plugin.test.ts +50 -0
  95. package/test/python/client.test.ts +56 -0
  96. package/test/python/models.test.ts +99 -0
  97. package/test/python/resources.test.ts +294 -0
  98. package/test/python/tests.test.ts +91 -0
  99. package/test/ruby/client.test.ts +81 -0
  100. package/test/ruby/resources.test.ts +386 -0
  101. package/test/shared/resolved-ops.test.ts +122 -0
  102. package/tsdown.config.ts +1 -1
  103. package/dist/index.mjs.map +0 -1
  104. package/scripts/generate-php.js +0 -13
  105. package/scripts/git-push-with-published-oagen.sh +0 -21
@@ -0,0 +1,7 @@
1
+ import { OagenConfig } from "@workos/oagen";
2
+
3
+ //#region src/plugin.d.ts
4
+ declare const workosEmittersPlugin: Pick<OagenConfig, 'emitters' | 'extractors' | 'smokeRunners'>;
5
+ //#endregion
6
+ export { workosEmittersPlugin };
7
+ //# sourceMappingURL=plugin.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;cAyBa,oBAAA,EAAsB,IAAA,CAAK,WAAA"}
@@ -0,0 +1,2 @@
1
+ import { t as workosEmittersPlugin } from "./plugin-BSop9f9z.mjs";
2
+ export { workosEmittersPlugin };
@@ -226,11 +226,11 @@ public class WorkOSList<T>
226
226
 
227
227
  The runtime translates HTTP status codes to SDK-native exceptions:
228
228
 
229
- - `AuthenticationError` (401)
230
- - `NotFoundError` (404)
231
- - `UnprocessableEntityError` (422)
232
- - `RateLimitExceededError` (429)
233
- - `ServerError` (500+)
229
+ - `AuthenticationException` (401)
230
+ - `NotFoundException` (404)
231
+ - `UnprocessableEntityException` (422)
232
+ - `RateLimitExceededException` (429)
233
+ - `ServerException` (500+)
234
234
 
235
235
  These are hand-maintained in the runtime. The emitter generates error-handling _tests_, not the error classes themselves.
236
236
 
package/oagen.config.ts CHANGED
@@ -1,377 +1,9 @@
1
- import type { OagenConfig, OperationHint } from '@workos/oagen';
2
- import { toCamelCase } from '@workos/oagen';
3
- import { nodeEmitter } from './src/node/index.js';
4
- import { pythonEmitter } from './src/python/index.js';
5
- import { phpEmitter } from './src/php/index.js';
6
- import { goEmitter } from './src/go/index.js';
7
- import { dotnetEmitter } from './src/dotnet/index.js';
8
- import { kotlinEmitter } from './src/kotlin/index.js';
9
- import { nodeExtractor } from './src/compat/extractors/node.js';
10
- import { rubyExtractor } from './src/compat/extractors/ruby.js';
11
- import { pythonExtractor } from './src/compat/extractors/python.js';
12
- import { phpExtractor } from './src/compat/extractors/php.js';
13
- import { goExtractor } from './src/compat/extractors/go.js';
14
- import { rustExtractor } from './src/compat/extractors/rust.js';
15
- import { kotlinExtractor } from './src/compat/extractors/kotlin.js';
16
- import { dotnetExtractor } from './src/compat/extractors/dotnet.js';
17
- import { elixirExtractor } from './src/compat/extractors/elixir.js';
18
-
19
- /**
20
- * NestJS-style operationId transform. Strips "Controller" and extracts the
21
- * action after the first underscore: `FooController_bar` → `bar`.
22
- */
23
- function nestjsOperationIdTransform(id: string): string {
24
- const stripped = id.replace(/Controller/g, '');
25
- const idx = stripped.indexOf('_');
26
- return idx !== -1 ? toCamelCase(stripped.slice(idx + 1)) : toCamelCase(stripped);
27
- }
28
-
29
- // ---------------------------------------------------------------------------
30
- // Operation hints — per-operation overrides for the operation resolver.
31
- // Keyed by "METHOD /path". Only operations that need overrides are listed;
32
- // the algorithm handles the rest.
33
- // ---------------------------------------------------------------------------
34
- const operationHints: Record<string, OperationHint> = {
35
- // ── Radar ────────────────────────────────────────────────────────────────
36
- 'POST /radar/lists/{type}/{action}': { name: 'add_list_entry' },
37
- 'DELETE /radar/lists/{type}/{action}': { name: 'remove_list_entry' },
38
-
39
- // ── SSO ──────────────────────────────────────────────────────────────────
40
- 'GET /sso/authorize': {
41
- name: 'get_authorization_url',
42
- defaults: { response_type: 'code' },
43
- inferFromClient: ['client_id'],
44
- urlBuilder: true,
45
- },
46
- 'GET /sso/logout': { name: 'get_logout_url', urlBuilder: true },
47
- 'GET /sso/profile': { name: 'get_profile' },
48
- 'POST /sso/token': {
49
- name: 'get_profile_and_token',
50
- defaults: { grant_type: 'authorization_code' },
51
- inferFromClient: ['client_id', 'client_secret'],
52
- },
53
-
54
- // ── SSO / JWKS (mounted on UserManagement via mountRules) ────────────────
55
- 'GET /sso/jwks/{clientId}': { name: 'get_jwks' },
56
-
57
- // ── User Management — auth ──────────────────────────────────────────────
58
- 'GET /user_management/authorize': {
59
- name: 'get_authorization_url',
60
- defaults: { response_type: 'code' },
61
- inferFromClient: ['client_id'],
62
- urlBuilder: true,
63
- },
64
- 'GET /user_management/sessions/logout': { name: 'get_logout_url', urlBuilder: true },
65
-
66
- // ── User Management — org membership actions ────────────────────────────
67
- 'PUT /user_management/organization_memberships/{id}/deactivate': {
68
- name: 'deactivate_organization_membership',
69
- },
70
- 'PUT /user_management/organization_memberships/{id}/reactivate': {
71
- name: 'reactivate_organization_membership',
72
- },
73
-
74
- // ── Admin Portal ────────────────────────────────────────────────────────
75
- 'POST /portal/generate_link': { name: 'generate_link' },
76
-
77
- // ── Feature Flags — disambiguate co-mounted list operations ─────────────
78
- 'GET /organizations/{organizationId}/feature-flags': { name: 'list_organization_feature_flags' },
79
- 'GET /user_management/users/{userId}/feature-flags': { name: 'list_user_feature_flags' },
80
-
81
- // ── External ID lookups (not derivable from path) ──────────────────────
82
- 'GET /organizations/external_id/{external_id}': { name: 'get_organization_by_external_id' },
83
- 'GET /user_management/users/external_id/{external_id}': { name: 'get_user_by_external_id' },
84
-
85
- // ── Authorization — environment-scoped roles ─────────────────────────────
86
- 'GET /authorization/roles': { name: 'list_environment_roles' },
87
- 'POST /authorization/roles': { name: 'create_environment_role' },
88
- 'GET /authorization/roles/{slug}': { name: 'get_environment_role' },
89
- 'PATCH /authorization/roles/{slug}': { name: 'update_environment_role' },
90
- 'PUT /authorization/roles/{slug}/permissions': {
91
- name: 'set_environment_role_permissions',
92
- },
93
- 'POST /authorization/roles/{slug}/permissions': {
94
- name: 'add_environment_role_permission',
95
- },
96
-
97
- // ── Authorization — singularized/shortened names ────────────────────────
98
- 'POST /authorization/permissions': { name: 'create_permission' },
99
- 'POST /authorization/resources': { name: 'create_resource' },
100
- 'POST /authorization/organization_memberships/{organization_membership_id}/check': {
101
- name: 'check',
102
- },
103
- 'POST /authorization/organization_memberships/{organization_membership_id}/role_assignments': {
104
- name: 'assign_role',
105
- },
106
- 'DELETE /authorization/organization_memberships/{organization_membership_id}/role_assignments': {
107
- name: 'remove_role',
108
- },
109
- 'POST /authorization/organizations/{organizationId}/roles': {
110
- name: 'create_organization_role',
111
- },
112
-
113
- // ── Authorization — env-scoped resource memberships ────────────────────
114
- 'GET /authorization/resources/{resource_id}/organization_memberships': { name: 'list_memberships_for_resource' },
115
-
116
- // ── User Management — singularized/shortened names ─────────────────────
117
- 'POST /user_management/users': { name: 'create_user' },
118
- 'POST /user_management/organization_memberships': {
119
- name: 'create_organization_membership',
120
- },
121
- 'POST /user_management/invitations': { name: 'send_invitation' },
122
- 'GET /user_management/invitations/by_token/{token}': {
123
- name: 'find_invitation_by_token',
124
- },
125
- 'POST /user_management/users/{id}/email_verification/send': {
126
- name: 'send_verification_email',
127
- },
128
- 'POST /user_management/users/{id}/email_verification/confirm': {
129
- name: 'verify_email',
130
- },
131
- 'POST /user_management/password_reset': { name: 'reset_password' },
132
- 'POST /user_management/password_reset/confirm': {
133
- name: 'confirm_password_reset',
134
- },
135
- 'GET /user_management/users/{id}/sessions': { name: 'list_sessions' },
136
- 'GET /user_management/users/{id}/identities': { name: 'get_user_identities' },
137
- 'POST /user_management/cors_origins': { name: 'create_cors_origin' },
138
- 'POST /user_management/redirect_uris': { name: 'create_redirect_uri' },
139
-
140
- // ── Organizations — singularized names ─────────────────────────────────
141
- 'POST /organizations': { name: 'create_organization' },
142
-
143
- // ── Directory Sync — shortened names ───────────────────────────────────
144
- 'GET /directory_groups': { name: 'list_groups' },
145
- 'GET /directory_groups/{id}': { name: 'get_group' },
146
- 'GET /directory_users': { name: 'list_users' },
147
- 'GET /directory_users/{id}': { name: 'get_user' },
148
-
149
- // ── Audit Logs — singularized names ────────────────────────────────────
150
- 'POST /audit_logs/events': { name: 'create_event' },
151
- 'POST /audit_logs/exports': { name: 'create_export' },
152
- 'POST /audit_logs/actions/{actionName}/schemas': { name: 'create_schema' },
153
-
154
- // ── Feature Flags — match SDK conventions ──────────────────────────────
155
- 'POST /feature-flags/{slug}/targets/{resourceId}': { name: 'add_flag_target' },
156
- 'DELETE /feature-flags/{slug}/targets/{resourceId}': {
157
- name: 'remove_flag_target',
158
- },
159
-
160
- // ── Organizations — audit log config (singular fetch, not a list) ───────
161
- 'GET /organizations/{id}/audit_log_configuration': {
162
- name: 'get_audit_log_configuration',
163
- },
164
-
165
- // ── Organizations — audit logs retention (mounted on AuditLogs) ─────────
166
- 'GET /organizations/{id}/audit_logs_retention': {
167
- name: 'get_organization_audit_logs_retention',
168
- mountOn: 'AuditLogs',
169
- },
170
- 'PUT /organizations/{id}/audit_logs_retention': { mountOn: 'AuditLogs' },
171
-
172
- // ── Union split: POST /user_management/authenticate (8 variants) ────────
173
- // Common optional fields appended to every variant's exposedParams so the
174
- // generated wrappers cover the full spec body shape (fraud/audit context the
175
- // server consumes when present).
176
- 'POST /user_management/authenticate': {
177
- split: [
178
- {
179
- name: 'authenticate_with_password',
180
- targetVariant: 'PasswordSessionAuthenticateRequest',
181
- defaults: { grant_type: 'password' },
182
- inferFromClient: ['client_id', 'client_secret'],
183
- exposedParams: ['email', 'password', 'invitation_token', 'ip_address', 'device_id', 'user_agent'],
184
- optionalParams: ['invitation_token', 'ip_address', 'device_id', 'user_agent'],
185
- },
186
- {
187
- name: 'authenticate_with_code',
188
- targetVariant: 'CodeSessionAuthenticateRequest',
189
- defaults: { grant_type: 'authorization_code' },
190
- inferFromClient: ['client_id', 'client_secret'],
191
- exposedParams: ['code', 'ip_address', 'device_id', 'user_agent'],
192
- optionalParams: ['ip_address', 'device_id', 'user_agent'],
193
- },
194
- {
195
- name: 'authenticate_with_refresh_token',
196
- targetVariant: 'RefreshTokenSessionAuthenticateRequest',
197
- defaults: { grant_type: 'refresh_token' },
198
- inferFromClient: ['client_id', 'client_secret'],
199
- exposedParams: ['refresh_token', 'organization_id', 'ip_address', 'device_id', 'user_agent'],
200
- optionalParams: ['organization_id', 'ip_address', 'device_id', 'user_agent'],
201
- },
202
- {
203
- name: 'authenticate_with_magic_auth',
204
- targetVariant: 'MagicAuthSessionAuthenticateRequest',
205
- defaults: { grant_type: 'urn:workos:oauth:grant-type:magic-auth:code' },
206
- inferFromClient: ['client_id', 'client_secret'],
207
- exposedParams: ['code', 'email', 'invitation_token', 'ip_address', 'device_id', 'user_agent'],
208
- optionalParams: ['invitation_token', 'ip_address', 'device_id', 'user_agent'],
209
- },
210
- {
211
- name: 'authenticate_with_email_verification',
212
- targetVariant: 'EmailVerificationSessionAuthenticateRequest',
213
- defaults: { grant_type: 'urn:workos:oauth:grant-type:email-verification:code' },
214
- inferFromClient: ['client_id', 'client_secret'],
215
- exposedParams: ['code', 'pending_authentication_token', 'ip_address', 'device_id', 'user_agent'],
216
- optionalParams: ['pending_authentication_token', 'ip_address', 'device_id', 'user_agent'],
217
- },
218
- {
219
- name: 'authenticate_with_totp',
220
- targetVariant: 'TotpSessionAuthenticateRequest',
221
- defaults: { grant_type: 'urn:workos:oauth:grant-type:mfa-totp' },
222
- inferFromClient: ['client_id', 'client_secret'],
223
- exposedParams: [
224
- 'code',
225
- 'pending_authentication_token',
226
- 'authentication_challenge_id',
227
- 'ip_address',
228
- 'device_id',
229
- 'user_agent',
230
- ],
231
- optionalParams: ['ip_address', 'device_id', 'user_agent'],
232
- },
233
- {
234
- name: 'authenticate_with_organization_selection',
235
- targetVariant: 'OrganizationSelectionSessionAuthenticateRequest',
236
- defaults: { grant_type: 'urn:workos:oauth:grant-type:organization-selection' },
237
- inferFromClient: ['client_id', 'client_secret'],
238
- exposedParams: ['pending_authentication_token', 'organization_id', 'ip_address', 'device_id', 'user_agent'],
239
- optionalParams: ['ip_address', 'device_id', 'user_agent'],
240
- },
241
- {
242
- name: 'authenticate_with_device_code',
243
- targetVariant: 'DeviceCodeSessionAuthenticateRequest',
244
- defaults: { grant_type: 'urn:ietf:params:oauth:grant-type:device_code' },
245
- inferFromClient: ['client_id'],
246
- exposedParams: ['device_code', 'ip_address', 'device_id', 'user_agent'],
247
- optionalParams: ['ip_address', 'device_id', 'user_agent'],
248
- },
249
- ],
250
- },
251
-
252
- // ── Union split: POST /connect/applications (2 variants) ────────────────
253
- 'POST /connect/applications': {
254
- split: [
255
- {
256
- name: 'create_oauth_application',
257
- targetVariant: 'CreateOAuthApplication',
258
- defaults: { application_type: 'oauth' },
259
- exposedParams: [
260
- 'name',
261
- 'is_first_party',
262
- 'description',
263
- 'scopes',
264
- 'redirect_uris',
265
- 'uses_pkce',
266
- 'organization_id',
267
- ],
268
- },
269
- {
270
- name: 'create_m2m_application',
271
- targetVariant: 'CreateM2MApplication',
272
- defaults: { application_type: 'm2m' },
273
- exposedParams: ['name', 'organization_id', 'description', 'scopes'],
274
- },
275
- ],
276
- },
277
- };
278
-
279
- // ---------------------------------------------------------------------------
280
- // Mount rules — service-level remounting. Maps IR service name → target
281
- // service/namespace (PascalCase). All operations in the source service are
282
- // mounted on the target unless overridden per-operation in operationHints.
283
- // ---------------------------------------------------------------------------
284
- const mountRules: Record<string, string> = {
285
- // MFA sub-services → MultiFactorAuth
286
- MultiFactorAuthChallenges: 'MultiFactorAuth',
287
-
288
- // RBAC permissions → Authorization
289
- Permissions: 'Authorization',
290
-
291
- // Connect sub-services → Connect
292
- WorkosConnect: 'Connect',
293
- Applications: 'Connect',
294
- ApplicationClientSecrets: 'Connect',
295
-
296
- // SSO connections → SSO
297
- Connections: 'SSO',
298
-
299
- // Directory Sync sub-services → DirectorySync
300
- Directories: 'DirectorySync',
301
- DirectoryGroups: 'DirectorySync',
302
- DirectoryUsers: 'DirectorySync',
303
-
304
- // Feature flag sub-services → FeatureFlags
305
- FeatureFlagsTargets: 'FeatureFlags',
306
- OrganizationsFeatureFlags: 'FeatureFlags',
307
- UserManagementUsersFeatureFlags: 'FeatureFlags',
308
-
309
- // Org API keys → ApiKeys
310
- OrganizationsApiKeys: 'ApiKeys',
311
-
312
- // User Management sub-services → UserManagement
313
- UserManagementSessionTokens: 'UserManagement',
314
- UserManagementAuthentication: 'UserManagement',
315
- UserManagementCorsOrigins: 'UserManagement',
316
- UserManagementUsers: 'UserManagement',
317
- UserManagementInvitations: 'UserManagement',
318
- UserManagementJWTTemplate: 'UserManagement',
319
- UserManagementMagicAuth: 'UserManagement',
320
- UserManagementOrganizationMembership: 'UserManagement',
321
- UserManagementRedirectUris: 'UserManagement',
322
- UserManagementUsersAuthorizedApplications: 'UserManagement',
323
-
324
- // Pipes / Data Providers → Pipes
325
- UserManagementDataProviders: 'Pipes',
326
-
327
- // User Management MFA → MultiFactorAuth
328
- UserManagementMultiFactorAuthentication: 'MultiFactorAuth',
329
- };
1
+ import type { OagenConfig } from '@workos/oagen';
2
+ import { workosEmittersPlugin } from './src/plugin.js';
330
3
 
4
+ // Minimal config for local emitter development.
5
+ // The canonical consumer config lives in openapi-spec/oagen.config.ts.
331
6
  const config: OagenConfig = {
332
- emitters: [nodeEmitter, pythonEmitter, phpEmitter, goEmitter, dotnetEmitter, kotlinEmitter],
333
- extractors: [
334
- nodeExtractor,
335
- rubyExtractor,
336
- pythonExtractor,
337
- phpExtractor,
338
- goExtractor,
339
- rustExtractor,
340
- kotlinExtractor,
341
- dotnetExtractor,
342
- elixirExtractor,
343
- ],
344
- smokeRunners: {
345
- node: './smoke/sdk-node.ts',
346
- ruby: './smoke/sdk-ruby.ts',
347
- python: './smoke/sdk-python.ts',
348
- php: './smoke/sdk-php.ts',
349
- go: './smoke/sdk-go.ts',
350
- rust: './smoke/sdk-rust.ts',
351
- elixir: './smoke/sdk-elixir.ts',
352
- kotlin: './smoke/sdk-kotlin.ts',
353
- dotnet: './smoke/sdk-dotnet.ts',
354
- },
355
- docUrl: 'https://workos.com/docs',
356
- operationIdTransform: nestjsOperationIdTransform,
357
- schemaNameTransform: (name: string) => {
358
- // Explicit renames for Dto models that collide with response models
359
- const COLLISION_RENAMES: Record<string, string> = {
360
- OrganizationDto: 'OrganizationInput',
361
- RedirectUriDto: 'RedirectUriInput',
362
- // Generic list-derived names that need domain-specific identifiers
363
- ListData: 'Role',
364
- ListModel: 'RoleList',
365
- // Double-List naming artifact
366
- EventListListMetadata: 'EventListMetadata',
367
- };
368
- if (COLLISION_RENAMES[name]) return COLLISION_RENAMES[name];
369
- return name
370
- .replace(/Dto/g, '')
371
- .replace(/DTO/g, '')
372
- .replace(/^Urn(?:IetfParams|Workos)O[Aa]uthGrantType/, '');
373
- },
374
- operationHints,
375
- mountRules,
7
+ ...workosEmittersPlugin,
376
8
  };
377
9
  export default config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workos/oagen-emitters",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "WorkOS' oagen emitters",
5
5
  "license": "MIT",
6
6
  "author": "WorkOS",
@@ -15,6 +15,10 @@
15
15
  ".": {
16
16
  "types": "./dist/index.d.mts",
17
17
  "import": "./dist/index.mjs"
18
+ },
19
+ "./plugin": {
20
+ "types": "./dist/plugin.d.mts",
21
+ "import": "./dist/plugin.mjs"
18
22
  }
19
23
  },
20
24
  "scripts": {
@@ -28,45 +32,17 @@
28
32
  "test": "vitest run",
29
33
  "test:watch": "vitest",
30
34
  "typecheck": "tsc --noEmit",
31
- "git:push": "sh ./scripts/git-push-with-published-oagen.sh",
32
35
  "oagen:build:local": "npm --prefix ../oagen run build",
33
- "oagen:use:local": "npm run oagen:build:local && npm link ../oagen",
34
- "oagen:use:published": "sh -c 'npm unlink @workos/oagen >/dev/null 2>&1 || true; npm install --ignore-scripts @workos/oagen@^0.4.0'",
35
- "prepare": "husky",
36
- "sdk:generate:dotnet": "oagen generate --lang dotnet --output ./sdk-dotnet --namespace workos --api-surface ./sdk-dotnet-surface.json",
37
- "sdk:verify:dotnet": "oagen verify --lang dotnet --output ./sdk-dotnet --api-surface ./sdk-dotnet-surface.json",
38
- "sdk:extract:dotnet": "oagen extract --lang dotnet --sdk-path ../backend/workos-dotnet --output ./sdk-dotnet-surface.json",
39
- "sdk:generate:elixir": "oagen generate --lang elixir --output ./sdk-elixir --namespace workos --api-surface ./sdk-elixir-surface.json",
40
- "sdk:verify:elixir": "oagen verify --lang elixir --output ./sdk-elixir --api-surface ./sdk-elixir-surface.json",
41
- "sdk:extract:elixir": "oagen extract --lang elixir --sdk-path ../backend/workos-elixir --output ./sdk-elixir-surface.json",
42
- "sdk:generate:go": "oagen generate --lang go --output ./sdk-go --namespace workos --api-surface ./sdk-go-surface.json",
43
- "sdk:verify:go": "oagen verify --lang go --output ./sdk-go --api-surface ./sdk-go-surface.json",
44
- "sdk:extract:go": "oagen extract --lang go --sdk-path ../backend/workos-go --output ./sdk-go-surface.json",
45
- "sdk:generate:kotlin": "oagen generate --lang kotlin --output ./sdk-kotlin --namespace workos --api-surface ./sdk-kotlin-surface.json",
46
- "sdk:verify:kotlin": "oagen verify --lang kotlin --output ./sdk-kotlin --api-surface ./sdk-kotlin-surface.json",
47
- "sdk:extract:kotlin": "oagen extract --lang kotlin --sdk-path ../backend/workos-kotlin --output ./sdk-kotlin-surface.json",
48
- "sdk:generate:node": "oagen generate --lang node --output ./sdk-node --namespace workos --api-surface ./sdk-node-surface.json",
49
- "sdk:verify:node": "oagen verify --lang node --output ./sdk-node --api-surface ./sdk-node-surface.json",
50
- "sdk:extract:node": "oagen extract --lang node --sdk-path ../backend/workos-node --output ./sdk-node-surface.json",
51
- "sdk:generate:php": "node scripts/generate-php.js",
52
- "sdk:verify:php": "oagen verify --lang php --output ./sdk-php --api-surface ./sdk-php-surface.json",
53
- "sdk:extract:php": "oagen extract --lang php --sdk-path ../backend/workos-php --output ./sdk-php-surface.json",
54
- "sdk:generate:python": "oagen generate --lang python --output ./sdk-python --namespace workos --api-surface ./sdk-python-surface.json",
55
- "sdk:verify:python": "oagen verify --lang python --output ./sdk-python --api-surface ./sdk-python-surface.json",
56
- "sdk:extract:python": "oagen extract --lang python --sdk-path ../backend/workos-python --output ./sdk-python-surface.json",
57
- "sdk:generate:ruby": "oagen generate --lang ruby --output ./sdk-ruby --namespace workos --api-surface ./sdk-ruby-surface.json",
58
- "sdk:verify:ruby": "oagen verify --lang ruby --output ./sdk-ruby --api-surface ./sdk-ruby-surface.json",
59
- "sdk:extract:ruby": "oagen extract --lang ruby --sdk-path ../backend/workos-ruby --output ./sdk-ruby-surface.json",
60
- "sdk:generate:rust": "oagen generate --lang rust --output ./sdk-rust --namespace workos --api-surface ./sdk-rust-surface.json",
61
- "sdk:verify:rust": "oagen verify --lang rust --output ./sdk-rust --api-surface ./sdk-rust-surface.json",
62
- "sdk:extract:rust": "oagen extract --lang rust --sdk-path ../backend/workos-rust --output ./sdk-rust-surface.json"
36
+ "dev:link": "npm run oagen:build:local && npm link --prefix ../oagen && npm link @workos/oagen",
37
+ "dev:unlink": "npm install",
38
+ "prepare": "husky"
63
39
  },
64
40
  "devDependencies": {
65
41
  "@commitlint/cli": "^20.5.0",
66
42
  "@commitlint/config-conventional": "^20.5.0",
67
43
  "@types/node": "^25.3.3",
68
44
  "husky": "^9.1.7",
69
- "oxfmt": "^0.36.0",
45
+ "oxfmt": "^0.45.0",
70
46
  "oxlint": "^1.51.0",
71
47
  "prettier": "^3.8.1",
72
48
  "tsdown": "^0.21.5",
@@ -78,6 +54,6 @@
78
54
  "node": ">=24.10.0"
79
55
  },
80
56
  "dependencies": {
81
- "@workos/oagen": "^0.6.0"
57
+ "@workos/oagen": "^0.7.0"
82
58
  }
83
59
  }
@@ -11,7 +11,7 @@ import type {
11
11
  import * as fs from 'node:fs';
12
12
  import * as path from 'node:path';
13
13
 
14
- import { generateModels } from './models.js';
14
+ import { generateModels, primeModelAliases } from './models.js';
15
15
  import { enrichModelsFromSpec, getSyntheticEnums } from '../shared/model-utils.js';
16
16
  import { generateEnums, primeEnumAliases } from './enums.js';
17
17
  import { generateResources } from './resources.js';
@@ -151,6 +151,7 @@ export const dotnetEmitter: Emitter = {
151
151
  const c = fixNamespace(ctx);
152
152
  const synEnums = getSyntheticEnums();
153
153
  primeEnumAliases(synEnums.length > 0 ? [...c.spec.enums, ...synEnums] : c.spec.enums);
154
+ primeModelAliases(enrichModelsFromSpec(c.spec.models));
154
155
  const files = generateResources(services, c);
155
156
 
156
157
  // Also generate wrapper options classes
@@ -201,6 +202,7 @@ export const dotnetEmitter: Emitter = {
201
202
  const c = fixNamespace(ctx);
202
203
  const synEnumsForTests = getSyntheticEnums();
203
204
  primeEnumAliases(synEnumsForTests.length > 0 ? [...spec.enums, ...synEnumsForTests] : spec.enums);
205
+ primeModelAliases(enrichModelsFromSpec(c.spec.models));
204
206
  return prefixTestPaths(ensureTrailingNewlines(generateTests(spec, c)));
205
207
  },
206
208
 
@@ -229,7 +231,7 @@ export const dotnetEmitter: Emitter = {
229
231
  args: ['format', workspace, '--no-restore', '--include'],
230
232
  // Keep batches small enough to stay under argv length limits while
231
233
  // still amortizing MSBuild startup across many files.
232
- batchSize: 50,
234
+ batchSize: 500,
233
235
  };
234
236
  },
235
237
  };
@@ -239,8 +241,8 @@ function findDotnetWorkspace(targetDir: string): string | null {
239
241
  if (!fs.existsSync(targetDir)) return null;
240
242
  const entries = fs.readdirSync(targetDir);
241
243
  const sln = entries.find((e) => e.endsWith('.sln') || e.endsWith('.slnx'));
242
- if (sln) return path.join(targetDir, sln);
244
+ if (sln) return path.resolve(targetDir, sln);
243
245
  const csproj = entries.find((e) => e.endsWith('.csproj'));
244
- if (csproj) return path.join(targetDir, csproj);
246
+ if (csproj) return path.resolve(targetDir, csproj);
245
247
  return null;
246
248
  }