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