@workos/oagen-emitters 0.18.2 → 0.18.4
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 +17 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{plugin-bqfwowQ3.mjs → plugin-Cciic50q.mjs} +457 -101
- package/dist/plugin-Cciic50q.mjs.map +1 -0
- package/dist/plugin.mjs +1 -1
- package/docs/sdk-architecture/rust.md +2 -2
- package/package.json +3 -3
- package/src/dotnet/fixtures.ts +17 -3
- package/src/dotnet/index.ts +2 -1
- package/src/dotnet/models.ts +30 -5
- package/src/dotnet/naming.ts +10 -0
- package/src/dotnet/tests.ts +5 -1
- package/src/go/fixtures.ts +4 -2
- package/src/go/index.ts +4 -0
- package/src/go/models.ts +4 -2
- package/src/go/naming.ts +10 -0
- package/src/go/resources.ts +19 -6
- package/src/kotlin/index.ts +2 -1
- package/src/kotlin/models.ts +5 -2
- package/src/kotlin/naming.ts +11 -0
- package/src/kotlin/tests.ts +5 -1
- package/src/node/field-plan.ts +3 -3
- package/src/node/index.ts +2 -1
- package/src/node/models.ts +40 -1
- package/src/node/naming.ts +10 -0
- package/src/node/options.ts +45 -1
- package/src/node/resources.ts +76 -19
- package/src/node/tests.ts +296 -30
- package/src/php/index.ts +2 -1
- package/src/php/models.ts +11 -5
- package/src/php/naming.ts +10 -0
- package/src/php/tests.ts +11 -2
- package/src/python/fixtures.ts +4 -3
- package/src/python/index.ts +2 -1
- package/src/python/models.ts +12 -6
- package/src/python/naming.ts +10 -0
- package/src/python/tests.ts +11 -6
- package/src/ruby/index.ts +2 -1
- package/src/ruby/models.ts +10 -7
- package/src/ruby/naming.ts +10 -0
- package/src/ruby/rbi.ts +3 -1
- package/src/ruby/tests.ts +4 -1
- package/src/rust/index.ts +2 -1
- package/src/rust/models.ts +87 -15
- package/src/rust/naming.ts +10 -0
- package/src/rust/resources.ts +6 -2
- package/src/shared/file-header.ts +13 -0
- package/test/node/resources.test.ts +31 -2
- package/test/rust/models.test.ts +49 -0
- package/dist/plugin-bqfwowQ3.mjs.map +0 -1
|
@@ -921,7 +921,7 @@ describe('inline object-literal baseline parameter types', () => {
|
|
|
921
921
|
],
|
|
922
922
|
});
|
|
923
923
|
|
|
924
|
-
const baselineCtx = (service: Service, models: any[]): EmitterContext => ({
|
|
924
|
+
const baselineCtx = (service: Service, models: any[], paramType: string = literalType): EmitterContext => ({
|
|
925
925
|
...ctx,
|
|
926
926
|
spec: { ...emptySpec, services: [service], models },
|
|
927
927
|
emitterOptions: { ownedServices: ['AdminPortal'] },
|
|
@@ -933,7 +933,7 @@ describe('inline object-literal baseline parameter types', () => {
|
|
|
933
933
|
generateLink: [
|
|
934
934
|
{
|
|
935
935
|
name: 'generateLink',
|
|
936
|
-
params: [{ name: 'options', type:
|
|
936
|
+
params: [{ name: 'options', type: paramType, passingStyle: 'options_object' }],
|
|
937
937
|
returnType: 'Promise<{ link: string }>',
|
|
938
938
|
async: true,
|
|
939
939
|
},
|
|
@@ -1007,6 +1007,35 @@ describe('inline object-literal baseline parameter types', () => {
|
|
|
1007
1007
|
expect(content).toContain(`async generateLink(options: ${literalType})`);
|
|
1008
1008
|
expect(content).not.toContain('import type { {');
|
|
1009
1009
|
});
|
|
1010
|
+
|
|
1011
|
+
it('keeps a `{ ... } & X` compound intersection inline even with a named request model', () => {
|
|
1012
|
+
// The adoption guard targets a PURE object literal. A baseline param that
|
|
1013
|
+
// LEADS with a literal but is actually a compound intersection
|
|
1014
|
+
// (`{ ... } & WithMetadata`) carries the hand-authored `& X` portion, which
|
|
1015
|
+
// a named-interface swap would silently drop. It must be preserved verbatim
|
|
1016
|
+
// even though the operation has a single named request-body model.
|
|
1017
|
+
const compoundType = `${literalType} & WithMetadata`;
|
|
1018
|
+
const service = adminPortalService({ kind: 'model', name: 'GenerateLinkBody' });
|
|
1019
|
+
const models = [
|
|
1020
|
+
{
|
|
1021
|
+
name: 'GenerateLinkBody',
|
|
1022
|
+
fields: [
|
|
1023
|
+
{ name: 'intent', type: { kind: 'primitive', type: 'string' }, required: true },
|
|
1024
|
+
{ name: 'organization', type: { kind: 'primitive', type: 'string' }, required: true },
|
|
1025
|
+
],
|
|
1026
|
+
},
|
|
1027
|
+
{ name: 'PortalLink', fields: [{ name: 'link', type: { kind: 'primitive', type: 'string' }, required: true }] },
|
|
1028
|
+
];
|
|
1029
|
+
|
|
1030
|
+
const result = generateResources([service], baselineCtx(service, models, compoundType));
|
|
1031
|
+
const content = result.find((f) => f.path === 'src/admin-portal/admin-portal.ts')!.content;
|
|
1032
|
+
|
|
1033
|
+
// The compound type (including the `& WithMetadata` tail) survives intact;
|
|
1034
|
+
// it is NOT replaced by the named `GenerateLinkBody` interface.
|
|
1035
|
+
expect(content).toContain(`async generateLink(options: ${compoundType})`);
|
|
1036
|
+
expect(content).not.toContain('async generateLink(options: GenerateLinkBody)');
|
|
1037
|
+
expect(content).not.toContain('import type { {');
|
|
1038
|
+
});
|
|
1010
1039
|
});
|
|
1011
1040
|
|
|
1012
1041
|
describe('@oagen-ignore region method filtering', () => {
|
package/test/rust/models.test.ts
CHANGED
|
@@ -119,6 +119,55 @@ describe('rust/models', () => {
|
|
|
119
119
|
expect(unions.content).toContain('pub enum EventPayloadOneOf {');
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
+
it('relaxes the discriminator field on internally-tagged union variants', () => {
|
|
123
|
+
// Mirrors the ApiKey `owner` union: serde's `#[serde(tag = "type")]`
|
|
124
|
+
// consumes `type` as the enum tag and strips it from the variant body, so
|
|
125
|
+
// a *required* `type` field on the variant struct can never be satisfied
|
|
126
|
+
// ("missing field `type`"). The emitter must mark it default+skip_serializing.
|
|
127
|
+
const owner = (name: string, extra: Model['fields'] = []): Model => ({
|
|
128
|
+
name,
|
|
129
|
+
fields: [
|
|
130
|
+
{ name: 'type', type: { kind: 'primitive', type: 'string' }, required: true },
|
|
131
|
+
{ name: 'id', type: { kind: 'primitive', type: 'string' }, required: true },
|
|
132
|
+
...extra,
|
|
133
|
+
],
|
|
134
|
+
});
|
|
135
|
+
const models: Model[] = [
|
|
136
|
+
{
|
|
137
|
+
name: 'ApiKey',
|
|
138
|
+
fields: [
|
|
139
|
+
{
|
|
140
|
+
name: 'owner',
|
|
141
|
+
type: {
|
|
142
|
+
kind: 'union',
|
|
143
|
+
variants: [
|
|
144
|
+
{ kind: 'model', name: 'ApiKeyOwner' },
|
|
145
|
+
{ kind: 'model', name: 'UserApiKeyOwner' },
|
|
146
|
+
],
|
|
147
|
+
discriminator: {
|
|
148
|
+
property: 'type',
|
|
149
|
+
mapping: { organization: 'ApiKeyOwner', user: 'UserApiKeyOwner' },
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
required: true,
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
owner('ApiKeyOwner'),
|
|
157
|
+
owner('UserApiKeyOwner', [
|
|
158
|
+
{ name: 'organization_id', type: { kind: 'primitive', type: 'string' }, required: true },
|
|
159
|
+
]),
|
|
160
|
+
];
|
|
161
|
+
const files = generateModels(models, ctx, new UnionRegistry());
|
|
162
|
+
for (const mod of ['api_key_owner', 'user_api_key_owner']) {
|
|
163
|
+
const f = files.find((x) => x.path === `src/models/${mod}.rs`)!;
|
|
164
|
+
expect(f.content).toContain('#[serde(rename = "type", default, skip_serializing)]');
|
|
165
|
+
expect(f.content).toContain('pub type_: String,');
|
|
166
|
+
// The non-discriminator field is untouched.
|
|
167
|
+
expect(f.content).toContain('pub id: String,');
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
122
171
|
it('documents Field.default as a "Defaults to" doc comment', () => {
|
|
123
172
|
const models: Model[] = [
|
|
124
173
|
{
|