@effect/language-service 0.61.0 → 0.62.1

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