@effect/language-service 0.73.0 → 0.74.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/index.js CHANGED
@@ -4247,7 +4247,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
4247
4247
  const lineOverrides = {};
4248
4248
  const sectionOverrides = {};
4249
4249
  const skippedRules = [];
4250
- const regex = /@effect-diagnostics(-next-line)?((?:\s[a-zA-Z0-9/]+:(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
4250
+ const regex = /@effect-diagnostics(-next-line)?((?:\s(?:[a-zA-Z0-9/]+|\*):(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
4251
4251
  let match3;
4252
4252
  while ((match3 = regex.exec(sourceFile.text)) !== null) {
4253
4253
  const nextLineCaptureGroup = match3[1];
@@ -4296,8 +4296,10 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
4296
4296
  const codeFixes = [];
4297
4297
  const ruleNameLowered = rule.name.toLowerCase();
4298
4298
  const defaultLevel = pluginOptions.diagnosticSeverity[ruleNameLowered] || rule.severity;
4299
- if (skippedRules.indexOf(ruleNameLowered) > -1) return { diagnostics: diagnostics2, codeFixes };
4300
- if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || []).length === 0) {
4299
+ if (skippedRules.indexOf(ruleNameLowered) > -1 || skippedRules.indexOf("*") > -1) {
4300
+ return { diagnostics: diagnostics2, codeFixes };
4301
+ }
4302
+ if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
4301
4303
  return { diagnostics: diagnostics2, codeFixes };
4302
4304
  }
4303
4305
  const fixByDisableNextLine = (node) => ({
@@ -4346,14 +4348,22 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
4346
4348
  const unusedLineOverrides = new Set(lineOverrides[ruleNameLowered] || []);
4347
4349
  for (const emitted of applicableDiagnostics.slice(0)) {
4348
4350
  let newLevel = defaultLevel;
4349
- const lineOverride = (lineOverrides[ruleNameLowered] || []).find(
4351
+ const specificLineOverride = (lineOverrides[ruleNameLowered] || []).find(
4350
4352
  (_) => _.pos < emitted.range.pos && _.end >= emitted.range.end
4351
4353
  );
4354
+ const wildcardLineOverride = (lineOverrides["*"] || []).find(
4355
+ (_) => _.pos < emitted.range.pos && _.end >= emitted.range.end
4356
+ );
4357
+ const lineOverride = specificLineOverride && wildcardLineOverride ? specificLineOverride.pos >= wildcardLineOverride.pos ? specificLineOverride : wildcardLineOverride : specificLineOverride || wildcardLineOverride;
4352
4358
  if (lineOverride) {
4353
4359
  newLevel = lineOverride.level;
4354
4360
  unusedLineOverrides.delete(lineOverride);
4355
4361
  } else {
4356
- const sectionOverride = (sectionOverrides[ruleNameLowered] || []).find((_) => _.pos < emitted.range.pos);
4362
+ const specificSectionOverride = (sectionOverrides[ruleNameLowered] || []).find(
4363
+ (_) => _.pos < emitted.range.pos
4364
+ );
4365
+ const wildcardSectionOverride = (sectionOverrides["*"] || []).find((_) => _.pos < emitted.range.pos);
4366
+ const sectionOverride = specificSectionOverride && wildcardSectionOverride ? specificSectionOverride.pos >= wildcardSectionOverride.pos ? specificSectionOverride : wildcardSectionOverride : specificSectionOverride || wildcardSectionOverride;
4357
4367
  if (sectionOverride) newLevel = sectionOverride.level;
4358
4368
  }
4359
4369
  if (!(newLevel in levelToDiagnosticCategory)) continue;
@@ -5740,6 +5750,28 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5740
5750
  `TypeParser.isNodeReferenceToEffectParseResultModuleApi(${memberName})`,
5741
5751
  (node) => node
5742
5752
  );
5753
+ const isEffectSchemaParserSourceFile = cachedBy(
5754
+ fn("TypeParser.isEffectSchemaParserSourceFile")(function* (sourceFile) {
5755
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
5756
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
5757
+ const parseIssueSymbol = typeChecker.tryGetMemberInModuleExports("Parser", moduleSymbol);
5758
+ if (!parseIssueSymbol) return yield* typeParserIssue("ParseIssue type not found", void 0, sourceFile);
5759
+ const decodeSyncSymbol = typeChecker.tryGetMemberInModuleExports("decodeEffect", moduleSymbol);
5760
+ if (!decodeSyncSymbol) return yield* typeParserIssue("decodeSync not found", void 0, sourceFile);
5761
+ const encodeSyncSymbol = typeChecker.tryGetMemberInModuleExports("encodeEffect", moduleSymbol);
5762
+ if (!encodeSyncSymbol) return yield* typeParserIssue("encodeSync not found", void 0, sourceFile);
5763
+ return sourceFile;
5764
+ }),
5765
+ "TypeParser.isEffectSchemaParserSourceFile",
5766
+ (sourceFile) => sourceFile
5767
+ );
5768
+ const isNodeReferenceToEffectSchemaParserModuleApi = (memberName) => cachedBy(
5769
+ fn("TypeParser.isNodeReferenceToEffectSchemaParserModuleApi")(function* (node) {
5770
+ return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectSchemaParserSourceFile, memberName);
5771
+ }),
5772
+ `TypeParser.isNodeReferenceToEffectSchemaParserModuleApi(${memberName})`,
5773
+ (node) => node
5774
+ );
5743
5775
  const contextTagVarianceStruct = (type, atLocation) => map8(
5744
5776
  all(
5745
5777
  varianceStructInvariantType(type, atLocation, "_Identifier"),
@@ -5747,6 +5779,31 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5747
5779
  ),
5748
5780
  ([Identifier, Service]) => ({ Identifier, Service })
5749
5781
  );
5782
+ const serviceVarianceStruct = (type, atLocation) => map8(
5783
+ all(
5784
+ varianceStructInvariantType(type, atLocation, "_Identifier"),
5785
+ varianceStructInvariantType(type, atLocation, "_Service")
5786
+ ),
5787
+ ([Identifier, Service]) => ({ Identifier, Service })
5788
+ );
5789
+ const serviceType = cachedBy(
5790
+ fn("TypeParser.serviceType")(function* (type, atLocation) {
5791
+ yield* pipeableType(type, atLocation);
5792
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
5793
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
5794
+ );
5795
+ if (propertiesSymbols.length === 0) {
5796
+ return yield* typeParserIssue("Type has no tag variance struct", type, atLocation);
5797
+ }
5798
+ propertiesSymbols.sort((a, b) => ts.symbolName(b).indexOf("TypeId") - ts.symbolName(a).indexOf("TypeId"));
5799
+ return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
5800
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
5801
+ return serviceVarianceStruct(propertyType, atLocation);
5802
+ }));
5803
+ }),
5804
+ "TypeParser.serviceType",
5805
+ (type) => type
5806
+ );
5750
5807
  const contextTag = cachedBy(
5751
5808
  fn("TypeParser.contextTag")(function* (type, atLocation) {
5752
5809
  yield* pipeableType(type, atLocation);
@@ -5828,14 +5885,22 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5828
5885
  );
5829
5886
  const scopeType = cachedBy(
5830
5887
  fn("TypeParser.scopeType")(function* (type, atLocation) {
5831
- yield* pipeableType(type, atLocation);
5832
- const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
5833
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
5834
- );
5835
- if (propertiesSymbols.some((s) => ts.symbolName(s).indexOf("ScopeTypeId") !== -1)) {
5836
- return type;
5888
+ if (supportedEffect() === "v4") {
5889
+ const typeIdSymbol = typeChecker.getPropertyOfType(type, "~effect/Scope");
5890
+ if (typeIdSymbol) {
5891
+ return type;
5892
+ }
5893
+ return yield* typeParserIssue("Type is not an effect", type, atLocation);
5894
+ } else {
5895
+ yield* pipeableType(type, atLocation);
5896
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
5897
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
5898
+ );
5899
+ if (propertiesSymbols.some((s) => ts.symbolName(s).indexOf("ScopeTypeId") !== -1)) {
5900
+ return type;
5901
+ }
5902
+ return yield* typeParserIssue("Type has no scope type id", type, atLocation);
5837
5903
  }
5838
- return yield* typeParserIssue("Type has no scope type id", type, atLocation);
5839
5904
  }),
5840
5905
  "TypeParser.scopeType",
5841
5906
  (type) => type
@@ -6317,6 +6382,55 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6317
6382
  "TypeParser.extendsEffectService",
6318
6383
  (atLocation) => atLocation
6319
6384
  );
6385
+ const extendsServiceMapService = cachedBy(
6386
+ fn("TypeParser.extendsServiceMapService")(function* (atLocation) {
6387
+ if (!atLocation.name) {
6388
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
6389
+ }
6390
+ const heritageClauses = atLocation.heritageClauses;
6391
+ if (!heritageClauses) {
6392
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
6393
+ }
6394
+ for (const heritageClause of heritageClauses) {
6395
+ for (const typeX of heritageClause.types) {
6396
+ if (ts.isExpressionWithTypeArguments(typeX)) {
6397
+ const wholeCall = typeX.expression;
6398
+ if (ts.isCallExpression(wholeCall)) {
6399
+ const serviceMapServiceCall = wholeCall.expression;
6400
+ if (ts.isCallExpression(serviceMapServiceCall) && serviceMapServiceCall.typeArguments && serviceMapServiceCall.typeArguments.length > 0) {
6401
+ const serviceMapServiceIdentifier = serviceMapServiceCall.expression;
6402
+ const selfTypeNode = serviceMapServiceCall.typeArguments[0];
6403
+ const isServiceMapService = yield* pipe(
6404
+ isNodeReferenceToServiceMapModuleApi("Service")(serviceMapServiceIdentifier),
6405
+ orUndefined
6406
+ );
6407
+ if (isServiceMapService) {
6408
+ const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
6409
+ if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
6410
+ const type = typeChecker.getTypeOfSymbol(classSym);
6411
+ const parsedServiceType = yield* pipe(
6412
+ serviceType(type, atLocation),
6413
+ orUndefined
6414
+ );
6415
+ if (parsedServiceType) {
6416
+ return {
6417
+ ...parsedServiceType,
6418
+ className: atLocation.name,
6419
+ selfTypeNode,
6420
+ keyStringLiteral: wholeCall.arguments.length > 0 && ts.isStringLiteral(wholeCall.arguments[0]) ? wholeCall.arguments[0] : void 0
6421
+ };
6422
+ }
6423
+ }
6424
+ }
6425
+ }
6426
+ }
6427
+ }
6428
+ }
6429
+ return yield* typeParserIssue("Class does not extend ServiceMap.Service", void 0, atLocation);
6430
+ }),
6431
+ "TypeParser.extendsServiceMapService",
6432
+ (atLocation) => atLocation
6433
+ );
6320
6434
  const isEffectSqlModelTypeSourceFile = cachedBy(
6321
6435
  fn("TypeParser.isEffectSqlModelTypeSourceFile")(function* (sourceFile) {
6322
6436
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -6409,6 +6523,24 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6409
6523
  `TypeParser.isNodeReferenceToEffectLayerModuleApi(${memberName})`,
6410
6524
  (node) => node
6411
6525
  );
6526
+ const isServiceMapTypeSourceFile = cachedBy(
6527
+ fn("TypeParser.isServiceMapTypeSourceFile")(function* (sourceFile) {
6528
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
6529
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
6530
+ const serviceMapSymbol = typeChecker.tryGetMemberInModuleExports("ServiceMap", moduleSymbol);
6531
+ if (!serviceMapSymbol) return yield* typeParserIssue("ServiceMap not found", void 0, sourceFile);
6532
+ return sourceFile;
6533
+ }),
6534
+ "TypeParser.isServiceMapTypeSourceFile",
6535
+ (sourceFile) => sourceFile
6536
+ );
6537
+ const isNodeReferenceToServiceMapModuleApi = (memberName) => cachedBy(
6538
+ fn("TypeParser.isNodeReferenceToServiceMapModuleApi")(function* (node) {
6539
+ return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isServiceMapTypeSourceFile, memberName);
6540
+ }),
6541
+ `TypeParser.isNodeReferenceToServiceMapModuleApi(${memberName})`,
6542
+ (node) => node
6543
+ );
6412
6544
  const lazyExpression = cachedBy(
6413
6545
  function(node) {
6414
6546
  if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
@@ -6739,6 +6871,9 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6739
6871
  isNodeReferenceToEffectContextModuleApi,
6740
6872
  isNodeReferenceToEffectSqlModelModuleApi,
6741
6873
  isNodeReferenceToEffectLayerModuleApi,
6874
+ isNodeReferenceToEffectSchemaParserModuleApi,
6875
+ isServiceMapTypeSourceFile,
6876
+ isNodeReferenceToServiceMapModuleApi,
6742
6877
  effectType,
6743
6878
  strictEffectType,
6744
6879
  layerType,
@@ -6754,6 +6889,7 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6754
6889
  unnecessaryEffectGen: unnecessaryEffectGen2,
6755
6890
  effectSchemaType,
6756
6891
  contextTag,
6892
+ serviceType,
6757
6893
  pipeableType,
6758
6894
  pipeCall,
6759
6895
  singleArgCall,
@@ -6761,6 +6897,7 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6761
6897
  promiseLike,
6762
6898
  extendsEffectTag,
6763
6899
  extendsEffectService,
6900
+ extendsServiceMapService,
6764
6901
  extendsContextTag,
6765
6902
  extendsSchemaClass,
6766
6903
  extendsSchemaTaggedClass,
@@ -7063,6 +7200,7 @@ var parse2 = fn("writeTagClassAccessors.parse")(function* (node) {
7063
7200
  const typeChecker = yield* service(TypeCheckerApi);
7064
7201
  const typeParser = yield* service(TypeParser);
7065
7202
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
7203
+ if (typeParser.supportedEffect() === "v4") return yield* fail3("not applicable to Effect v4");
7066
7204
  if (!ts.isClassDeclaration(node)) return yield* fail3("not a class declaration");
7067
7205
  const { Service, accessors: accessors2, className, kind } = yield* pipe(
7068
7206
  map8(typeParser.extendsEffectService(node), (_) => ({ kind: "effectService", ..._ })),
@@ -7305,16 +7443,16 @@ var pushHoistedVariableStatement = fn("StructuralSchemaGen.pushHoistedVariableSt
7305
7443
  );
7306
7444
  }
7307
7445
  );
7308
- var createProcessingContext = (maxDepth = 200) => ({
7446
+ var createProcessingContext = (supportedEffect, maxDepth = 200) => ({
7309
7447
  depth: 0,
7310
7448
  maxDepth,
7311
- hoistName: void 0
7449
+ hoistName: void 0,
7450
+ supportedEffect
7312
7451
  });
7313
7452
  var processType = fn(
7314
7453
  "StructuralSchemaGen.processType"
7315
7454
  )(
7316
- function* (type, context) {
7317
- const processingContext = context || createProcessingContext();
7455
+ function* (type, processingContext) {
7318
7456
  const { hoistedSchemas, nameToType, ts, typeChecker, usedGlobalIdentifiers } = yield* service(
7319
7457
  StructuralSchemaGenContext
7320
7458
  );
@@ -7449,7 +7587,7 @@ var processUnionType = fn(
7449
7587
  const allLiterals = types.every(
7450
7588
  (t) => t.flags & ts.TypeFlags.StringLiteral || t.flags & ts.TypeFlags.NumberLiteral || t.flags & ts.TypeFlags.BooleanLiteral
7451
7589
  );
7452
- if (allLiterals) {
7590
+ if (allLiterals && context.supportedEffect !== "v4") {
7453
7591
  const literals = yield* all(
7454
7592
  ...types.map((t) => processType(t, context))
7455
7593
  );
@@ -7459,7 +7597,13 @@ var processUnionType = fn(
7459
7597
  }
7460
7598
  return expr;
7461
7599
  }).filter((arg) => arg !== void 0);
7462
- return [createApiCall("Literal", literalValues), false];
7600
+ return [
7601
+ createApiCall(
7602
+ "Literal",
7603
+ literalValues
7604
+ ),
7605
+ false
7606
+ ];
7463
7607
  }
7464
7608
  const members = yield* all(
7465
7609
  ...types.map((t) => processType(t, context))
@@ -7467,7 +7611,13 @@ var processUnionType = fn(
7467
7611
  if (members.length === 1) {
7468
7612
  return [members[0], false];
7469
7613
  }
7470
- return [createApiCall("Union", members), false];
7614
+ return [
7615
+ createApiCall(
7616
+ "Union",
7617
+ context.supportedEffect === "v4" ? [ts.factory.createArrayLiteralExpression(members)] : members
7618
+ ),
7619
+ false
7620
+ ];
7471
7621
  }
7472
7622
  );
7473
7623
  var processIntersectionType = fn(
@@ -7513,12 +7663,18 @@ var processTupleType = fn(
7513
7663
  "StructuralSchemaGen.processTupleType"
7514
7664
  )(
7515
7665
  function* (type, context) {
7516
- const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
7666
+ const { createApiCall, ts, typeChecker } = yield* service(StructuralSchemaGenContext);
7517
7667
  const typeArgs = typeChecker.getTypeArguments(type);
7518
7668
  const elementSchemas = yield* all(
7519
7669
  ...typeArgs.map((t) => processType(t, context))
7520
7670
  );
7521
- return [createApiCall("Tuple", elementSchemas), false];
7671
+ return [
7672
+ createApiCall(
7673
+ "Tuple",
7674
+ context.supportedEffect === "v4" ? [ts.factory.createArrayLiteralExpression(elementSchemas)] : elementSchemas
7675
+ ),
7676
+ false
7677
+ ];
7522
7678
  }
7523
7679
  );
7524
7680
  var processObjectType = fn(
@@ -7535,7 +7691,6 @@ var processObjectType = fn(
7535
7691
  } = yield* service(
7536
7692
  StructuralSchemaGenContext
7537
7693
  );
7538
- let hasRecords = false;
7539
7694
  const properties = typeChecker.getPropertiesOfType(type);
7540
7695
  const propertyAssignments = [];
7541
7696
  for (const property of properties) {
@@ -7575,20 +7730,28 @@ var processObjectType = fn(
7575
7730
  const args2 = [
7576
7731
  ts.factory.createObjectLiteralExpression(propertyAssignments, propertyAssignments.length > 0)
7577
7732
  ];
7733
+ const records = [];
7578
7734
  for (const indexInfo of indexInfos) {
7579
- hasRecords = true;
7580
7735
  const keyType = indexInfo.keyType;
7581
7736
  const valueType = indexInfo.type;
7582
7737
  const keySchema = yield* processType(keyType, context);
7583
7738
  const valueSchema = yield* processType(valueType, context);
7584
- args2.push(
7585
- ts.factory.createObjectLiteralExpression([
7586
- ts.factory.createPropertyAssignment("key", keySchema),
7587
- ts.factory.createPropertyAssignment("value", valueSchema)
7588
- ])
7589
- );
7739
+ records.push({ key: keySchema, value: valueSchema });
7740
+ }
7741
+ if (context.supportedEffect === "v4") {
7742
+ if (records.length > 0) {
7743
+ return [
7744
+ createApiCall("StructWithRest", [
7745
+ createApiCall("Struct", args2),
7746
+ ts.factory.createArrayLiteralExpression(
7747
+ records.map(({ key, value }) => createApiCall("Record", [key, value]))
7748
+ )
7749
+ ]),
7750
+ propertyAssignments.length === 0
7751
+ ];
7752
+ }
7590
7753
  }
7591
- if (!hasRecords && context.hoistName) {
7754
+ if (records.length === 0 && context.hoistName) {
7592
7755
  const ctx = yield* service(StructuralSchemaGenContext);
7593
7756
  yield* pushHoistedStatement(
7594
7757
  ctx,
@@ -7623,6 +7786,14 @@ var processObjectType = fn(
7623
7786
  );
7624
7787
  return [ctx.hoistedSchemas.get(type)(), true];
7625
7788
  }
7789
+ for (const { key, value } of records) {
7790
+ args2.push(
7791
+ ts.factory.createObjectLiteralExpression([
7792
+ ts.factory.createPropertyAssignment("key", key),
7793
+ ts.factory.createPropertyAssignment("value", value)
7794
+ ])
7795
+ );
7796
+ }
7626
7797
  return [createApiCall("Struct", args2), propertyAssignments.length === 0];
7627
7798
  }
7628
7799
  );
@@ -7708,7 +7879,7 @@ var process = fn("StructuralSchemaGen.process")(
7708
7879
  all(
7709
7880
  ...fromIterable(ctx.nameToType.entries()).map(
7710
7881
  ([name, type]) => pipe(
7711
- processType(type),
7882
+ processType(type, createProcessingContext(typeParser.supportedEffect())),
7712
7883
  orElse2(
7713
7884
  (error) => succeed(ts.addSyntheticLeadingComment(
7714
7885
  ts.factory.createIdentifier(""),
@@ -8367,6 +8538,7 @@ var deterministicKeys = createDiagnostic({
8367
8538
  typeParser.extendsEffectService(node),
8368
8539
  orElse2(() => typeParser.extendsContextTag(node)),
8369
8540
  orElse2(() => typeParser.extendsEffectTag(node)),
8541
+ orElse2(() => typeParser.extendsServiceMapService(node)),
8370
8542
  map8(({ className, keyStringLiteral }) => ({ keyStringLiteral, className, target: "service" }))
8371
8543
  ),
8372
8544
  orElse2(
@@ -9762,6 +9934,9 @@ More info and examples at https://effect.website/docs/requirements-management/la
9762
9934
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "GenericTag") {
9763
9935
  const nodeType = typeCheckerUtils.getTypeAtLocation(node);
9764
9936
  if (nodeType) typesToCheck.push([nodeType, node]);
9937
+ } else if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "Service") {
9938
+ const nodeType = typeCheckerUtils.getTypeAtLocation(node);
9939
+ if (nodeType) typesToCheck.push([nodeType, node]);
9765
9940
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
9766
9941
  const classSym = typeChecker.getSymbolAtLocation(node.name);
9767
9942
  if (classSym) {
@@ -9775,6 +9950,7 @@ More info and examples at https://effect.website/docs/requirements-management/la
9775
9950
  for (const [type, reportAt] of typesToCheck) {
9776
9951
  yield* pipe(
9777
9952
  typeParser.contextTag(type, node),
9953
+ orElse2(() => typeParser.serviceType(type, node)),
9778
9954
  flatMap4(
9779
9955
  ({ Service }) => pipe(
9780
9956
  parseLeakedRequirements(Service, node),
@@ -10549,6 +10725,7 @@ var nonObjectEffectServiceType = createDiagnostic({
10549
10725
  const typeChecker = yield* service(TypeCheckerApi);
10550
10726
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
10551
10727
  const typeParser = yield* service(TypeParser);
10728
+ if (typeParser.supportedEffect() === "v4") return;
10552
10729
  function isPrimitiveType(type) {
10553
10730
  return typeCheckerUtils.unrollUnionMembers(type).some(
10554
10731
  (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)
@@ -11027,6 +11204,7 @@ var runEffectInsideEffect = createDiagnostic({
11027
11204
  const ts = yield* service(TypeScriptApi);
11028
11205
  const typeParser = yield* service(TypeParser);
11029
11206
  const tsUtils = yield* service(TypeScriptUtils);
11207
+ if (typeParser.supportedEffect() === "v4") return;
11030
11208
  const parseEffectMethod = (node, methodName) => pipe(
11031
11209
  typeParser.isNodeReferenceToEffectModuleApi(methodName)(node),
11032
11210
  map8(() => ({ node, methodName }))
@@ -11221,12 +11399,18 @@ var schemaStructWithTag = createDiagnostic({
11221
11399
  });
11222
11400
 
11223
11401
  // src/diagnostics/schemaSyncInEffect.ts
11224
- var syncToEffectMethod = {
11402
+ var syncToEffectMethodV3 = {
11225
11403
  decodeSync: "decode",
11226
11404
  decodeUnknownSync: "decodeUnknown",
11227
11405
  encodeSync: "encode",
11228
11406
  encodeUnknownSync: "encodeUnknown"
11229
11407
  };
11408
+ var syncToEffectMethodV4 = {
11409
+ decodeSync: "decodeEffect",
11410
+ decodeUnknownSync: "decodeUnknownEffect",
11411
+ encodeSync: "encodeEffect",
11412
+ encodeUnknownSync: "encodeUnknownEffect"
11413
+ };
11230
11414
  var schemaSyncInEffect = createDiagnostic({
11231
11415
  name: "schemaSyncInEffect",
11232
11416
  code: 43,
@@ -11235,8 +11419,10 @@ var schemaSyncInEffect = createDiagnostic({
11235
11419
  apply: fn("schemaSyncInEffect.apply")(function* (sourceFile, report) {
11236
11420
  const ts = yield* service(TypeScriptApi);
11237
11421
  const typeParser = yield* service(TypeParser);
11422
+ const syncToEffectMethod = typeParser.supportedEffect() === "v3" ? syncToEffectMethodV3 : syncToEffectMethodV4;
11238
11423
  const parseSchemaSyncMethod = (node, methodName) => pipe(
11239
11424
  typeParser.isNodeReferenceToEffectParseResultModuleApi(methodName)(node),
11425
+ orElse2(() => typeParser.isNodeReferenceToEffectSchemaParserModuleApi(methodName)(node)),
11240
11426
  map8(() => ({ node, methodName }))
11241
11427
  );
11242
11428
  const nodeToVisit = [];
@@ -11266,7 +11452,7 @@ var schemaSyncInEffect = createDiagnostic({
11266
11452
  const effectMethodName = syncToEffectMethod[isSchemaSyncCall.value.methodName];
11267
11453
  report({
11268
11454
  location: node.expression,
11269
- messageText: `Using ${nodeText} inside an Effect generator is not recommended. Use Schema.${effectMethodName} instead to get properly typed ParseError in the error channel.`,
11455
+ messageText: `Using ${nodeText} inside an Effect generator is not recommended. Use Schema.${effectMethodName} instead to get properly typed error channel.`,
11270
11456
  fixes: []
11271
11457
  });
11272
11458
  }
@@ -11282,6 +11468,7 @@ var schemaUnionOfLiterals = createDiagnostic({
11282
11468
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
11283
11469
  const ts = yield* service(TypeScriptApi);
11284
11470
  const typeParser = yield* service(TypeParser);
11471
+ if (typeParser.supportedEffect() === "v4") return;
11285
11472
  const nodeToVisit = [];
11286
11473
  const appendNodeToVisit = (node) => {
11287
11474
  nodeToVisit.push(node);
@@ -19075,7 +19262,7 @@ var _findSchemaVariableDeclaration = fn(
19075
19262
  );
19076
19263
  }
19077
19264
  );
19078
- var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, inferFromName, typeA, opaqueTypeName, typeE, opaqueEncodedName, opaqueContextName) {
19265
+ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, inferFromName, typeA, opaqueTypeName, typeE, opaqueEncodedName, opaqueContextName, isV4, opaqueEncodingServicesName) {
19079
19266
  const ts = yield* service(TypeScriptApi);
19080
19267
  const opaqueInferred = ts.factory.createExpressionWithTypeArguments(
19081
19268
  ts.factory.createPropertyAccessExpression(
@@ -19108,7 +19295,7 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
19108
19295
  ts.factory.createPropertyAccessExpression(
19109
19296
  ts.factory.createPropertyAccessExpression(
19110
19297
  ts.factory.createIdentifier(effectSchemaName),
19111
- ts.factory.createIdentifier("Schema")
19298
+ ts.factory.createIdentifier(isV4 ? "Codec" : "Schema")
19112
19299
  ),
19113
19300
  ts.factory.createIdentifier("Encoded")
19114
19301
  ),
@@ -19135,9 +19322,9 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
19135
19322
  ts.factory.createPropertyAccessExpression(
19136
19323
  ts.factory.createPropertyAccessExpression(
19137
19324
  ts.factory.createIdentifier(effectSchemaName),
19138
- ts.factory.createIdentifier("Schema")
19325
+ ts.factory.createIdentifier(isV4 ? "Codec" : "Schema")
19139
19326
  ),
19140
- ts.factory.createIdentifier("Context")
19327
+ ts.factory.createIdentifier(isV4 ? "DecodingServices" : "Context")
19141
19328
  ),
19142
19329
  [ts.factory.createTypeQueryNode(
19143
19330
  ts.factory.createIdentifier(inferFromName)
@@ -19149,7 +19336,25 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
19149
19336
  [],
19150
19337
  contextInferred
19151
19338
  );
19152
- return { contextType, encodedType, opaqueType };
19339
+ const contextEncodeInferred = ts.factory.createExpressionWithTypeArguments(
19340
+ ts.factory.createPropertyAccessExpression(
19341
+ ts.factory.createPropertyAccessExpression(
19342
+ ts.factory.createIdentifier(effectSchemaName),
19343
+ ts.factory.createIdentifier(isV4 ? "Codec" : "Schema")
19344
+ ),
19345
+ ts.factory.createIdentifier(isV4 ? "EncodingServices" : "Context")
19346
+ ),
19347
+ [ts.factory.createTypeQueryNode(
19348
+ ts.factory.createIdentifier(inferFromName)
19349
+ )]
19350
+ );
19351
+ const contextEncodeType = ts.factory.createTypeAliasDeclaration(
19352
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
19353
+ opaqueEncodingServicesName,
19354
+ [],
19355
+ contextEncodeInferred
19356
+ );
19357
+ return { contextType, contextEncodeType, encodedType, opaqueType };
19153
19358
  });
19154
19359
  var makeSchemaOpaque = createRefactor({
19155
19360
  name: "makeSchemaOpaque",
@@ -19157,6 +19362,8 @@ var makeSchemaOpaque = createRefactor({
19157
19362
  apply: fn("makeSchemaOpaque.apply")(function* (sourceFile, textRange) {
19158
19363
  const ts = yield* service(TypeScriptApi);
19159
19364
  const tsUtils = yield* service(TypeScriptUtils);
19365
+ const typeParser = yield* service(TypeParser);
19366
+ const supportedEffect = typeParser.supportedEffect();
19160
19367
  const maybeNode = yield* _findSchemaVariableDeclaration(sourceFile, textRange);
19161
19368
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
19162
19369
  const { identifier, types, variableDeclarationList, variableStatement } = maybeNode.value;
@@ -19172,14 +19379,16 @@ var makeSchemaOpaque = createRefactor({
19172
19379
  "Schema"
19173
19380
  ) || "Schema";
19174
19381
  const newIdentifier = ts.factory.createIdentifier(ts.idText(identifier) + "_");
19175
- const { contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19382
+ const { contextEncodeType, contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19176
19383
  effectSchemaName,
19177
19384
  ts.idText(newIdentifier),
19178
19385
  types.A,
19179
19386
  ts.idText(identifier),
19180
19387
  types.I,
19181
19388
  ts.idText(identifier) + "Encoded",
19182
- ts.idText(identifier) + "Context"
19389
+ supportedEffect === "v4" ? ts.idText(identifier) + "DecodingServices" : ts.idText(identifier) + "Context",
19390
+ supportedEffect === "v4",
19391
+ supportedEffect === "v4" ? ts.idText(identifier) + "EncodingServices" : ts.idText(identifier) + "Context"
19183
19392
  );
19184
19393
  changeTracker.replaceNode(
19185
19394
  sourceFile,
@@ -19189,16 +19398,19 @@ var makeSchemaOpaque = createRefactor({
19189
19398
  changeTracker.insertNodeAfter(sourceFile, variableStatement, opaqueType);
19190
19399
  changeTracker.insertNodeAfter(sourceFile, variableStatement, encodedType);
19191
19400
  changeTracker.insertNodeAfter(sourceFile, variableStatement, contextType);
19401
+ if (supportedEffect === "v4") {
19402
+ changeTracker.insertNodeAfter(sourceFile, variableStatement, contextEncodeType);
19403
+ }
19192
19404
  const newSchemaType = ts.factory.createTypeReferenceNode(
19193
19405
  ts.factory.createQualifiedName(
19194
19406
  ts.factory.createIdentifier(effectSchemaName),
19195
- ts.factory.createIdentifier("Schema")
19407
+ supportedEffect === "v4" ? ts.factory.createIdentifier("Codec") : ts.factory.createIdentifier("Schema")
19196
19408
  ),
19197
19409
  [
19198
19410
  ts.factory.createTypeReferenceNode(opaqueType.name),
19199
19411
  ts.factory.createTypeReferenceNode(encodedType.name),
19200
19412
  ts.factory.createTypeReferenceNode(contextType.name)
19201
- ]
19413
+ ].concat(supportedEffect === "v4" ? [ts.factory.createTypeReferenceNode(contextEncodeType.name)] : [])
19202
19414
  );
19203
19415
  const newConstDeclaration = ts.factory.createVariableStatement(
19204
19416
  variableStatement.modifiers,
@@ -19228,6 +19440,8 @@ var makeSchemaOpaqueWithNs = createRefactor({
19228
19440
  apply: fn("makeSchemaOpaqueWithNs.apply")(function* (sourceFile, textRange) {
19229
19441
  const ts = yield* service(TypeScriptApi);
19230
19442
  const tsUtils = yield* service(TypeScriptUtils);
19443
+ const typeParser = yield* service(TypeParser);
19444
+ const supportedEffect = typeParser.supportedEffect();
19231
19445
  const maybeNode = yield* _findSchemaVariableDeclaration(sourceFile, textRange);
19232
19446
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
19233
19447
  const { identifier, types, variableDeclarationList, variableStatement } = maybeNode.value;
@@ -19243,14 +19457,16 @@ var makeSchemaOpaqueWithNs = createRefactor({
19243
19457
  "Schema"
19244
19458
  ) || "Schema";
19245
19459
  const newIdentifier = ts.factory.createIdentifier(ts.idText(identifier) + "_");
19246
- const { contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19460
+ const { contextEncodeType, contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19247
19461
  effectSchemaName,
19248
19462
  ts.idText(newIdentifier),
19249
19463
  types.A,
19250
19464
  ts.idText(identifier),
19251
19465
  types.I,
19252
19466
  "Encoded",
19253
- "Context"
19467
+ supportedEffect === "v4" ? "DecodingServices" : "Context",
19468
+ supportedEffect === "v4",
19469
+ supportedEffect === "v4" ? "EncodingServices" : "Context"
19254
19470
  );
19255
19471
  const namespace = ts.factory.createModuleDeclaration(
19256
19472
  [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
@@ -19258,7 +19474,7 @@ var makeSchemaOpaqueWithNs = createRefactor({
19258
19474
  ts.factory.createModuleBlock([
19259
19475
  encodedType,
19260
19476
  contextType
19261
- ]),
19477
+ ].concat(supportedEffect === "v4" ? [contextEncodeType] : [])),
19262
19478
  ts.NodeFlags.Namespace
19263
19479
  );
19264
19480
  changeTracker.replaceNode(
@@ -19732,12 +19948,14 @@ var makeSchemaGenContext = fn("SchemaGen.makeSchemaGenContext")(function* (sourc
19732
19948
  "Schema"
19733
19949
  ) || "Schema";
19734
19950
  const moduleToImportedName = {};
19735
- for (const moduleName of ["Option", "Either", "Chunk", "Duration"]) {
19951
+ for (const moduleName of ["Option", "Either", "Chunk", "Duration", "Result"]) {
19736
19952
  const importedName = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", moduleName);
19737
19953
  if (importedName) moduleToImportedName[moduleName] = importedName;
19738
19954
  }
19739
19955
  const ts = yield* service(TypeScriptApi);
19956
+ const typeParser = yield* service(TypeParser);
19740
19957
  return {
19958
+ supportedEffect: typeParser.supportedEffect(),
19741
19959
  sourceFile,
19742
19960
  createApiPropertyAccess: (apiName) => ts.factory.createPropertyAccessExpression(
19743
19961
  ts.factory.createIdentifier(effectSchemaIdentifier),
@@ -19821,7 +20039,7 @@ var createUnsupportedNodeComment = (ts, sourceFile, node) => ts.addSyntheticTrai
19821
20039
  " Not supported conversion: " + node.getText(sourceFile) + " "
19822
20040
  );
19823
20041
  var processNode = (node, isVirtualTypeNode) => gen(function* () {
19824
- const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, ts } = yield* service(
20042
+ const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, supportedEffect, ts } = yield* service(
19825
20043
  SchemaGenContext
19826
20044
  );
19827
20045
  switch (node.kind) {
@@ -19853,9 +20071,12 @@ var processNode = (node, isVirtualTypeNode) => gen(function* () {
19853
20071
  }
19854
20072
  if (ts.isUnionTypeNode(node)) {
19855
20073
  const allLiterals = yield* option(parseAllLiterals(node));
19856
- if (isSome2(allLiterals)) return createApiCall("Literal", allLiterals.value);
20074
+ if (supportedEffect !== "v4" && isSome2(allLiterals)) return createApiCall("Literal", allLiterals.value);
19857
20075
  const members = yield* all(...node.types.map((_) => processNode(_, isVirtualTypeNode)));
19858
- return createApiCall("Union", members);
20076
+ return createApiCall(
20077
+ "Union",
20078
+ supportedEffect === "v4" ? [ts.factory.createArrayLiteralExpression(members)] : members
20079
+ );
19859
20080
  }
19860
20081
  if (ts.isIntersectionTypeNode(node)) {
19861
20082
  const [firstSchema, ...otherSchemas] = yield* all(
@@ -19930,6 +20151,9 @@ var processNode = (node, isVirtualTypeNode) => gen(function* () {
19930
20151
  ...node.typeArguments ? node.typeArguments.map((_) => processNode(_, isVirtualTypeNode)) : []
19931
20152
  );
19932
20153
  if (elements.length >= 2) {
20154
+ if (supportedEffect === "v4" && elements.length === 2) {
20155
+ return createApiCall("Record", [elements[0], elements[1]]);
20156
+ }
19933
20157
  return createApiCall(parsedName.value, [
19934
20158
  ts.factory.createObjectLiteralExpression([
19935
20159
  ts.factory.createPropertyAssignment("key", elements[0]),
@@ -20164,6 +20388,7 @@ var typeToEffectSchema = createRefactor({
20164
20388
  const tsUtils = yield* service(TypeScriptUtils);
20165
20389
  const typeChecker = yield* service(TypeCheckerApi);
20166
20390
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
20391
+ const typeParser = yield* service(TypeParser);
20167
20392
  const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
20168
20393
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
20169
20394
  const node = maybeNode.value;
@@ -20175,7 +20400,8 @@ var typeToEffectSchema = createRefactor({
20175
20400
  provideService(TypeCheckerApi, typeChecker),
20176
20401
  provideService(TypeScriptUtils, tsUtils),
20177
20402
  provideService(TypeScriptApi, ts),
20178
- provideService(TypeCheckerUtils, typeCheckerUtils)
20403
+ provideService(TypeCheckerUtils, typeCheckerUtils),
20404
+ provideService(TypeParser, typeParser)
20179
20405
  )
20180
20406
  };
20181
20407
  })
@@ -20190,6 +20416,7 @@ var typeToEffectSchemaClass = createRefactor({
20190
20416
  const tsUtils = yield* service(TypeScriptUtils);
20191
20417
  const typeChecker = yield* service(TypeCheckerApi);
20192
20418
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
20419
+ const typeParser = yield* service(TypeParser);
20193
20420
  const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
20194
20421
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
20195
20422
  const node = maybeNode.value;
@@ -20201,7 +20428,8 @@ var typeToEffectSchemaClass = createRefactor({
20201
20428
  provideService(TypeCheckerApi, typeChecker),
20202
20429
  provideService(TypeScriptUtils, tsUtils),
20203
20430
  provideService(TypeScriptApi, ts),
20204
- provideService(TypeCheckerUtils, typeCheckerUtils)
20431
+ provideService(TypeCheckerUtils, typeCheckerUtils),
20432
+ provideService(TypeParser, typeParser)
20205
20433
  )
20206
20434
  };
20207
20435
  })