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