@workos/oagen-emitters 0.11.0 → 0.12.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.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +4 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{plugin-DW3cnedr.mjs → plugin-C408Wh-o.mjs} +2082 -514
- package/dist/plugin-C408Wh-o.mjs.map +1 -0
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +1 -1
- package/docs/sdk-architecture/rust.md +323 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/plugin.ts +2 -1
- package/src/python/path-expression.ts +75 -26
- package/src/python/resources.ts +0 -9
- package/src/rust/client.ts +62 -0
- package/src/rust/enums.ts +201 -0
- package/src/rust/fixtures.ts +110 -0
- package/src/rust/index.ts +95 -0
- package/src/rust/manifest.ts +31 -0
- package/src/rust/models.ts +150 -0
- package/src/rust/naming.ts +131 -0
- package/src/rust/resources.ts +689 -0
- package/src/rust/secret.ts +59 -0
- package/src/rust/tests.ts +298 -0
- package/src/rust/type-map.ts +225 -0
- package/test/entrypoint.test.ts +1 -0
- package/test/plugin.test.ts +2 -1
- package/test/python/resources.test.ts +2 -2
- package/test/rust/client.test.ts +62 -0
- package/test/rust/enums.test.ts +117 -0
- package/test/rust/manifest.test.ts +73 -0
- package/test/rust/models.test.ts +139 -0
- package/test/rust/resources.test.ts +245 -0
- package/test/rust/type-map.test.ts +83 -0
- package/dist/plugin-DW3cnedr.mjs.map +0 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Operation, Service, EmitterContext } from '@workos/oagen';
|
|
2
|
+
import { toPascalCase, toSnakeCase, deriveMethodName } from '@workos/oagen';
|
|
3
|
+
import { stripUrnPrefix } from '../shared/naming-utils.js';
|
|
4
|
+
|
|
5
|
+
const RUST_KEYWORDS = new Set([
|
|
6
|
+
'as',
|
|
7
|
+
'break',
|
|
8
|
+
'const',
|
|
9
|
+
'continue',
|
|
10
|
+
'crate',
|
|
11
|
+
'else',
|
|
12
|
+
'enum',
|
|
13
|
+
'extern',
|
|
14
|
+
'false',
|
|
15
|
+
'fn',
|
|
16
|
+
'for',
|
|
17
|
+
'if',
|
|
18
|
+
'impl',
|
|
19
|
+
'in',
|
|
20
|
+
'let',
|
|
21
|
+
'loop',
|
|
22
|
+
'match',
|
|
23
|
+
'mod',
|
|
24
|
+
'move',
|
|
25
|
+
'mut',
|
|
26
|
+
'pub',
|
|
27
|
+
'ref',
|
|
28
|
+
'return',
|
|
29
|
+
'self',
|
|
30
|
+
'Self',
|
|
31
|
+
'static',
|
|
32
|
+
'struct',
|
|
33
|
+
'super',
|
|
34
|
+
'trait',
|
|
35
|
+
'true',
|
|
36
|
+
'type',
|
|
37
|
+
'unsafe',
|
|
38
|
+
'use',
|
|
39
|
+
'where',
|
|
40
|
+
'while',
|
|
41
|
+
'async',
|
|
42
|
+
'await',
|
|
43
|
+
'dyn',
|
|
44
|
+
'abstract',
|
|
45
|
+
'become',
|
|
46
|
+
'box',
|
|
47
|
+
'do',
|
|
48
|
+
'final',
|
|
49
|
+
'macro',
|
|
50
|
+
'override',
|
|
51
|
+
'priv',
|
|
52
|
+
'typeof',
|
|
53
|
+
'unsized',
|
|
54
|
+
'virtual',
|
|
55
|
+
'yield',
|
|
56
|
+
'try',
|
|
57
|
+
'union',
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
/** PascalCase type name (for structs and enums). */
|
|
61
|
+
export function typeName(name: string): string {
|
|
62
|
+
return toPascalCase(stripUrnPrefix(name));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** snake_case module/file basename (no extension). */
|
|
66
|
+
export function moduleName(name: string): string {
|
|
67
|
+
return escapeKeyword(toSnakeCase(stripUrnPrefix(name)));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** snake_case method name. */
|
|
71
|
+
export function methodName(name: string): string {
|
|
72
|
+
return escapeKeyword(toSnakeCase(stripUrnPrefix(name)));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** snake_case struct field. */
|
|
76
|
+
export function fieldName(name: string): string {
|
|
77
|
+
return escapeKeyword(toSnakeCase(name));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** PascalCase enum variant. */
|
|
81
|
+
export function variantName(value: string | number): string {
|
|
82
|
+
const s = String(value);
|
|
83
|
+
// Numbers and values starting with a digit must be prefixed.
|
|
84
|
+
const pascal = toPascalCase(s);
|
|
85
|
+
if (/^[0-9]/.test(pascal)) return `V${pascal}`;
|
|
86
|
+
return pascal || 'Empty';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Resource handle struct name (e.g., `OrganizationsApi`). Suffix is chosen
|
|
90
|
+
* to avoid collisions with API entity models (`AuthorizationResource`,
|
|
91
|
+
* `Service`, etc.) that may share the singular noun. */
|
|
92
|
+
export function resourceStructName(serviceName: string): string {
|
|
93
|
+
const base = typeName(serviceName);
|
|
94
|
+
if (base.endsWith('Api')) return base;
|
|
95
|
+
// Drop a pre-existing `Resource` suffix; the conventional Rust handle name
|
|
96
|
+
// here is `…Api` regardless of the service's spec-side label.
|
|
97
|
+
const trimmed = base.endsWith('Resource') ? base.slice(0, -'Resource'.length) : base;
|
|
98
|
+
return `${trimmed}Api`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Client accessor method name on `Client` (snake_case service name). */
|
|
102
|
+
export function resourceAccessorName(serviceName: string): string {
|
|
103
|
+
return moduleName(serviceName);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Rust file path for a resource module. */
|
|
107
|
+
export function resourceFileBasename(serviceName: string): string {
|
|
108
|
+
return moduleName(serviceName);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Resolve the SDK method name for an operation, honoring overlay hints. */
|
|
112
|
+
export function resolveMethodName(op: Operation, service: Service, ctx: EmitterContext): string {
|
|
113
|
+
const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
|
|
114
|
+
const overlayName = ctx.overlayLookup?.methodByOperation.get(httpKey)?.methodName;
|
|
115
|
+
if (overlayName) return methodName(overlayName);
|
|
116
|
+
|
|
117
|
+
const resolved = ctx.resolvedOperations?.find(
|
|
118
|
+
(r) => r.operation.path === op.path && r.operation.httpMethod === op.httpMethod,
|
|
119
|
+
);
|
|
120
|
+
if (resolved?.methodName) return methodName(resolved.methodName);
|
|
121
|
+
|
|
122
|
+
return methodName(deriveMethodName(op, service));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Suffix any Rust reserved word with `_` so it parses as an identifier. */
|
|
126
|
+
function escapeKeyword(s: string): string {
|
|
127
|
+
if (s.length === 0) return '_';
|
|
128
|
+
if (RUST_KEYWORDS.has(s)) return `${s}_`;
|
|
129
|
+
if (/^[0-9]/.test(s)) return `_${s}`;
|
|
130
|
+
return s;
|
|
131
|
+
}
|