@effect/language-service 0.61.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/transform.js CHANGED
@@ -764,6 +764,10 @@ var isEmptyArray = (self) => self.length === 0;
764
764
  var isEmptyReadonlyArray = isEmptyArray;
765
765
  var isNonEmptyReadonlyArray = isNonEmptyArray;
766
766
  var isOutOfBounds = (i, as) => i < 0 || i >= as.length;
767
+ var get = /* @__PURE__ */ dual(2, (self, index) => {
768
+ const i = Math.floor(index);
769
+ return isOutOfBounds(i, self) ? none2() : some2(self[i]);
770
+ });
767
771
  var unsafeGet = /* @__PURE__ */ dual(2, (self, index) => {
768
772
  const i = Math.floor(index);
769
773
  if (isOutOfBounds(i, self)) {
@@ -771,6 +775,7 @@ var unsafeGet = /* @__PURE__ */ dual(2, (self, index) => {
771
775
  }
772
776
  return self[i];
773
777
  });
778
+ var head = /* @__PURE__ */ get(0);
774
779
  var headNonEmpty = /* @__PURE__ */ unsafeGet(0);
775
780
  var tailNonEmpty = (self) => self.slice(1);
776
781
  var reverse = (self) => Array.from(self).reverse();
@@ -834,6 +839,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
834
839
  return [];
835
840
  });
836
841
  var dedupe = (self) => dedupeWith(self, equivalence());
842
+ var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
837
843
 
838
844
  // src/core/Nano.ts
839
845
  var NanoTag = class {
@@ -2188,6 +2194,9 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2188
2194
  function isThisTypeParameter(type) {
2189
2195
  return !!(type.flags & ts.TypeFlags.TypeParameter && type.isThisType);
2190
2196
  }
2197
+ function isMissingIntrinsicType(type) {
2198
+ return (type.flags & ts.TypeFlags.Undefined) !== 0 && "debugIntrinsicName" in type && type.debugIntrinsicName === "missing";
2199
+ }
2191
2200
  function getTypeParameterAtPosition(signature, pos) {
2192
2201
  const type = typeChecker.getParameterType(signature, pos);
2193
2202
  if (isIndexType(type) && isThisTypeParameter(type.type)) {
@@ -2492,6 +2501,7 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2492
2501
  }
2493
2502
  return {
2494
2503
  isUnion,
2504
+ isMissingIntrinsicType,
2495
2505
  getTypeParameterAtPosition,
2496
2506
  getMissingTypeEntriesInTargetType,
2497
2507
  unrollUnionMembers,
@@ -5663,8 +5673,662 @@ var annotate = createCodegen({
5663
5673
  })
5664
5674
  });
5665
5675
 
5676
+ // src/utils/StructuralSchemaGen.ts
5677
+ var UnsupportedTypeError = class {
5678
+ constructor(type, reason) {
5679
+ this.type = type;
5680
+ this.reason = reason;
5681
+ }
5682
+ _tag = "@effect/language-service/UnsupportedTypeError";
5683
+ toString() {
5684
+ return `Unsupported type: ${this.reason}`;
5685
+ }
5686
+ };
5687
+ var StructuralSchemaGenContext = Tag("StructuralSchemaGenContext");
5688
+ var makeStructuralSchemaGenContext = fn("StructuralSchemaGen.makeContext")(
5689
+ function* (sourceFile, schemaIdentifier) {
5690
+ const ts = yield* service(TypeScriptApi);
5691
+ const program = yield* service(TypeScriptProgram);
5692
+ const typeChecker = yield* service(TypeCheckerApi);
5693
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5694
+ const effectSchemaIdentifier = schemaIdentifier || "Schema";
5695
+ return identity({
5696
+ ts,
5697
+ program,
5698
+ typeChecker,
5699
+ typeCheckerUtils,
5700
+ sourceFile,
5701
+ createApiPropertyAccess: (apiName) => ts.factory.createPropertyAccessExpression(
5702
+ ts.factory.createIdentifier(effectSchemaIdentifier),
5703
+ apiName
5704
+ ),
5705
+ createApiCall: (apiName, args2) => ts.factory.createCallExpression(
5706
+ ts.factory.createPropertyAccessExpression(
5707
+ ts.factory.createIdentifier(effectSchemaIdentifier),
5708
+ apiName
5709
+ ),
5710
+ [],
5711
+ args2
5712
+ ),
5713
+ hoistedSchemas: /* @__PURE__ */ new Map(),
5714
+ typeToStatementIndex: /* @__PURE__ */ new Map(),
5715
+ nameToType: /* @__PURE__ */ new Map(),
5716
+ usedGlobalIdentifiers: /* @__PURE__ */ new Map(),
5717
+ schemaStatements: [],
5718
+ rangesToDelete: []
5719
+ });
5720
+ }
5721
+ );
5722
+ var pushHoistedStatement = fn("StructuralSchemaGen.pushHoistedStatement")(
5723
+ function* (ctx, name, type, statement, createReference) {
5724
+ ctx.usedGlobalIdentifiers.set(name, (ctx.usedGlobalIdentifiers.get(name) || 0) + 1);
5725
+ ctx.schemaStatements.push(statement);
5726
+ ctx.typeToStatementIndex.set(type, ctx.schemaStatements.length - 1);
5727
+ ctx.hoistedSchemas.set(type, createReference);
5728
+ }
5729
+ );
5730
+ var pushHoistedVariableStatement = fn("StructuralSchemaGen.pushHoistedVariableStatement")(
5731
+ function* (ts, ctx, name, type, result) {
5732
+ return yield* pushHoistedStatement(
5733
+ ctx,
5734
+ name,
5735
+ type,
5736
+ ts.factory.createVariableStatement(
5737
+ void 0,
5738
+ ts.factory.createVariableDeclarationList(
5739
+ [ts.factory.createVariableDeclaration(ts.factory.createIdentifier(name), void 0, void 0, result)],
5740
+ ts.NodeFlags.Const
5741
+ )
5742
+ ),
5743
+ () => ts.factory.createIdentifier(name)
5744
+ );
5745
+ }
5746
+ );
5747
+ var createProcessingContext = (maxDepth = 200) => ({
5748
+ depth: 0,
5749
+ maxDepth,
5750
+ hoistName: void 0
5751
+ });
5752
+ var processType = fn(
5753
+ "StructuralSchemaGen.processType"
5754
+ )(
5755
+ function* (type, context) {
5756
+ const processingContext = context || createProcessingContext();
5757
+ const { hoistedSchemas, nameToType, ts, typeChecker, usedGlobalIdentifiers } = yield* service(
5758
+ StructuralSchemaGenContext
5759
+ );
5760
+ if (processingContext.depth >= processingContext.maxDepth) {
5761
+ return yield* fail(new UnsupportedTypeError(type, "Maximum depth exceeded"));
5762
+ }
5763
+ let hoistName = fromIterable(nameToType.entries()).find(([_, existingType]) => existingType === type)?.[0];
5764
+ if (!hoistName && type && type.symbol && type.symbol.declarations && type.symbol.declarations.length === 1) {
5765
+ const declaration = type.symbol.declarations[0];
5766
+ if (ts.isInterfaceDeclaration(declaration)) {
5767
+ hoistName = ts.idText(declaration.name);
5768
+ } else if (declaration.parent && ts.isTypeAliasDeclaration(declaration.parent)) {
5769
+ hoistName = ts.idText(declaration.parent.name);
5770
+ }
5771
+ if (hoistName) {
5772
+ const existingType = nameToType.get(hoistName);
5773
+ const isSame = existingType && typeChecker.isTypeAssignableTo(type, existingType) && typeChecker.isTypeAssignableTo(existingType, type);
5774
+ if (!isSame) {
5775
+ const usedCount = usedGlobalIdentifiers.get(hoistName) || 0;
5776
+ hoistName = usedCount > 0 ? hoistName + "_" + usedCount : hoistName;
5777
+ }
5778
+ }
5779
+ }
5780
+ const nestedContext = {
5781
+ ...processingContext,
5782
+ depth: processingContext.depth + 1,
5783
+ hoistName
5784
+ };
5785
+ for (const [hoistedType, hoistedSchema] of hoistedSchemas.entries()) {
5786
+ if (hoistedType === type || typeChecker.isTypeAssignableTo(type, hoistedType) && typeChecker.isTypeAssignableTo(hoistedType, type)) {
5787
+ return hoistedSchema();
5788
+ }
5789
+ }
5790
+ const [schemaExpr, skipHoisting] = yield* processTypeImpl(type, nestedContext);
5791
+ if (!skipHoisting && hoistName) {
5792
+ const ctx = yield* service(StructuralSchemaGenContext);
5793
+ yield* pushHoistedVariableStatement(ts, ctx, hoistName, type, schemaExpr);
5794
+ return ctx.hoistedSchemas.get(type)();
5795
+ }
5796
+ return schemaExpr;
5797
+ }
5798
+ );
5799
+ var processTypeImpl = fn(
5800
+ "StructuralSchemaGen.processTypeImpl"
5801
+ )(
5802
+ function* (type, context) {
5803
+ const { createApiCall, createApiPropertyAccess, ts, typeChecker, typeCheckerUtils } = yield* service(
5804
+ StructuralSchemaGenContext
5805
+ );
5806
+ if (type.flags & ts.TypeFlags.String) {
5807
+ return [createApiPropertyAccess("String"), true];
5808
+ }
5809
+ if (type.flags & ts.TypeFlags.Number) {
5810
+ return [createApiPropertyAccess("Number"), true];
5811
+ }
5812
+ if (type.flags & ts.TypeFlags.Boolean) {
5813
+ return [createApiPropertyAccess("Boolean"), true];
5814
+ }
5815
+ if (type.flags & ts.TypeFlags.BigInt) {
5816
+ return [createApiPropertyAccess("BigInt"), true];
5817
+ }
5818
+ if (type.flags & ts.TypeFlags.Void) {
5819
+ return [createApiPropertyAccess("Void"), true];
5820
+ }
5821
+ if (type.flags & ts.TypeFlags.Undefined) {
5822
+ return [createApiPropertyAccess("Undefined"), true];
5823
+ }
5824
+ if (type.flags & ts.TypeFlags.Null) {
5825
+ return [createApiPropertyAccess("Null"), true];
5826
+ }
5827
+ if (type.flags & ts.TypeFlags.Never) {
5828
+ return [createApiPropertyAccess("Never"), true];
5829
+ }
5830
+ if (type.flags & ts.TypeFlags.Any) {
5831
+ return [createApiPropertyAccess("Any"), true];
5832
+ }
5833
+ if (type.flags & ts.TypeFlags.Unknown) {
5834
+ return [createApiPropertyAccess("Unknown"), true];
5835
+ }
5836
+ if (type.flags & ts.TypeFlags.StringLiteral) {
5837
+ const literalType = type;
5838
+ return [createApiCall("Literal", [ts.factory.createStringLiteral(literalType.value)]), true];
5839
+ }
5840
+ if (type.flags & ts.TypeFlags.NumberLiteral) {
5841
+ const literalType = type;
5842
+ return [createApiCall("Literal", [ts.factory.createNumericLiteral(literalType.value)]), true];
5843
+ }
5844
+ if (type.flags & ts.TypeFlags.BooleanLiteral) {
5845
+ const value = type.intrinsicName === "true";
5846
+ return [createApiCall("Literal", [value ? ts.factory.createTrue() : ts.factory.createFalse()]), true];
5847
+ }
5848
+ if (typeCheckerUtils.isUnion(type)) {
5849
+ return yield* processUnionType(type.types, context);
5850
+ }
5851
+ if (type.flags & ts.TypeFlags.Intersection) {
5852
+ return yield* processIntersectionType(type, context);
5853
+ }
5854
+ if (typeChecker.isArrayType(type)) {
5855
+ return yield* processArrayType(type, context);
5856
+ }
5857
+ if (typeChecker.isTupleType(type)) {
5858
+ return yield* processTupleType(type, context);
5859
+ }
5860
+ if (type.flags & ts.TypeFlags.Object) {
5861
+ const symbol3 = type.symbol || type.aliasSymbol;
5862
+ if (symbol3) {
5863
+ const typeName = typeChecker.symbolToString(symbol3);
5864
+ if (typeName === "Date") {
5865
+ return [createApiPropertyAccess("Date"), false];
5866
+ }
5867
+ if (typeName === "ReadonlyArray" || typeName === "Array") {
5868
+ return yield* processArrayType(type, context);
5869
+ }
5870
+ }
5871
+ const objectType = type;
5872
+ return yield* processObjectType(objectType, context);
5873
+ }
5874
+ return yield* fail(
5875
+ new UnsupportedTypeError(
5876
+ type,
5877
+ `Type with flags ${type.flags} is not supported`
5878
+ )
5879
+ );
5880
+ }
5881
+ );
5882
+ var processUnionType = fn(
5883
+ "StructuralSchemaGen.processUnionType"
5884
+ )(
5885
+ function* (types, context) {
5886
+ const { createApiCall, ts } = yield* service(StructuralSchemaGenContext);
5887
+ const allLiterals = types.every(
5888
+ (t) => t.flags & ts.TypeFlags.StringLiteral || t.flags & ts.TypeFlags.NumberLiteral || t.flags & ts.TypeFlags.BooleanLiteral
5889
+ );
5890
+ if (allLiterals) {
5891
+ const literals = yield* all(
5892
+ ...types.map((t) => processType(t, context))
5893
+ );
5894
+ const literalValues = literals.map((expr) => {
5895
+ if (ts.isCallExpression(expr) && expr.arguments.length > 0) {
5896
+ return expr.arguments[0];
5897
+ }
5898
+ return expr;
5899
+ }).filter((arg) => arg !== void 0);
5900
+ return [createApiCall("Literal", literalValues), false];
5901
+ }
5902
+ const members = yield* all(
5903
+ ...types.map((t) => processType(t, context))
5904
+ );
5905
+ if (members.length === 1) {
5906
+ return [members[0], false];
5907
+ }
5908
+ return [createApiCall("Union", members), false];
5909
+ }
5910
+ );
5911
+ var processIntersectionType = fn(
5912
+ "StructuralSchemaGen.processIntersectionType"
5913
+ )(
5914
+ function* (type, context) {
5915
+ const { createApiCall, ts } = yield* service(StructuralSchemaGenContext);
5916
+ const [firstSchema, ...otherSchemas] = yield* all(
5917
+ ...type.types.map((t) => processType(t, context))
5918
+ );
5919
+ if (otherSchemas.length === 0) {
5920
+ return [firstSchema, false];
5921
+ }
5922
+ return [
5923
+ ts.factory.createCallExpression(
5924
+ ts.factory.createPropertyAccessExpression(
5925
+ firstSchema,
5926
+ "pipe"
5927
+ ),
5928
+ [],
5929
+ otherSchemas.map((schema) => createApiCall("extend", [schema]))
5930
+ ),
5931
+ false
5932
+ ];
5933
+ }
5934
+ );
5935
+ var processArrayType = fn(
5936
+ "StructuralSchemaGen.processArrayType"
5937
+ )(
5938
+ function* (type, context) {
5939
+ const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
5940
+ const typeArgs = typeChecker.getTypeArguments(type);
5941
+ if (typeArgs.length === 0) {
5942
+ return yield* fail(new UnsupportedTypeError(type, "Array type has no type arguments"));
5943
+ }
5944
+ const elementSchema = yield* processType(typeArgs[0], context);
5945
+ return [createApiCall("Array", [elementSchema]), false];
5946
+ }
5947
+ );
5948
+ var processTupleType = fn(
5949
+ "StructuralSchemaGen.processTupleType"
5950
+ )(
5951
+ function* (type, context) {
5952
+ const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
5953
+ const typeArgs = typeChecker.getTypeArguments(type);
5954
+ const elementSchemas = yield* all(
5955
+ ...typeArgs.map((t) => processType(t, context))
5956
+ );
5957
+ return [createApiCall("Tuple", elementSchemas), false];
5958
+ }
5959
+ );
5960
+ var processObjectType = fn(
5961
+ "StructuralSchemaGen.processObjectType"
5962
+ )(
5963
+ function* (type, context) {
5964
+ const {
5965
+ createApiCall,
5966
+ createApiPropertyAccess,
5967
+ program,
5968
+ ts,
5969
+ typeChecker,
5970
+ typeCheckerUtils
5971
+ } = yield* service(
5972
+ StructuralSchemaGenContext
5973
+ );
5974
+ let hasRecords = false;
5975
+ const properties = typeChecker.getPropertiesOfType(type);
5976
+ const propertyAssignments = [];
5977
+ for (const property of properties) {
5978
+ const propertyName = typeChecker.symbolToString(property);
5979
+ const propertyType = typeChecker.getTypeOfSymbol(property);
5980
+ const isOptional = (property.flags & ts.SymbolFlags.Optional) !== 0;
5981
+ let schemaExpr;
5982
+ if (isOptional) {
5983
+ if (program.getCompilerOptions().exactOptionalPropertyTypes) {
5984
+ if (typeCheckerUtils.isUnion(propertyType)) {
5985
+ const typeWithoutMissing = propertyType.types.filter((t) => !typeCheckerUtils.isMissingIntrinsicType(t));
5986
+ const [result, _] = yield* processUnionType(typeWithoutMissing, context);
5987
+ schemaExpr = createApiCall("optionalWith", [
5988
+ result,
5989
+ ts.factory.createObjectLiteralExpression([
5990
+ ts.factory.createPropertyAssignment("exact", ts.factory.createTrue())
5991
+ ])
5992
+ ]);
5993
+ }
5994
+ } else {
5995
+ schemaExpr = yield* processType(propertyType, context);
5996
+ schemaExpr = createApiCall("optional", [schemaExpr]);
5997
+ }
5998
+ }
5999
+ if (!schemaExpr) {
6000
+ schemaExpr = yield* processType(propertyType, context);
6001
+ }
6002
+ const propertyNameNode = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(propertyName) ? ts.factory.createIdentifier(propertyName) : ts.factory.createStringLiteral(propertyName);
6003
+ propertyAssignments.push(
6004
+ ts.factory.createPropertyAssignment(
6005
+ propertyNameNode,
6006
+ schemaExpr
6007
+ )
6008
+ );
6009
+ }
6010
+ const indexInfos = typeChecker.getIndexInfosOfType(type);
6011
+ const args2 = [
6012
+ ts.factory.createObjectLiteralExpression(propertyAssignments, propertyAssignments.length > 0)
6013
+ ];
6014
+ for (const indexInfo of indexInfos) {
6015
+ hasRecords = true;
6016
+ const keyType = indexInfo.keyType;
6017
+ const valueType = indexInfo.type;
6018
+ const keySchema = yield* processType(keyType, context);
6019
+ const valueSchema = yield* processType(valueType, context);
6020
+ args2.push(
6021
+ ts.factory.createObjectLiteralExpression([
6022
+ ts.factory.createPropertyAssignment("key", keySchema),
6023
+ ts.factory.createPropertyAssignment("value", valueSchema)
6024
+ ])
6025
+ );
6026
+ }
6027
+ if (!hasRecords && context.hoistName) {
6028
+ const ctx = yield* service(StructuralSchemaGenContext);
6029
+ yield* pushHoistedStatement(
6030
+ ctx,
6031
+ context.hoistName,
6032
+ type,
6033
+ ts.factory.createClassDeclaration(
6034
+ void 0,
6035
+ ts.factory.createIdentifier(context.hoistName),
6036
+ [],
6037
+ [ts.factory.createHeritageClause(
6038
+ ts.SyntaxKind.ExtendsKeyword,
6039
+ [
6040
+ ts.factory.createExpressionWithTypeArguments(
6041
+ ts.factory.createCallExpression(
6042
+ ts.factory.createCallExpression(
6043
+ createApiPropertyAccess("Class"),
6044
+ [ts.factory.createTypeReferenceNode(
6045
+ context.hoistName
6046
+ )],
6047
+ [ts.factory.createStringLiteral(context.hoistName)]
6048
+ ),
6049
+ [],
6050
+ args2
6051
+ ),
6052
+ []
6053
+ )
6054
+ ]
6055
+ )],
6056
+ []
6057
+ ),
6058
+ () => ts.factory.createIdentifier(context.hoistName)
6059
+ );
6060
+ return [ctx.hoistedSchemas.get(type)(), true];
6061
+ }
6062
+ return [createApiCall("Struct", args2), propertyAssignments.length === 0];
6063
+ }
6064
+ );
6065
+ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6066
+ function* (sourceFile, textRange) {
6067
+ const ts = yield* service(TypeScriptApi);
6068
+ const tsUtils = yield* service(TypeScriptUtils);
6069
+ const typeChecker = yield* service(TypeCheckerApi);
6070
+ return pipe(
6071
+ tsUtils.getAncestorNodesInRange(sourceFile, textRange),
6072
+ filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
6073
+ filter((node) => tsUtils.isNodeInRange(textRange)(node.name)),
6074
+ filter((node) => (node.typeParameters || []).length === 0),
6075
+ map3((node) => ({
6076
+ node,
6077
+ identifier: node.name,
6078
+ type: typeChecker.getTypeAtLocation(node.name),
6079
+ isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
6080
+ })),
6081
+ filter(({ type }) => !!type),
6082
+ head
6083
+ );
6084
+ }
6085
+ );
6086
+ var process = fn("StructuralSchemaGen.process")(
6087
+ function* (sourceFile, scope, typeMap, isExported, handleCodegeneratedComments) {
6088
+ const ts = yield* service(TypeScriptApi);
6089
+ const tsUtils = yield* service(TypeScriptUtils);
6090
+ const typeChecker = yield* service(TypeCheckerApi);
6091
+ const typeParser = yield* service(TypeParser);
6092
+ const schemaIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Schema") || "Schema";
6093
+ const ctx = yield* makeStructuralSchemaGenContext(sourceFile, schemaIdentifier);
6094
+ for (const [name, type] of typeMap.entries()) {
6095
+ ctx.nameToType.set(name, type);
6096
+ }
6097
+ if (handleCodegeneratedComments) {
6098
+ for (const declaration of sourceFile.statements) {
6099
+ const nodeText = sourceFile.text.slice(declaration.pos, declaration.end);
6100
+ if (!nodeText.toLowerCase().includes("@effect-schema-codegenerated")) continue;
6101
+ const interleavingRange = ctx.rangesToDelete.find(
6102
+ (range) => range.pos < declaration.end && range.end > declaration.pos
6103
+ );
6104
+ if (interleavingRange) {
6105
+ interleavingRange.pos = Math.min(interleavingRange.pos, declaration.pos);
6106
+ interleavingRange.end = Math.max(interleavingRange.end, declaration.end);
6107
+ } else {
6108
+ ctx.rangesToDelete.push({
6109
+ pos: declaration.pos,
6110
+ end: declaration.end
6111
+ });
6112
+ }
6113
+ }
6114
+ }
6115
+ for (const symbol3 of typeChecker.getSymbolsInScope(scope, ts.SymbolFlags.Value)) {
6116
+ const name = typeChecker.symbolToString(symbol3);
6117
+ ctx.usedGlobalIdentifiers.set(name, 1);
6118
+ const type = typeChecker.getTypeOfSymbolAtLocation(symbol3, sourceFile);
6119
+ if (type) {
6120
+ const schemaType = yield* pipe(
6121
+ typeParser.effectSchemaType(type, scope),
6122
+ orElse2(() => void_)
6123
+ );
6124
+ if (schemaType) {
6125
+ ctx.hoistedSchemas.set(
6126
+ schemaType.A,
6127
+ () => {
6128
+ const expression = typeChecker.symbolToExpression(
6129
+ symbol3,
6130
+ ts.SymbolFlags.Value,
6131
+ scope,
6132
+ ts.NodeBuilderFlags.NoTruncation
6133
+ );
6134
+ if (expression) {
6135
+ return expression;
6136
+ }
6137
+ return ts.factory.createIdentifier(name);
6138
+ }
6139
+ );
6140
+ }
6141
+ }
6142
+ }
6143
+ const results = yield* pipe(
6144
+ all(
6145
+ ...fromIterable(ctx.nameToType.entries()).map(
6146
+ ([name, type]) => pipe(
6147
+ processType(type),
6148
+ orElse2(
6149
+ (error) => succeed(ts.addSyntheticLeadingComment(
6150
+ ts.factory.createIdentifier(""),
6151
+ ts.SyntaxKind.MultiLineCommentTrivia,
6152
+ " " + String(error) + " ",
6153
+ true
6154
+ ))
6155
+ ),
6156
+ map4((_) => ({ requestedName: name, type, result: _ }))
6157
+ )
6158
+ )
6159
+ ),
6160
+ provideService(StructuralSchemaGenContext, ctx)
6161
+ );
6162
+ for (const { requestedName, result, type } of results) {
6163
+ const statementIndex = ctx.typeToStatementIndex.get(type);
6164
+ if (statementIndex !== void 0) continue;
6165
+ ctx.schemaStatements.push(ts.factory.createVariableStatement(
6166
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
6167
+ ts.factory.createVariableDeclarationList(
6168
+ [ts.factory.createVariableDeclaration(
6169
+ ts.factory.createIdentifier(requestedName),
6170
+ void 0,
6171
+ void 0,
6172
+ result
6173
+ )],
6174
+ ts.NodeFlags.Const
6175
+ )
6176
+ ));
6177
+ ctx.typeToStatementIndex.set(type, ctx.schemaStatements.length - 1);
6178
+ }
6179
+ if (isExported) {
6180
+ const statementsToExport = pipe(
6181
+ fromIterable(ctx.nameToType),
6182
+ map3(([_, type]) => ctx.typeToStatementIndex.get(type)),
6183
+ filter((index) => index !== void 0),
6184
+ dedupe
6185
+ );
6186
+ for (let i = 0; i < ctx.schemaStatements.length; i++) {
6187
+ if (!statementsToExport.includes(i)) continue;
6188
+ const statement = ctx.schemaStatements[i];
6189
+ if (ts.isVariableStatement(statement)) {
6190
+ ctx.schemaStatements[i] = ts.factory.updateVariableStatement(
6191
+ statement,
6192
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export),
6193
+ statement.declarationList
6194
+ );
6195
+ } else if (ts.isClassDeclaration(statement)) {
6196
+ ctx.schemaStatements[i] = ts.factory.updateClassDeclaration(
6197
+ statement,
6198
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export),
6199
+ statement.name,
6200
+ statement.typeParameters,
6201
+ statement.heritageClauses,
6202
+ statement.members
6203
+ );
6204
+ }
6205
+ }
6206
+ }
6207
+ if (handleCodegeneratedComments) {
6208
+ for (let i = 0; i < ctx.schemaStatements.length; i++) {
6209
+ const statement = ctx.schemaStatements[i];
6210
+ ctx.schemaStatements[i] = ts.addSyntheticLeadingComment(
6211
+ statement,
6212
+ ts.SyntaxKind.SingleLineCommentTrivia,
6213
+ " @effect-schema-codegenerated: This schema will be re-generated by the effect-schema-codegens command, remove this comment to disable re-generation.",
6214
+ true
6215
+ );
6216
+ }
6217
+ }
6218
+ return ctx;
6219
+ }
6220
+ );
6221
+ var applyAtNode = fn("StructuralSchemaGen.applyAtNode")(
6222
+ function* (sourceFile, node, identifier, type, isExported) {
6223
+ const changeTracker = yield* service(ChangeTracker);
6224
+ const ts = yield* service(TypeScriptApi);
6225
+ const ctx = yield* process(sourceFile, node, /* @__PURE__ */ new Map([[ts.idText(identifier), type]]), isExported, false);
6226
+ for (const statement of ctx.schemaStatements) {
6227
+ changeTracker.insertNodeAt(sourceFile, node.pos, statement, { prefix: "\n", suffix: "\n" });
6228
+ }
6229
+ }
6230
+ );
6231
+
6232
+ // src/codegens/typeToSchema.ts
6233
+ var typeToSchema = createCodegen({
6234
+ name: "typeToSchema",
6235
+ apply: fn("typeToSchema.apply")(function* (sourceFile, textRange) {
6236
+ const ts = yield* service(TypeScriptApi);
6237
+ const tsUtils = yield* service(TypeScriptUtils);
6238
+ const typeChecker = yield* service(TypeCheckerApi);
6239
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6240
+ const typeParser = yield* service(TypeParser);
6241
+ const program = yield* service(TypeScriptProgram);
6242
+ const inThisFile = yield* getCodegensForSourceFile([typeToSchema], sourceFile);
6243
+ if (inThisFile.length > 1) {
6244
+ return yield* fail(
6245
+ new CodegenNotApplicableError("the typeToSchema codegen can be used only once per file")
6246
+ );
6247
+ }
6248
+ const parse3 = (node) => gen(function* () {
6249
+ if (!ts.isTypeAliasDeclaration(node)) {
6250
+ return yield* fail(
6251
+ new CodegenNotApplicableError(
6252
+ "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}`"
6253
+ )
6254
+ );
6255
+ }
6256
+ const type = typeChecker.getTypeAtLocation(node.name);
6257
+ if (!type) {
6258
+ return yield* fail(
6259
+ new CodegenNotApplicableError(
6260
+ "error getting the type to process"
6261
+ )
6262
+ );
6263
+ }
6264
+ const nameToType = /* @__PURE__ */ new Map();
6265
+ const typeProperties = typeChecker.getPropertiesOfType(type);
6266
+ for (const symProp of typeProperties) {
6267
+ const symName = ts.symbolName(symProp);
6268
+ const propType = typeChecker.getTypeOfSymbolAtLocation(symProp, node);
6269
+ if (propType) nameToType.set(symName, propType);
6270
+ }
6271
+ const hash2 = pipe(
6272
+ fromIterable(nameToType),
6273
+ map3(([name, type2]) => {
6274
+ const typeString = typeChecker.typeToString(
6275
+ type2,
6276
+ node,
6277
+ ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseStructuralFallback
6278
+ );
6279
+ return name + ": " + typeString;
6280
+ }),
6281
+ join("\n"),
6282
+ cyrb53
6283
+ );
6284
+ return {
6285
+ hash: hash2,
6286
+ nameToType
6287
+ };
6288
+ });
6289
+ const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
6290
+ if (!nodeAndCommentRange) {
6291
+ return yield* fail(new CodegenNotApplicableError("no node and comment range affected"));
6292
+ }
6293
+ return yield* pipe(
6294
+ parse3(nodeAndCommentRange.node),
6295
+ map4(
6296
+ (_) => ({
6297
+ hash: _.hash,
6298
+ description: "Generate Schemas from types",
6299
+ apply: pipe(
6300
+ gen(function* () {
6301
+ const changeTracker = yield* service(ChangeTracker);
6302
+ const ctx = yield* process(
6303
+ sourceFile,
6304
+ nodeAndCommentRange.node,
6305
+ _.nameToType,
6306
+ true,
6307
+ true
6308
+ );
6309
+ const pos = sourceFile.end;
6310
+ for (const range of ctx.rangesToDelete) {
6311
+ changeTracker.deleteRange(sourceFile, range);
6312
+ }
6313
+ for (const statement of ctx.schemaStatements) {
6314
+ changeTracker.insertNodeAt(sourceFile, pos, statement, { prefix: "\n", suffix: "\n" });
6315
+ }
6316
+ }),
6317
+ provideService(TypeScriptApi, ts),
6318
+ provideService(TypeScriptUtils, tsUtils),
6319
+ provideService(TypeCheckerApi, typeChecker),
6320
+ provideService(TypeCheckerUtils, typeCheckerUtils),
6321
+ provideService(TypeParser, typeParser),
6322
+ provideService(TypeScriptProgram, program)
6323
+ )
6324
+ })
6325
+ )
6326
+ );
6327
+ })
6328
+ });
6329
+
5666
6330
  // src/codegens.ts
5667
- var codegens = [accessors, annotate];
6331
+ var codegens = [accessors, annotate, typeToSchema];
5668
6332
 
5669
6333
  // src/diagnostics/outdatedEffectCodegen.ts
5670
6334
  var outdatedEffectCodegen = createDiagnostic({