@effect/language-service 0.59.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
@@ -3526,7 +3526,8 @@ var defaults = {
3526
3526
  }],
3527
3527
  extendedKeyDetection: false,
3528
3528
  pipeableMinArgCount: 1,
3529
- layerGraphFollowDepth: 0
3529
+ layerGraphFollowDepth: 0,
3530
+ mermaidProvider: "mermaid.live"
3530
3531
  };
3531
3532
  function parseKeyPatterns(patterns) {
3532
3533
  const result = [];
@@ -3564,7 +3565,8 @@ function parse(config) {
3564
3565
  keyPatterns: isObject(config) && hasProperty(config, "keyPatterns") && isArray(config.keyPatterns) ? parseKeyPatterns(config.keyPatterns) : defaults.keyPatterns,
3565
3566
  extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection,
3566
3567
  pipeableMinArgCount: isObject(config) && hasProperty(config, "pipeableMinArgCount") && isNumber(config.pipeableMinArgCount) ? config.pipeableMinArgCount : defaults.pipeableMinArgCount,
3567
- layerGraphFollowDepth: isObject(config) && hasProperty(config, "layerGraphFollowDepth") && isNumber(config.layerGraphFollowDepth) ? config.layerGraphFollowDepth : defaults.layerGraphFollowDepth
3568
+ layerGraphFollowDepth: isObject(config) && hasProperty(config, "layerGraphFollowDepth") && isNumber(config.layerGraphFollowDepth) ? config.layerGraphFollowDepth : defaults.layerGraphFollowDepth,
3569
+ mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider
3568
3570
  };
3569
3571
  }
3570
3572
 
@@ -4476,7 +4478,11 @@ var getEditsForCodegen = fn("LSP.getEditsForCodegen")(function* (codegens2, sour
4476
4478
  service(ChangeTracker),
4477
4479
  map8((changeTracker) => {
4478
4480
  changeTracker.deleteRange(sourceFile, range);
4479
- 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
+ );
4480
4486
  })
4481
4487
  );
4482
4488
  return {
@@ -15311,13 +15317,19 @@ var formatLayerProvidersAndRequirersInfo = fn("formatLayerProvidersAndRequirersI
15311
15317
  );
15312
15318
 
15313
15319
  // src/quickinfo/layerInfo.ts
15314
- function generateMarmaidUri(code) {
15320
+ function generateMarmaidUri(code, mermaidProvider) {
15315
15321
  return gen(function* () {
15316
15322
  const state = JSON.stringify({ code });
15317
15323
  const data = new TextEncoder().encode(state);
15318
15324
  const compressed = deflate_1(data, { level: 9 });
15319
15325
  const pakoString = "pako:" + encodeBase64Url(compressed);
15320
- return "https://www.mermaidchart.com/play#" + pakoString;
15326
+ if (mermaidProvider === "mermaid.com") {
15327
+ return "https://www.mermaidchart.com/play#" + pakoString;
15328
+ } else if (mermaidProvider === "mermaid.live") {
15329
+ return "https://mermaid.live/edit#" + pakoString;
15330
+ } else {
15331
+ return mermaidProvider + "/edit#" + pakoString;
15332
+ }
15321
15333
  });
15322
15334
  }
15323
15335
  function getAdjustedNode(sourceFile, position) {
@@ -15388,8 +15400,8 @@ function layerInfo(sourceFile, position, quickInfo2) {
15388
15400
  ({ nestedGraphMermaid, outlineGraphMermaid, providersAndRequirersTextualExplanation }) => gen(function* () {
15389
15401
  const linkParts = [];
15390
15402
  if (!options.noExternal) {
15391
- const mermaidUri = yield* generateMarmaidUri(nestedGraphMermaid);
15392
- const outlineMermaidUri = yield* generateMarmaidUri(outlineGraphMermaid);
15403
+ const mermaidUri = yield* generateMarmaidUri(nestedGraphMermaid, options.mermaidProvider);
15404
+ const outlineMermaidUri = yield* generateMarmaidUri(outlineGraphMermaid, options.mermaidProvider);
15393
15405
  linkParts.push({ kind: "space", text: "\n" });
15394
15406
  linkParts.push({ kind: "link", text: "{@link " });
15395
15407
  linkParts.push({ kind: "linkText", text: mermaidUri + " Show full Layer graph" });
@@ -16502,6 +16514,536 @@ var removeUnnecessaryEffectGen = createRefactor({
16502
16514
  })
16503
16515
  });
16504
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
+
16505
17047
  // src/refactors/toggleLazyConst.ts
16506
17048
  var toggleLazyConst = createRefactor({
16507
17049
  name: "toggleLazyConst",
@@ -17153,7 +17695,7 @@ var createExportSchemaClassDeclaration = fn("SchemaGen.createExportSchemaClassDe
17153
17695
  );
17154
17696
  }
17155
17697
  );
17156
- var process = fn("SchemaGen.process")(
17698
+ var process2 = fn("SchemaGen.process")(
17157
17699
  function* (sourceFile, node, preferClass) {
17158
17700
  const ctx = yield* makeSchemaGenContext(sourceFile);
17159
17701
  const ts = yield* service(TypeScriptApi);
@@ -17163,7 +17705,7 @@ var process = fn("SchemaGen.process")(
17163
17705
  );
17164
17706
  }
17165
17707
  );
17166
- var findNodeToProcess = fn("SchemaGen.findNodeToProcess")(
17708
+ var findNodeToProcess2 = fn("SchemaGen.findNodeToProcess")(
17167
17709
  function* (sourceFile, textRange) {
17168
17710
  const ts = yield* service(TypeScriptApi);
17169
17711
  const tsUtils = yield* service(TypeScriptUtils);
@@ -17176,12 +17718,12 @@ var findNodeToProcess = fn("SchemaGen.findNodeToProcess")(
17176
17718
  );
17177
17719
  }
17178
17720
  );
17179
- var applyAtNode = fn("SchemaGen.applyAtNode")(
17721
+ var applyAtNode2 = fn("SchemaGen.applyAtNode")(
17180
17722
  function* (sourceFile, node, preferClass) {
17181
17723
  const ts = yield* service(TypeScriptApi);
17182
17724
  const changeTracker = yield* service(ChangeTracker);
17183
17725
  const newNode = yield* pipe(
17184
- process(sourceFile, node, preferClass),
17726
+ process2(sourceFile, node, preferClass),
17185
17727
  orElse2(
17186
17728
  (error) => succeed(ts.addSyntheticLeadingComment(
17187
17729
  ts.factory.createIdentifier(""),
@@ -17206,14 +17748,14 @@ var typeToEffectSchema = createRefactor({
17206
17748
  const tsUtils = yield* service(TypeScriptUtils);
17207
17749
  const typeChecker = yield* service(TypeCheckerApi);
17208
17750
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
17209
- const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17751
+ const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
17210
17752
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
17211
17753
  const node = maybeNode.value;
17212
17754
  return {
17213
17755
  kind: "refactor.rewrite.effect.typeToEffectSchema",
17214
17756
  description: "Refactor to Schema",
17215
17757
  apply: pipe(
17216
- applyAtNode(sourceFile, node, false),
17758
+ applyAtNode2(sourceFile, node, false),
17217
17759
  provideService(TypeCheckerApi, typeChecker),
17218
17760
  provideService(TypeScriptUtils, tsUtils),
17219
17761
  provideService(TypeScriptApi, ts),
@@ -17232,14 +17774,14 @@ var typeToEffectSchemaClass = createRefactor({
17232
17774
  const tsUtils = yield* service(TypeScriptUtils);
17233
17775
  const typeChecker = yield* service(TypeCheckerApi);
17234
17776
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
17235
- const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17777
+ const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
17236
17778
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
17237
17779
  const node = maybeNode.value;
17238
17780
  return {
17239
17781
  kind: "refactor.rewrite.effect.typeToEffectSchemaClass",
17240
17782
  description: "Refactor to Schema.Class",
17241
17783
  apply: pipe(
17242
- applyAtNode(sourceFile, node, true),
17784
+ applyAtNode2(sourceFile, node, true),
17243
17785
  provideService(TypeCheckerApi, typeChecker),
17244
17786
  provideService(TypeScriptUtils, tsUtils),
17245
17787
  provideService(TypeScriptApi, ts),
@@ -17330,6 +17872,7 @@ var refactors = [
17330
17872
  functionToArrow,
17331
17873
  typeToEffectSchema,
17332
17874
  typeToEffectSchemaClass,
17875
+ structuralTypeToSchema,
17333
17876
  makeSchemaOpaque,
17334
17877
  makeSchemaOpaqueWithNs,
17335
17878
  pipeableToDatafirst,