From f5379c9af86fdf8a6abaa76f211b38393ec9eee1 Mon Sep 17 00:00:00 2001 From: Gideon Wald Date: Mon, 10 Nov 2025 15:51:04 -0800 Subject: [PATCH 1/7] actually fix name collisions in derive closures --- .../src/closures/transformer.ts | 150 ++++++++++++++++-- .../derive-name-collision.expected.tsx | 29 +++- .../closures/derive-name-collision.input.tsx | 8 +- 3 files changed, 167 insertions(+), 20 deletions(-) diff --git a/packages/ts-transformers/src/closures/transformer.ts b/packages/ts-transformers/src/closures/transformer.ts index 03fdc0f0ad..6d2f8f82c5 100644 --- a/packages/ts-transformers/src/closures/transformer.ts +++ b/packages/ts-transformers/src/closures/transformer.ts @@ -1441,6 +1441,39 @@ function extractDeriveCallback( return undefined; } +/** + * Resolve capture name collisions with the original input parameter name. + * If a capture has the same name as originalInputParamName, rename it (e.g., multiplier -> multiplier_1). + * Returns a mapping from original capture names to their potentially renamed versions. + */ +function resolveDeriveCaptureNameCollisions( + originalInputParamName: string, + captureTree: Map, +): Map { + const captureNameMap = new Map(); + const usedNames = new Set([originalInputParamName]); + + for (const [captureName] of captureTree) { + if (captureName === originalInputParamName) { + // Collision detected - rename the capture + let renamed = `${captureName}_1`; + let suffix = 1; + while (usedNames.has(renamed) || captureTree.has(renamed)) { + suffix++; + renamed = `${captureName}_${suffix}`; + } + captureNameMap.set(captureName, renamed); + usedNames.add(renamed); + } else { + // No collision - use original name + captureNameMap.set(captureName, captureName); + usedNames.add(captureName); + } + } + + return captureNameMap; +} + /** * Build the merged input object containing both the original input and captures. * Example: {value, multiplier} where value is the original input and multiplier is a capture. @@ -1452,6 +1485,7 @@ function buildDeriveInputObject( originalInput: ts.Expression, originalInputParamName: string, captureTree: Map, + captureNameMap: Map, factory: ts.NodeFactory, hadZeroParameters: boolean, ): ts.ObjectLiteralExpression { @@ -1478,8 +1512,16 @@ function buildDeriveInputObject( } } - // Add captures - properties.push(...buildCapturePropertyAssignments(captureTree, factory)); + // Add captures with potentially renamed property names + for (const [originalName, node] of captureTree) { + const propertyName = captureNameMap.get(originalName) ?? originalName; + properties.push( + factory.createPropertyAssignment( + createPropertyName(propertyName, factory), + buildHierarchicalParamsValue(node, originalName, factory), + ), + ); + } return factory.createObjectLiteralExpression( properties, @@ -1487,6 +1529,44 @@ function buildDeriveInputObject( ); } +/** + * Rewrite the callback body to use renamed capture identifiers. + * For example, if `multiplier` was renamed to `multiplier_1`, replace all + * references to the captured `multiplier` with `multiplier_1`. + */ +function rewriteCaptureReferences( + body: ts.ConciseBody, + captureNameMap: Map, + factory: ts.NodeFactory, +): ts.ConciseBody { + // Build a reverse map: original capture name -> list of renamed names that should be substituted + const substitutions = new Map(); + for (const [originalName, renamedName] of captureNameMap) { + if (originalName !== renamedName) { + substitutions.set(originalName, renamedName); + } + } + + if (substitutions.size === 0) { + return body; // No substitutions needed + } + + const visitor = (node: ts.Node): ts.Node => { + // Only substitute root-level identifiers that match captured variable names + // Don't substitute property names or nested references + if (ts.isIdentifier(node)) { + const substituteName = substitutions.get(node.text); + if (substituteName) { + return factory.createIdentifier(substituteName); + } + } + + return ts.visitEachChild(node, visitor, undefined); + }; + + return ts.visitNode(body, visitor) as ts.ConciseBody; +} + /** * Create the derive callback with parameter aliasing to preserve user's parameter name. * Example: ({value: v, multiplier}) => v * multiplier @@ -1499,6 +1579,7 @@ function createDeriveCallback( transformedBody: ts.ConciseBody, originalInputParamName: string, captureTree: Map, + captureNameMap: Map, context: TransformationContext, hadZeroParameters: boolean, ): ts.ArrowFunction | ts.FunctionExpression { @@ -1590,14 +1671,19 @@ function createDeriveCallback( ), ); - // Add bindings for captures + // Add bindings for captures using the potentially renamed property names const createBindingIdentifier = (name: string): ts.Identifier => { return reserveIdentifier(name, usedBindingNames, factory); }; + // Create binding elements using the renamed capture names + const renamedCaptureNames = Array.from(captureTree.keys()).map( + (originalName) => captureNameMap.get(originalName) ?? originalName, + ); + bindingElements.push( ...createBindingElementsFromNames( - captureTree.keys(), + renamedCaptureNames, factory, createBindingIdentifier, ), @@ -1613,6 +1699,13 @@ function createDeriveCallback( undefined, ); + // Rewrite the body to use renamed capture identifiers + const rewrittenBody = rewriteCaptureReferences( + transformedBody, + captureNameMap, + factory, + ); + // Create the new callback if (ts.isArrowFunction(callback)) { return factory.createArrowFunction( @@ -1621,7 +1714,7 @@ function createDeriveCallback( [parameter], undefined, // No return type - rely on inference callback.equalsGreaterThanToken, - transformedBody, + rewrittenBody, ); } else { return factory.createFunctionExpression( @@ -1631,7 +1724,7 @@ function createDeriveCallback( callback.typeParameters, [parameter], undefined, // No return type - rely on inference - transformedBody as ts.Block, + rewrittenBody as ts.Block, ); } } @@ -1646,6 +1739,7 @@ function buildDeriveInputSchema( originalInputParamName: string, originalInput: ts.Expression, captureTree: Map, + captureNameMap: Map, context: TransformationContext, hadZeroParameters: boolean, ): ts.TypeNode { @@ -1677,11 +1771,40 @@ function buildDeriveInputSchema( ); } - // Add type elements for captures - typeElements.push( - ...buildTypeElementsFromCaptureTree(captureTree, context), + // Add type elements for captures using the existing helper + const captureTypeElements = buildTypeElementsFromCaptureTree( + captureTree, + context, ); + // Rename the property signatures if there are collisions + for (const typeElement of captureTypeElements) { + if ( + ts.isPropertySignature(typeElement) && ts.isIdentifier(typeElement.name) + ) { + const originalName = typeElement.name.text; + const renamedName = captureNameMap.get(originalName) ?? originalName; + + if (renamedName !== originalName) { + // Create a new property signature with the renamed identifier + typeElements.push( + factory.createPropertySignature( + typeElement.modifiers, + factory.createIdentifier(renamedName), + typeElement.questionToken, + typeElement.type, + ), + ); + } else { + // No renaming needed + typeElements.push(typeElement); + } + } else { + // Not a simple property signature, keep as-is + typeElements.push(typeElement); + } + } + // Create object type literal return factory.createTypeLiteralNode(typeElements); } @@ -1757,11 +1880,18 @@ function transformDeriveCall( // In this case, we don't need to preserve the input - just use captures const hadZeroParameters = callback.parameters.length === 0; + // Resolve capture name collisions with the original input parameter name + const captureNameMap = resolveDeriveCaptureNameCollisions( + originalInputParamName, + captureTree, + ); + // Build merged input object const mergedInput = buildDeriveInputObject( originalInput, originalInputParamName, captureTree, + captureNameMap, factory, hadZeroParameters, ); @@ -1772,6 +1902,7 @@ function transformDeriveCall( transformedBody, originalInputParamName, captureTree, + captureNameMap, context, hadZeroParameters, ); @@ -1782,6 +1913,7 @@ function transformDeriveCall( originalInputParamName, originalInput, captureTree, + captureNameMap, context, hadZeroParameters, ); diff --git a/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx index e005613aee..de29024ee4 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx @@ -1,15 +1,30 @@ import * as __ctHelpers from "commontools"; import { cell, derive } from "commontools"; export default function TestDerive() { - const value = cell(10); - const _multiplier = cell(2); - // Parameter name collides with capture name - const result = derive({ - type: "number", - asCell: true + const multiplier = cell(2); + // Input name collides with capture name + // multiplier is both the input AND a captured variable (used via .get()) + const result = __ctHelpers.derive({ + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + multiplier: { + type: "number", + asOpaque: true + }, + multiplier_1: { + type: "number", + asOpaque: true + } + }, + required: ["multiplier", "multiplier_1"] } as const satisfies __ctHelpers.JSONSchema, { + $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" - } as const satisfies __ctHelpers.JSONSchema, value, (multiplier) => multiplier * 3); + } as const satisfies __ctHelpers.JSONSchema, { + multiplier, + multiplier_1: multiplier + }, ({ multiplier: m, multiplier_1 }) => m * 3 + multiplier_1.get()); return result; } // @ts-ignore: Internals diff --git a/packages/ts-transformers/test/fixtures/closures/derive-name-collision.input.tsx b/packages/ts-transformers/test/fixtures/closures/derive-name-collision.input.tsx index fda68e3c6e..9809e1b80e 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-name-collision.input.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-name-collision.input.tsx @@ -2,11 +2,11 @@ import { cell, derive } from "commontools"; export default function TestDerive() { - const value = cell(10); - const _multiplier = cell(2); + const multiplier = cell(2); - // Parameter name collides with capture name - const result = derive(value, (multiplier) => multiplier * 3); + // Input name collides with capture name + // multiplier is both the input AND a captured variable (used via .get()) + const result = derive(multiplier, (m) => m * 3 + multiplier.get()); return result; } From f4696830289eb7f054ea9e64770bb57d2476c4dd Mon Sep 17 00:00:00 2001 From: Gideon Wald Date: Tue, 11 Nov 2025 11:47:28 -0800 Subject: [PATCH 2/7] fix issue reviewer bot noticed --- .../src/closures/transformer.ts | 24 ++++++++-- .../derive-collision-property.expected.tsx | 46 +++++++++++++++++++ .../derive-collision-property.input.tsx | 16 +++++++ 3 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx create mode 100644 packages/ts-transformers/test/fixtures/closures/derive-collision-property.input.tsx diff --git a/packages/ts-transformers/src/closures/transformer.ts b/packages/ts-transformers/src/closures/transformer.ts index 6d2f8f82c5..dbc7673771 100644 --- a/packages/ts-transformers/src/closures/transformer.ts +++ b/packages/ts-transformers/src/closures/transformer.ts @@ -1551,20 +1551,34 @@ function rewriteCaptureReferences( return body; // No substitutions needed } - const visitor = (node: ts.Node): ts.Node => { - // Only substitute root-level identifiers that match captured variable names - // Don't substitute property names or nested references + const visitor = (node: ts.Node, parent?: ts.Node): ts.Node => { + // Don't substitute identifiers that are property names if (ts.isIdentifier(node)) { + // Skip if this identifier is the property name in a property access (e.g., '.get' in 'obj.get') + if (parent && ts.isPropertyAccessExpression(parent) && parent.name === node) { + return node; + } + + // Skip if this identifier is a property name in an object literal (e.g., 'foo' in '{ foo: value }') + if (parent && ts.isPropertyAssignment(parent) && parent.name === node) { + return node; + } + + // Skip if this identifier is a shorthand property name (e.g., 'foo' in '{ foo }') + if (parent && ts.isShorthandPropertyAssignment(parent) && parent.name === node) { + return node; + } + const substituteName = substitutions.get(node.text); if (substituteName) { return factory.createIdentifier(substituteName); } } - return ts.visitEachChild(node, visitor, undefined); + return ts.visitEachChild(node, (child) => visitor(child, node), undefined); }; - return ts.visitNode(body, visitor) as ts.ConciseBody; + return ts.visitNode(body, (node) => visitor(node, undefined)) as ts.ConciseBody; } /** diff --git a/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx new file mode 100644 index 0000000000..95540bfc3e --- /dev/null +++ b/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx @@ -0,0 +1,46 @@ +import * as __ctHelpers from "commontools"; +import { cell, derive } from "commontools"; +export default function TestDeriveCollisionProperty() { + const multiplier = cell(2); + // Input name 'multiplier' collides with captured variable 'multiplier' + // The callback returns an object with a property named 'multiplier' + // Only the variable reference should be renamed, NOT the property name + const result = __ctHelpers.derive({ + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + multiplier: { + type: "number", + asOpaque: true + }, + multiplier_1: { + type: "number", + asOpaque: true + } + }, + required: ["multiplier", "multiplier_1"] + } as const satisfies __ctHelpers.JSONSchema, { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + multiplier: { + type: "number" + }, + value: { + type: "number" + } + }, + required: ["multiplier", "value"] + } as const satisfies __ctHelpers.JSONSchema, { + multiplier, + multiplier_1: multiplier + }, ({ multiplier: m, multiplier_1 }) => ({ + multiplier: multiplier_1.get(), + value: m * 3, + })); + return result; +} +// @ts-ignore: Internals +function h(...args: any[]) { return __ctHelpers.h.apply(null, args); } +// @ts-ignore: Internals +h.fragment = __ctHelpers.h.fragment; diff --git a/packages/ts-transformers/test/fixtures/closures/derive-collision-property.input.tsx b/packages/ts-transformers/test/fixtures/closures/derive-collision-property.input.tsx new file mode 100644 index 0000000000..c2412176b0 --- /dev/null +++ b/packages/ts-transformers/test/fixtures/closures/derive-collision-property.input.tsx @@ -0,0 +1,16 @@ +/// +import { cell, derive } from "commontools"; + +export default function TestDeriveCollisionProperty() { + const multiplier = cell(2); + + // Input name 'multiplier' collides with captured variable 'multiplier' + // The callback returns an object with a property named 'multiplier' + // Only the variable reference should be renamed, NOT the property name + const result = derive(multiplier, (m) => ({ + multiplier: multiplier.get(), + value: m * 3, + })); + + return result; +} From ac6b853e2514eeaeef77619ff8b62125345a2d75 Mon Sep 17 00:00:00 2001 From: Gideon Wald Date: Tue, 11 Nov 2025 11:55:32 -0800 Subject: [PATCH 3/7] fmt --- .../ts-transformers/src/closures/transformer.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/ts-transformers/src/closures/transformer.ts b/packages/ts-transformers/src/closures/transformer.ts index dbc7673771..ef6254ca35 100644 --- a/packages/ts-transformers/src/closures/transformer.ts +++ b/packages/ts-transformers/src/closures/transformer.ts @@ -1555,7 +1555,9 @@ function rewriteCaptureReferences( // Don't substitute identifiers that are property names if (ts.isIdentifier(node)) { // Skip if this identifier is the property name in a property access (e.g., '.get' in 'obj.get') - if (parent && ts.isPropertyAccessExpression(parent) && parent.name === node) { + if ( + parent && ts.isPropertyAccessExpression(parent) && parent.name === node + ) { return node; } @@ -1565,7 +1567,10 @@ function rewriteCaptureReferences( } // Skip if this identifier is a shorthand property name (e.g., 'foo' in '{ foo }') - if (parent && ts.isShorthandPropertyAssignment(parent) && parent.name === node) { + if ( + parent && ts.isShorthandPropertyAssignment(parent) && + parent.name === node + ) { return node; } @@ -1578,7 +1583,10 @@ function rewriteCaptureReferences( return ts.visitEachChild(node, (child) => visitor(child, node), undefined); }; - return ts.visitNode(body, (node) => visitor(node, undefined)) as ts.ConciseBody; + return ts.visitNode( + body, + (node) => visitor(node, undefined), + ) as ts.ConciseBody; } /** From 26b50e8698a16f92916ba505473c7cbacbbe6454 Mon Sep 17 00:00:00 2001 From: Gideon Wald Date: Tue, 11 Nov 2025 12:20:46 -0800 Subject: [PATCH 4/7] handle shorthand property names in symbol collisions --- .../src/closures/transformer.ts | 23 ++++++--- .../derive-collision-shorthand.expected.tsx | 50 +++++++++++++++++++ .../derive-collision-shorthand.input.tsx | 16 ++++++ 3 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx create mode 100644 packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.input.tsx diff --git a/packages/ts-transformers/src/closures/transformer.ts b/packages/ts-transformers/src/closures/transformer.ts index ef6254ca35..f1d4289e53 100644 --- a/packages/ts-transformers/src/closures/transformer.ts +++ b/packages/ts-transformers/src/closures/transformer.ts @@ -1552,6 +1552,21 @@ function rewriteCaptureReferences( } const visitor = (node: ts.Node, parent?: ts.Node): ts.Node => { + // Handle shorthand property assignments specially + // { multiplier } needs to become { multiplier: multiplier_1 } if multiplier is renamed + if (ts.isShorthandPropertyAssignment(node)) { + const substituteName = substitutions.get(node.name.text); + if (substituteName) { + // Expand shorthand into full property assignment + return factory.createPropertyAssignment( + node.name, // Property name stays the same + factory.createIdentifier(substituteName), // Value uses renamed identifier + ); + } + // No substitution needed, keep as shorthand + return node; + } + // Don't substitute identifiers that are property names if (ts.isIdentifier(node)) { // Skip if this identifier is the property name in a property access (e.g., '.get' in 'obj.get') @@ -1566,14 +1581,6 @@ function rewriteCaptureReferences( return node; } - // Skip if this identifier is a shorthand property name (e.g., 'foo' in '{ foo }') - if ( - parent && ts.isShorthandPropertyAssignment(parent) && - parent.name === node - ) { - return node; - } - const substituteName = substitutions.get(node.text); if (substituteName) { return factory.createIdentifier(substituteName); diff --git a/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx new file mode 100644 index 0000000000..e8cf0cbdab --- /dev/null +++ b/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx @@ -0,0 +1,50 @@ +import * as __ctHelpers from "commontools"; +import { cell, derive } from "commontools"; +export default function TestDeriveCollisionShorthand() { + const multiplier = cell(2); + // Input name 'multiplier' collides with captured variable 'multiplier' + // The callback uses shorthand property { multiplier } + // This should expand to { multiplier: multiplier_1 } after renaming + const result = __ctHelpers.derive({ + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + multiplier: { + type: "number", + asOpaque: true + }, + multiplier_1: { + type: "number", + asOpaque: true + } + }, + required: ["multiplier", "multiplier_1"] + } as const satisfies __ctHelpers.JSONSchema, { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + value: { + type: "number" + }, + data: { + type: "object", + properties: { + multiplier: true + }, + required: ["multiplier"] + } + }, + required: ["value", "data"] + } as const satisfies __ctHelpers.JSONSchema, { + multiplier, + multiplier_1: multiplier + }, ({ multiplier: m, multiplier_1 }) => ({ + value: m * 3, + data: { multiplier: multiplier_1 }, + })); + return result; +} +// @ts-ignore: Internals +function h(...args: any[]) { return __ctHelpers.h.apply(null, args); } +// @ts-ignore: Internals +h.fragment = __ctHelpers.h.fragment; diff --git a/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.input.tsx b/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.input.tsx new file mode 100644 index 0000000000..3c2e7960a3 --- /dev/null +++ b/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.input.tsx @@ -0,0 +1,16 @@ +/// +import { cell, derive } from "commontools"; + +export default function TestDeriveCollisionShorthand() { + const multiplier = cell(2); + + // Input name 'multiplier' collides with captured variable 'multiplier' + // The callback uses shorthand property { multiplier } + // This should expand to { multiplier: multiplier_1 } after renaming + const result = derive(multiplier, (m) => ({ + value: m * 3, + data: { multiplier }, + })); + + return result; +} From f24c583260e4dc1f6895b029d118dc16c4511f60 Mon Sep 17 00:00:00 2001 From: Gideon Wald Date: Wed, 12 Nov 2025 11:31:59 -0800 Subject: [PATCH 5/7] fix shorthand property assignments; also remove everywhere --- .../schema-generator/src/schema-generator.ts | 9 ++------- .../src/closures/transformer.ts | 13 ++++++++++--- .../src/transformers/schema-injection.ts | 18 ++++++++++++++++-- .../recipe-array-map.expected.tsx | 1 - .../schema-generation-builders.expected.tsx | 1 - ...ema-generation-lift-cell-array.expected.tsx | 2 -- .../cell-map-with-captures.expected.tsx | 1 - .../closures/derive-4arg-form.expected.tsx | 2 -- .../derive-array-element-access.expected.tsx | 2 -- .../closures/derive-basic-capture.expected.tsx | 2 -- .../derive-collision-property.expected.tsx | 2 -- .../derive-collision-shorthand.expected.tsx | 7 ++++--- .../derive-complex-expression.expected.tsx | 2 -- .../derive-computed-property.expected.tsx | 2 -- .../derive-conditional-expression.expected.tsx | 2 -- .../derive-destructured-param.expected.tsx | 2 -- .../derive-map-union-return.expected.tsx | 2 -- .../derive-multiple-captures.expected.tsx | 2 -- .../derive-name-collision.expected.tsx | 2 -- .../derive-nested-property.expected.tsx | 2 -- .../derive-optional-chaining.expected.tsx | 2 -- .../derive-param-initializer.expected.tsx | 2 -- .../derive-reserved-names.expected.tsx | 2 -- .../derive-template-literal.expected.tsx | 2 -- .../derive-type-assertion.expected.tsx | 2 -- .../derive-union-undefined.expected.tsx | 2 -- .../closures/filter-map-chain.expected.tsx | 2 -- .../closures/handler-basic.expected.tsx | 1 - .../closures/handler-computed-key.expected.tsx | 1 - .../handler-destructured-params.expected.tsx | 1 - .../closures/handler-event-param.expected.tsx | 1 - .../handler-existing-reference.expected.tsx | 1 - .../closures/handler-nested-map.expected.tsx | 2 -- .../closures/handler-no-captures.expected.tsx | 1 - .../handler-reserved-capture.expected.tsx | 1 - .../closures/handler-unused-event.expected.tsx | 1 - ...ap-array-destructure-shorthand.expected.tsx | 3 --- .../map-array-destructured.expected.tsx | 3 --- ...map-capture-cell-param-no-name.expected.tsx | 2 -- .../map-capture-cell-param.expected.tsx | 3 --- ...map-computed-alias-side-effect.expected.tsx | 1 - .../map-computed-alias-strict.expected.tsx | 2 -- ...puted-alias-with-plain-binding.expected.tsx | 2 -- .../map-conditional-expression.expected.tsx | 2 -- .../map-destructured-alias.expected.tsx | 1 - ...ap-destructured-computed-alias.expected.tsx | 2 -- ...map-destructured-numeric-alias.expected.tsx | 1 - .../map-destructured-param.expected.tsx | 2 -- .../map-destructured-string-alias.expected.tsx | 1 - .../map-element-access-opaque.expected.tsx | 1 - .../map-handler-reference-no-name.expected.tsx | 1 - ...eference-with-type-arg-no-name.expected.tsx | 2 -- .../map-handler-reference.expected.tsx | 2 -- .../closures/map-import-reference.expected.tsx | 2 -- .../closures/map-index-param-used.expected.tsx | 2 -- .../closures/map-index-shorthand.expected.tsx | 3 --- .../map-multiple-captures.expected.tsx | 2 -- .../map-multiple-similar-captures.expected.tsx | 1 - .../closures/map-nested-callback.expected.tsx | 3 --- .../closures/map-nested-property.expected.tsx | 2 -- .../closures/map-no-captures.expected.tsx | 2 -- .../closures/map-outer-element.expected.tsx | 1 - ...-capture-with-type-arg-no-name.expected.tsx | 1 - .../closures/map-single-capture.expected.tsx | 1 - .../closures/map-template-literal.expected.tsx | 2 -- .../closures/map-type-assertion.expected.tsx | 1 - .../map-with-array-param-no-name.expected.tsx | 1 - .../closures/map-with-array-param.expected.tsx | 1 - .../array-cell-remove-intersection.expected.ts | 2 -- .../date-and-map-types.expected.ts | 2 -- .../jsx-complex-mixed.expected.tsx | 2 -- .../jsx-property-access.expected.tsx | 1 - .../jsx-expressions/method-chains.expected.tsx | 3 --- .../optional-chain-captures.expected.tsx | 2 -- .../manual-map-with-pattern.expected.tsx | 1 - .../nested-default-optional.expected.tsx | 2 -- .../opaque-ref-map.expected.ts | 3 --- .../recipe-with-types.expected.tsx | 3 --- 78 files changed, 32 insertions(+), 145 deletions(-) diff --git a/packages/schema-generator/src/schema-generator.ts b/packages/schema-generator/src/schema-generator.ts index 04a84198bd..25ff84d6e9 100644 --- a/packages/schema-generator/src/schema-generator.ts +++ b/packages/schema-generator/src/schema-generator.ts @@ -400,7 +400,6 @@ export class SchemaGenerator implements ISchemaGenerator { // final output const filtered = this.collectReferencedDefinitions(base, definitions); const out: Record = { - $schema: "https://json-schema.org/draft/2020-12/schema", ...(base as Record), }; if (Object.keys(filtered).length > 0) out.$defs = filtered; @@ -701,18 +700,14 @@ export class SchemaGenerator implements ISchemaGenerator { return rootSchema; } - // If no definitions were created or used, return simple schema with $schema + // If no definitions were created or used, return simple schema if (Object.keys(definitions).length === 0 || emittedRefs.size === 0) { - return { - $schema: "https://json-schema.org/draft/2020-12/schema", - ...(rootSchema as Record), - } as SchemaDefinition; + return rootSchema; } // Object schema: attach only the definitions actually referenced const filtered = this.collectReferencedDefinitions(rootSchema, definitions); const out: Record = { - $schema: "https://json-schema.org/draft/2020-12/schema", ...(rootSchema as Record), }; if (Object.keys(filtered).length > 0) out.$defs = filtered; diff --git a/packages/ts-transformers/src/closures/transformer.ts b/packages/ts-transformers/src/closures/transformer.ts index f1d4289e53..d9b16e42ef 100644 --- a/packages/ts-transformers/src/closures/transformer.ts +++ b/packages/ts-transformers/src/closures/transformer.ts @@ -1951,19 +1951,26 @@ function transformDeriveCall( // SchemaInjectionTransformer will use this to generate the result schema const signature = context.checker.getSignatureFromDeclaration(callback); let resultTypeNode: ts.TypeNode | undefined; + let resultType: ts.Type | undefined; if (callback.type) { - // Explicit return type annotation - use it + // Explicit return type annotation - use it directly (no need to register in typeRegistry) resultTypeNode = callback.type; } else if (signature) { // Infer from callback signature - const returnType = signature.getReturnType(); + resultType = signature.getReturnType(); resultTypeNode = context.checker.typeToTypeNode( - returnType, + resultType, context.sourceFile, ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.UseStructuralFallback, ); + + // Register the result Type in typeRegistry for the synthetic TypeNode + // This fixes schema generation for shorthand properties referencing captured variables + if (resultTypeNode && context.options.typeRegistry) { + context.options.typeRegistry.set(resultTypeNode, resultType); + } } // Build the derive call expression diff --git a/packages/ts-transformers/src/transformers/schema-injection.ts b/packages/ts-transformers/src/transformers/schema-injection.ts index b3b26bb509..c6546fcf0f 100644 --- a/packages/ts-transformers/src/transformers/schema-injection.ts +++ b/packages/ts-transformers/src/transformers/schema-injection.ts @@ -345,11 +345,25 @@ export class SchemaInjectionTransformer extends Transformer { return ts.visitEachChild(node, visit, transformation); } + // Check if ClosureTransformer registered Types for these TypeNodes + // This preserves type information for shorthand properties with captured variables + let argumentTypeValue: ts.Type | undefined; + let resultTypeValue: ts.Type | undefined; + + if (typeRegistry) { + if (typeRegistry.has(argumentType)) { + argumentTypeValue = typeRegistry.get(argumentType); + } + if (typeRegistry.has(resultType)) { + resultTypeValue = typeRegistry.get(resultType); + } + } + return updateWithSchemas( argumentType, - undefined, + argumentTypeValue, resultType, - undefined, + resultTypeValue, ); } diff --git a/packages/ts-transformers/test/fixtures/ast-transform/recipe-array-map.expected.tsx b/packages/ts-transformers/test/fixtures/ast-transform/recipe-array-map.expected.tsx index 9fdd0210f1..0f8f940d08 100644 --- a/packages/ts-transformers/test/fixtures/ast-transform/recipe-array-map.expected.tsx +++ b/packages/ts-transformers/test/fixtures/ast-transform/recipe-array-map.expected.tsx @@ -43,7 +43,6 @@ export default recipe({
{values.mapWithPattern(__ctHelpers.recipe({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { element: { diff --git a/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-builders.expected.tsx b/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-builders.expected.tsx index 12e4246e67..d6fa62a7c3 100644 --- a/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-builders.expected.tsx +++ b/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-builders.expected.tsx @@ -47,7 +47,6 @@ export default recipe({
    {state.items.mapWithPattern(__ctHelpers.recipe({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { element: { diff --git a/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-lift-cell-array.expected.tsx b/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-lift-cell-array.expected.tsx index 3f4fa45d34..81dc227422 100644 --- a/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-lift-cell-array.expected.tsx +++ b/packages/ts-transformers/test/fixtures/ast-transform/schema-generation-lift-cell-array.expected.tsx @@ -7,7 +7,6 @@ interface CharmEntry { // Test that lift with single generic parameter preserves Cell wrapper // This was broken on main - Cell would be unwrapped to ProxyArray const logCharmsList = lift({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { charmsList: { @@ -34,7 +33,6 @@ const logCharmsList = lift({ } } } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "array", items: { $ref: "#/$defs/CharmEntry" diff --git a/packages/ts-transformers/test/fixtures/closures/cell-map-with-captures.expected.tsx b/packages/ts-transformers/test/fixtures/closures/cell-map-with-captures.expected.tsx index f82538fcfc..bf6582b065 100644 --- a/packages/ts-transformers/test/fixtures/closures/cell-map-with-captures.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/cell-map-with-captures.expected.tsx @@ -24,7 +24,6 @@ export default recipe({ return { [UI]: (
    {typedValues.mapWithPattern(__ctHelpers.recipe({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { element: { diff --git a/packages/ts-transformers/test/fixtures/closures/derive-4arg-form.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-4arg-form.expected.tsx index eec3e1a538..ed780fc6af 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-4arg-form.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-4arg-form.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { const multiplier = cell(2); // Explicit 4-arg form with schemas - should still transform captures const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -19,7 +18,6 @@ export default function TestDerive() { }, required: ["value", "multiplier"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-array-element-access.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-array-element-access.expected.tsx index bc928eb33e..e91f14973c 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-array-element-access.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-array-element-access.expected.tsx @@ -4,7 +4,6 @@ export default function TestDerive() { const value = cell(10); const factors = [2, 3, 4]; const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -20,7 +19,6 @@ export default function TestDerive() { }, required: ["value", "factors"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-basic-capture.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-basic-capture.expected.tsx index 5d972a5854..ac81933009 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-basic-capture.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-basic-capture.expected.tsx @@ -4,7 +4,6 @@ export default function TestDerive() { const value = cell(10); const multiplier = cell(2); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -18,7 +17,6 @@ export default function TestDerive() { }, required: ["value", "multiplier"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx index 95540bfc3e..63b247aa49 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-collision-property.expected.tsx @@ -6,7 +6,6 @@ export default function TestDeriveCollisionProperty() { // The callback returns an object with a property named 'multiplier' // Only the variable reference should be renamed, NOT the property name const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { multiplier: { @@ -20,7 +19,6 @@ export default function TestDeriveCollisionProperty() { }, required: ["multiplier", "multiplier_1"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { multiplier: { diff --git a/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx index e8cf0cbdab..7ccfe208c4 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-collision-shorthand.expected.tsx @@ -6,7 +6,6 @@ export default function TestDeriveCollisionShorthand() { // The callback uses shorthand property { multiplier } // This should expand to { multiplier: multiplier_1 } after renaming const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { multiplier: { @@ -20,7 +19,6 @@ export default function TestDeriveCollisionShorthand() { }, required: ["multiplier", "multiplier_1"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -29,7 +27,10 @@ export default function TestDeriveCollisionShorthand() { data: { type: "object", properties: { - multiplier: true + multiplier: { + type: "number", + asOpaque: true + } }, required: ["multiplier"] } diff --git a/packages/ts-transformers/test/fixtures/closures/derive-complex-expression.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-complex-expression.expected.tsx index d78b67e3fa..1be24104b8 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-complex-expression.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-complex-expression.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { const b = cell(20); const c = cell(30); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { a: { @@ -23,7 +22,6 @@ export default function TestDerive() { }, required: ["a", "b", "c"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { a, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-computed-property.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-computed-property.expected.tsx index 6cf72d794c..defe8c1539 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-computed-property.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-computed-property.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { const config = { multiplier: 2, divisor: 5 }; const key = "multiplier"; const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -31,7 +30,6 @@ export default function TestDerive() { }, required: ["value", "config", "key"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-conditional-expression.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-conditional-expression.expected.tsx index c0213cd47d..4a11f099e4 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-conditional-expression.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-conditional-expression.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { const threshold = cell(5); const multiplier = cell(2); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -23,7 +22,6 @@ export default function TestDerive() { }, required: ["value", "threshold", "multiplier"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-destructured-param.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-destructured-param.expected.tsx index 86eb89ec99..21560a6cce 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-destructured-param.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-destructured-param.expected.tsx @@ -9,7 +9,6 @@ export default function TestDerive() { const multiplier = cell(2); // Destructured parameter const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { point: { @@ -37,7 +36,6 @@ export default function TestDerive() { } } } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { point, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-map-union-return.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-map-union-return.expected.tsx index 387377a017..8ecac1f10f 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-map-union-return.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-map-union-return.expected.tsx @@ -13,7 +13,6 @@ interface State { messages: Message[]; } export default recipe({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { messages: { @@ -66,7 +65,6 @@ export default recipe({ // caused type inference to fail, resulting in a 'true' schema instead of // the correct union type schema. const latestMessage = derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "array", items: { $ref: "#/$defs/Message" diff --git a/packages/ts-transformers/test/fixtures/closures/derive-multiple-captures.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-multiple-captures.expected.tsx index e78ff7e1c9..a91e26a9eb 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-multiple-captures.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-multiple-captures.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { const multiplier = cell(2); const offset = cell(5); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -23,7 +22,6 @@ export default function TestDerive() { }, required: ["value", "multiplier", "offset"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx index de29024ee4..f4094b24b3 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-name-collision.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { // Input name collides with capture name // multiplier is both the input AND a captured variable (used via .get()) const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { multiplier: { @@ -19,7 +18,6 @@ export default function TestDerive() { }, required: ["multiplier", "multiplier_1"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { multiplier, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-nested-property.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-nested-property.expected.tsx index 2a521595a1..4a32110c32 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-nested-property.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-nested-property.expected.tsx @@ -8,7 +8,6 @@ interface State { export default function TestDerive(state: State) { const value = cell(10); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -33,7 +32,6 @@ export default function TestDerive(state: State) { }, required: ["value", "state"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-optional-chaining.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-optional-chaining.expected.tsx index c249acade5..453e4573e3 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-optional-chaining.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-optional-chaining.expected.tsx @@ -6,7 +6,6 @@ interface Config { export default function TestDerive(config: Config) { const value = cell(10); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -24,7 +23,6 @@ export default function TestDerive(config: Config) { }, required: ["value", "config"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-param-initializer.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-param-initializer.expected.tsx index 8fba9b6a32..c6304abee5 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-param-initializer.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-param-initializer.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { const multiplier = cell(2); // Test parameter with default value const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -19,7 +18,6 @@ export default function TestDerive() { }, required: ["value", "multiplier"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-reserved-names.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-reserved-names.expected.tsx index 3ffd905986..3679f7fd27 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-reserved-names.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-reserved-names.expected.tsx @@ -5,7 +5,6 @@ export default function TestDerive() { // Reserved JavaScript keyword as variable name (valid in TS with quotes) const __ct_reserved = cell(2); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -19,7 +18,6 @@ export default function TestDerive() { }, required: ["value", "__ct_reserved"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-template-literal.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-template-literal.expected.tsx index c223b06129..abf3f1e9cf 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-template-literal.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-template-literal.expected.tsx @@ -4,7 +4,6 @@ export default function TestDerive() { const value = cell(10); const prefix = cell("Value: "); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -18,7 +17,6 @@ export default function TestDerive() { }, required: ["value", "prefix"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "string" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-type-assertion.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-type-assertion.expected.tsx index 3674b9c376..b03320243d 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-type-assertion.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-type-assertion.expected.tsx @@ -4,7 +4,6 @@ export default function TestDerive() { const value = cell(10); const multiplier = cell(2); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -18,7 +17,6 @@ export default function TestDerive() { }, required: ["value", "multiplier"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/derive-union-undefined.expected.tsx b/packages/ts-transformers/test/fixtures/closures/derive-union-undefined.expected.tsx index 35bae404ea..cb8390b958 100644 --- a/packages/ts-transformers/test/fixtures/closures/derive-union-undefined.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/derive-union-undefined.expected.tsx @@ -7,7 +7,6 @@ interface Config { export default function TestDerive(config: Config) { const value = cell(10); const result = __ctHelpers.derive({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { value: { @@ -29,7 +28,6 @@ export default function TestDerive(config: Config) { }, required: ["value", "config"] } as const satisfies __ctHelpers.JSONSchema, { - $schema: "https://json-schema.org/draft/2020-12/schema", type: "number" } as const satisfies __ctHelpers.JSONSchema, { value, diff --git a/packages/ts-transformers/test/fixtures/closures/filter-map-chain.expected.tsx b/packages/ts-transformers/test/fixtures/closures/filter-map-chain.expected.tsx index ad62d4b40a..47ab607e66 100644 --- a/packages/ts-transformers/test/fixtures/closures/filter-map-chain.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/filter-map-chain.expected.tsx @@ -10,7 +10,6 @@ interface State { taxRate: number; } export default recipe({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { items: { @@ -49,7 +48,6 @@ export default recipe({ items: state.items } }, ({ state }) => state.items .filter((item) => item.active)).mapWithPattern(__ctHelpers.recipe({ - $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { element: { diff --git a/packages/ts-transformers/test/fixtures/closures/handler-basic.expected.tsx b/packages/ts-transformers/test/fixtures/closures/handler-basic.expected.tsx index 6cb983f56f..e982e81141 100644 --- a/packages/ts-transformers/test/fixtures/closures/handler-basic.expected.tsx +++ b/packages/ts-transformers/test/fixtures/closures/handler-basic.expected.tsx @@ -15,7 +15,6 @@ export default recipe({ } as const satisfies __ctHelpers.JSONSchema, (state) => { return { [UI]: (