@effect/language-service 0.45.0 → 0.46.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/language-service",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "A Language-Service Plugin to Refactor and Diagnostic effect-ts projects",
5
5
  "main": "index.cjs",
6
6
  "bin": {
package/transform.js CHANGED
@@ -24,7 +24,7 @@ __export(transform_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(transform_exports);
26
26
 
27
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Function.js
27
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Function.js
28
28
  var isFunction = (input) => typeof input === "function";
29
29
  var dual = function(arity, body) {
30
30
  if (typeof arity === "function") {
@@ -118,7 +118,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
118
118
  }
119
119
  }
120
120
 
121
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/GlobalValue.js
121
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/GlobalValue.js
122
122
  var globalStoreId = `effect/GlobalValue`;
123
123
  var globalStore;
124
124
  var globalValue = (id, compute) => {
@@ -132,7 +132,7 @@ var globalValue = (id, compute) => {
132
132
  return globalStore.get(id);
133
133
  };
134
134
 
135
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Predicate.js
135
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Predicate.js
136
136
  var isString = (input) => typeof input === "string";
137
137
  var isNumber = (input) => typeof input === "number";
138
138
  var isBoolean = (input) => typeof input === "boolean";
@@ -142,7 +142,7 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
142
142
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
143
143
  var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
144
144
 
145
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Utils.js
145
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Utils.js
146
146
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
147
147
  var GenKindImpl = class {
148
148
  value;
@@ -264,7 +264,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
264
264
  var genConstructor = function* () {
265
265
  }.constructor;
266
266
 
267
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Hash.js
267
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Hash.js
268
268
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
269
269
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
270
270
  var hash = (self) => {
@@ -363,7 +363,7 @@ var cached = function() {
363
363
  return hash2;
364
364
  };
365
365
 
366
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Equal.js
366
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Equal.js
367
367
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
368
368
  function equals() {
369
369
  if (arguments.length === 1) {
@@ -417,7 +417,7 @@ function compareBoth(self, that) {
417
417
  var isEqual = (u) => hasProperty(u, symbol2);
418
418
  var equivalence = () => equals;
419
419
 
420
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Inspectable.js
420
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Inspectable.js
421
421
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
422
422
  var toJSON = (x) => {
423
423
  try {
@@ -469,7 +469,7 @@ var redact = (u) => {
469
469
  return u;
470
470
  };
471
471
 
472
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Pipeable.js
472
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Pipeable.js
473
473
  var pipeArguments = (self, args2) => {
474
474
  switch (args2.length) {
475
475
  case 0:
@@ -502,14 +502,14 @@ var pipeArguments = (self, args2) => {
502
502
  }
503
503
  };
504
504
 
505
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/opCodes/effect.js
505
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/internal/opCodes/effect.js
506
506
  var OP_COMMIT = "Commit";
507
507
 
508
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/version.js
509
- var moduleVersion = "3.17.8";
508
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/internal/version.js
509
+ var moduleVersion = "3.18.4";
510
510
  var getCurrentVersion = () => moduleVersion;
511
511
 
512
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/effectable.js
512
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/internal/effectable.js
513
513
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
514
514
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
515
515
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -596,7 +596,7 @@ var StructuralCommitPrototype = {
596
596
  ...StructuralPrototype
597
597
  };
598
598
 
599
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/option.js
599
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/internal/option.js
600
600
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
601
601
  var CommonProto = {
602
602
  ...EffectPrototype,
@@ -654,7 +654,7 @@ var some = (value) => {
654
654
  return a;
655
655
  };
656
656
 
657
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/either.js
657
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/internal/either.js
658
658
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
659
659
  var CommonProto2 = {
660
660
  ...EffectPrototype,
@@ -716,7 +716,7 @@ var right = (right3) => {
716
716
  return a;
717
717
  };
718
718
 
719
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Either.js
719
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Either.js
720
720
  var right2 = right;
721
721
  var left2 = left;
722
722
  var isLeft2 = isLeft;
@@ -724,14 +724,14 @@ var isRight2 = isRight;
724
724
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
725
725
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
726
726
 
727
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/internal/array.js
727
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/internal/array.js
728
728
  var isNonEmptyArray = (self) => self.length > 0;
729
729
 
730
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Order.js
730
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Order.js
731
731
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
732
732
  var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
733
733
 
734
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Option.js
734
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Option.js
735
735
  var none2 = () => none;
736
736
  var some2 = some;
737
737
  var isNone2 = isNone;
@@ -739,7 +739,7 @@ var isSome2 = isSome;
739
739
  var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
740
740
  var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
741
741
 
742
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Record.js
742
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Record.js
743
743
  var map2 = /* @__PURE__ */ dual(2, (self, f) => {
744
744
  const out = {
745
745
  ...self
@@ -751,7 +751,7 @@ var map2 = /* @__PURE__ */ dual(2, (self, f) => {
751
751
  });
752
752
  var keys = (self) => Object.keys(self);
753
753
 
754
- // node_modules/.pnpm/effect@3.17.8/node_modules/effect/dist/esm/Array.js
754
+ // node_modules/.pnpm/effect@3.18.4/node_modules/effect/dist/esm/Array.js
755
755
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
756
756
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
757
757
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
@@ -1160,6 +1160,9 @@ var all = fn("all")(
1160
1160
 
1161
1161
  // src/core/LanguageServicePluginOptions.ts
1162
1162
  var LanguageServicePluginOptions = Tag("PluginOptions");
1163
+ function isValidSeverityLevel(value) {
1164
+ return value === "off" || value === "error" || value === "warning" || value === "message" || value === "suggestion";
1165
+ }
1163
1166
  function parseDiagnosticSeverity(config) {
1164
1167
  if (!isRecord(config)) return {};
1165
1168
  return Object.fromEntries(
@@ -1167,9 +1170,7 @@ function parseDiagnosticSeverity(config) {
1167
1170
  Object.entries(config),
1168
1171
  filter(([key, value]) => isString(key) && isString(value)),
1169
1172
  map3(([key, value]) => [String(key).toLowerCase(), String(value).toLowerCase()]),
1170
- filter(
1171
- ([_, value]) => value === "off" || value === "error" || value === "warning" || value === "message" || value === "suggestion"
1172
- )
1173
+ filter(([_, value]) => isValidSeverityLevel(value))
1173
1174
  )
1174
1175
  );
1175
1176
  }
@@ -1178,6 +1179,7 @@ var defaults = {
1178
1179
  diagnostics: true,
1179
1180
  diagnosticSeverity: {},
1180
1181
  diagnosticsName: true,
1182
+ missingDiagnosticNextLine: "warning",
1181
1183
  quickinfo: true,
1182
1184
  quickinfoEffectParameters: "whentruncated",
1183
1185
  quickinfoMaximumLength: -1,
@@ -1220,6 +1222,7 @@ function parse(config) {
1220
1222
  diagnostics: isObject(config) && hasProperty(config, "diagnostics") && isBoolean(config.diagnostics) ? config.diagnostics : defaults.diagnostics,
1221
1223
  diagnosticSeverity: isObject(config) && hasProperty(config, "diagnosticSeverity") && isRecord(config.diagnosticSeverity) ? parseDiagnosticSeverity(config.diagnosticSeverity) : defaults.diagnosticSeverity,
1222
1224
  diagnosticsName: isObject(config) && hasProperty(config, "diagnosticsName") && isBoolean(config.diagnosticsName) ? config.diagnosticsName : defaults.diagnosticsName,
1225
+ missingDiagnosticNextLine: isObject(config) && hasProperty(config, "missingDiagnosticNextLine") && isString(config.missingDiagnosticNextLine) && isValidSeverityLevel(config.missingDiagnosticNextLine) ? config.missingDiagnosticNextLine : defaults.missingDiagnosticNextLine,
1223
1226
  quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
1224
1227
  quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
1225
1228
  quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
@@ -1893,7 +1896,8 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1893
1896
  lineOverrides[ruleName].unshift({
1894
1897
  pos: foundNode.node.pos,
1895
1898
  end: foundNode.node.end,
1896
- level: ruleLevel
1899
+ level: ruleLevel,
1900
+ commentRange: foundNode.commentRange
1897
1901
  });
1898
1902
  }
1899
1903
  } else {
@@ -1966,6 +1970,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1966
1970
  fixes: entry.fixes.concat(node ? [fixByDisableNextLine(node)] : []).concat([fixByDisableEntireFile])
1967
1971
  });
1968
1972
  });
1973
+ const unusedLineOverrides = new Set(lineOverrides[ruleNameLowered] || []);
1969
1974
  for (const emitted of applicableDiagnostics.slice(0)) {
1970
1975
  let newLevel = defaultLevel;
1971
1976
  const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
@@ -1973,6 +1978,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1973
1978
  );
1974
1979
  if (lineOverride) {
1975
1980
  newLevel = lineOverride.level;
1981
+ unusedLineOverrides.delete(lineOverride);
1976
1982
  } else {
1977
1983
  const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find((_) => _.pos < emitted.range.pos);
1978
1984
  if (sectionOverride) newLevel = sectionOverride.level;
@@ -1996,6 +2002,19 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1996
2002
  });
1997
2003
  }
1998
2004
  }
2005
+ if (pluginOptions.missingDiagnosticNextLine !== "off" && unusedLineOverrides.size > 0) {
2006
+ for (const unusedLineOverride of unusedLineOverrides) {
2007
+ diagnostics2.push({
2008
+ file: sourceFile,
2009
+ start: unusedLineOverride.commentRange.pos,
2010
+ length: unusedLineOverride.commentRange.end - unusedLineOverride.commentRange.pos,
2011
+ messageText: `@effect-diagnostics-next-line ${rule.name}:${unusedLineOverride.level} has no effect, make sure you are suppressing the right rule.`,
2012
+ category: levelToDiagnosticCategory[pluginOptions.missingDiagnosticNextLine],
2013
+ code: -1,
2014
+ source: "effect"
2015
+ });
2016
+ }
2017
+ }
1999
2018
  return { diagnostics: diagnostics2, codeFixes };
2000
2019
  });
2001
2020
  return { execute };
@@ -4044,6 +4063,7 @@ var leakingRequirements = createDiagnostic({
4044
4063
  const typeChecker = yield* service(TypeCheckerApi);
4045
4064
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
4046
4065
  const typeParser = yield* service(TypeParser);
4066
+ const tsUtils = yield* service(TypeScriptUtils);
4047
4067
  const parseLeakedRequirements = cachedBy(
4048
4068
  fn("leakingServices.checkServiceLeaking")(
4049
4069
  function* (service2, atLocation) {
@@ -4101,7 +4121,21 @@ var leakingRequirements = createDiagnostic({
4101
4121
  }
4102
4122
  }
4103
4123
  if (sharedRequirementsKeys && sharedRequirementsKeys.length > 0 && effectMembers >= 2) {
4104
- return sharedRequirementsKeys.map((key) => memory.get(key));
4124
+ return sharedRequirementsKeys.map((key) => memory.get(key)).filter(
4125
+ (type) => {
4126
+ let symbol3 = type.symbol;
4127
+ if (symbol3 && symbol3.flags & ts.SymbolFlags.Alias) {
4128
+ symbol3 = typeChecker.getAliasedSymbol(symbol3);
4129
+ }
4130
+ return !(symbol3.declarations || []).some((declaration) => {
4131
+ const declarationSource = tsUtils.getSourceFileOfNode(declaration);
4132
+ if (!declarationSource) return false;
4133
+ return declarationSource.text.substring(declaration.pos, declaration.end).toLowerCase().indexOf(
4134
+ "@effect-leakable-service"
4135
+ ) > -1;
4136
+ });
4137
+ }
4138
+ );
4105
4139
  }
4106
4140
  return [];
4107
4141
  }
@@ -4114,7 +4148,7 @@ var leakingRequirements = createDiagnostic({
4114
4148
  report({
4115
4149
  location: node,
4116
4150
  messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement.
4117
- If these requirements cannot be cached and are expected to be provided per method invocation (e.g. HttpServerRequest), you can safely disable this diagnostic for this line through quickfixes.
4151
+ If these requirements cannot be cached and are expected to be provided per method invocation (e.g. HttpServerRequest), you can either safely disable this diagnostic for this line through quickfixes or mark the service declaration with a JSDoc @effect-leakable-service.
4118
4152
  More info at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage`,
4119
4153
  fixes: []
4120
4154
  });
@@ -5140,17 +5174,67 @@ var overriddenSchemaConstructor = createDiagnostic({
5140
5174
  const members = node.members;
5141
5175
  for (const member of members) {
5142
5176
  if (ts.isConstructorDeclaration(member)) {
5177
+ const fixAsStaticNew = {
5178
+ fixName: "overriddenSchemaConstructor_static",
5179
+ description: "Rewrite using the static 'new' pattern",
5180
+ apply: gen(function* () {
5181
+ const changeTracker = yield* service(ChangeTracker);
5182
+ const visitor = (node2) => {
5183
+ if (ts.isExpressionStatement(node2) && ts.isCallExpression(node2.expression) && ts.isToken(node2.expression.expression) && node2.expression.expression.kind === ts.SyntaxKind.SuperKeyword) {
5184
+ const constructThis = ts.factory.createNewExpression(
5185
+ ts.factory.createIdentifier("this"),
5186
+ void 0,
5187
+ node2.expression.arguments
5188
+ );
5189
+ return ts.factory.createVariableStatement(
5190
+ void 0,
5191
+ ts.factory.createVariableDeclarationList(
5192
+ [ts.factory.createVariableDeclaration(
5193
+ "_this",
5194
+ void 0,
5195
+ void 0,
5196
+ constructThis
5197
+ )],
5198
+ ts.NodeFlags.Const
5199
+ )
5200
+ );
5201
+ }
5202
+ if (ts.isToken(node2) && node2.kind === ts.SyntaxKind.ThisKeyword) {
5203
+ return ts.factory.createIdentifier("_this");
5204
+ }
5205
+ return ts.visitEachChild(node2, visitor, ts.nullTransformationContext);
5206
+ };
5207
+ const newBody = visitor(member.body);
5208
+ const bodyWithReturn = ts.factory.updateBlock(
5209
+ newBody,
5210
+ newBody.statements.concat([
5211
+ ts.factory.createReturnStatement(ts.factory.createIdentifier("_this"))
5212
+ ])
5213
+ );
5214
+ const newMethod = ts.factory.createMethodDeclaration(
5215
+ ts.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Public | ts.ModifierFlags.Static),
5216
+ void 0,
5217
+ "new",
5218
+ void 0,
5219
+ member.typeParameters,
5220
+ member.parameters,
5221
+ member.type,
5222
+ bodyWithReturn
5223
+ );
5224
+ changeTracker.replaceNode(sourceFile, member, newMethod);
5225
+ })
5226
+ };
5143
5227
  report({
5144
5228
  location: member,
5145
- messageText: "Classes extending Schema must not override the constructor",
5146
- fixes: [{
5229
+ messageText: "Classes extending Schema must not override the constructor; this is because it silently breaks the schema decoding behaviour. If that's needed, we recommend instead to use a static 'new' method that constructs the instance.",
5230
+ fixes: (member.body ? [fixAsStaticNew] : []).concat([{
5147
5231
  fixName: "overriddenSchemaConstructor_fix",
5148
5232
  description: "Remove the constructor override",
5149
5233
  apply: gen(function* () {
5150
5234
  const changeTracker = yield* service(ChangeTracker);
5151
5235
  changeTracker.delete(sourceFile, member);
5152
5236
  })
5153
- }]
5237
+ }])
5154
5238
  });
5155
5239
  break;
5156
5240
  }