effect-app 4.0.0-beta.60 → 4.0.0-beta.62

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @effect-app/prelude
2
2
 
3
+ ## 4.0.0-beta.62
4
+
5
+ ### Patch Changes
6
+
7
+ - 0b21a02: fix: flatten simple allOf constraints in JSON Schema output for better codegen compatibility
8
+
9
+ ## 4.0.0-beta.61
10
+
3
11
  ## 4.0.0-beta.60
4
12
 
5
13
  ## 4.0.0-beta.59
@@ -37,4 +37,14 @@ import { type JsonSchema, type Schema } from "effect";
37
37
  * ```
38
38
  */
39
39
  export declare function specialJsonSchemaDocument(schema: Schema.Top, options?: Schema.ToJsonSchemaOptions): JsonSchema.Document<"draft-2020-12">;
40
+ /**
41
+ * Flattens `allOf` entries into the parent when the parent already has a
42
+ * `type` and every `allOf` entry is a plain constraint object (no `$ref`,
43
+ * no `type`). Merged properties from `allOf` entries win on conflict.
44
+ */
45
+ export declare function flattenSimpleAllOf(obj: unknown): unknown;
46
+ /**
47
+ * Applies JSON Schema post-processing: flattens simple allOf.
48
+ */
49
+ export declare function postProcessJsonSchema(obj: JsonSchema.JsonSchema): JsonSchema.JsonSchema;
40
50
  //# sourceMappingURL=SpecialJsonSchema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SpecialJsonSchema.d.ts","sourceRoot":"","sources":["../../src/Schema/SpecialJsonSchema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,MAAM,EAAwB,MAAM,QAAQ,CAAA;AAEtF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,GAAG,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,mBAAmB,GACnC,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,CAStC"}
1
+ {"version":3,"file":"SpecialJsonSchema.d.ts","sourceRoot":"","sources":["../../src/Schema/SpecialJsonSchema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,MAAM,EAAwB,MAAM,QAAQ,CAAA;AAEtF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,GAAG,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,mBAAmB,GACnC,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,CAatC;AA6ID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CA6BxD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAEvF"}
@@ -40,10 +40,14 @@ export function specialJsonSchemaDocument(schema, options) {
40
40
  const doc = SchemaRepresentation.fromAST(schema.ast);
41
41
  const deduped = deduplicateReferences(doc);
42
42
  const jd = SchemaRepresentation.toJsonSchemaDocument(deduped, options);
43
+ const processedDefs = {};
44
+ for (const [key, def] of Object.entries(jd.definitions)) {
45
+ processedDefs[key] = postProcessJsonSchema(def);
46
+ }
43
47
  return {
44
48
  dialect: "draft-2020-12",
45
- schema: jd.schema,
46
- definitions: jd.definitions
49
+ schema: postProcessJsonSchema(jd.schema),
50
+ definitions: processedDefs
47
51
  };
48
52
  }
49
53
  /**
@@ -175,6 +179,42 @@ function rewriteRefs(rep, remapping) {
175
179
  return rep;
176
180
  }
177
181
  }
182
+ /**
183
+ * Flattens `allOf` entries into the parent when the parent already has a
184
+ * `type` and every `allOf` entry is a plain constraint object (no `$ref`,
185
+ * no `type`). Merged properties from `allOf` entries win on conflict.
186
+ */
187
+ export function flattenSimpleAllOf(obj) {
188
+ if (obj === null || typeof obj !== "object")
189
+ return obj;
190
+ if (globalThis.Array.isArray(obj)) {
191
+ return obj.map(flattenSimpleAllOf);
192
+ }
193
+ const record = obj;
194
+ const result = {};
195
+ for (const [key, value] of Object.entries(record)) {
196
+ result[key] = flattenSimpleAllOf(value);
197
+ }
198
+ if (result["type"] && globalThis.Array.isArray(result["allOf"])) {
199
+ const allOf = result["allOf"];
200
+ const canFlatten = allOf.every((entry) => typeof entry === "object" && entry !== null && !("$ref" in entry) && !("type" in entry));
201
+ if (canFlatten) {
202
+ const { allOf: _, ...rest } = result;
203
+ let merged = { ...rest };
204
+ for (const entry of allOf) {
205
+ merged = { ...merged, ...entry };
206
+ }
207
+ return merged;
208
+ }
209
+ }
210
+ return result;
211
+ }
212
+ /**
213
+ * Applies JSON Schema post-processing: flattens simple allOf.
214
+ */
215
+ export function postProcessJsonSchema(obj) {
216
+ return flattenSimpleAllOf(obj);
217
+ }
178
218
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
219
  function rewriteChecks(checks, remapping) {
180
220
  return checks.map((c) => {
@@ -196,4 +236,4 @@ function rewriteChecks(checks, remapping) {
196
236
  }
197
237
  });
198
238
  }
199
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3BlY2lhbEpzb25TY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU2NoZW1hL1NwZWNpYWxKc29uU2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBQ0gsT0FBTyxFQUFFLFNBQVMsRUFBZ0Msb0JBQW9CLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFFdEY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FDdkMsTUFBa0IsRUFDbEIsT0FBb0M7SUFFcEMsTUFBTSxHQUFHLEdBQUcsb0JBQW9CLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNwRCxNQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUMxQyxNQUFNLEVBQUUsR0FBRyxvQkFBb0IsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDdEUsT0FBTztRQUNMLE9BQU8sRUFBRSxlQUFlO1FBQ3hCLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTTtRQUNqQixXQUFXLEVBQUUsRUFBRSxDQUFDLFdBQVc7S0FDNUIsQ0FBQTtBQUNILENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMscUJBQXFCLENBQzVCLEdBQWtDO0lBRWxDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUE7SUFDM0IsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNqQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sR0FBRyxDQUFBO0lBRXBDLDZFQUE2RTtJQUM3RSxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxFQUF1RCxDQUFBO0lBQ3ZGLEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLEdB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
239
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3BlY2lhbEpzb25TY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU2NoZW1hL1NwZWNpYWxKc29uU2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBQ0gsT0FBTyxFQUFFLFNBQVMsRUFBZ0Msb0JBQW9CLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFFdEY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FDdkMsTUFBa0IsRUFDbEIsT0FBb0M7SUFFcEMsTUFBTSxHQUFHLEdBQUcsb0JBQW9CLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNwRCxNQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUMxQyxNQUFNLEVBQUUsR0FBRyxvQkFBb0IsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDdEUsTUFBTSxhQUFhLEdBQTJCLEVBQUUsQ0FBQTtJQUNoRCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUN4RCxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDakQsQ0FBQztJQUNELE9BQU87UUFDTCxPQUFPLEVBQUUsZUFBZTtRQUN4QixNQUFNLEVBQUUscUJBQXFCLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUN4QyxXQUFXLEVBQUUsYUFBYTtLQUMzQixDQUFBO0FBQ0gsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxxQkFBcUIsQ0FDNUIsR0FBa0M7SUFFbEMsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQTtJQUMzQixNQUFNLE9BQU8sR0FBRyxNQUFN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
@@ -1,10 +1,12 @@
1
1
  /**
2
- * SpecialOpenApi — Deduplicates `components/schemas` entries in an OpenAPI spec.
2
+ * SpecialOpenApi — Deduplicates `components/schemas` entries in an OpenAPI spec
3
+ * and applies JSON Schema post-processing (null removal, allOf flattening).
3
4
  *
4
5
  * When `OpenApi.fromApi` generates the spec, different AST nodes sharing the
5
6
  * same identifier can produce duplicate entries (e.g. "X" and "X1") in
6
7
  * `components.schemas`. This module provides a transform function that
7
- * collapses those duplicates and rewrites all `$ref` pointers accordingly.
8
+ * collapses those duplicates, rewrites all `$ref` pointers accordingly,
9
+ * and post-processes schemas for better codegen compatibility.
8
10
  *
9
11
  * Usage with the OpenApi `Transform` annotation:
10
12
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SpecialOpenApi.d.ts","sourceRoot":"","sources":["../../src/Schema/SpecialOpenApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqDrB"}
1
+ {"version":3,"file":"SpecialOpenApi.d.ts","sourceRoot":"","sources":["../../src/Schema/SpecialOpenApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqDrB"}
@@ -1,10 +1,12 @@
1
1
  /**
2
- * SpecialOpenApi — Deduplicates `components/schemas` entries in an OpenAPI spec.
2
+ * SpecialOpenApi — Deduplicates `components/schemas` entries in an OpenAPI spec
3
+ * and applies JSON Schema post-processing (null removal, allOf flattening).
3
4
  *
4
5
  * When `OpenApi.fromApi` generates the spec, different AST nodes sharing the
5
6
  * same identifier can produce duplicate entries (e.g. "X" and "X1") in
6
7
  * `components.schemas`. This module provides a transform function that
7
- * collapses those duplicates and rewrites all `$ref` pointers accordingly.
8
+ * collapses those duplicates, rewrites all `$ref` pointers accordingly,
9
+ * and post-processes schemas for better codegen compatibility.
8
10
  *
9
11
  * Usage with the OpenApi `Transform` annotation:
10
12
  *
@@ -16,6 +18,7 @@
16
18
  * .pipe(HttpApi.annotateContext(OpenApi.annotations({ transform: deduplicateOpenApiSchemas })))
17
19
  * ```
18
20
  */
21
+ import { postProcessJsonSchema } from "./SpecialJsonSchema.js";
19
22
  /**
20
23
  * Deduplicates `components.schemas` entries in an OpenAPI spec.
21
24
  *
@@ -66,7 +69,7 @@ export function deduplicateOpenApiSchemas(spec) {
66
69
  }
67
70
  }
68
71
  if (remapping.size === 0)
69
- return spec;
72
+ return postProcessJsonSchema(spec);
70
73
  // Build new schemas object without duplicates
71
74
  const newSchemas = {};
72
75
  for (const key of keys) {
@@ -78,7 +81,7 @@ export function deduplicateOpenApiSchemas(spec) {
78
81
  const newSpec = structuredClone(spec);
79
82
  newSpec["components"]["schemas"] = newSchemas;
80
83
  rewriteRefs(newSpec, remapping);
81
- return newSpec;
84
+ return postProcessJsonSchema(newSpec);
82
85
  }
83
86
  /**
84
87
  * Extracts the base identifier from a schema key by stripping trailing
@@ -117,4 +120,4 @@ function rewriteRefs(obj, remapping) {
117
120
  rewriteRefs(value, remapping);
118
121
  }
119
122
  }
120
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3BlY2lhbE9wZW5BcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU2NoZW1hL1NwZWNpYWxPcGVuQXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVIOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FDdkMsSUFBeUI7SUFFekIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBb0MsQ0FBQTtJQUN4RSxJQUFJLENBQUMsVUFBVTtRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQzVCLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQW9DLENBQUE7SUFDeEUsSUFBSSxDQUFDLE9BQU87UUFBRSxPQUFPLElBQUksQ0FBQTtJQUV6QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2pDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFFbEMsd0RBQXdEO0lBQ3hELE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUF1RCxDQUFBO0lBQzdFLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkIsTUFBTSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDbkMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUNoRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlCLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQzFDLENBQUM7YUFBTSxD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
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3BlY2lhbE9wZW5BcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU2NoZW1hL1NwZWNpYWxPcGVuQXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBRUgsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFFOUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QixDQUN2QyxJQUF5QjtJQUV6QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFvQyxDQUFBO0lBQ3hFLElBQUksQ0FBQyxVQUFVO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDNUIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBb0MsQ0FBQTtJQUN4RSxJQUFJLENBQUMsT0FBTztRQUFFLE9BQU8sSUFBSSxDQUFBO0lBRXpCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDakMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUVsQyx3REFBd0Q7SUFDeEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXVELENBQUE7SUFDN0UsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNuQyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ2hELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUIsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-app",
3
- "version": "4.0.0-beta.60",
3
+ "version": "4.0.0-beta.62",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -44,10 +44,14 @@ export function specialJsonSchemaDocument(
44
44
  const doc = SchemaRepresentation.fromAST(schema.ast)
45
45
  const deduped = deduplicateReferences(doc)
46
46
  const jd = SchemaRepresentation.toJsonSchemaDocument(deduped, options)
47
+ const processedDefs: JsonSchema.Definitions = {}
48
+ for (const [key, def] of Object.entries(jd.definitions)) {
49
+ processedDefs[key] = postProcessJsonSchema(def)
50
+ }
47
51
  return {
48
52
  dialect: "draft-2020-12",
49
- schema: jd.schema,
50
- definitions: jd.definitions
53
+ schema: postProcessJsonSchema(jd.schema),
54
+ definitions: processedDefs
51
55
  }
52
56
  }
53
57
 
@@ -190,6 +194,49 @@ function rewriteRefs(
190
194
  }
191
195
  }
192
196
 
197
+ /**
198
+ * Flattens `allOf` entries into the parent when the parent already has a
199
+ * `type` and every `allOf` entry is a plain constraint object (no `$ref`,
200
+ * no `type`). Merged properties from `allOf` entries win on conflict.
201
+ */
202
+ export function flattenSimpleAllOf(obj: unknown): unknown {
203
+ if (obj === null || typeof obj !== "object") return obj
204
+
205
+ if (globalThis.Array.isArray(obj)) {
206
+ return obj.map(flattenSimpleAllOf)
207
+ }
208
+
209
+ const record = obj as Record<string, unknown>
210
+ const result: Record<string, unknown> = {}
211
+ for (const [key, value] of Object.entries(record)) {
212
+ result[key] = flattenSimpleAllOf(value)
213
+ }
214
+
215
+ if (result["type"] && globalThis.Array.isArray(result["allOf"])) {
216
+ const allOf = result["allOf"] as Array<Record<string, unknown>>
217
+ const canFlatten = allOf.every((entry) =>
218
+ typeof entry === "object" && entry !== null && !("$ref" in entry) && !("type" in entry)
219
+ )
220
+ if (canFlatten) {
221
+ const { allOf: _, ...rest } = result
222
+ let merged: Record<string, unknown> = { ...rest }
223
+ for (const entry of allOf) {
224
+ merged = { ...merged, ...entry }
225
+ }
226
+ return merged
227
+ }
228
+ }
229
+
230
+ return result
231
+ }
232
+
233
+ /**
234
+ * Applies JSON Schema post-processing: flattens simple allOf.
235
+ */
236
+ export function postProcessJsonSchema(obj: JsonSchema.JsonSchema): JsonSchema.JsonSchema {
237
+ return flattenSimpleAllOf(obj) as JsonSchema.JsonSchema
238
+ }
239
+
193
240
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
194
241
  function rewriteChecks<M>(
195
242
  checks: ReadonlyArray<SchemaRepresentation.Check<M>>,
@@ -1,10 +1,12 @@
1
1
  /**
2
- * SpecialOpenApi — Deduplicates `components/schemas` entries in an OpenAPI spec.
2
+ * SpecialOpenApi — Deduplicates `components/schemas` entries in an OpenAPI spec
3
+ * and applies JSON Schema post-processing (null removal, allOf flattening).
3
4
  *
4
5
  * When `OpenApi.fromApi` generates the spec, different AST nodes sharing the
5
6
  * same identifier can produce duplicate entries (e.g. "X" and "X1") in
6
7
  * `components.schemas`. This module provides a transform function that
7
- * collapses those duplicates and rewrites all `$ref` pointers accordingly.
8
+ * collapses those duplicates, rewrites all `$ref` pointers accordingly,
9
+ * and post-processes schemas for better codegen compatibility.
8
10
  *
9
11
  * Usage with the OpenApi `Transform` annotation:
10
12
  *
@@ -17,6 +19,8 @@
17
19
  * ```
18
20
  */
19
21
 
22
+ import { postProcessJsonSchema } from "./SpecialJsonSchema.js"
23
+
20
24
  /**
21
25
  * Deduplicates `components.schemas` entries in an OpenAPI spec.
22
26
  *
@@ -66,7 +70,7 @@ export function deduplicateOpenApiSchemas(
66
70
  }
67
71
  }
68
72
 
69
- if (remapping.size === 0) return spec
73
+ if (remapping.size === 0) return postProcessJsonSchema(spec) as Record<string, any>
70
74
 
71
75
  // Build new schemas object without duplicates
72
76
  const newSchemas: Record<string, any> = {}
@@ -81,7 +85,7 @@ export function deduplicateOpenApiSchemas(
81
85
  newSpec["components"]["schemas"] = newSchemas
82
86
  rewriteRefs(newSpec, remapping)
83
87
 
84
- return newSpec
88
+ return postProcessJsonSchema(newSpec) as Record<string, any>
85
89
  }
86
90
 
87
91
  /**
@@ -1,7 +1,8 @@
1
1
  import { Option, Predicate, Schema, SchemaGetter } from "effect"
2
2
  import { InvalidStateError, LoginError, NotFoundError, NotLoggedInError, OptimisticConcurrencyException, ServiceUnavailableError, UnauthorizedError, ValidationError } from "effect-app/client/errors"
3
+ import * as AppSchema from "effect-app/Schema"
3
4
  import { Class, TaggedClass } from "effect-app/Schema/Class"
4
- import { specialJsonSchemaDocument } from "effect-app/Schema/SpecialJsonSchema"
5
+ import { flattenSimpleAllOf, specialJsonSchemaDocument } from "effect-app/Schema/SpecialJsonSchema"
5
6
  import { deduplicateOpenApiSchemas } from "effect-app/Schema/SpecialOpenApi"
6
7
  import * as S from "effect/Schema"
7
8
  import { describe, expect, it } from "vitest"
@@ -447,7 +448,7 @@ describe("SpecialOpenApi", () => {
447
448
  }
448
449
 
449
450
  const result = deduplicateOpenApiSchemas(spec)
450
- expect(result).toBe(spec) // same reference, no cloning needed
451
+ expect(result).toStrictEqual(spec)
451
452
  })
452
453
 
453
454
  it("rewrites nested $ref pointers in allOf/anyOf/oneOf", () => {
@@ -520,6 +521,212 @@ describe("SpecialOpenApi", () => {
520
521
 
521
522
  it("handles spec without components gracefully", () => {
522
523
  const spec = { openapi: "3.1.0", info: { title: "Test", version: "1.0" }, paths: {} }
523
- expect(deduplicateOpenApiSchemas(spec)).toBe(spec)
524
+ const result = deduplicateOpenApiSchemas(spec)
525
+ expect(result).toStrictEqual(spec)
526
+ })
527
+
528
+ it("flattens allOf in components.schemas", () => {
529
+ const spec = {
530
+ openapi: "3.1.0",
531
+ info: { title: "Test", version: "1.0" },
532
+ paths: {},
533
+ components: {
534
+ schemas: {
535
+ PositiveInt: {
536
+ type: "integer",
537
+ allOf: [{ exclusiveMinimum: 0, title: "PositiveInt" }]
538
+ }
539
+ }
540
+ }
541
+ }
542
+
543
+ const result = deduplicateOpenApiSchemas(spec) as any
544
+
545
+ expect(result.components.schemas.PositiveInt).toStrictEqual({
546
+ type: "integer",
547
+ exclusiveMinimum: 0,
548
+ title: "PositiveInt"
549
+ })
550
+ })
551
+
552
+ it("does not flatten allOf containing $ref entries", () => {
553
+ const spec = {
554
+ openapi: "3.1.0",
555
+ info: { title: "Test", version: "1.0" },
556
+ paths: {},
557
+ components: {
558
+ schemas: {
559
+ Composed: {
560
+ type: "object",
561
+ allOf: [{ $ref: "#/components/schemas/Base" }]
562
+ },
563
+ Base: { type: "object", properties: { id: { type: "string" } } }
564
+ }
565
+ }
566
+ }
567
+
568
+ const result = deduplicateOpenApiSchemas(spec) as any
569
+
570
+ expect(result.components.schemas.Composed).toStrictEqual({
571
+ type: "object",
572
+ allOf: [{ $ref: "#/components/schemas/Base" }]
573
+ })
574
+ })
575
+
576
+ it("does not flatten allOf entries that define their own type", () => {
577
+ const spec = {
578
+ openapi: "3.1.0",
579
+ info: { title: "Test", version: "1.0" },
580
+ paths: {},
581
+ components: {
582
+ schemas: {
583
+ Mixed: {
584
+ type: "object",
585
+ allOf: [{ type: "string", minLength: 1 }]
586
+ }
587
+ }
588
+ }
589
+ }
590
+
591
+ const result = deduplicateOpenApiSchemas(spec) as any
592
+
593
+ expect(result.components.schemas.Mixed).toStrictEqual({
594
+ type: "object",
595
+ allOf: [{ type: "string", minLength: 1 }]
596
+ })
597
+ })
598
+ })
599
+
600
+ describe("flattenSimpleAllOf", () => {
601
+ it("flattens constraint-only allOf into parent with type", () => {
602
+ const input = {
603
+ type: "integer",
604
+ allOf: [{ exclusiveMinimum: 0, title: "PositiveInt" }]
605
+ }
606
+ expect(flattenSimpleAllOf(input)).toStrictEqual({
607
+ type: "integer",
608
+ exclusiveMinimum: 0,
609
+ title: "PositiveInt"
610
+ })
611
+ })
612
+
613
+ it("flattens string type with multiple constraints", () => {
614
+ const input = {
615
+ type: "string",
616
+ allOf: [
617
+ { minLength: 1, maxLength: 255 },
618
+ { title: "NonEmptyString255" }
619
+ ]
620
+ }
621
+ expect(flattenSimpleAllOf(input)).toStrictEqual({
622
+ type: "string",
623
+ minLength: 1,
624
+ maxLength: 255,
625
+ title: "NonEmptyString255"
626
+ })
627
+ })
628
+
629
+ it("does not flatten allOf with $ref", () => {
630
+ const input = {
631
+ type: "object",
632
+ allOf: [{ $ref: "#/components/schemas/Base" }]
633
+ }
634
+ expect(flattenSimpleAllOf(input)).toStrictEqual(input)
635
+ })
636
+
637
+ it("does not flatten allOf entries with their own type", () => {
638
+ const input = {
639
+ type: "object",
640
+ allOf: [{ type: "string", minLength: 1 }]
641
+ }
642
+ expect(flattenSimpleAllOf(input)).toStrictEqual(input)
643
+ })
644
+
645
+ it("allOf entry wins on property conflict", () => {
646
+ const input = {
647
+ type: "integer",
648
+ title: "OldTitle",
649
+ allOf: [{ title: "NewTitle", minimum: 0 }]
650
+ }
651
+ expect(flattenSimpleAllOf(input)).toStrictEqual({
652
+ type: "integer",
653
+ title: "NewTitle",
654
+ minimum: 0
655
+ })
656
+ })
657
+ })
658
+
659
+ describe("Post-processing integration — real Effect Schema types", () => {
660
+ it("PositiveInt — allOf flattened, no wrapping", () => {
661
+ const doc = specialJsonSchemaDocument(AppSchema.PositiveInt)
662
+ expect(doc.definitions["PositiveInt"]).toStrictEqual({
663
+ type: "integer",
664
+ exclusiveMinimum: 0,
665
+ title: "PositiveInt"
666
+ })
667
+ })
668
+
669
+ it("NonEmptyString255 — multiple allOf constraints merged", () => {
670
+ const doc = specialJsonSchemaDocument(AppSchema.NonEmptyString255)
671
+ expect(doc.definitions["NonEmptyString255"]).toStrictEqual({
672
+ type: "string",
673
+ minLength: 1,
674
+ maxLength: 255,
675
+ title: "NonEmptyString255"
676
+ })
677
+ })
678
+
679
+ it("NullOr(NonEmptyString64k) — null preserved in anyOf, allOf flattened in definition", () => {
680
+ const schema = S.Struct({ note: S.NullOr(AppSchema.NonEmptyString64k) })
681
+ const doc = specialJsonSchemaDocument(schema)
682
+
683
+ // null variant preserved (correct JSON Schema for NullOr)
684
+ expect(doc.schema).toStrictEqual({
685
+ type: "object",
686
+ properties: {
687
+ note: {
688
+ anyOf: [
689
+ { $ref: "#/$defs/NonEmptyString64k" },
690
+ { type: "null" }
691
+ ]
692
+ }
693
+ },
694
+ required: ["note"],
695
+ additionalProperties: false
696
+ })
697
+
698
+ // allOf flattened in the referenced definition
699
+ expect(doc.definitions["NonEmptyString64k"]).toStrictEqual({
700
+ type: "string",
701
+ minLength: 1,
702
+ maxLength: 65536,
703
+ title: "NonEmptyString64k"
704
+ })
705
+ })
706
+
707
+ it("NonNegativeInt — allOf flattened", () => {
708
+ const doc = specialJsonSchemaDocument(AppSchema.NonNegativeInt)
709
+ expect(doc.definitions["NonNegativeInt"]).toStrictEqual({
710
+ type: "integer",
711
+ minimum: 0,
712
+ title: "NonNegativeInt"
713
+ })
714
+ })
715
+
716
+ it("NullOr union preserves null and non-null members in anyOf", () => {
717
+ const A = S.String.annotate({ identifier: "A", title: "A" })
718
+ const B = S.Boolean.annotate({ identifier: "B", title: "B" })
719
+ const schema = S.Struct({
720
+ value: S.NullOr(S.Union([A, B]))
721
+ })
722
+ const doc = specialJsonSchemaDocument(schema)
723
+ const valueProp = (doc.schema as Record<string, any>)["properties"]["value"]
724
+
725
+ expect(valueProp).toStrictEqual({
726
+ anyOf: [
727
+ { anyOf: [{ $ref: "#/$defs/A" }, { $ref: "#/$defs/B" }] },
728
+ { type: "null" }
729
+ ]
730
+ })
524
731
  })
525
732
  })