@effect/language-service 0.60.0 → 0.62.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
@@ -869,6 +869,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
869
869
  return [];
870
870
  });
871
871
  var dedupe = (self) => dedupeWith(self, equivalence());
872
+ var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
872
873
 
873
874
  // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Chunk.js
874
875
  var TypeId3 = /* @__PURE__ */ Symbol.for("effect/Chunk");
@@ -4478,7 +4479,11 @@ var getEditsForCodegen = fn("LSP.getEditsForCodegen")(function* (codegens2, sour
4478
4479
  service(ChangeTracker),
4479
4480
  map8((changeTracker) => {
4480
4481
  changeTracker.deleteRange(sourceFile, range);
4481
- changeTracker.insertText(sourceFile, range.pos, `${codegen.name}:${edit.hash}`);
4482
+ changeTracker.insertText(
4483
+ sourceFile,
4484
+ range.pos,
4485
+ edit.hash.length > 0 ? `${codegen.name}:${edit.hash}` : codegen.name
4486
+ );
4482
4487
  })
4483
4488
  );
4484
4489
  return {
@@ -4590,6 +4595,9 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
4590
4595
  function isThisTypeParameter(type) {
4591
4596
  return !!(type.flags & ts.TypeFlags.TypeParameter && type.isThisType);
4592
4597
  }
4598
+ function isMissingIntrinsicType(type) {
4599
+ return (type.flags & ts.TypeFlags.Undefined) !== 0 && "debugIntrinsicName" in type && type.debugIntrinsicName === "missing";
4600
+ }
4593
4601
  function getTypeParameterAtPosition(signature, pos) {
4594
4602
  const type = typeChecker.getParameterType(signature, pos);
4595
4603
  if (isIndexType(type) && isThisTypeParameter(type.type)) {
@@ -4894,6 +4902,7 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
4894
4902
  }
4895
4903
  return {
4896
4904
  isUnion,
4905
+ isMissingIntrinsicType,
4897
4906
  getTypeParameterAtPosition,
4898
4907
  getMissingTypeEntriesInTargetType,
4899
4908
  unrollUnionMembers,
@@ -6531,8 +6540,662 @@ var annotate = createCodegen({
6531
6540
  })
6532
6541
  });
6533
6542
 
6543
+ // src/utils/StructuralSchemaGen.ts
6544
+ var UnsupportedTypeError = class {
6545
+ constructor(type, reason) {
6546
+ this.type = type;
6547
+ this.reason = reason;
6548
+ }
6549
+ _tag = "@effect/language-service/UnsupportedTypeError";
6550
+ toString() {
6551
+ return `Unsupported type: ${this.reason}`;
6552
+ }
6553
+ };
6554
+ var StructuralSchemaGenContext = Tag("StructuralSchemaGenContext");
6555
+ var makeStructuralSchemaGenContext = fn("StructuralSchemaGen.makeContext")(
6556
+ function* (sourceFile, schemaIdentifier) {
6557
+ const ts = yield* service(TypeScriptApi);
6558
+ const program = yield* service(TypeScriptProgram);
6559
+ const typeChecker = yield* service(TypeCheckerApi);
6560
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6561
+ const effectSchemaIdentifier = schemaIdentifier || "Schema";
6562
+ return identity({
6563
+ ts,
6564
+ program,
6565
+ typeChecker,
6566
+ typeCheckerUtils,
6567
+ sourceFile,
6568
+ createApiPropertyAccess: (apiName) => ts.factory.createPropertyAccessExpression(
6569
+ ts.factory.createIdentifier(effectSchemaIdentifier),
6570
+ apiName
6571
+ ),
6572
+ createApiCall: (apiName, args2) => ts.factory.createCallExpression(
6573
+ ts.factory.createPropertyAccessExpression(
6574
+ ts.factory.createIdentifier(effectSchemaIdentifier),
6575
+ apiName
6576
+ ),
6577
+ [],
6578
+ args2
6579
+ ),
6580
+ hoistedSchemas: /* @__PURE__ */ new Map(),
6581
+ typeToStatementIndex: /* @__PURE__ */ new Map(),
6582
+ nameToType: /* @__PURE__ */ new Map(),
6583
+ usedGlobalIdentifiers: /* @__PURE__ */ new Map(),
6584
+ schemaStatements: [],
6585
+ rangesToDelete: []
6586
+ });
6587
+ }
6588
+ );
6589
+ var pushHoistedStatement = fn("StructuralSchemaGen.pushHoistedStatement")(
6590
+ function* (ctx, name, type, statement, createReference) {
6591
+ ctx.usedGlobalIdentifiers.set(name, (ctx.usedGlobalIdentifiers.get(name) || 0) + 1);
6592
+ ctx.schemaStatements.push(statement);
6593
+ ctx.typeToStatementIndex.set(type, ctx.schemaStatements.length - 1);
6594
+ ctx.hoistedSchemas.set(type, createReference);
6595
+ }
6596
+ );
6597
+ var pushHoistedVariableStatement = fn("StructuralSchemaGen.pushHoistedVariableStatement")(
6598
+ function* (ts, ctx, name, type, result) {
6599
+ return yield* pushHoistedStatement(
6600
+ ctx,
6601
+ name,
6602
+ type,
6603
+ ts.factory.createVariableStatement(
6604
+ void 0,
6605
+ ts.factory.createVariableDeclarationList(
6606
+ [ts.factory.createVariableDeclaration(ts.factory.createIdentifier(name), void 0, void 0, result)],
6607
+ ts.NodeFlags.Const
6608
+ )
6609
+ ),
6610
+ () => ts.factory.createIdentifier(name)
6611
+ );
6612
+ }
6613
+ );
6614
+ var createProcessingContext = (maxDepth = 200) => ({
6615
+ depth: 0,
6616
+ maxDepth,
6617
+ hoistName: void 0
6618
+ });
6619
+ var processType = fn(
6620
+ "StructuralSchemaGen.processType"
6621
+ )(
6622
+ function* (type, context) {
6623
+ const processingContext = context || createProcessingContext();
6624
+ const { hoistedSchemas, nameToType, ts, typeChecker, usedGlobalIdentifiers } = yield* service(
6625
+ StructuralSchemaGenContext
6626
+ );
6627
+ if (processingContext.depth >= processingContext.maxDepth) {
6628
+ return yield* fail3(new UnsupportedTypeError(type, "Maximum depth exceeded"));
6629
+ }
6630
+ let hoistName = fromIterable(nameToType.entries()).find(([_, existingType]) => existingType === type)?.[0];
6631
+ if (!hoistName && type && type.symbol && type.symbol.declarations && type.symbol.declarations.length === 1) {
6632
+ const declaration = type.symbol.declarations[0];
6633
+ if (ts.isInterfaceDeclaration(declaration)) {
6634
+ hoistName = ts.idText(declaration.name);
6635
+ } else if (declaration.parent && ts.isTypeAliasDeclaration(declaration.parent)) {
6636
+ hoistName = ts.idText(declaration.parent.name);
6637
+ }
6638
+ if (hoistName) {
6639
+ const existingType = nameToType.get(hoistName);
6640
+ const isSame = existingType && typeChecker.isTypeAssignableTo(type, existingType) && typeChecker.isTypeAssignableTo(existingType, type);
6641
+ if (!isSame) {
6642
+ const usedCount = usedGlobalIdentifiers.get(hoistName) || 0;
6643
+ hoistName = usedCount > 0 ? hoistName + "_" + usedCount : hoistName;
6644
+ }
6645
+ }
6646
+ }
6647
+ const nestedContext = {
6648
+ ...processingContext,
6649
+ depth: processingContext.depth + 1,
6650
+ hoistName
6651
+ };
6652
+ for (const [hoistedType, hoistedSchema] of hoistedSchemas.entries()) {
6653
+ if (hoistedType === type || typeChecker.isTypeAssignableTo(type, hoistedType) && typeChecker.isTypeAssignableTo(hoistedType, type)) {
6654
+ return hoistedSchema();
6655
+ }
6656
+ }
6657
+ const [schemaExpr, skipHoisting] = yield* processTypeImpl(type, nestedContext);
6658
+ if (!skipHoisting && hoistName) {
6659
+ const ctx = yield* service(StructuralSchemaGenContext);
6660
+ yield* pushHoistedVariableStatement(ts, ctx, hoistName, type, schemaExpr);
6661
+ return ctx.hoistedSchemas.get(type)();
6662
+ }
6663
+ return schemaExpr;
6664
+ }
6665
+ );
6666
+ var processTypeImpl = fn(
6667
+ "StructuralSchemaGen.processTypeImpl"
6668
+ )(
6669
+ function* (type, context) {
6670
+ const { createApiCall, createApiPropertyAccess, ts, typeChecker, typeCheckerUtils } = yield* service(
6671
+ StructuralSchemaGenContext
6672
+ );
6673
+ if (type.flags & ts.TypeFlags.String) {
6674
+ return [createApiPropertyAccess("String"), true];
6675
+ }
6676
+ if (type.flags & ts.TypeFlags.Number) {
6677
+ return [createApiPropertyAccess("Number"), true];
6678
+ }
6679
+ if (type.flags & ts.TypeFlags.Boolean) {
6680
+ return [createApiPropertyAccess("Boolean"), true];
6681
+ }
6682
+ if (type.flags & ts.TypeFlags.BigInt) {
6683
+ return [createApiPropertyAccess("BigInt"), true];
6684
+ }
6685
+ if (type.flags & ts.TypeFlags.Void) {
6686
+ return [createApiPropertyAccess("Void"), true];
6687
+ }
6688
+ if (type.flags & ts.TypeFlags.Undefined) {
6689
+ return [createApiPropertyAccess("Undefined"), true];
6690
+ }
6691
+ if (type.flags & ts.TypeFlags.Null) {
6692
+ return [createApiPropertyAccess("Null"), true];
6693
+ }
6694
+ if (type.flags & ts.TypeFlags.Never) {
6695
+ return [createApiPropertyAccess("Never"), true];
6696
+ }
6697
+ if (type.flags & ts.TypeFlags.Any) {
6698
+ return [createApiPropertyAccess("Any"), true];
6699
+ }
6700
+ if (type.flags & ts.TypeFlags.Unknown) {
6701
+ return [createApiPropertyAccess("Unknown"), true];
6702
+ }
6703
+ if (type.flags & ts.TypeFlags.StringLiteral) {
6704
+ const literalType = type;
6705
+ return [createApiCall("Literal", [ts.factory.createStringLiteral(literalType.value)]), true];
6706
+ }
6707
+ if (type.flags & ts.TypeFlags.NumberLiteral) {
6708
+ const literalType = type;
6709
+ return [createApiCall("Literal", [ts.factory.createNumericLiteral(literalType.value)]), true];
6710
+ }
6711
+ if (type.flags & ts.TypeFlags.BooleanLiteral) {
6712
+ const value = type.intrinsicName === "true";
6713
+ return [createApiCall("Literal", [value ? ts.factory.createTrue() : ts.factory.createFalse()]), true];
6714
+ }
6715
+ if (typeCheckerUtils.isUnion(type)) {
6716
+ return yield* processUnionType(type.types, context);
6717
+ }
6718
+ if (type.flags & ts.TypeFlags.Intersection) {
6719
+ return yield* processIntersectionType(type, context);
6720
+ }
6721
+ if (typeChecker.isArrayType(type)) {
6722
+ return yield* processArrayType(type, context);
6723
+ }
6724
+ if (typeChecker.isTupleType(type)) {
6725
+ return yield* processTupleType(type, context);
6726
+ }
6727
+ if (type.flags & ts.TypeFlags.Object) {
6728
+ const symbol3 = type.symbol || type.aliasSymbol;
6729
+ if (symbol3) {
6730
+ const typeName = typeChecker.symbolToString(symbol3);
6731
+ if (typeName === "Date") {
6732
+ return [createApiPropertyAccess("Date"), false];
6733
+ }
6734
+ if (typeName === "ReadonlyArray" || typeName === "Array") {
6735
+ return yield* processArrayType(type, context);
6736
+ }
6737
+ }
6738
+ const objectType = type;
6739
+ return yield* processObjectType(objectType, context);
6740
+ }
6741
+ return yield* fail3(
6742
+ new UnsupportedTypeError(
6743
+ type,
6744
+ `Type with flags ${type.flags} is not supported`
6745
+ )
6746
+ );
6747
+ }
6748
+ );
6749
+ var processUnionType = fn(
6750
+ "StructuralSchemaGen.processUnionType"
6751
+ )(
6752
+ function* (types, context) {
6753
+ const { createApiCall, ts } = yield* service(StructuralSchemaGenContext);
6754
+ const allLiterals = types.every(
6755
+ (t) => t.flags & ts.TypeFlags.StringLiteral || t.flags & ts.TypeFlags.NumberLiteral || t.flags & ts.TypeFlags.BooleanLiteral
6756
+ );
6757
+ if (allLiterals) {
6758
+ const literals = yield* all(
6759
+ ...types.map((t) => processType(t, context))
6760
+ );
6761
+ const literalValues = literals.map((expr) => {
6762
+ if (ts.isCallExpression(expr) && expr.arguments.length > 0) {
6763
+ return expr.arguments[0];
6764
+ }
6765
+ return expr;
6766
+ }).filter((arg) => arg !== void 0);
6767
+ return [createApiCall("Literal", literalValues), false];
6768
+ }
6769
+ const members = yield* all(
6770
+ ...types.map((t) => processType(t, context))
6771
+ );
6772
+ if (members.length === 1) {
6773
+ return [members[0], false];
6774
+ }
6775
+ return [createApiCall("Union", members), false];
6776
+ }
6777
+ );
6778
+ var processIntersectionType = fn(
6779
+ "StructuralSchemaGen.processIntersectionType"
6780
+ )(
6781
+ function* (type, context) {
6782
+ const { createApiCall, ts } = yield* service(StructuralSchemaGenContext);
6783
+ const [firstSchema, ...otherSchemas] = yield* all(
6784
+ ...type.types.map((t) => processType(t, context))
6785
+ );
6786
+ if (otherSchemas.length === 0) {
6787
+ return [firstSchema, false];
6788
+ }
6789
+ return [
6790
+ ts.factory.createCallExpression(
6791
+ ts.factory.createPropertyAccessExpression(
6792
+ firstSchema,
6793
+ "pipe"
6794
+ ),
6795
+ [],
6796
+ otherSchemas.map((schema) => createApiCall("extend", [schema]))
6797
+ ),
6798
+ false
6799
+ ];
6800
+ }
6801
+ );
6802
+ var processArrayType = fn(
6803
+ "StructuralSchemaGen.processArrayType"
6804
+ )(
6805
+ function* (type, context) {
6806
+ const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
6807
+ const typeArgs = typeChecker.getTypeArguments(type);
6808
+ if (typeArgs.length === 0) {
6809
+ return yield* fail3(new UnsupportedTypeError(type, "Array type has no type arguments"));
6810
+ }
6811
+ const elementSchema = yield* processType(typeArgs[0], context);
6812
+ return [createApiCall("Array", [elementSchema]), false];
6813
+ }
6814
+ );
6815
+ var processTupleType = fn(
6816
+ "StructuralSchemaGen.processTupleType"
6817
+ )(
6818
+ function* (type, context) {
6819
+ const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
6820
+ const typeArgs = typeChecker.getTypeArguments(type);
6821
+ const elementSchemas = yield* all(
6822
+ ...typeArgs.map((t) => processType(t, context))
6823
+ );
6824
+ return [createApiCall("Tuple", elementSchemas), false];
6825
+ }
6826
+ );
6827
+ var processObjectType = fn(
6828
+ "StructuralSchemaGen.processObjectType"
6829
+ )(
6830
+ function* (type, context) {
6831
+ const {
6832
+ createApiCall,
6833
+ createApiPropertyAccess,
6834
+ program,
6835
+ ts,
6836
+ typeChecker,
6837
+ typeCheckerUtils
6838
+ } = yield* service(
6839
+ StructuralSchemaGenContext
6840
+ );
6841
+ let hasRecords = false;
6842
+ const properties = typeChecker.getPropertiesOfType(type);
6843
+ const propertyAssignments = [];
6844
+ for (const property of properties) {
6845
+ const propertyName = typeChecker.symbolToString(property);
6846
+ const propertyType = typeChecker.getTypeOfSymbol(property);
6847
+ const isOptional = (property.flags & ts.SymbolFlags.Optional) !== 0;
6848
+ let schemaExpr;
6849
+ if (isOptional) {
6850
+ if (program.getCompilerOptions().exactOptionalPropertyTypes) {
6851
+ if (typeCheckerUtils.isUnion(propertyType)) {
6852
+ const typeWithoutMissing = propertyType.types.filter((t) => !typeCheckerUtils.isMissingIntrinsicType(t));
6853
+ const [result, _] = yield* processUnionType(typeWithoutMissing, context);
6854
+ schemaExpr = createApiCall("optionalWith", [
6855
+ result,
6856
+ ts.factory.createObjectLiteralExpression([
6857
+ ts.factory.createPropertyAssignment("exact", ts.factory.createTrue())
6858
+ ])
6859
+ ]);
6860
+ }
6861
+ } else {
6862
+ schemaExpr = yield* processType(propertyType, context);
6863
+ schemaExpr = createApiCall("optional", [schemaExpr]);
6864
+ }
6865
+ }
6866
+ if (!schemaExpr) {
6867
+ schemaExpr = yield* processType(propertyType, context);
6868
+ }
6869
+ const propertyNameNode = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(propertyName) ? ts.factory.createIdentifier(propertyName) : ts.factory.createStringLiteral(propertyName);
6870
+ propertyAssignments.push(
6871
+ ts.factory.createPropertyAssignment(
6872
+ propertyNameNode,
6873
+ schemaExpr
6874
+ )
6875
+ );
6876
+ }
6877
+ const indexInfos = typeChecker.getIndexInfosOfType(type);
6878
+ const args2 = [
6879
+ ts.factory.createObjectLiteralExpression(propertyAssignments, propertyAssignments.length > 0)
6880
+ ];
6881
+ for (const indexInfo of indexInfos) {
6882
+ hasRecords = true;
6883
+ const keyType = indexInfo.keyType;
6884
+ const valueType = indexInfo.type;
6885
+ const keySchema = yield* processType(keyType, context);
6886
+ const valueSchema = yield* processType(valueType, context);
6887
+ args2.push(
6888
+ ts.factory.createObjectLiteralExpression([
6889
+ ts.factory.createPropertyAssignment("key", keySchema),
6890
+ ts.factory.createPropertyAssignment("value", valueSchema)
6891
+ ])
6892
+ );
6893
+ }
6894
+ if (!hasRecords && context.hoistName) {
6895
+ const ctx = yield* service(StructuralSchemaGenContext);
6896
+ yield* pushHoistedStatement(
6897
+ ctx,
6898
+ context.hoistName,
6899
+ type,
6900
+ ts.factory.createClassDeclaration(
6901
+ void 0,
6902
+ ts.factory.createIdentifier(context.hoistName),
6903
+ [],
6904
+ [ts.factory.createHeritageClause(
6905
+ ts.SyntaxKind.ExtendsKeyword,
6906
+ [
6907
+ ts.factory.createExpressionWithTypeArguments(
6908
+ ts.factory.createCallExpression(
6909
+ ts.factory.createCallExpression(
6910
+ createApiPropertyAccess("Class"),
6911
+ [ts.factory.createTypeReferenceNode(
6912
+ context.hoistName
6913
+ )],
6914
+ [ts.factory.createStringLiteral(context.hoistName)]
6915
+ ),
6916
+ [],
6917
+ args2
6918
+ ),
6919
+ []
6920
+ )
6921
+ ]
6922
+ )],
6923
+ []
6924
+ ),
6925
+ () => ts.factory.createIdentifier(context.hoistName)
6926
+ );
6927
+ return [ctx.hoistedSchemas.get(type)(), true];
6928
+ }
6929
+ return [createApiCall("Struct", args2), propertyAssignments.length === 0];
6930
+ }
6931
+ );
6932
+ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6933
+ function* (sourceFile, textRange) {
6934
+ const ts = yield* service(TypeScriptApi);
6935
+ const tsUtils = yield* service(TypeScriptUtils);
6936
+ const typeChecker = yield* service(TypeCheckerApi);
6937
+ return pipe(
6938
+ tsUtils.getAncestorNodesInRange(sourceFile, textRange),
6939
+ filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
6940
+ filter((node) => tsUtils.isNodeInRange(textRange)(node.name)),
6941
+ filter((node) => (node.typeParameters || []).length === 0),
6942
+ map4((node) => ({
6943
+ node,
6944
+ identifier: node.name,
6945
+ type: typeChecker.getTypeAtLocation(node.name),
6946
+ isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
6947
+ })),
6948
+ filter(({ type }) => !!type),
6949
+ head
6950
+ );
6951
+ }
6952
+ );
6953
+ var process = fn("StructuralSchemaGen.process")(
6954
+ function* (sourceFile, scope, typeMap, isExported, handleCodegeneratedComments) {
6955
+ const ts = yield* service(TypeScriptApi);
6956
+ const tsUtils = yield* service(TypeScriptUtils);
6957
+ const typeChecker = yield* service(TypeCheckerApi);
6958
+ const typeParser = yield* service(TypeParser);
6959
+ const schemaIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Schema") || "Schema";
6960
+ const ctx = yield* makeStructuralSchemaGenContext(sourceFile, schemaIdentifier);
6961
+ for (const [name, type] of typeMap.entries()) {
6962
+ ctx.nameToType.set(name, type);
6963
+ }
6964
+ if (handleCodegeneratedComments) {
6965
+ for (const declaration of sourceFile.statements) {
6966
+ const nodeText = sourceFile.text.slice(declaration.pos, declaration.end);
6967
+ if (!nodeText.toLowerCase().includes("@effect-schema-codegenerated")) continue;
6968
+ const interleavingRange = ctx.rangesToDelete.find(
6969
+ (range) => range.pos < declaration.end && range.end > declaration.pos
6970
+ );
6971
+ if (interleavingRange) {
6972
+ interleavingRange.pos = Math.min(interleavingRange.pos, declaration.pos);
6973
+ interleavingRange.end = Math.max(interleavingRange.end, declaration.end);
6974
+ } else {
6975
+ ctx.rangesToDelete.push({
6976
+ pos: declaration.pos,
6977
+ end: declaration.end
6978
+ });
6979
+ }
6980
+ }
6981
+ }
6982
+ for (const symbol3 of typeChecker.getSymbolsInScope(scope, ts.SymbolFlags.Value)) {
6983
+ const name = typeChecker.symbolToString(symbol3);
6984
+ ctx.usedGlobalIdentifiers.set(name, 1);
6985
+ const type = typeChecker.getTypeOfSymbolAtLocation(symbol3, sourceFile);
6986
+ if (type) {
6987
+ const schemaType = yield* pipe(
6988
+ typeParser.effectSchemaType(type, scope),
6989
+ orElse2(() => void_)
6990
+ );
6991
+ if (schemaType) {
6992
+ ctx.hoistedSchemas.set(
6993
+ schemaType.A,
6994
+ () => {
6995
+ const expression = typeChecker.symbolToExpression(
6996
+ symbol3,
6997
+ ts.SymbolFlags.Value,
6998
+ scope,
6999
+ ts.NodeBuilderFlags.NoTruncation
7000
+ );
7001
+ if (expression) {
7002
+ return expression;
7003
+ }
7004
+ return ts.factory.createIdentifier(name);
7005
+ }
7006
+ );
7007
+ }
7008
+ }
7009
+ }
7010
+ const results = yield* pipe(
7011
+ all(
7012
+ ...fromIterable(ctx.nameToType.entries()).map(
7013
+ ([name, type]) => pipe(
7014
+ processType(type),
7015
+ orElse2(
7016
+ (error) => succeed(ts.addSyntheticLeadingComment(
7017
+ ts.factory.createIdentifier(""),
7018
+ ts.SyntaxKind.MultiLineCommentTrivia,
7019
+ " " + String(error) + " ",
7020
+ true
7021
+ ))
7022
+ ),
7023
+ map8((_) => ({ requestedName: name, type, result: _ }))
7024
+ )
7025
+ )
7026
+ ),
7027
+ provideService(StructuralSchemaGenContext, ctx)
7028
+ );
7029
+ for (const { requestedName, result, type } of results) {
7030
+ const statementIndex = ctx.typeToStatementIndex.get(type);
7031
+ if (statementIndex !== void 0) continue;
7032
+ ctx.schemaStatements.push(ts.factory.createVariableStatement(
7033
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
7034
+ ts.factory.createVariableDeclarationList(
7035
+ [ts.factory.createVariableDeclaration(
7036
+ ts.factory.createIdentifier(requestedName),
7037
+ void 0,
7038
+ void 0,
7039
+ result
7040
+ )],
7041
+ ts.NodeFlags.Const
7042
+ )
7043
+ ));
7044
+ ctx.typeToStatementIndex.set(type, ctx.schemaStatements.length - 1);
7045
+ }
7046
+ if (isExported) {
7047
+ const statementsToExport = pipe(
7048
+ fromIterable(ctx.nameToType),
7049
+ map4(([_, type]) => ctx.typeToStatementIndex.get(type)),
7050
+ filter((index) => index !== void 0),
7051
+ dedupe
7052
+ );
7053
+ for (let i = 0; i < ctx.schemaStatements.length; i++) {
7054
+ if (!statementsToExport.includes(i)) continue;
7055
+ const statement = ctx.schemaStatements[i];
7056
+ if (ts.isVariableStatement(statement)) {
7057
+ ctx.schemaStatements[i] = ts.factory.updateVariableStatement(
7058
+ statement,
7059
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export),
7060
+ statement.declarationList
7061
+ );
7062
+ } else if (ts.isClassDeclaration(statement)) {
7063
+ ctx.schemaStatements[i] = ts.factory.updateClassDeclaration(
7064
+ statement,
7065
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export),
7066
+ statement.name,
7067
+ statement.typeParameters,
7068
+ statement.heritageClauses,
7069
+ statement.members
7070
+ );
7071
+ }
7072
+ }
7073
+ }
7074
+ if (handleCodegeneratedComments) {
7075
+ for (let i = 0; i < ctx.schemaStatements.length; i++) {
7076
+ const statement = ctx.schemaStatements[i];
7077
+ ctx.schemaStatements[i] = ts.addSyntheticLeadingComment(
7078
+ statement,
7079
+ ts.SyntaxKind.SingleLineCommentTrivia,
7080
+ " @effect-schema-codegenerated: This schema will be re-generated by the effect-schema-codegens command, remove this comment to disable re-generation.",
7081
+ true
7082
+ );
7083
+ }
7084
+ }
7085
+ return ctx;
7086
+ }
7087
+ );
7088
+ var applyAtNode = fn("StructuralSchemaGen.applyAtNode")(
7089
+ function* (sourceFile, node, identifier, type, isExported) {
7090
+ const changeTracker = yield* service(ChangeTracker);
7091
+ const ts = yield* service(TypeScriptApi);
7092
+ const ctx = yield* process(sourceFile, node, /* @__PURE__ */ new Map([[ts.idText(identifier), type]]), isExported, false);
7093
+ for (const statement of ctx.schemaStatements) {
7094
+ changeTracker.insertNodeAt(sourceFile, node.pos, statement, { prefix: "\n", suffix: "\n" });
7095
+ }
7096
+ }
7097
+ );
7098
+
7099
+ // src/codegens/typeToSchema.ts
7100
+ var typeToSchema = createCodegen({
7101
+ name: "typeToSchema",
7102
+ apply: fn("typeToSchema.apply")(function* (sourceFile, textRange) {
7103
+ const ts = yield* service(TypeScriptApi);
7104
+ const tsUtils = yield* service(TypeScriptUtils);
7105
+ const typeChecker = yield* service(TypeCheckerApi);
7106
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7107
+ const typeParser = yield* service(TypeParser);
7108
+ const program = yield* service(TypeScriptProgram);
7109
+ const inThisFile = yield* getCodegensForSourceFile([typeToSchema], sourceFile);
7110
+ if (inThisFile.length > 1) {
7111
+ return yield* fail3(
7112
+ new CodegenNotApplicableError("the typeToSchema codegen can be used only once per file")
7113
+ );
7114
+ }
7115
+ const parse3 = (node) => gen(function* () {
7116
+ if (!ts.isTypeAliasDeclaration(node)) {
7117
+ return yield* fail3(
7118
+ new CodegenNotApplicableError(
7119
+ "this codegen is applicable only to a type alias where each object member is a schema to generate. e.g. `type ToGenerate = { UserSchema: User, TodoSchema: Todo}`"
7120
+ )
7121
+ );
7122
+ }
7123
+ const type = typeChecker.getTypeAtLocation(node.name);
7124
+ if (!type) {
7125
+ return yield* fail3(
7126
+ new CodegenNotApplicableError(
7127
+ "error getting the type to process"
7128
+ )
7129
+ );
7130
+ }
7131
+ const nameToType = /* @__PURE__ */ new Map();
7132
+ const typeProperties = typeChecker.getPropertiesOfType(type);
7133
+ for (const symProp of typeProperties) {
7134
+ const symName = ts.symbolName(symProp);
7135
+ const propType = typeChecker.getTypeOfSymbolAtLocation(symProp, node);
7136
+ if (propType) nameToType.set(symName, propType);
7137
+ }
7138
+ const hash2 = pipe(
7139
+ fromIterable(nameToType),
7140
+ map4(([name, type2]) => {
7141
+ const typeString = typeChecker.typeToString(
7142
+ type2,
7143
+ node,
7144
+ ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseStructuralFallback
7145
+ );
7146
+ return name + ": " + typeString;
7147
+ }),
7148
+ join("\n"),
7149
+ cyrb53
7150
+ );
7151
+ return {
7152
+ hash: hash2,
7153
+ nameToType
7154
+ };
7155
+ });
7156
+ const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
7157
+ if (!nodeAndCommentRange) {
7158
+ return yield* fail3(new CodegenNotApplicableError("no node and comment range affected"));
7159
+ }
7160
+ return yield* pipe(
7161
+ parse3(nodeAndCommentRange.node),
7162
+ map8(
7163
+ (_) => ({
7164
+ hash: _.hash,
7165
+ description: "Generate Schemas from types",
7166
+ apply: pipe(
7167
+ gen(function* () {
7168
+ const changeTracker = yield* service(ChangeTracker);
7169
+ const ctx = yield* process(
7170
+ sourceFile,
7171
+ nodeAndCommentRange.node,
7172
+ _.nameToType,
7173
+ true,
7174
+ true
7175
+ );
7176
+ const pos = sourceFile.end;
7177
+ for (const range of ctx.rangesToDelete) {
7178
+ changeTracker.deleteRange(sourceFile, range);
7179
+ }
7180
+ for (const statement of ctx.schemaStatements) {
7181
+ changeTracker.insertNodeAt(sourceFile, pos, statement, { prefix: "\n", suffix: "\n" });
7182
+ }
7183
+ }),
7184
+ provideService(TypeScriptApi, ts),
7185
+ provideService(TypeScriptUtils, tsUtils),
7186
+ provideService(TypeCheckerApi, typeChecker),
7187
+ provideService(TypeCheckerUtils, typeCheckerUtils),
7188
+ provideService(TypeParser, typeParser),
7189
+ provideService(TypeScriptProgram, program)
7190
+ )
7191
+ })
7192
+ )
7193
+ );
7194
+ })
7195
+ });
7196
+
6534
7197
  // src/codegens.ts
6535
- var codegens = [accessors, annotate];
7198
+ var codegens = [accessors, annotate, typeToSchema];
6536
7199
 
6537
7200
  // src/completions/effectCodegensComment.ts
6538
7201
  var effectCodegensComment = createCompletion({
@@ -16510,6 +17173,38 @@ var removeUnnecessaryEffectGen = createRefactor({
16510
17173
  })
16511
17174
  });
16512
17175
 
17176
+ // src/refactors/structuralTypeToSchema.ts
17177
+ var structuralTypeToSchema = createRefactor({
17178
+ name: "structuralTypeToSchema",
17179
+ description: "Refactor to Schema (Structural)",
17180
+ apply: fn("structuralTypeToSchema.apply")(function* (sourceFile, textRange) {
17181
+ const ts = yield* service(TypeScriptApi);
17182
+ const tsUtils = yield* service(TypeScriptUtils);
17183
+ const typeChecker = yield* service(TypeCheckerApi);
17184
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
17185
+ const typeParser = yield* service(TypeParser);
17186
+ const program = yield* service(TypeScriptProgram);
17187
+ const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17188
+ if (isNone2(maybeNode)) {
17189
+ return yield* fail3(new RefactorNotApplicableError());
17190
+ }
17191
+ const { identifier, isExported, node, type } = maybeNode.value;
17192
+ return {
17193
+ kind: "refactor.rewrite.effect.structuralTypeToSchema",
17194
+ description: "Refactor to Schema (Recursive Structural)",
17195
+ apply: pipe(
17196
+ applyAtNode(sourceFile, node, identifier, type, isExported),
17197
+ provideService(TypeCheckerApi, typeChecker),
17198
+ provideService(TypeScriptUtils, tsUtils),
17199
+ provideService(TypeScriptApi, ts),
17200
+ provideService(TypeCheckerUtils, typeCheckerUtils),
17201
+ provideService(TypeParser, typeParser),
17202
+ provideService(TypeScriptProgram, program)
17203
+ )
17204
+ };
17205
+ })
17206
+ });
17207
+
16513
17208
  // src/refactors/toggleLazyConst.ts
16514
17209
  var toggleLazyConst = createRefactor({
16515
17210
  name: "toggleLazyConst",
@@ -17161,7 +17856,7 @@ var createExportSchemaClassDeclaration = fn("SchemaGen.createExportSchemaClassDe
17161
17856
  );
17162
17857
  }
17163
17858
  );
17164
- var process = fn("SchemaGen.process")(
17859
+ var process2 = fn("SchemaGen.process")(
17165
17860
  function* (sourceFile, node, preferClass) {
17166
17861
  const ctx = yield* makeSchemaGenContext(sourceFile);
17167
17862
  const ts = yield* service(TypeScriptApi);
@@ -17171,7 +17866,7 @@ var process = fn("SchemaGen.process")(
17171
17866
  );
17172
17867
  }
17173
17868
  );
17174
- var findNodeToProcess = fn("SchemaGen.findNodeToProcess")(
17869
+ var findNodeToProcess2 = fn("SchemaGen.findNodeToProcess")(
17175
17870
  function* (sourceFile, textRange) {
17176
17871
  const ts = yield* service(TypeScriptApi);
17177
17872
  const tsUtils = yield* service(TypeScriptUtils);
@@ -17184,12 +17879,12 @@ var findNodeToProcess = fn("SchemaGen.findNodeToProcess")(
17184
17879
  );
17185
17880
  }
17186
17881
  );
17187
- var applyAtNode = fn("SchemaGen.applyAtNode")(
17882
+ var applyAtNode2 = fn("SchemaGen.applyAtNode")(
17188
17883
  function* (sourceFile, node, preferClass) {
17189
17884
  const ts = yield* service(TypeScriptApi);
17190
17885
  const changeTracker = yield* service(ChangeTracker);
17191
17886
  const newNode = yield* pipe(
17192
- process(sourceFile, node, preferClass),
17887
+ process2(sourceFile, node, preferClass),
17193
17888
  orElse2(
17194
17889
  (error) => succeed(ts.addSyntheticLeadingComment(
17195
17890
  ts.factory.createIdentifier(""),
@@ -17214,14 +17909,14 @@ var typeToEffectSchema = createRefactor({
17214
17909
  const tsUtils = yield* service(TypeScriptUtils);
17215
17910
  const typeChecker = yield* service(TypeCheckerApi);
17216
17911
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
17217
- const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17912
+ const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
17218
17913
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
17219
17914
  const node = maybeNode.value;
17220
17915
  return {
17221
17916
  kind: "refactor.rewrite.effect.typeToEffectSchema",
17222
17917
  description: "Refactor to Schema",
17223
17918
  apply: pipe(
17224
- applyAtNode(sourceFile, node, false),
17919
+ applyAtNode2(sourceFile, node, false),
17225
17920
  provideService(TypeCheckerApi, typeChecker),
17226
17921
  provideService(TypeScriptUtils, tsUtils),
17227
17922
  provideService(TypeScriptApi, ts),
@@ -17240,14 +17935,14 @@ var typeToEffectSchemaClass = createRefactor({
17240
17935
  const tsUtils = yield* service(TypeScriptUtils);
17241
17936
  const typeChecker = yield* service(TypeCheckerApi);
17242
17937
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
17243
- const maybeNode = yield* findNodeToProcess(sourceFile, textRange);
17938
+ const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
17244
17939
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
17245
17940
  const node = maybeNode.value;
17246
17941
  return {
17247
17942
  kind: "refactor.rewrite.effect.typeToEffectSchemaClass",
17248
17943
  description: "Refactor to Schema.Class",
17249
17944
  apply: pipe(
17250
- applyAtNode(sourceFile, node, true),
17945
+ applyAtNode2(sourceFile, node, true),
17251
17946
  provideService(TypeCheckerApi, typeChecker),
17252
17947
  provideService(TypeScriptUtils, tsUtils),
17253
17948
  provideService(TypeScriptApi, ts),
@@ -17338,6 +18033,7 @@ var refactors = [
17338
18033
  functionToArrow,
17339
18034
  typeToEffectSchema,
17340
18035
  typeToEffectSchemaClass,
18036
+ structuralTypeToSchema,
17341
18037
  makeSchemaOpaque,
17342
18038
  makeSchemaOpaqueWithNs,
17343
18039
  pipeableToDatafirst,