@effect/language-service 0.40.1 → 0.41.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/index.js CHANGED
@@ -1064,6 +1064,68 @@ var all = fn("all")(
1064
1064
  var TypeScriptApi = Tag("TypeScriptApi");
1065
1065
  var TypeScriptProgram = Tag("TypeScriptProgram");
1066
1066
  var ChangeTracker = Tag("ChangeTracker");
1067
+ function getPackageJsonInfoCache(program) {
1068
+ try {
1069
+ if (hasProperty(program, "getModuleResolutionCache") && isFunction2(program.getModuleResolutionCache)) {
1070
+ const moduleResolutionCache = program.getModuleResolutionCache();
1071
+ if (hasProperty(moduleResolutionCache, "getPackageJsonInfoCache") && isFunction2(moduleResolutionCache.getPackageJsonInfoCache)) {
1072
+ return moduleResolutionCache.getPackageJsonInfoCache();
1073
+ }
1074
+ }
1075
+ } catch (_) {
1076
+ return void 0;
1077
+ }
1078
+ return void 0;
1079
+ }
1080
+ function getDirectoryPath(ts, path) {
1081
+ try {
1082
+ if (hasProperty(ts, "getDirectoryPath") && isFunction2(ts.getDirectoryPath)) {
1083
+ return ts.getDirectoryPath(path);
1084
+ }
1085
+ return path;
1086
+ } catch (_) {
1087
+ return path;
1088
+ }
1089
+ }
1090
+ function makeGetModuleSpecifier(ts) {
1091
+ if (!(hasProperty(ts, "moduleSpecifiers") && hasProperty(ts.moduleSpecifiers, "getModuleSpecifier") && isFunction2(ts.moduleSpecifiers.getModuleSpecifier))) return;
1092
+ const _internal = ts.moduleSpecifiers.getModuleSpecifier;
1093
+ return (compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, options) => {
1094
+ return _internal(
1095
+ compilerOptions,
1096
+ importingSourceFile,
1097
+ importingSourceFileName,
1098
+ toFileName,
1099
+ host,
1100
+ options
1101
+ );
1102
+ };
1103
+ }
1104
+ function makeGetTemporaryModuleResolutionState(ts) {
1105
+ if (hasProperty(ts, "getTemporaryModuleResolutionState") && isFunction2(ts.getTemporaryModuleResolutionState)) {
1106
+ const _internal = ts.getTemporaryModuleResolutionState;
1107
+ return (cache, program, compilerOptions) => _internal(cache, program, compilerOptions);
1108
+ }
1109
+ return void 0;
1110
+ }
1111
+ function makeGetPackageScopeForPath(ts) {
1112
+ if (hasProperty(ts, "getPackageScopeForPath") && isFunction2(ts.getPackageScopeForPath)) {
1113
+ const _internal = ts.getPackageScopeForPath;
1114
+ return (path, state) => _internal(path, state);
1115
+ }
1116
+ }
1117
+ function makeResolvePackageNameToPackageJson(ts) {
1118
+ if (hasProperty(ts, "resolvePackageNameToPackageJson") && isFunction2(ts.resolvePackageNameToPackageJson)) {
1119
+ const _internal = ts.resolvePackageNameToPackageJson;
1120
+ return (packageName, fromFileName, compilerOptions, host) => _internal(packageName, fromFileName, compilerOptions, host);
1121
+ }
1122
+ }
1123
+ function makeGetEntrypointsFromPackageJsonInfo(ts) {
1124
+ if (hasProperty(ts, "getEntrypointsFromPackageJsonInfo") && isFunction2(ts.getEntrypointsFromPackageJsonInfo)) {
1125
+ const _internal = ts.getEntrypointsFromPackageJsonInfo;
1126
+ return (packageJsonInfo, compilerOptions, host) => _internal(packageJsonInfo, compilerOptions, host);
1127
+ }
1128
+ }
1067
1129
 
1068
1130
  // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/array.js
1069
1131
  var isNonEmptyArray = (self) => self.length > 0;
@@ -1185,6 +1247,8 @@ var nanoLayer = (fa) => pipe(
1185
1247
  flatMap((ts) => pipe(fa, provideService(TypeScriptUtils, makeTypeScriptUtils(ts))))
1186
1248
  );
1187
1249
  function makeTypeScriptUtils(ts) {
1250
+ const getTemporaryModuleResolutionState = makeGetTemporaryModuleResolutionState(ts);
1251
+ const getPackageScopeForPath = makeGetPackageScopeForPath(ts);
1188
1252
  function parsePackageContentNameAndVersionFromScope(v) {
1189
1253
  if (!isObject(v)) return;
1190
1254
  if (!hasProperty(v, "packageJsonScope")) return;
@@ -1219,20 +1283,26 @@ function makeTypeScriptUtils(ts) {
1219
1283
  exportsKeys
1220
1284
  };
1221
1285
  }
1222
- function resolveModulePattern(program, sourceFile, pattern) {
1223
- if (pattern.indexOf("*") === -1) return [pattern.toLowerCase()];
1286
+ function resolveModuleWithPackageInfoFromSourceFile(program, sourceFile) {
1224
1287
  let packageJsonScope = parsePackageContentNameAndVersionFromScope(sourceFile);
1225
- if (!packageJsonScope && hasProperty(ts, "getPackageScopeForPath") && isFunction2(ts.getPackageScopeForPath) && hasProperty(ts, "getTemporaryModuleResolutionState") && isFunction2(ts.getTemporaryModuleResolutionState) && hasProperty(ts, "getPackageScopeForPath") && isFunction2(ts.getPackageScopeForPath)) {
1226
- const temporaryModuleResolutionState = ts.getTemporaryModuleResolutionState(
1227
- void 0,
1288
+ if (!packageJsonScope && getPackageScopeForPath && getTemporaryModuleResolutionState) {
1289
+ const packageJsonInfoCache = getPackageJsonInfoCache(program);
1290
+ const temporaryModuleResolutionState = getTemporaryModuleResolutionState(
1291
+ packageJsonInfoCache,
1228
1292
  program,
1229
1293
  program.getCompilerOptions()
1230
1294
  );
1295
+ const directoryPath = getDirectoryPath(ts, sourceFile.fileName);
1231
1296
  packageJsonScope = parsePackageContentNameAndVersionFromScope({
1232
1297
  ...sourceFile,
1233
- packageJsonScope: ts.getPackageScopeForPath(sourceFile.fileName, temporaryModuleResolutionState)
1298
+ packageJsonScope: getPackageScopeForPath(directoryPath, temporaryModuleResolutionState)
1234
1299
  });
1235
1300
  }
1301
+ return packageJsonScope;
1302
+ }
1303
+ function resolveModulePattern(program, sourceFile, pattern) {
1304
+ if (pattern.indexOf("*") === -1) return [pattern.toLowerCase()];
1305
+ const packageJsonScope = resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
1236
1306
  const referencedPackages = [];
1237
1307
  for (const statement of sourceFile.statements) {
1238
1308
  if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
@@ -1250,20 +1320,6 @@ function makeTypeScriptUtils(ts) {
1250
1320
  )
1251
1321
  );
1252
1322
  }
1253
- function makeGetModuleSpecifier() {
1254
- if (!(hasProperty(ts, "moduleSpecifiers") && hasProperty(ts.moduleSpecifiers, "getModuleSpecifier") && isFunction2(ts.moduleSpecifiers.getModuleSpecifier))) return;
1255
- const _internal = ts.moduleSpecifiers.getModuleSpecifier;
1256
- return (compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, options) => {
1257
- return _internal(
1258
- compilerOptions,
1259
- importingSourceFile,
1260
- importingSourceFileName,
1261
- toFileName,
1262
- host,
1263
- options
1264
- );
1265
- };
1266
- }
1267
1323
  function findNodeWithLeadingCommentAtPosition(sourceFile, position) {
1268
1324
  const sourceText = sourceFile.text;
1269
1325
  let result;
@@ -1652,6 +1708,7 @@ function makeTypeScriptUtils(ts) {
1652
1708
  findNodeAtPositionIncludingTrivia,
1653
1709
  parsePackageContentNameAndVersionFromScope,
1654
1710
  resolveModulePattern,
1711
+ resolveModuleWithPackageInfoFromSourceFile,
1655
1712
  findNodeWithLeadingCommentAtPosition,
1656
1713
  getCommentAtPosition,
1657
1714
  getAncestorNodesInRange,
@@ -1666,7 +1723,6 @@ function makeTypeScriptUtils(ts) {
1666
1723
  parseDataForExtendsClassCompletion,
1667
1724
  createEffectGenCallExpressionWithBlock,
1668
1725
  createReturnYieldStarStatement,
1669
- makeGetModuleSpecifier,
1670
1726
  parseAccessedExpressionForCompletion,
1671
1727
  getSourceFileOfNode
1672
1728
  };
@@ -4143,14 +4199,14 @@ var importFromBarrel = createDiagnostic({
4143
4199
  const tsUtils = yield* service(TypeScriptUtils);
4144
4200
  const typeChecker = yield* service(TypeCheckerApi);
4145
4201
  const program = yield* service(TypeScriptProgram);
4202
+ const getModuleSpecifier = makeGetModuleSpecifier(ts);
4203
+ const resolveExternalModuleName = makeResolveExternalModuleName(typeChecker);
4146
4204
  const packageNamesToCheck = flatten(
4147
4205
  languageServicePluginOptions.namespaceImportPackages.map(
4148
4206
  (packageName) => tsUtils.resolveModulePattern(program, sourceFile, packageName)
4149
4207
  )
4150
4208
  );
4151
4209
  const isImportedFromBarrelExport = (element) => {
4152
- const getModuleSpecifier = tsUtils.makeGetModuleSpecifier();
4153
- const resolveExternalModuleName = makeResolveExternalModuleName(typeChecker);
4154
4210
  if (!(getModuleSpecifier && resolveExternalModuleName)) return;
4155
4211
  const importDeclaration = ts.findAncestor(element, (node) => ts.isImportDeclaration(node));
4156
4212
  if (!importDeclaration) return;
@@ -4585,7 +4641,7 @@ var missingEffectError = createDiagnostic({
4585
4641
  // src/diagnostics/missingEffectServiceDependency.ts
4586
4642
  var missingEffectServiceDependency = createDiagnostic({
4587
4643
  name: "missingEffectServiceDependency",
4588
- code: 21,
4644
+ code: 22,
4589
4645
  severity: "off",
4590
4646
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
4591
4647
  const ts = yield* service(TypeScriptApi);
@@ -4907,6 +4963,96 @@ var multipleEffectProvide = createDiagnostic({
4907
4963
  })
4908
4964
  });
4909
4965
 
4966
+ // src/diagnostics/nonObjectEffectServiceType.ts
4967
+ var nonObjectEffectServiceType = createDiagnostic({
4968
+ name: "nonObjectEffectServiceType",
4969
+ code: 24,
4970
+ severity: "error",
4971
+ apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
4972
+ const ts = yield* service(TypeScriptApi);
4973
+ const typeChecker = yield* service(TypeCheckerApi);
4974
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4975
+ const typeParser = yield* service(TypeParser);
4976
+ function isPrimitiveType(type) {
4977
+ return typeCheckerUtils.unrollUnionMembers(type).some(
4978
+ (type2) => !!(type2.flags & ts.TypeFlags.String || type2.flags & ts.TypeFlags.Number || type2.flags & ts.TypeFlags.Boolean || type2.flags & ts.TypeFlags.StringLiteral || type2.flags & ts.TypeFlags.NumberLiteral || type2.flags & ts.TypeFlags.BooleanLiteral || type2.flags & ts.TypeFlags.Undefined || type2.flags & ts.TypeFlags.Null)
4979
+ );
4980
+ }
4981
+ const nodeToVisit = [];
4982
+ const appendNodeToVisit = (node) => {
4983
+ nodeToVisit.push(node);
4984
+ return void 0;
4985
+ };
4986
+ ts.forEachChild(sourceFile, appendNodeToVisit);
4987
+ while (nodeToVisit.length > 0) {
4988
+ const node = nodeToVisit.shift();
4989
+ if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
4990
+ const serviceResult = yield* pipe(
4991
+ typeParser.extendsEffectService(node),
4992
+ orElse2(() => void_)
4993
+ );
4994
+ if (serviceResult && serviceResult.options && ts.isObjectLiteralExpression(serviceResult.options)) {
4995
+ const options = serviceResult.options;
4996
+ for (const property of options.properties) {
4997
+ if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name)) {
4998
+ continue;
4999
+ }
5000
+ const propertyName = ts.idText(property.name);
5001
+ const propertyValue = property.initializer;
5002
+ const errorToReport = {
5003
+ location: property.name,
5004
+ messageText: "Effect.Service requires the service type to be an object {} and not a primitive type. \nConsider wrapping the value in an object, or manually using Context.Tag or Effect.Tag if you want to use a primitive instead.",
5005
+ fixes: []
5006
+ };
5007
+ if (propertyName === "succeed") {
5008
+ const valueType = typeChecker.getTypeAtLocation(propertyValue);
5009
+ if (isPrimitiveType(valueType)) {
5010
+ report(errorToReport);
5011
+ }
5012
+ } else if (propertyName === "sync") {
5013
+ const valueType = typeChecker.getTypeAtLocation(propertyValue);
5014
+ const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
5015
+ for (const signature of signatures) {
5016
+ const returnType = typeChecker.getReturnTypeOfSignature(signature);
5017
+ if (isPrimitiveType(returnType)) {
5018
+ report(errorToReport);
5019
+ break;
5020
+ }
5021
+ }
5022
+ } else if (propertyName === "effect" || propertyName === "scoped") {
5023
+ const valueType = typeChecker.getTypeAtLocation(propertyValue);
5024
+ const effectResult = yield* pipe(
5025
+ typeParser.effectType(valueType, propertyValue),
5026
+ orElse2(() => void_)
5027
+ );
5028
+ if (effectResult) {
5029
+ if (isPrimitiveType(effectResult.A)) {
5030
+ report(errorToReport);
5031
+ continue;
5032
+ }
5033
+ } else {
5034
+ const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
5035
+ for (const signature of signatures) {
5036
+ const returnType = typeChecker.getReturnTypeOfSignature(signature);
5037
+ const effectReturnResult = yield* pipe(
5038
+ typeParser.effectType(returnType, propertyValue),
5039
+ orElse2(() => void_)
5040
+ );
5041
+ if (effectReturnResult && isPrimitiveType(effectReturnResult.A)) {
5042
+ report(errorToReport);
5043
+ break;
5044
+ }
5045
+ }
5046
+ }
5047
+ }
5048
+ }
5049
+ }
5050
+ }
5051
+ ts.forEachChild(node, appendNodeToVisit);
5052
+ }
5053
+ })
5054
+ });
5055
+
4910
5056
  // src/diagnostics/outdatedEffectCodegen.ts
4911
5057
  var outdatedEffectCodegen = createDiagnostic({
4912
5058
  name: "outdatedEffectCodegen",
@@ -5527,7 +5673,8 @@ var diagnostics = [
5527
5673
  multipleEffectProvide,
5528
5674
  outdatedEffectCodegen,
5529
5675
  overriddenSchemaConstructor,
5530
- unsupportedServiceAccessors
5676
+ unsupportedServiceAccessors,
5677
+ nonObjectEffectServiceType
5531
5678
  ];
5532
5679
 
5533
5680
  // src/completions/effectDiagnosticsComment.ts
@@ -5629,6 +5776,12 @@ var effectSelfInClasses = createCompletion({
5629
5776
  insertText: `${effectIdentifier}.Service<${name}>()("${name}", {${"${0}"}}){}`,
5630
5777
  replacementSpan,
5631
5778
  isSnippet: true
5779
+ }, {
5780
+ name: `Tag("${name}")`,
5781
+ kind: ts.ScriptElementKind.constElement,
5782
+ insertText: `${effectIdentifier}.Tag("${name}")<${name}, {${"${0}"}}>(){}`,
5783
+ replacementSpan,
5784
+ isSnippet: true
5632
5785
  }];
5633
5786
  })
5634
5787
  });
@@ -5799,7 +5952,9 @@ var makeAutoImportProvider = fn("TypeScriptApi")(function* (fromSourceFile) {
5799
5952
  const program = yield* service(TypeScriptProgram);
5800
5953
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
5801
5954
  const host = program;
5802
- const getModuleSpecifier = tsUtils.makeGetModuleSpecifier();
5955
+ const getModuleSpecifier = makeGetModuleSpecifier(ts);
5956
+ const resolvePackageNameToPackageJson = makeResolvePackageNameToPackageJson(ts);
5957
+ const getEntrypointsFromPackageJsonInfo = makeGetEntrypointsFromPackageJsonInfo(ts);
5803
5958
  function collectSourceFileReexports(sourceFile) {
5804
5959
  const namespaceExports = [];
5805
5960
  const namedExports = [];
@@ -5837,14 +5992,15 @@ var makeAutoImportProvider = fn("TypeScriptApi")(function* (fromSourceFile) {
5837
5992
  }
5838
5993
  function getPackageInfo(fromFileName, packageName) {
5839
5994
  try {
5840
- const packageJsonInfo = ts.resolvePackageNameToPackageJson(
5995
+ if (!resolvePackageNameToPackageJson || !getEntrypointsFromPackageJsonInfo) return;
5996
+ const packageJsonInfo = resolvePackageNameToPackageJson(
5841
5997
  packageName,
5842
5998
  fromFileName,
5843
5999
  program.getCompilerOptions(),
5844
6000
  host
5845
6001
  );
5846
6002
  if (!packageJsonInfo) return;
5847
- const _entrypoints = ts.getEntrypointsFromPackageJsonInfo(
6003
+ const _entrypoints = getEntrypointsFromPackageJsonInfo(
5848
6004
  packageJsonInfo,
5849
6005
  program.getCompilerOptions(),
5850
6006
  host