@effect/language-service 0.60.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -4478,7 +4478,11 @@ var getEditsForCodegen = fn("LSP.getEditsForCodegen")(function* (codegens2, sour
4478
4478
  service(ChangeTracker),
4479
4479
  map8((changeTracker) => {
4480
4480
  changeTracker.deleteRange(sourceFile, range);
4481
- changeTracker.insertText(sourceFile, range.pos, `${codegen.name}:${edit.hash}`);
4481
+ changeTracker.insertText(
4482
+ sourceFile,
4483
+ range.pos,
4484
+ edit.hash.length > 0 ? `${codegen.name}:${edit.hash}` : codegen.name
4485
+ );
4482
4486
  })
4483
4487
  );
4484
4488
  return {
@@ -16510,6 +16514,536 @@ var removeUnnecessaryEffectGen = createRefactor({
16510
16514
  })
16511
16515
  });
16512
16516
 
16517
+ // src/utils/StructuralSchemaGen.ts
16518
+ var UnsupportedTypeError = class {
16519
+ constructor(type, reason) {
16520
+ this.type = type;
16521
+ this.reason = reason;
16522
+ }
16523
+ _tag = "@effect/language-service/UnsupportedTypeError";
16524
+ toString() {
16525
+ return `Unsupported type: ${this.reason}`;
16526
+ }
16527
+ };
16528
+ var StructuralSchemaGenContext = Tag("StructuralSchemaGenContext");
16529
+ var makeStructuralSchemaGenContext = fn("StructuralSchemaGen.makeContext")(
16530
+ function* (sourceFile, schemaIdentifier) {
16531
+ const ts = yield* service(TypeScriptApi);
16532
+ const typeChecker = yield* service(TypeCheckerApi);
16533
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
16534
+ const effectSchemaIdentifier = schemaIdentifier || "Schema";
16535
+ return identity({
16536
+ ts,
16537
+ typeChecker,
16538
+ typeCheckerUtils,
16539
+ sourceFile,
16540
+ createApiPropertyAccess: (apiName) => ts.factory.createPropertyAccessExpression(
16541
+ ts.factory.createIdentifier(effectSchemaIdentifier),
16542
+ apiName
16543
+ ),
16544
+ createApiCall: (apiName, args2) => ts.factory.createCallExpression(
16545
+ ts.factory.createPropertyAccessExpression(
16546
+ ts.factory.createIdentifier(effectSchemaIdentifier),
16547
+ apiName
16548
+ ),
16549
+ [],
16550
+ args2
16551
+ ),
16552
+ hoistedSchemas: /* @__PURE__ */ new Map(),
16553
+ typeToStatementIndex: /* @__PURE__ */ new Map(),
16554
+ nameToType: /* @__PURE__ */ new Map(),
16555
+ usedGlobalIdentifiers: /* @__PURE__ */ new Map(),
16556
+ schemaStatements: []
16557
+ });
16558
+ }
16559
+ );
16560
+ var pushHoistedStatement = fn("StructuralSchemaGen.pushHoistedStatement")(
16561
+ function* (ctx, name, type, statement, createReference) {
16562
+ ctx.usedGlobalIdentifiers.set(name, (ctx.usedGlobalIdentifiers.get(name) || 0) + 1);
16563
+ ctx.schemaStatements.push(statement);
16564
+ ctx.typeToStatementIndex.set(type, ctx.schemaStatements.length - 1);
16565
+ ctx.hoistedSchemas.set(type, createReference);
16566
+ }
16567
+ );
16568
+ var pushHoistedVariableStatement = fn("StructuralSchemaGen.pushHoistedVariableStatement")(
16569
+ function* (ts, ctx, name, type, result) {
16570
+ return yield* pushHoistedStatement(
16571
+ ctx,
16572
+ name,
16573
+ type,
16574
+ ts.factory.createVariableStatement(
16575
+ void 0,
16576
+ ts.factory.createVariableDeclarationList(
16577
+ [ts.factory.createVariableDeclaration(ts.factory.createIdentifier(name), void 0, void 0, result)],
16578
+ ts.NodeFlags.Const
16579
+ )
16580
+ ),
16581
+ () => ts.factory.createIdentifier(name)
16582
+ );
16583
+ }
16584
+ );
16585
+ var createProcessingContext = (maxDepth = 200) => ({
16586
+ depth: 0,
16587
+ maxDepth,
16588
+ hoistName: void 0
16589
+ });
16590
+ var processType = fn(
16591
+ "StructuralSchemaGen.processType"
16592
+ )(
16593
+ function* (type, context) {
16594
+ const processingContext = context || createProcessingContext();
16595
+ const { hoistedSchemas, nameToType, ts, typeChecker, usedGlobalIdentifiers } = yield* service(
16596
+ StructuralSchemaGenContext
16597
+ );
16598
+ if (processingContext.depth >= processingContext.maxDepth) {
16599
+ return yield* fail3(new UnsupportedTypeError(type, "Maximum depth exceeded"));
16600
+ }
16601
+ let hoistName = fromIterable(nameToType.entries()).find(([_, existingType]) => existingType === type)?.[0];
16602
+ if (!hoistName && type && type.symbol && type.symbol.declarations && type.symbol.declarations.length === 1) {
16603
+ const declaration = type.symbol.declarations[0];
16604
+ if (ts.isInterfaceDeclaration(declaration)) {
16605
+ hoistName = ts.idText(declaration.name);
16606
+ } else if (declaration.parent && ts.isTypeAliasDeclaration(declaration.parent)) {
16607
+ hoistName = ts.idText(declaration.parent.name);
16608
+ }
16609
+ if (hoistName) {
16610
+ const existingType = nameToType.get(hoistName);
16611
+ const isSame = existingType && typeChecker.isTypeAssignableTo(type, existingType) && typeChecker.isTypeAssignableTo(existingType, type);
16612
+ if (!isSame) {
16613
+ const usedCount = usedGlobalIdentifiers.get(hoistName) || 0;
16614
+ hoistName = usedCount > 0 ? hoistName + "_" + usedCount : hoistName;
16615
+ }
16616
+ }
16617
+ }
16618
+ const nestedContext = {
16619
+ ...processingContext,
16620
+ depth: processingContext.depth + 1,
16621
+ hoistName
16622
+ };
16623
+ for (const [hoistedType, hoistedSchema] of hoistedSchemas.entries()) {
16624
+ if (hoistedType === type || typeChecker.isTypeAssignableTo(type, hoistedType) && typeChecker.isTypeAssignableTo(hoistedType, type)) {
16625
+ return hoistedSchema();
16626
+ }
16627
+ }
16628
+ const [schemaExpr, skipHoisting] = yield* processTypeImpl(type, nestedContext);
16629
+ if (!skipHoisting && hoistName) {
16630
+ const ctx = yield* service(StructuralSchemaGenContext);
16631
+ yield* pushHoistedVariableStatement(ts, ctx, hoistName, type, schemaExpr);
16632
+ return ctx.hoistedSchemas.get(type)();
16633
+ }
16634
+ return schemaExpr;
16635
+ }
16636
+ );
16637
+ var processTypeImpl = fn(
16638
+ "StructuralSchemaGen.processTypeImpl"
16639
+ )(
16640
+ function* (type, context) {
16641
+ const { createApiCall, createApiPropertyAccess, ts, typeChecker, typeCheckerUtils } = yield* service(
16642
+ StructuralSchemaGenContext
16643
+ );
16644
+ if (type.flags & ts.TypeFlags.String) {
16645
+ return [createApiPropertyAccess("String"), true];
16646
+ }
16647
+ if (type.flags & ts.TypeFlags.Number) {
16648
+ return [createApiPropertyAccess("Number"), true];
16649
+ }
16650
+ if (type.flags & ts.TypeFlags.Boolean) {
16651
+ return [createApiPropertyAccess("Boolean"), true];
16652
+ }
16653
+ if (type.flags & ts.TypeFlags.BigInt) {
16654
+ return [createApiPropertyAccess("BigInt"), true];
16655
+ }
16656
+ if (type.flags & ts.TypeFlags.Void) {
16657
+ return [createApiPropertyAccess("Void"), true];
16658
+ }
16659
+ if (type.flags & ts.TypeFlags.Undefined) {
16660
+ return [createApiPropertyAccess("Undefined"), true];
16661
+ }
16662
+ if (type.flags & ts.TypeFlags.Null) {
16663
+ return [createApiPropertyAccess("Null"), true];
16664
+ }
16665
+ if (type.flags & ts.TypeFlags.Never) {
16666
+ return [createApiPropertyAccess("Never"), true];
16667
+ }
16668
+ if (type.flags & ts.TypeFlags.Any) {
16669
+ return [createApiPropertyAccess("Any"), true];
16670
+ }
16671
+ if (type.flags & ts.TypeFlags.Unknown) {
16672
+ return [createApiPropertyAccess("Unknown"), true];
16673
+ }
16674
+ if (type.flags & ts.TypeFlags.StringLiteral) {
16675
+ const literalType = type;
16676
+ return [createApiCall("Literal", [ts.factory.createStringLiteral(literalType.value)]), true];
16677
+ }
16678
+ if (type.flags & ts.TypeFlags.NumberLiteral) {
16679
+ const literalType = type;
16680
+ return [createApiCall("Literal", [ts.factory.createNumericLiteral(literalType.value)]), true];
16681
+ }
16682
+ if (type.flags & ts.TypeFlags.BooleanLiteral) {
16683
+ const value = type.intrinsicName === "true";
16684
+ return [createApiCall("Literal", [value ? ts.factory.createTrue() : ts.factory.createFalse()]), true];
16685
+ }
16686
+ if (typeCheckerUtils.isUnion(type)) {
16687
+ return yield* processUnionType(type, context);
16688
+ }
16689
+ if (type.flags & ts.TypeFlags.Intersection) {
16690
+ return yield* processIntersectionType(type, context);
16691
+ }
16692
+ if (typeChecker.isArrayType(type)) {
16693
+ return yield* processArrayType(type, context);
16694
+ }
16695
+ if (typeChecker.isTupleType(type)) {
16696
+ return yield* processTupleType(type, context);
16697
+ }
16698
+ if (type.flags & ts.TypeFlags.Object) {
16699
+ const symbol3 = type.symbol || type.aliasSymbol;
16700
+ if (symbol3) {
16701
+ const typeName = typeChecker.symbolToString(symbol3);
16702
+ if (typeName === "Date") {
16703
+ return [createApiPropertyAccess("Date"), false];
16704
+ }
16705
+ if (typeName === "ReadonlyArray" || typeName === "Array") {
16706
+ return yield* processArrayType(type, context);
16707
+ }
16708
+ }
16709
+ const objectType = type;
16710
+ return yield* processObjectType(objectType, context);
16711
+ }
16712
+ return yield* fail3(
16713
+ new UnsupportedTypeError(
16714
+ type,
16715
+ `Type with flags ${type.flags} is not supported`
16716
+ )
16717
+ );
16718
+ }
16719
+ );
16720
+ var processUnionType = fn(
16721
+ "StructuralSchemaGen.processUnionType"
16722
+ )(
16723
+ function* (type, context) {
16724
+ const { createApiCall, ts } = yield* service(StructuralSchemaGenContext);
16725
+ const allLiterals = type.types.every(
16726
+ (t) => t.flags & ts.TypeFlags.StringLiteral || t.flags & ts.TypeFlags.NumberLiteral || t.flags & ts.TypeFlags.BooleanLiteral
16727
+ );
16728
+ if (allLiterals) {
16729
+ const literals = yield* all(
16730
+ ...type.types.map((t) => processType(t, context))
16731
+ );
16732
+ const literalValues = literals.map((expr) => {
16733
+ if (ts.isCallExpression(expr) && expr.arguments.length > 0) {
16734
+ return expr.arguments[0];
16735
+ }
16736
+ return expr;
16737
+ }).filter((arg) => arg !== void 0);
16738
+ return [createApiCall("Literal", literalValues), false];
16739
+ }
16740
+ const members = yield* all(
16741
+ ...type.types.map((t) => processType(t, context))
16742
+ );
16743
+ return [createApiCall("Union", members), false];
16744
+ }
16745
+ );
16746
+ var processIntersectionType = fn(
16747
+ "StructuralSchemaGen.processIntersectionType"
16748
+ )(
16749
+ function* (type, context) {
16750
+ const { createApiCall, ts } = yield* service(StructuralSchemaGenContext);
16751
+ const [firstSchema, ...otherSchemas] = yield* all(
16752
+ ...type.types.map((t) => processType(t, context))
16753
+ );
16754
+ if (otherSchemas.length === 0) {
16755
+ return [firstSchema, false];
16756
+ }
16757
+ return [
16758
+ ts.factory.createCallExpression(
16759
+ ts.factory.createPropertyAccessExpression(
16760
+ firstSchema,
16761
+ "pipe"
16762
+ ),
16763
+ [],
16764
+ otherSchemas.map((schema) => createApiCall("extend", [schema]))
16765
+ ),
16766
+ false
16767
+ ];
16768
+ }
16769
+ );
16770
+ var processArrayType = fn(
16771
+ "StructuralSchemaGen.processArrayType"
16772
+ )(
16773
+ function* (type, context) {
16774
+ const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
16775
+ const typeArgs = typeChecker.getTypeArguments(type);
16776
+ if (typeArgs.length === 0) {
16777
+ return yield* fail3(new UnsupportedTypeError(type, "Array type has no type arguments"));
16778
+ }
16779
+ const elementSchema = yield* processType(typeArgs[0], context);
16780
+ return [createApiCall("Array", [elementSchema]), false];
16781
+ }
16782
+ );
16783
+ var processTupleType = fn(
16784
+ "StructuralSchemaGen.processTupleType"
16785
+ )(
16786
+ function* (type, context) {
16787
+ const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
16788
+ const typeArgs = typeChecker.getTypeArguments(type);
16789
+ const elementSchemas = yield* all(
16790
+ ...typeArgs.map((t) => processType(t, context))
16791
+ );
16792
+ return [createApiCall("Tuple", elementSchemas), false];
16793
+ }
16794
+ );
16795
+ var processObjectType = fn(
16796
+ "StructuralSchemaGen.processObjectType"
16797
+ )(
16798
+ function* (type, context) {
16799
+ const {
16800
+ createApiCall,
16801
+ createApiPropertyAccess,
16802
+ ts,
16803
+ typeChecker
16804
+ } = yield* service(
16805
+ StructuralSchemaGenContext
16806
+ );
16807
+ let hasRecords = false;
16808
+ const properties = typeChecker.getPropertiesOfType(type);
16809
+ const propertyAssignments = [];
16810
+ for (const property of properties) {
16811
+ const propertyName = typeChecker.symbolToString(property);
16812
+ const propertyType = typeChecker.getTypeOfSymbol(property);
16813
+ const propertySchema = yield* processType(propertyType, context);
16814
+ const isOptional = (property.flags & ts.SymbolFlags.Optional) !== 0;
16815
+ const schemaExpr = isOptional ? createApiCall("optional", [propertySchema]) : propertySchema;
16816
+ const propertyNameNode = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(propertyName) ? ts.factory.createIdentifier(propertyName) : ts.factory.createStringLiteral(propertyName);
16817
+ propertyAssignments.push(
16818
+ ts.factory.createPropertyAssignment(
16819
+ propertyNameNode,
16820
+ schemaExpr
16821
+ )
16822
+ );
16823
+ }
16824
+ const indexInfos = typeChecker.getIndexInfosOfType(type);
16825
+ const args2 = [
16826
+ ts.factory.createObjectLiteralExpression(propertyAssignments, propertyAssignments.length > 0)
16827
+ ];
16828
+ for (const indexInfo of indexInfos) {
16829
+ hasRecords = true;
16830
+ const keyType = indexInfo.keyType;
16831
+ const valueType = indexInfo.type;
16832
+ const keySchema = yield* processType(keyType, context);
16833
+ const valueSchema = yield* processType(valueType, context);
16834
+ args2.push(
16835
+ ts.factory.createObjectLiteralExpression([
16836
+ ts.factory.createPropertyAssignment("key", keySchema),
16837
+ ts.factory.createPropertyAssignment("value", valueSchema)
16838
+ ])
16839
+ );
16840
+ }
16841
+ if (!hasRecords && context.hoistName) {
16842
+ const ctx = yield* service(StructuralSchemaGenContext);
16843
+ yield* pushHoistedStatement(
16844
+ ctx,
16845
+ context.hoistName,
16846
+ type,
16847
+ ts.factory.createClassDeclaration(
16848
+ void 0,
16849
+ ts.factory.createIdentifier(context.hoistName),
16850
+ [],
16851
+ [ts.factory.createHeritageClause(
16852
+ ts.SyntaxKind.ExtendsKeyword,
16853
+ [
16854
+ ts.factory.createExpressionWithTypeArguments(
16855
+ ts.factory.createCallExpression(
16856
+ ts.factory.createCallExpression(
16857
+ createApiPropertyAccess("Class"),
16858
+ [ts.factory.createTypeReferenceNode(
16859
+ context.hoistName
16860
+ )],
16861
+ [ts.factory.createStringLiteral(context.hoistName)]
16862
+ ),
16863
+ [],
16864
+ args2
16865
+ ),
16866
+ []
16867
+ )
16868
+ ]
16869
+ )],
16870
+ []
16871
+ ),
16872
+ () => ts.factory.createIdentifier(context.hoistName)
16873
+ );
16874
+ return [ctx.hoistedSchemas.get(type)(), true];
16875
+ }
16876
+ return [createApiCall("Struct", args2), propertyAssignments.length === 0];
16877
+ }
16878
+ );
16879
+ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
16880
+ function* (sourceFile, textRange) {
16881
+ const ts = yield* service(TypeScriptApi);
16882
+ const tsUtils = yield* service(TypeScriptUtils);
16883
+ const typeChecker = yield* service(TypeCheckerApi);
16884
+ return pipe(
16885
+ tsUtils.getAncestorNodesInRange(sourceFile, textRange),
16886
+ filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
16887
+ filter((node) => tsUtils.isNodeInRange(textRange)(node.name)),
16888
+ filter((node) => (node.typeParameters || []).length === 0),
16889
+ map4((node) => ({
16890
+ node,
16891
+ identifier: node.name,
16892
+ type: typeChecker.getTypeAtLocation(node.name),
16893
+ isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
16894
+ })),
16895
+ filter(({ type }) => !!type),
16896
+ head
16897
+ );
16898
+ }
16899
+ );
16900
+ var process = fn("StructuralSchemaGen.process")(
16901
+ function* (sourceFile, scope, typeMap, isExported) {
16902
+ const ts = yield* service(TypeScriptApi);
16903
+ const tsUtils = yield* service(TypeScriptUtils);
16904
+ const typeChecker = yield* service(TypeCheckerApi);
16905
+ const typeParser = yield* service(TypeParser);
16906
+ const schemaIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Schema") || "Schema";
16907
+ const ctx = yield* makeStructuralSchemaGenContext(sourceFile, schemaIdentifier);
16908
+ for (const [name, type] of typeMap.entries()) {
16909
+ ctx.nameToType.set(name, type);
16910
+ }
16911
+ for (const symbol3 of typeChecker.getSymbolsInScope(scope, ts.SymbolFlags.Value)) {
16912
+ const name = typeChecker.symbolToString(symbol3);
16913
+ ctx.usedGlobalIdentifiers.set(name, 1);
16914
+ const type = typeChecker.getTypeOfSymbol(symbol3);
16915
+ if (type) {
16916
+ const schemaType = yield* pipe(
16917
+ typeParser.effectSchemaType(type, scope),
16918
+ orElse2(() => void_)
16919
+ );
16920
+ if (schemaType) {
16921
+ ctx.hoistedSchemas.set(
16922
+ schemaType.A,
16923
+ () => {
16924
+ const expression = typeChecker.symbolToExpression(
16925
+ symbol3,
16926
+ ts.SymbolFlags.Value,
16927
+ scope,
16928
+ ts.NodeBuilderFlags.NoTruncation
16929
+ );
16930
+ if (expression) {
16931
+ return expression;
16932
+ }
16933
+ return ts.factory.createIdentifier(name);
16934
+ }
16935
+ );
16936
+ }
16937
+ }
16938
+ }
16939
+ const results = yield* pipe(
16940
+ all(
16941
+ ...fromIterable(ctx.nameToType.entries()).map(
16942
+ ([name, type]) => pipe(
16943
+ processType(type),
16944
+ orElse2(
16945
+ (error) => succeed(ts.addSyntheticLeadingComment(
16946
+ ts.factory.createIdentifier(""),
16947
+ ts.SyntaxKind.MultiLineCommentTrivia,
16948
+ " " + String(error) + " ",
16949
+ true
16950
+ ))
16951
+ ),
16952
+ map8((_) => ({ requestedName: name, type, result: _ }))
16953
+ )
16954
+ )
16955
+ ),
16956
+ provideService(StructuralSchemaGenContext, ctx)
16957
+ );
16958
+ for (const { requestedName, result, type } of results) {
16959
+ const statementIndex = ctx.typeToStatementIndex.get(type);
16960
+ if (statementIndex !== void 0) continue;
16961
+ ctx.schemaStatements.push(ts.factory.createVariableStatement(
16962
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
16963
+ ts.factory.createVariableDeclarationList(
16964
+ [ts.factory.createVariableDeclaration(
16965
+ ts.factory.createIdentifier(requestedName),
16966
+ void 0,
16967
+ void 0,
16968
+ result
16969
+ )],
16970
+ ts.NodeFlags.Const
16971
+ )
16972
+ ));
16973
+ ctx.typeToStatementIndex.set(type, ctx.schemaStatements.length - 1);
16974
+ }
16975
+ if (isExported) {
16976
+ const statementsToExport = pipe(
16977
+ fromIterable(ctx.nameToType),
16978
+ map4(([_, type]) => ctx.typeToStatementIndex.get(type)),
16979
+ filter((index) => index !== void 0),
16980
+ dedupe
16981
+ );
16982
+ for (let i = 0; i < ctx.schemaStatements.length; i++) {
16983
+ if (!statementsToExport.includes(i)) continue;
16984
+ const statement = ctx.schemaStatements[i];
16985
+ if (ts.isVariableStatement(statement)) {
16986
+ ctx.schemaStatements[i] = ts.factory.updateVariableStatement(
16987
+ statement,
16988
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export),
16989
+ statement.declarationList
16990
+ );
16991
+ } else if (ts.isClassDeclaration(statement)) {
16992
+ ctx.schemaStatements[i] = ts.factory.updateClassDeclaration(
16993
+ statement,
16994
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export),
16995
+ statement.name,
16996
+ statement.typeParameters,
16997
+ statement.heritageClauses,
16998
+ statement.members
16999
+ );
17000
+ }
17001
+ }
17002
+ }
17003
+ return ctx;
17004
+ }
17005
+ );
17006
+ var applyAtNode = fn("StructuralSchemaGen.applyAtNode")(
17007
+ function* (sourceFile, node, identifier, type, isExported) {
17008
+ const changeTracker = yield* service(ChangeTracker);
17009
+ const ts = yield* service(TypeScriptApi);
17010
+ const ctx = yield* process(sourceFile, node, /* @__PURE__ */ new Map([[ts.idText(identifier), type]]), isExported);
17011
+ for (const statement of ctx.schemaStatements) {
17012
+ changeTracker.insertNodeAt(sourceFile, node.pos, statement, { prefix: "\n", suffix: "\n" });
17013
+ }
17014
+ }
17015
+ );
17016
+
17017
+ // src/refactors/structuralTypeToSchema.ts
17018
+ var structuralTypeToSchema = createRefactor({
17019
+ name: "structuralTypeToSchema",
17020
+ description: "Refactor to Schema (Structural)",
17021
+ apply: fn("structuralTypeToSchema.apply")(function* (sourceFile, textRange) {
17022
+ const ts = yield* service(TypeScriptApi);
17023
+ const tsUtils = yield* service(TypeScriptUtils);
17024
+ const typeChecker = yield* service(TypeCheckerApi);
17025
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
17026
+ const typeParser = yield* service(TypeParser);
17027
+ const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17028
+ if (isNone2(maybeNode)) {
17029
+ return yield* fail3(new RefactorNotApplicableError());
17030
+ }
17031
+ const { identifier, isExported, node, type } = maybeNode.value;
17032
+ return {
17033
+ kind: "refactor.rewrite.effect.structuralTypeToSchema",
17034
+ description: "Refactor to Schema (Recursive Structural)",
17035
+ apply: pipe(
17036
+ applyAtNode(sourceFile, node, identifier, type, isExported),
17037
+ provideService(TypeCheckerApi, typeChecker),
17038
+ provideService(TypeScriptUtils, tsUtils),
17039
+ provideService(TypeScriptApi, ts),
17040
+ provideService(TypeCheckerUtils, typeCheckerUtils),
17041
+ provideService(TypeParser, typeParser)
17042
+ )
17043
+ };
17044
+ })
17045
+ });
17046
+
16513
17047
  // src/refactors/toggleLazyConst.ts
16514
17048
  var toggleLazyConst = createRefactor({
16515
17049
  name: "toggleLazyConst",
@@ -17161,7 +17695,7 @@ var createExportSchemaClassDeclaration = fn("SchemaGen.createExportSchemaClassDe
17161
17695
  );
17162
17696
  }
17163
17697
  );
17164
- var process = fn("SchemaGen.process")(
17698
+ var process2 = fn("SchemaGen.process")(
17165
17699
  function* (sourceFile, node, preferClass) {
17166
17700
  const ctx = yield* makeSchemaGenContext(sourceFile);
17167
17701
  const ts = yield* service(TypeScriptApi);
@@ -17171,7 +17705,7 @@ var process = fn("SchemaGen.process")(
17171
17705
  );
17172
17706
  }
17173
17707
  );
17174
- var findNodeToProcess = fn("SchemaGen.findNodeToProcess")(
17708
+ var findNodeToProcess2 = fn("SchemaGen.findNodeToProcess")(
17175
17709
  function* (sourceFile, textRange) {
17176
17710
  const ts = yield* service(TypeScriptApi);
17177
17711
  const tsUtils = yield* service(TypeScriptUtils);
@@ -17184,12 +17718,12 @@ var findNodeToProcess = fn("SchemaGen.findNodeToProcess")(
17184
17718
  );
17185
17719
  }
17186
17720
  );
17187
- var applyAtNode = fn("SchemaGen.applyAtNode")(
17721
+ var applyAtNode2 = fn("SchemaGen.applyAtNode")(
17188
17722
  function* (sourceFile, node, preferClass) {
17189
17723
  const ts = yield* service(TypeScriptApi);
17190
17724
  const changeTracker = yield* service(ChangeTracker);
17191
17725
  const newNode = yield* pipe(
17192
- process(sourceFile, node, preferClass),
17726
+ process2(sourceFile, node, preferClass),
17193
17727
  orElse2(
17194
17728
  (error) => succeed(ts.addSyntheticLeadingComment(
17195
17729
  ts.factory.createIdentifier(""),
@@ -17214,14 +17748,14 @@ var typeToEffectSchema = createRefactor({
17214
17748
  const tsUtils = yield* service(TypeScriptUtils);
17215
17749
  const typeChecker = yield* service(TypeCheckerApi);
17216
17750
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
17217
- const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17751
+ const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
17218
17752
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
17219
17753
  const node = maybeNode.value;
17220
17754
  return {
17221
17755
  kind: "refactor.rewrite.effect.typeToEffectSchema",
17222
17756
  description: "Refactor to Schema",
17223
17757
  apply: pipe(
17224
- applyAtNode(sourceFile, node, false),
17758
+ applyAtNode2(sourceFile, node, false),
17225
17759
  provideService(TypeCheckerApi, typeChecker),
17226
17760
  provideService(TypeScriptUtils, tsUtils),
17227
17761
  provideService(TypeScriptApi, ts),
@@ -17240,14 +17774,14 @@ var typeToEffectSchemaClass = createRefactor({
17240
17774
  const tsUtils = yield* service(TypeScriptUtils);
17241
17775
  const typeChecker = yield* service(TypeCheckerApi);
17242
17776
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
17243
- const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17777
+ const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
17244
17778
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
17245
17779
  const node = maybeNode.value;
17246
17780
  return {
17247
17781
  kind: "refactor.rewrite.effect.typeToEffectSchemaClass",
17248
17782
  description: "Refactor to Schema.Class",
17249
17783
  apply: pipe(
17250
- applyAtNode(sourceFile, node, true),
17784
+ applyAtNode2(sourceFile, node, true),
17251
17785
  provideService(TypeCheckerApi, typeChecker),
17252
17786
  provideService(TypeScriptUtils, tsUtils),
17253
17787
  provideService(TypeScriptApi, ts),
@@ -17338,6 +17872,7 @@ var refactors = [
17338
17872
  functionToArrow,
17339
17873
  typeToEffectSchema,
17340
17874
  typeToEffectSchemaClass,
17875
+ structuralTypeToSchema,
17341
17876
  makeSchemaOpaque,
17342
17877
  makeSchemaOpaqueWithNs,
17343
17878
  pipeableToDatafirst,