@workos/oagen-emitters 0.6.3 → 0.6.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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.6.3"
2
+ ".": "0.6.5"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.5](https://github.com/workos/oagen-emitters/compare/v0.6.4...v0.6.5) (2026-04-28)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **python,kotlin,dotnet:** skip literal defaults for optional fields; fix dotnet JsonConverter nullability ([#56](https://github.com/workos/oagen-emitters/issues/56)) ([78d4c4c](https://github.com/workos/oagen-emitters/commit/78d4c4c303d67f7399d799dc37ad06d8e8997faa))
9
+
10
+ ## [0.6.4](https://github.com/workos/oagen-emitters/compare/v0.6.3...v0.6.4) (2026-04-28)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **dotnet,kotlin:** restore fields on discriminated base models ([#54](https://github.com/workos/oagen-emitters/issues/54)) ([6928b8f](https://github.com/workos/oagen-emitters/commit/6928b8f5012d2dc77069950cb438a72963086277))
16
+ * **php,python:** use fallback defaults for literal fields during deserialization ([#55](https://github.com/workos/oagen-emitters/issues/55)) ([0affb47](https://github.com/workos/oagen-emitters/commit/0affb47296f14121e2797545edc0b6fa0f8ba30f))
17
+ * **ruby:** eagerly load configuration.rb to fix WorkOS.configure ([#52](https://github.com/workos/oagen-emitters/issues/52)) ([fc99d36](https://github.com/workos/oagen-emitters/commit/fc99d365fe14778fa3e000335ead369dfe7abec6))
18
+
3
19
  ## [0.6.3](https://github.com/workos/oagen-emitters/compare/v0.6.2...v0.6.3) (2026-04-27)
4
20
 
5
21
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/node/index.ts","../src/python/index.ts","../src/php/index.ts","../src/go/index.ts","../src/dotnet/index.ts","../src/kotlin/index.ts","../src/ruby/index.ts"],"mappings":";;;;;cAgCa,WAAA,EAAa,OAAA;;;cCOb,aAAA,EAAe,OAAA;;;cCHf,UAAA,EAAY,OAAA;;;cCPZ,SAAA,EAAW,OAAA;;;cCqCX,aAAA,EAAe,OAAA;;;cCnCf,aAAA,EAAe,OAAA;;;cCHf,WAAA,EAAa,OAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/node/index.ts","../src/python/index.ts","../src/php/index.ts","../src/go/index.ts","../src/dotnet/index.ts","../src/kotlin/index.ts","../src/ruby/index.ts"],"mappings":";;;;;cAgCa,WAAA,EAAa,OAAA;;;cCOb,aAAA,EAAe,OAAA;;;cCHf,UAAA,EAAY,OAAA;;;cCPZ,SAAA,EAAW,OAAA;;;cCsCX,aAAA,EAAe,OAAA;;;cCpCf,aAAA,EAAe,OAAA;;;cCHf,WAAA,EAAa,OAAA"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as nodeEmitter, a as rustExtractor, c as pythonExtractor, d as rubyEmitter, f as kotlinEmitter, g as pythonEmitter, h as phpEmitter, i as kotlinExtractor, l as rubyExtractor, m as goEmitter, n as elixirExtractor, o as goExtractor, p as dotnetEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor } from "./plugin-DgjQSh2G.mjs";
1
+ import { _ as nodeEmitter, a as rustExtractor, c as pythonExtractor, d as rubyEmitter, f as kotlinEmitter, g as pythonEmitter, h as phpEmitter, i as kotlinExtractor, l as rubyExtractor, m as goEmitter, n as elixirExtractor, o as goExtractor, p as dotnetEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor } from "./plugin-BV_wDWDO.mjs";
2
2
  export { dotnetEmitter, dotnetExtractor, elixirExtractor, goEmitter, goExtractor, kotlinEmitter, kotlinExtractor, nodeEmitter, nodeExtractor, phpEmitter, phpExtractor, pythonEmitter, pythonExtractor, rubyEmitter, rubyExtractor, rustExtractor, workosEmittersPlugin };
@@ -7321,7 +7321,9 @@ function generateModels$5(models, ctx) {
7321
7321
  const pyFieldName = fieldName$4(field.name);
7322
7322
  const wireKey = field.name;
7323
7323
  const isRequired = !isOptionalField(model.name, field, ctx);
7324
- const accessor = isRequired ? `data["${wireKey}"]` : `data.get("${wireKey}")`;
7324
+ let accessor;
7325
+ if (field.type.kind === "literal" && isRequired) accessor = `data.get("${wireKey}", ${pythonLiteralDefault(field.type.value)})`;
7326
+ else accessor = isRequired ? `data["${wireKey}"]` : `data.get("${wireKey}")`;
7325
7327
  const deserRequired = isRequired && field.type.kind !== "nullable";
7326
7328
  const walrusVar = `_v_${pyFieldName}`;
7327
7329
  const deserExpr = deserializeField(field.type, accessor, deserRequired, walrusVar);
@@ -7514,6 +7516,13 @@ function isOptionalField(modelName, field, ctx) {
7514
7516
  if (!field.required || field.deprecated) return true;
7515
7517
  return false;
7516
7518
  }
7519
+ /** Convert a LiteralType value to a Python default expression for use in data.get(). */
7520
+ function pythonLiteralDefault(value) {
7521
+ if (value === null) return "None";
7522
+ if (typeof value === "boolean") return value ? "True" : "False";
7523
+ if (typeof value === "string") return `"${value}"`;
7524
+ return String(value);
7525
+ }
7517
7526
  function resolveModelFieldType(ref) {
7518
7527
  if (ref.kind === "nullable" && isDateTimeType(ref.inner)) return "Optional[datetime]";
7519
7528
  if (isDateTimeType(ref)) return "datetime";
@@ -10629,6 +10638,7 @@ function generateFromArrayAccessor(ref, wireName, required) {
10629
10638
  if (isNullable) return `$data['${wireName}'] ?? null`;
10630
10639
  return `$data['${wireName}'] ?? null`;
10631
10640
  }
10641
+ if (ref.kind === "literal") return `$data['${wireName}'] ?? ${phpLiteralDefault(ref.value)}`;
10632
10642
  return generateFromArrayValue(ref, `$data['${wireName}']`);
10633
10643
  }
10634
10644
  /**
@@ -10652,6 +10662,13 @@ function generateFromArrayValue(ref, accessor) {
10652
10662
  case "literal": return accessor;
10653
10663
  }
10654
10664
  }
10665
+ /** Convert a LiteralType value to a PHP default expression for use with ??. */
10666
+ function phpLiteralDefault(value) {
10667
+ if (value === null) return "null";
10668
+ if (typeof value === "boolean") return value ? "true" : "false";
10669
+ if (typeof value === "string") return `'${value}'`;
10670
+ return String(value);
10671
+ }
10655
10672
  /**
10656
10673
  * Check if a TypeRef needs special handling (not a simple key access).
10657
10674
  */
@@ -14917,12 +14934,20 @@ function joinUnionVariants$1(_ref, variants) {
14917
14934
  * Each model becomes a separate .cs file under Services/{mount}/Entities/.
14918
14935
  * For initial generation, all models go into a flat Entities/ directory.
14919
14936
  */
14920
- function generateModels$2(models, ctx) {
14937
+ function generateModels$2(models, ctx, discCtx) {
14921
14938
  if (models.length === 0) return [];
14922
14939
  const enumConstByName = /* @__PURE__ */ new Map();
14923
14940
  for (const e of ctx.spec.enums) if (e.values.length === 1) enumConstByName.set(e.name, String(e.values[0].value));
14924
14941
  const files = [];
14925
14942
  primeModelAliases(models);
14943
+ const baseFieldLookup = /* @__PURE__ */ new Map();
14944
+ if (discCtx) {
14945
+ for (const model of models) if (discCtx.discriminatorBases.has(model.name)) {
14946
+ const fieldMap = /* @__PURE__ */ new Map();
14947
+ for (const field of model.fields) fieldMap.set(fieldName$1(field.name), mapTypeRef$2(field.type));
14948
+ baseFieldLookup.set(model.name, fieldMap);
14949
+ }
14950
+ }
14926
14951
  for (const model of models) {
14927
14952
  if (isListWrapperModel(model) || isListMetadataModel(model)) continue;
14928
14953
  const csClassName = modelClassName(model.name);
@@ -14946,7 +14971,12 @@ function generateModels$2(models, ctx) {
14946
14971
  const human = humanize$1(model.name);
14947
14972
  lines.push(` /// <summary>Represents ${articleFor(human)} ${human}.</summary>`);
14948
14973
  }
14949
- lines.push(` public class ${csClassName}`);
14974
+ if (discCtx?.discriminatorBases.has(model.name) ?? false) lines.push(` [Newtonsoft.Json.JsonConverter(typeof(${csClassName}DiscriminatorConverter))]`);
14975
+ const baseName = discCtx?.variantToBase.get(model.name);
14976
+ const baseClassName = baseName ? modelClassName(baseName) : null;
14977
+ const baseFields = baseName ? baseFieldLookup.get(baseName) : void 0;
14978
+ if (baseClassName) lines.push(` public class ${csClassName} : ${baseClassName}`);
14979
+ else lines.push(` public class ${csClassName}`);
14950
14980
  lines.push(" {");
14951
14981
  const dictObjectFields = [];
14952
14982
  const seenFieldNames = /* @__PURE__ */ new Set();
@@ -14954,6 +14984,14 @@ function generateModels$2(models, ctx) {
14954
14984
  const csFieldName = fieldName$1(field.name);
14955
14985
  if (seenFieldNames.has(csFieldName)) continue;
14956
14986
  seenFieldNames.add(csFieldName);
14987
+ let useNewModifier = false;
14988
+ if (baseFields) {
14989
+ const baseType = baseFields.get(csFieldName);
14990
+ if (baseType !== void 0) {
14991
+ if (baseType === mapTypeRef$2(field.type)) continue;
14992
+ useNewModifier = true;
14993
+ }
14994
+ }
14957
14995
  const isOptional = !field.required;
14958
14996
  const baseType = mapTypeRef$2(field.type);
14959
14997
  const isAlreadyNullable = baseType.endsWith("?");
@@ -14961,7 +14999,7 @@ function generateModels$2(models, ctx) {
14961
14999
  let csType;
14962
15000
  let initializer = "";
14963
15001
  let setterModifier = "";
14964
- if (constInit !== null) {
15002
+ if (constInit !== null && !isOptional) {
14965
15003
  csType = baseType;
14966
15004
  initializer = ` = ${constInit};`;
14967
15005
  setterModifier = "internal ";
@@ -14983,7 +15021,8 @@ function generateModels$2(models, ctx) {
14983
15021
  }
14984
15022
  const isRequiredEnum = field.required && isEnumRef(field.type) && constInit === null;
14985
15023
  lines.push(...emitJsonPropertyAttributes(field.name, { isRequiredEnum }));
14986
- lines.push(` public ${csType} ${csFieldName} { get; ${setterModifier}set; }${initializer}`);
15024
+ const newMod = useNewModifier ? "new " : "";
15025
+ lines.push(` public ${newMod}${csType} ${csFieldName} { get; ${setterModifier}set; }${initializer}`);
14987
15026
  if (isDictionaryOfObject(csType) && !field.deprecated) dictObjectFields.push({
14988
15027
  csName: csFieldName,
14989
15028
  typeText: csType
@@ -16814,15 +16853,35 @@ const dotnetEmitter = {
16814
16853
  const enriched = enrichModelsFromSpec(models);
16815
16854
  const synEnumsForModels = getSyntheticEnums();
16816
16855
  if (synEnumsForModels.length > 0) primeEnumAliases([...c.spec.enums, ...synEnumsForModels]);
16817
- const files = generateModels$2(enriched, c);
16856
+ const originalByName = new Map(models.map((m) => [m.name, m]));
16857
+ const discriminatorBases = /* @__PURE__ */ new Set();
16858
+ const variantToBase = /* @__PURE__ */ new Map();
16859
+ const modelDiscriminators = /* @__PURE__ */ new Map();
16860
+ const files = generateModels$2(enriched.map((m) => {
16861
+ const disc = m.discriminator;
16862
+ if (disc && m.fields.length === 0) {
16863
+ const original = originalByName.get(m.name);
16864
+ if (original && original.fields.length > 0) {
16865
+ discriminatorBases.add(m.name);
16866
+ modelDiscriminators.set(m.name, disc);
16867
+ for (const variantName of Object.values(disc.mapping)) variantToBase.set(variantName, m.name);
16868
+ return {
16869
+ ...m,
16870
+ fields: original.fields
16871
+ };
16872
+ }
16873
+ }
16874
+ return m;
16875
+ }), c, {
16876
+ discriminatorBases,
16877
+ variantToBase
16878
+ });
16818
16879
  if (discriminatedUnions$1.size > 0) for (const [baseName, disc] of discriminatedUnions$1) {
16819
16880
  const converterName = `${baseName}DiscriminatorConverter`;
16820
16881
  const lines = [];
16821
16882
  lines.push(`namespace ${c.namespacePascal}`);
16822
16883
  lines.push("{");
16823
16884
  lines.push(" using System;");
16824
- lines.push(" using System.Text.Json;");
16825
- lines.push(" using System.Text.Json.Serialization;");
16826
16885
  lines.push(" using Newtonsoft.Json;");
16827
16886
  lines.push(" using Newtonsoft.Json.Linq;");
16828
16887
  lines.push("");
@@ -16834,21 +16893,70 @@ const dotnetEmitter = {
16834
16893
  lines.push(" {");
16835
16894
  lines.push(" public override bool CanConvert(Type objectType) => objectType == typeof(object);");
16836
16895
  lines.push("");
16837
- lines.push(" public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)");
16896
+ lines.push(" public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object? existingValue, Newtonsoft.Json.JsonSerializer serializer)");
16838
16897
  lines.push(" {");
16839
16898
  lines.push(" var jObject = JObject.Load(reader);");
16840
16899
  lines.push(` var discriminatorValue = jObject["${disc.property}"]?.ToString();`);
16841
16900
  lines.push(" switch (discriminatorValue)");
16842
16901
  lines.push(" {");
16843
16902
  for (const [value, modelName] of Object.entries(disc.mapping)) {
16844
- const csName = modelName.replace(/([a-z])([A-Z])/g, "$1$2");
16903
+ const csName = modelClassName(modelName);
16845
16904
  lines.push(` case "${value}": return jObject.ToObject<${csName}>(serializer);`);
16846
16905
  }
16847
16906
  lines.push(" default: return jObject.ToObject<object>(serializer);");
16848
16907
  lines.push(" }");
16849
16908
  lines.push(" }");
16850
16909
  lines.push("");
16851
- lines.push(" public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)");
16910
+ lines.push(" public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object? value, Newtonsoft.Json.JsonSerializer serializer)");
16911
+ lines.push(" {");
16912
+ lines.push(" serializer.Serialize(writer, value);");
16913
+ lines.push(" }");
16914
+ lines.push(" }");
16915
+ lines.push("}");
16916
+ files.push({
16917
+ path: `Client/Utilities/${converterName}.cs`,
16918
+ content: lines.join("\n"),
16919
+ overwriteExisting: true
16920
+ });
16921
+ }
16922
+ for (const [baseName, disc] of modelDiscriminators) {
16923
+ const baseClass = modelClassName(baseName);
16924
+ const converterName = `${baseClass}DiscriminatorConverter`;
16925
+ const lines = [];
16926
+ lines.push(`namespace ${c.namespacePascal}`);
16927
+ lines.push("{");
16928
+ lines.push(" using System;");
16929
+ lines.push(" using Newtonsoft.Json;");
16930
+ lines.push(" using Newtonsoft.Json.Linq;");
16931
+ lines.push("");
16932
+ lines.push(` /// <summary>`);
16933
+ lines.push(` /// JSON converter that deserializes <see cref="${baseClass}"/> into the`);
16934
+ lines.push(` /// correct variant subclass based on the "${disc.property}" property.`);
16935
+ lines.push(` /// </summary>`);
16936
+ lines.push(` public class ${converterName} : Newtonsoft.Json.JsonConverter`);
16937
+ lines.push(" {");
16938
+ lines.push(` public override bool CanConvert(Type objectType) => typeof(${baseClass}).IsAssignableFrom(objectType);`);
16939
+ lines.push("");
16940
+ lines.push(" public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object? existingValue, Newtonsoft.Json.JsonSerializer serializer)");
16941
+ lines.push(" {");
16942
+ lines.push(" var jObject = JObject.Load(reader);");
16943
+ lines.push(` var discriminatorValue = jObject["${disc.property}"]?.ToString();`);
16944
+ lines.push("");
16945
+ lines.push(" object target;");
16946
+ lines.push(" switch (discriminatorValue)");
16947
+ lines.push(" {");
16948
+ for (const [value, variantModelName] of Object.entries(disc.mapping)) {
16949
+ const csName = modelClassName(variantModelName);
16950
+ lines.push(` case "${value}": target = new ${csName}(); break;`);
16951
+ }
16952
+ lines.push(` default: target = new ${baseClass}(); break;`);
16953
+ lines.push(" }");
16954
+ lines.push("");
16955
+ lines.push(" serializer.Populate(jObject.CreateReader(), target);");
16956
+ lines.push(" return target;");
16957
+ lines.push(" }");
16958
+ lines.push("");
16959
+ lines.push(" public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object? value, Newtonsoft.Json.JsonSerializer serializer)");
16852
16960
  lines.push(" {");
16853
16961
  lines.push(" serializer.Serialize(writer, value);");
16854
16962
  lines.push(" }");
@@ -17543,7 +17651,7 @@ function renderFields(fields, overrideFields = /* @__PURE__ */ new Set()) {
17543
17651
  let kotlinType;
17544
17652
  let defaultExpr = null;
17545
17653
  const literalDefault = literalDefaultExpr(field.type);
17546
- if (literalDefault !== null) {
17654
+ if (literalDefault !== null && field.required) {
17547
17655
  kotlinType = baseType;
17548
17656
  defaultExpr = literalDefault;
17549
17657
  } else if (!field.required) {
@@ -19369,7 +19477,18 @@ function ensureTrailingNewlines$1(files) {
19369
19477
  const kotlinEmitter = {
19370
19478
  language: "kotlin",
19371
19479
  generateModels(models, ctx) {
19372
- return ensureTrailingNewlines$1(generateModels$1(enrichModelsFromSpec(models), ctx));
19480
+ const enriched = enrichModelsFromSpec(models);
19481
+ const originalByName = new Map(models.map((m) => [m.name, m]));
19482
+ return ensureTrailingNewlines$1(generateModels$1(enriched.map((m) => {
19483
+ if (m.discriminator && m.fields.length === 0) {
19484
+ const original = originalByName.get(m.name);
19485
+ if (original && original.fields.length > 0) return {
19486
+ ...m,
19487
+ fields: original.fields
19488
+ };
19489
+ }
19490
+ return m;
19491
+ }), ctx));
19373
19492
  },
19374
19493
  generateEnums(enums, ctx) {
19375
19494
  const syntheticEnums = getSyntheticEnums();
@@ -20734,9 +20853,11 @@ function generateMainEntryFile(spec, ctx) {
20734
20853
  for (const dir of modelSubdirs) lines.push(`loader.collapse("#{__dir__}/workos/${dir}")`);
20735
20854
  lines.push(`loader.ignore("#{__dir__}/workos/errors.rb")`);
20736
20855
  lines.push(`loader.ignore("#{__dir__}/workos/inflections.rb")`);
20856
+ lines.push(`loader.ignore("#{__dir__}/workos/configuration.rb")`);
20737
20857
  lines.push("loader.setup");
20738
20858
  lines.push("");
20739
20859
  lines.push(`require 'workos/errors'`);
20860
+ lines.push(`require 'workos/configuration'`);
20740
20861
  return {
20741
20862
  path: "lib/workos.rb",
20742
20863
  content: lines.join("\n"),
@@ -21468,4 +21589,4 @@ const workosEmittersPlugin = {
21468
21589
  //#endregion
21469
21590
  export { nodeEmitter as _, rustExtractor as a, pythonExtractor as c, rubyEmitter as d, kotlinEmitter as f, pythonEmitter as g, phpEmitter as h, kotlinExtractor as i, rubyExtractor as l, goEmitter as m, elixirExtractor as n, goExtractor as o, dotnetEmitter as p, dotnetExtractor as r, phpExtractor as s, workosEmittersPlugin as t, nodeExtractor as u };
21470
21591
 
21471
- //# sourceMappingURL=plugin-DgjQSh2G.mjs.map
21592
+ //# sourceMappingURL=plugin-BV_wDWDO.mjs.map