@effect/language-service 0.73.1 → 0.75.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
@@ -5750,6 +5750,28 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5750
5750
  `TypeParser.isNodeReferenceToEffectParseResultModuleApi(${memberName})`,
5751
5751
  (node) => node
5752
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
+ );
5753
5775
  const contextTagVarianceStruct = (type, atLocation) => map8(
5754
5776
  all(
5755
5777
  varianceStructInvariantType(type, atLocation, "_Identifier"),
@@ -5757,6 +5779,31 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5757
5779
  ),
5758
5780
  ([Identifier, Service]) => ({ Identifier, Service })
5759
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
+ );
5760
5807
  const contextTag = cachedBy(
5761
5808
  fn("TypeParser.contextTag")(function* (type, atLocation) {
5762
5809
  yield* pipeableType(type, atLocation);
@@ -5838,14 +5885,22 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5838
5885
  );
5839
5886
  const scopeType = cachedBy(
5840
5887
  fn("TypeParser.scopeType")(function* (type, atLocation) {
5841
- yield* pipeableType(type, atLocation);
5842
- const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
5843
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
5844
- );
5845
- if (propertiesSymbols.some((s) => ts.symbolName(s).indexOf("ScopeTypeId") !== -1)) {
5846
- 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);
5847
5903
  }
5848
- return yield* typeParserIssue("Type has no scope type id", type, atLocation);
5849
5904
  }),
5850
5905
  "TypeParser.scopeType",
5851
5906
  (type) => type
@@ -6327,6 +6382,55 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6327
6382
  "TypeParser.extendsEffectService",
6328
6383
  (atLocation) => atLocation
6329
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
+ );
6330
6434
  const isEffectSqlModelTypeSourceFile = cachedBy(
6331
6435
  fn("TypeParser.isEffectSqlModelTypeSourceFile")(function* (sourceFile) {
6332
6436
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -6419,6 +6523,24 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6419
6523
  `TypeParser.isNodeReferenceToEffectLayerModuleApi(${memberName})`,
6420
6524
  (node) => node
6421
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
+ );
6422
6544
  const lazyExpression = cachedBy(
6423
6545
  function(node) {
6424
6546
  if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
@@ -6749,6 +6871,9 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6749
6871
  isNodeReferenceToEffectContextModuleApi,
6750
6872
  isNodeReferenceToEffectSqlModelModuleApi,
6751
6873
  isNodeReferenceToEffectLayerModuleApi,
6874
+ isNodeReferenceToEffectSchemaParserModuleApi,
6875
+ isServiceMapTypeSourceFile,
6876
+ isNodeReferenceToServiceMapModuleApi,
6752
6877
  effectType,
6753
6878
  strictEffectType,
6754
6879
  layerType,
@@ -6764,6 +6889,7 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6764
6889
  unnecessaryEffectGen: unnecessaryEffectGen2,
6765
6890
  effectSchemaType,
6766
6891
  contextTag,
6892
+ serviceType,
6767
6893
  pipeableType,
6768
6894
  pipeCall,
6769
6895
  singleArgCall,
@@ -6771,6 +6897,7 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6771
6897
  promiseLike,
6772
6898
  extendsEffectTag,
6773
6899
  extendsEffectService,
6900
+ extendsServiceMapService,
6774
6901
  extendsContextTag,
6775
6902
  extendsSchemaClass,
6776
6903
  extendsSchemaTaggedClass,
@@ -7073,6 +7200,7 @@ var parse2 = fn("writeTagClassAccessors.parse")(function* (node) {
7073
7200
  const typeChecker = yield* service(TypeCheckerApi);
7074
7201
  const typeParser = yield* service(TypeParser);
7075
7202
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
7203
+ if (typeParser.supportedEffect() === "v4") return yield* fail3("not applicable to Effect v4");
7076
7204
  if (!ts.isClassDeclaration(node)) return yield* fail3("not a class declaration");
7077
7205
  const { Service, accessors: accessors2, className, kind } = yield* pipe(
7078
7206
  map8(typeParser.extendsEffectService(node), (_) => ({ kind: "effectService", ..._ })),
@@ -7315,16 +7443,16 @@ var pushHoistedVariableStatement = fn("StructuralSchemaGen.pushHoistedVariableSt
7315
7443
  );
7316
7444
  }
7317
7445
  );
7318
- var createProcessingContext = (maxDepth = 200) => ({
7446
+ var createProcessingContext = (supportedEffect, maxDepth = 200) => ({
7319
7447
  depth: 0,
7320
7448
  maxDepth,
7321
- hoistName: void 0
7449
+ hoistName: void 0,
7450
+ supportedEffect
7322
7451
  });
7323
7452
  var processType = fn(
7324
7453
  "StructuralSchemaGen.processType"
7325
7454
  )(
7326
- function* (type, context) {
7327
- const processingContext = context || createProcessingContext();
7455
+ function* (type, processingContext) {
7328
7456
  const { hoistedSchemas, nameToType, ts, typeChecker, usedGlobalIdentifiers } = yield* service(
7329
7457
  StructuralSchemaGenContext
7330
7458
  );
@@ -7459,7 +7587,7 @@ var processUnionType = fn(
7459
7587
  const allLiterals = types.every(
7460
7588
  (t) => t.flags & ts.TypeFlags.StringLiteral || t.flags & ts.TypeFlags.NumberLiteral || t.flags & ts.TypeFlags.BooleanLiteral
7461
7589
  );
7462
- if (allLiterals) {
7590
+ if (allLiterals && context.supportedEffect !== "v4") {
7463
7591
  const literals = yield* all(
7464
7592
  ...types.map((t) => processType(t, context))
7465
7593
  );
@@ -7469,7 +7597,13 @@ var processUnionType = fn(
7469
7597
  }
7470
7598
  return expr;
7471
7599
  }).filter((arg) => arg !== void 0);
7472
- return [createApiCall("Literal", literalValues), false];
7600
+ return [
7601
+ createApiCall(
7602
+ "Literal",
7603
+ literalValues
7604
+ ),
7605
+ false
7606
+ ];
7473
7607
  }
7474
7608
  const members = yield* all(
7475
7609
  ...types.map((t) => processType(t, context))
@@ -7477,7 +7611,13 @@ var processUnionType = fn(
7477
7611
  if (members.length === 1) {
7478
7612
  return [members[0], false];
7479
7613
  }
7480
- return [createApiCall("Union", members), false];
7614
+ return [
7615
+ createApiCall(
7616
+ "Union",
7617
+ context.supportedEffect === "v4" ? [ts.factory.createArrayLiteralExpression(members)] : members
7618
+ ),
7619
+ false
7620
+ ];
7481
7621
  }
7482
7622
  );
7483
7623
  var processIntersectionType = fn(
@@ -7523,12 +7663,18 @@ var processTupleType = fn(
7523
7663
  "StructuralSchemaGen.processTupleType"
7524
7664
  )(
7525
7665
  function* (type, context) {
7526
- const { createApiCall, typeChecker } = yield* service(StructuralSchemaGenContext);
7666
+ const { createApiCall, ts, typeChecker } = yield* service(StructuralSchemaGenContext);
7527
7667
  const typeArgs = typeChecker.getTypeArguments(type);
7528
7668
  const elementSchemas = yield* all(
7529
7669
  ...typeArgs.map((t) => processType(t, context))
7530
7670
  );
7531
- return [createApiCall("Tuple", elementSchemas), false];
7671
+ return [
7672
+ createApiCall(
7673
+ "Tuple",
7674
+ context.supportedEffect === "v4" ? [ts.factory.createArrayLiteralExpression(elementSchemas)] : elementSchemas
7675
+ ),
7676
+ false
7677
+ ];
7532
7678
  }
7533
7679
  );
7534
7680
  var processObjectType = fn(
@@ -7545,7 +7691,6 @@ var processObjectType = fn(
7545
7691
  } = yield* service(
7546
7692
  StructuralSchemaGenContext
7547
7693
  );
7548
- let hasRecords = false;
7549
7694
  const properties = typeChecker.getPropertiesOfType(type);
7550
7695
  const propertyAssignments = [];
7551
7696
  for (const property of properties) {
@@ -7585,20 +7730,28 @@ var processObjectType = fn(
7585
7730
  const args2 = [
7586
7731
  ts.factory.createObjectLiteralExpression(propertyAssignments, propertyAssignments.length > 0)
7587
7732
  ];
7733
+ const records = [];
7588
7734
  for (const indexInfo of indexInfos) {
7589
- hasRecords = true;
7590
7735
  const keyType = indexInfo.keyType;
7591
7736
  const valueType = indexInfo.type;
7592
7737
  const keySchema = yield* processType(keyType, context);
7593
7738
  const valueSchema = yield* processType(valueType, context);
7594
- args2.push(
7595
- ts.factory.createObjectLiteralExpression([
7596
- ts.factory.createPropertyAssignment("key", keySchema),
7597
- ts.factory.createPropertyAssignment("value", valueSchema)
7598
- ])
7599
- );
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
+ }
7600
7753
  }
7601
- if (!hasRecords && context.hoistName) {
7754
+ if (records.length === 0 && context.hoistName) {
7602
7755
  const ctx = yield* service(StructuralSchemaGenContext);
7603
7756
  yield* pushHoistedStatement(
7604
7757
  ctx,
@@ -7633,6 +7786,14 @@ var processObjectType = fn(
7633
7786
  );
7634
7787
  return [ctx.hoistedSchemas.get(type)(), true];
7635
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
+ }
7636
7797
  return [createApiCall("Struct", args2), propertyAssignments.length === 0];
7637
7798
  }
7638
7799
  );
@@ -7718,7 +7879,7 @@ var process = fn("StructuralSchemaGen.process")(
7718
7879
  all(
7719
7880
  ...fromIterable(ctx.nameToType.entries()).map(
7720
7881
  ([name, type]) => pipe(
7721
- processType(type),
7882
+ processType(type, createProcessingContext(typeParser.supportedEffect())),
7722
7883
  orElse2(
7723
7884
  (error) => succeed(ts.addSyntheticLeadingComment(
7724
7885
  ts.factory.createIdentifier(""),
@@ -8377,6 +8538,7 @@ var deterministicKeys = createDiagnostic({
8377
8538
  typeParser.extendsEffectService(node),
8378
8539
  orElse2(() => typeParser.extendsContextTag(node)),
8379
8540
  orElse2(() => typeParser.extendsEffectTag(node)),
8541
+ orElse2(() => typeParser.extendsServiceMapService(node)),
8380
8542
  map8(({ className, keyStringLiteral }) => ({ keyStringLiteral, className, target: "service" }))
8381
8543
  ),
8382
8544
  orElse2(
@@ -9772,6 +9934,9 @@ More info and examples at https://effect.website/docs/requirements-management/la
9772
9934
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "GenericTag") {
9773
9935
  const nodeType = typeCheckerUtils.getTypeAtLocation(node);
9774
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]);
9775
9940
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
9776
9941
  const classSym = typeChecker.getSymbolAtLocation(node.name);
9777
9942
  if (classSym) {
@@ -9785,6 +9950,7 @@ More info and examples at https://effect.website/docs/requirements-management/la
9785
9950
  for (const [type, reportAt] of typesToCheck) {
9786
9951
  yield* pipe(
9787
9952
  typeParser.contextTag(type, node),
9953
+ orElse2(() => typeParser.serviceType(type, node)),
9788
9954
  flatMap4(
9789
9955
  ({ Service }) => pipe(
9790
9956
  parseLeakedRequirements(Service, node),
@@ -10559,6 +10725,7 @@ var nonObjectEffectServiceType = createDiagnostic({
10559
10725
  const typeChecker = yield* service(TypeCheckerApi);
10560
10726
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
10561
10727
  const typeParser = yield* service(TypeParser);
10728
+ if (typeParser.supportedEffect() === "v4") return;
10562
10729
  function isPrimitiveType(type) {
10563
10730
  return typeCheckerUtils.unrollUnionMembers(type).some(
10564
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)
@@ -11037,6 +11204,7 @@ var runEffectInsideEffect = createDiagnostic({
11037
11204
  const ts = yield* service(TypeScriptApi);
11038
11205
  const typeParser = yield* service(TypeParser);
11039
11206
  const tsUtils = yield* service(TypeScriptUtils);
11207
+ if (typeParser.supportedEffect() === "v4") return;
11040
11208
  const parseEffectMethod = (node, methodName) => pipe(
11041
11209
  typeParser.isNodeReferenceToEffectModuleApi(methodName)(node),
11042
11210
  map8(() => ({ node, methodName }))
@@ -11231,12 +11399,18 @@ var schemaStructWithTag = createDiagnostic({
11231
11399
  });
11232
11400
 
11233
11401
  // src/diagnostics/schemaSyncInEffect.ts
11234
- var syncToEffectMethod = {
11402
+ var syncToEffectMethodV3 = {
11235
11403
  decodeSync: "decode",
11236
11404
  decodeUnknownSync: "decodeUnknown",
11237
11405
  encodeSync: "encode",
11238
11406
  encodeUnknownSync: "encodeUnknown"
11239
11407
  };
11408
+ var syncToEffectMethodV4 = {
11409
+ decodeSync: "decodeEffect",
11410
+ decodeUnknownSync: "decodeUnknownEffect",
11411
+ encodeSync: "encodeEffect",
11412
+ encodeUnknownSync: "encodeUnknownEffect"
11413
+ };
11240
11414
  var schemaSyncInEffect = createDiagnostic({
11241
11415
  name: "schemaSyncInEffect",
11242
11416
  code: 43,
@@ -11245,8 +11419,10 @@ var schemaSyncInEffect = createDiagnostic({
11245
11419
  apply: fn("schemaSyncInEffect.apply")(function* (sourceFile, report) {
11246
11420
  const ts = yield* service(TypeScriptApi);
11247
11421
  const typeParser = yield* service(TypeParser);
11422
+ const syncToEffectMethod = typeParser.supportedEffect() === "v3" ? syncToEffectMethodV3 : syncToEffectMethodV4;
11248
11423
  const parseSchemaSyncMethod = (node, methodName) => pipe(
11249
11424
  typeParser.isNodeReferenceToEffectParseResultModuleApi(methodName)(node),
11425
+ orElse2(() => typeParser.isNodeReferenceToEffectSchemaParserModuleApi(methodName)(node)),
11250
11426
  map8(() => ({ node, methodName }))
11251
11427
  );
11252
11428
  const nodeToVisit = [];
@@ -11276,7 +11452,7 @@ var schemaSyncInEffect = createDiagnostic({
11276
11452
  const effectMethodName = syncToEffectMethod[isSchemaSyncCall.value.methodName];
11277
11453
  report({
11278
11454
  location: node.expression,
11279
- 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.`,
11280
11456
  fixes: []
11281
11457
  });
11282
11458
  }
@@ -11292,6 +11468,7 @@ var schemaUnionOfLiterals = createDiagnostic({
11292
11468
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
11293
11469
  const ts = yield* service(TypeScriptApi);
11294
11470
  const typeParser = yield* service(TypeParser);
11471
+ if (typeParser.supportedEffect() === "v4") return;
11295
11472
  const nodeToVisit = [];
11296
11473
  const appendNodeToVisit = (node) => {
11297
11474
  nodeToVisit.push(node);
@@ -12129,23 +12306,38 @@ var effectSchemaSelfInClasses = createCompletion({
12129
12306
  });
12130
12307
  }
12131
12308
  }
12132
- if (typeParser.supportedEffect() === "v3") {
12133
- const hasTaggedClassCompletion = isFullyQualified || isSome2(
12309
+ if (typeParser.supportedEffect() === "v4") {
12310
+ const hasTaggedErrorCompletion = isFullyQualified || isSome2(
12134
12311
  yield* pipe(
12135
- typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(accessedObject),
12312
+ typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedErrorClass")(accessedObject),
12136
12313
  option
12137
12314
  )
12138
12315
  );
12139
- if (hasTaggedClassCompletion) {
12316
+ if (hasTaggedErrorCompletion) {
12140
12317
  completions2.push({
12141
- name: `TaggedClass<${name}>`,
12318
+ name: `TaggedError<${name}>`,
12142
12319
  kind: ts.ScriptElementKind.constElement,
12143
- insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>()("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>()("${name}", {${"${0}"}}){}`,
12320
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedErrorClass<${name}>()("${errorTagKey}", {${"${0}"}}){}` : `TaggedErrorClass<${name}>()("${errorTagKey}", {${"${0}"}}){}`,
12144
12321
  replacementSpan,
12145
12322
  isSnippet: true
12146
12323
  });
12147
12324
  }
12148
12325
  }
12326
+ const hasTaggedClassCompletion = isFullyQualified || isSome2(
12327
+ yield* pipe(
12328
+ typeParser.isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(accessedObject),
12329
+ option
12330
+ )
12331
+ );
12332
+ if (hasTaggedClassCompletion) {
12333
+ completions2.push({
12334
+ name: `TaggedClass<${name}>`,
12335
+ kind: ts.ScriptElementKind.constElement,
12336
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>()("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>()("${name}", {${"${0}"}}){}`,
12337
+ replacementSpan,
12338
+ isSnippet: true
12339
+ });
12340
+ }
12149
12341
  if (typeParser.supportedEffect() === "v3") {
12150
12342
  const hasTaggedRequestCompletion = isFullyQualified || isSome2(
12151
12343
  yield* pipe(
@@ -12174,24 +12366,7 @@ var effectSchemaSelfInClasses = createCompletion({
12174
12366
  completions2.push({
12175
12367
  name: `ErrorClass<${name}>`,
12176
12368
  kind: ts.ScriptElementKind.constElement,
12177
- insertText: isFullyQualified ? `${schemaIdentifier}.ErrorClass<${name}>()({${"${0}"}}){}` : `ErrorClass<${name}>()({${"${0}"}}){}`,
12178
- replacementSpan,
12179
- isSnippet: true
12180
- });
12181
- }
12182
- }
12183
- if (typeParser.supportedEffect() === "v4") {
12184
- const hasRequestClassCompletion = isFullyQualified || isSome2(
12185
- yield* pipe(
12186
- typeParser.isNodeReferenceToEffectSchemaModuleApi("RequestClass")(accessedObject),
12187
- option
12188
- )
12189
- );
12190
- if (hasRequestClassCompletion) {
12191
- completions2.push({
12192
- name: `RequestClass<${name}>`,
12193
- kind: ts.ScriptElementKind.constElement,
12194
- insertText: isFullyQualified ? `${schemaIdentifier}.RequestClass<${name}>("${name}")({${"${0}"}}){}` : `RequestClass<${name}>("${name}")({${"${0}"}}){}`,
12369
+ insertText: isFullyQualified ? `${schemaIdentifier}.ErrorClass<${name}>("${name}")({${"${0}"}}){}` : `ErrorClass<${name}>()({${"${0}"}}){}`,
12195
12370
  replacementSpan,
12196
12371
  isSnippet: true
12197
12372
  });
@@ -12446,8 +12621,55 @@ var schemaBrand = createCompletion({
12446
12621
  })
12447
12622
  });
12448
12623
 
12624
+ // src/completions/serviceMapSelfInClasses.ts
12625
+ var serviceMapSelfInClasses = createCompletion({
12626
+ name: "serviceMapSelfInClasses",
12627
+ apply: fn("serviceMapSelfInClasses")(function* (sourceFile, position) {
12628
+ const ts = yield* service(TypeScriptApi);
12629
+ const tsUtils = yield* service(TypeScriptUtils);
12630
+ const typeParser = yield* service(TypeParser);
12631
+ if (typeParser.supportedEffect() === "v3") return [];
12632
+ const maybeInfos = tsUtils.parseDataForExtendsClassCompletion(sourceFile, position);
12633
+ if (!maybeInfos) return [];
12634
+ const { accessedObject, className, replacementSpan } = maybeInfos;
12635
+ const serviceMapIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
12636
+ sourceFile,
12637
+ "effect",
12638
+ "ServiceMap"
12639
+ ) || "ServiceMap";
12640
+ const isFullyQualified = serviceMapIdentifier === ts.idText(accessedObject);
12641
+ const name = ts.idText(className);
12642
+ const tagKey = (yield* createString(sourceFile, name, "service")) || name;
12643
+ const completions2 = [];
12644
+ const hasServiceCompletion = isFullyQualified || isSome2(
12645
+ yield* pipe(
12646
+ typeParser.isNodeReferenceToServiceMapModuleApi("Service")(accessedObject),
12647
+ option
12648
+ )
12649
+ );
12650
+ if (hasServiceCompletion) {
12651
+ completions2.push({
12652
+ name: `Service<${name}, {}>`,
12653
+ kind: ts.ScriptElementKind.constElement,
12654
+ insertText: isFullyQualified ? `${serviceMapIdentifier}.Service<${name}, {${"${0}"}}>()("${tagKey}"){}` : `Service<${name}, {${"${0}"}}>()("${tagKey}"){}`,
12655
+ replacementSpan,
12656
+ isSnippet: true
12657
+ });
12658
+ completions2.push({
12659
+ name: `Service<${name}>({ make })`,
12660
+ kind: ts.ScriptElementKind.constElement,
12661
+ insertText: isFullyQualified ? `${serviceMapIdentifier}.Service<${name}>()("${tagKey}", { make: ${"${0}"} }){}` : `Service<${name}>()("${tagKey}", { make: ${"${0}"} }){}`,
12662
+ replacementSpan,
12663
+ isSnippet: true
12664
+ });
12665
+ }
12666
+ return completions2;
12667
+ })
12668
+ });
12669
+
12449
12670
  // src/completions.ts
12450
12671
  var completions = [
12672
+ serviceMapSelfInClasses,
12451
12673
  effectSqlModelSelfInClasses,
12452
12674
  effectSchemaSelfInClasses,
12453
12675
  effectSelfInClasses,
@@ -19085,7 +19307,7 @@ var _findSchemaVariableDeclaration = fn(
19085
19307
  );
19086
19308
  }
19087
19309
  );
19088
- var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, inferFromName, typeA, opaqueTypeName, typeE, opaqueEncodedName, opaqueContextName) {
19310
+ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, inferFromName, typeA, opaqueTypeName, typeE, opaqueEncodedName, opaqueContextName, isV4, opaqueEncodingServicesName) {
19089
19311
  const ts = yield* service(TypeScriptApi);
19090
19312
  const opaqueInferred = ts.factory.createExpressionWithTypeArguments(
19091
19313
  ts.factory.createPropertyAccessExpression(
@@ -19118,7 +19340,7 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
19118
19340
  ts.factory.createPropertyAccessExpression(
19119
19341
  ts.factory.createPropertyAccessExpression(
19120
19342
  ts.factory.createIdentifier(effectSchemaName),
19121
- ts.factory.createIdentifier("Schema")
19343
+ ts.factory.createIdentifier(isV4 ? "Codec" : "Schema")
19122
19344
  ),
19123
19345
  ts.factory.createIdentifier("Encoded")
19124
19346
  ),
@@ -19145,9 +19367,9 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
19145
19367
  ts.factory.createPropertyAccessExpression(
19146
19368
  ts.factory.createPropertyAccessExpression(
19147
19369
  ts.factory.createIdentifier(effectSchemaName),
19148
- ts.factory.createIdentifier("Schema")
19370
+ ts.factory.createIdentifier(isV4 ? "Codec" : "Schema")
19149
19371
  ),
19150
- ts.factory.createIdentifier("Context")
19372
+ ts.factory.createIdentifier(isV4 ? "DecodingServices" : "Context")
19151
19373
  ),
19152
19374
  [ts.factory.createTypeQueryNode(
19153
19375
  ts.factory.createIdentifier(inferFromName)
@@ -19159,7 +19381,25 @@ var _createOpaqueTypes = fn("_createOpaqueTypes")(function* (effectSchemaName, i
19159
19381
  [],
19160
19382
  contextInferred
19161
19383
  );
19162
- return { contextType, encodedType, opaqueType };
19384
+ const contextEncodeInferred = ts.factory.createExpressionWithTypeArguments(
19385
+ ts.factory.createPropertyAccessExpression(
19386
+ ts.factory.createPropertyAccessExpression(
19387
+ ts.factory.createIdentifier(effectSchemaName),
19388
+ ts.factory.createIdentifier(isV4 ? "Codec" : "Schema")
19389
+ ),
19390
+ ts.factory.createIdentifier(isV4 ? "EncodingServices" : "Context")
19391
+ ),
19392
+ [ts.factory.createTypeQueryNode(
19393
+ ts.factory.createIdentifier(inferFromName)
19394
+ )]
19395
+ );
19396
+ const contextEncodeType = ts.factory.createTypeAliasDeclaration(
19397
+ [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
19398
+ opaqueEncodingServicesName,
19399
+ [],
19400
+ contextEncodeInferred
19401
+ );
19402
+ return { contextType, contextEncodeType, encodedType, opaqueType };
19163
19403
  });
19164
19404
  var makeSchemaOpaque = createRefactor({
19165
19405
  name: "makeSchemaOpaque",
@@ -19167,6 +19407,8 @@ var makeSchemaOpaque = createRefactor({
19167
19407
  apply: fn("makeSchemaOpaque.apply")(function* (sourceFile, textRange) {
19168
19408
  const ts = yield* service(TypeScriptApi);
19169
19409
  const tsUtils = yield* service(TypeScriptUtils);
19410
+ const typeParser = yield* service(TypeParser);
19411
+ const supportedEffect = typeParser.supportedEffect();
19170
19412
  const maybeNode = yield* _findSchemaVariableDeclaration(sourceFile, textRange);
19171
19413
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
19172
19414
  const { identifier, types, variableDeclarationList, variableStatement } = maybeNode.value;
@@ -19182,14 +19424,16 @@ var makeSchemaOpaque = createRefactor({
19182
19424
  "Schema"
19183
19425
  ) || "Schema";
19184
19426
  const newIdentifier = ts.factory.createIdentifier(ts.idText(identifier) + "_");
19185
- const { contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19427
+ const { contextEncodeType, contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19186
19428
  effectSchemaName,
19187
19429
  ts.idText(newIdentifier),
19188
19430
  types.A,
19189
19431
  ts.idText(identifier),
19190
19432
  types.I,
19191
19433
  ts.idText(identifier) + "Encoded",
19192
- ts.idText(identifier) + "Context"
19434
+ supportedEffect === "v4" ? ts.idText(identifier) + "DecodingServices" : ts.idText(identifier) + "Context",
19435
+ supportedEffect === "v4",
19436
+ supportedEffect === "v4" ? ts.idText(identifier) + "EncodingServices" : ts.idText(identifier) + "Context"
19193
19437
  );
19194
19438
  changeTracker.replaceNode(
19195
19439
  sourceFile,
@@ -19199,16 +19443,19 @@ var makeSchemaOpaque = createRefactor({
19199
19443
  changeTracker.insertNodeAfter(sourceFile, variableStatement, opaqueType);
19200
19444
  changeTracker.insertNodeAfter(sourceFile, variableStatement, encodedType);
19201
19445
  changeTracker.insertNodeAfter(sourceFile, variableStatement, contextType);
19446
+ if (supportedEffect === "v4") {
19447
+ changeTracker.insertNodeAfter(sourceFile, variableStatement, contextEncodeType);
19448
+ }
19202
19449
  const newSchemaType = ts.factory.createTypeReferenceNode(
19203
19450
  ts.factory.createQualifiedName(
19204
19451
  ts.factory.createIdentifier(effectSchemaName),
19205
- ts.factory.createIdentifier("Schema")
19452
+ supportedEffect === "v4" ? ts.factory.createIdentifier("Codec") : ts.factory.createIdentifier("Schema")
19206
19453
  ),
19207
19454
  [
19208
19455
  ts.factory.createTypeReferenceNode(opaqueType.name),
19209
19456
  ts.factory.createTypeReferenceNode(encodedType.name),
19210
19457
  ts.factory.createTypeReferenceNode(contextType.name)
19211
- ]
19458
+ ].concat(supportedEffect === "v4" ? [ts.factory.createTypeReferenceNode(contextEncodeType.name)] : [])
19212
19459
  );
19213
19460
  const newConstDeclaration = ts.factory.createVariableStatement(
19214
19461
  variableStatement.modifiers,
@@ -19238,6 +19485,8 @@ var makeSchemaOpaqueWithNs = createRefactor({
19238
19485
  apply: fn("makeSchemaOpaqueWithNs.apply")(function* (sourceFile, textRange) {
19239
19486
  const ts = yield* service(TypeScriptApi);
19240
19487
  const tsUtils = yield* service(TypeScriptUtils);
19488
+ const typeParser = yield* service(TypeParser);
19489
+ const supportedEffect = typeParser.supportedEffect();
19241
19490
  const maybeNode = yield* _findSchemaVariableDeclaration(sourceFile, textRange);
19242
19491
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
19243
19492
  const { identifier, types, variableDeclarationList, variableStatement } = maybeNode.value;
@@ -19253,14 +19502,16 @@ var makeSchemaOpaqueWithNs = createRefactor({
19253
19502
  "Schema"
19254
19503
  ) || "Schema";
19255
19504
  const newIdentifier = ts.factory.createIdentifier(ts.idText(identifier) + "_");
19256
- const { contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19505
+ const { contextEncodeType, contextType, encodedType, opaqueType } = yield* _createOpaqueTypes(
19257
19506
  effectSchemaName,
19258
19507
  ts.idText(newIdentifier),
19259
19508
  types.A,
19260
19509
  ts.idText(identifier),
19261
19510
  types.I,
19262
19511
  "Encoded",
19263
- "Context"
19512
+ supportedEffect === "v4" ? "DecodingServices" : "Context",
19513
+ supportedEffect === "v4",
19514
+ supportedEffect === "v4" ? "EncodingServices" : "Context"
19264
19515
  );
19265
19516
  const namespace = ts.factory.createModuleDeclaration(
19266
19517
  [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
@@ -19268,7 +19519,7 @@ var makeSchemaOpaqueWithNs = createRefactor({
19268
19519
  ts.factory.createModuleBlock([
19269
19520
  encodedType,
19270
19521
  contextType
19271
- ]),
19522
+ ].concat(supportedEffect === "v4" ? [contextEncodeType] : [])),
19272
19523
  ts.NodeFlags.Namespace
19273
19524
  );
19274
19525
  changeTracker.replaceNode(
@@ -19742,12 +19993,14 @@ var makeSchemaGenContext = fn("SchemaGen.makeSchemaGenContext")(function* (sourc
19742
19993
  "Schema"
19743
19994
  ) || "Schema";
19744
19995
  const moduleToImportedName = {};
19745
- for (const moduleName of ["Option", "Either", "Chunk", "Duration"]) {
19996
+ for (const moduleName of ["Option", "Either", "Chunk", "Duration", "Result"]) {
19746
19997
  const importedName = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", moduleName);
19747
19998
  if (importedName) moduleToImportedName[moduleName] = importedName;
19748
19999
  }
19749
20000
  const ts = yield* service(TypeScriptApi);
20001
+ const typeParser = yield* service(TypeParser);
19750
20002
  return {
20003
+ supportedEffect: typeParser.supportedEffect(),
19751
20004
  sourceFile,
19752
20005
  createApiPropertyAccess: (apiName) => ts.factory.createPropertyAccessExpression(
19753
20006
  ts.factory.createIdentifier(effectSchemaIdentifier),
@@ -19831,7 +20084,7 @@ var createUnsupportedNodeComment = (ts, sourceFile, node) => ts.addSyntheticTrai
19831
20084
  " Not supported conversion: " + node.getText(sourceFile) + " "
19832
20085
  );
19833
20086
  var processNode = (node, isVirtualTypeNode) => gen(function* () {
19834
- const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, ts } = yield* service(
20087
+ const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, supportedEffect, ts } = yield* service(
19835
20088
  SchemaGenContext
19836
20089
  );
19837
20090
  switch (node.kind) {
@@ -19863,9 +20116,12 @@ var processNode = (node, isVirtualTypeNode) => gen(function* () {
19863
20116
  }
19864
20117
  if (ts.isUnionTypeNode(node)) {
19865
20118
  const allLiterals = yield* option(parseAllLiterals(node));
19866
- if (isSome2(allLiterals)) return createApiCall("Literal", allLiterals.value);
20119
+ if (supportedEffect !== "v4" && isSome2(allLiterals)) return createApiCall("Literal", allLiterals.value);
19867
20120
  const members = yield* all(...node.types.map((_) => processNode(_, isVirtualTypeNode)));
19868
- return createApiCall("Union", members);
20121
+ return createApiCall(
20122
+ "Union",
20123
+ supportedEffect === "v4" ? [ts.factory.createArrayLiteralExpression(members)] : members
20124
+ );
19869
20125
  }
19870
20126
  if (ts.isIntersectionTypeNode(node)) {
19871
20127
  const [firstSchema, ...otherSchemas] = yield* all(
@@ -19940,6 +20196,9 @@ var processNode = (node, isVirtualTypeNode) => gen(function* () {
19940
20196
  ...node.typeArguments ? node.typeArguments.map((_) => processNode(_, isVirtualTypeNode)) : []
19941
20197
  );
19942
20198
  if (elements.length >= 2) {
20199
+ if (supportedEffect === "v4" && elements.length === 2) {
20200
+ return createApiCall("Record", [elements[0], elements[1]]);
20201
+ }
19943
20202
  return createApiCall(parsedName.value, [
19944
20203
  ts.factory.createObjectLiteralExpression([
19945
20204
  ts.factory.createPropertyAssignment("key", elements[0]),
@@ -20174,6 +20433,7 @@ var typeToEffectSchema = createRefactor({
20174
20433
  const tsUtils = yield* service(TypeScriptUtils);
20175
20434
  const typeChecker = yield* service(TypeCheckerApi);
20176
20435
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
20436
+ const typeParser = yield* service(TypeParser);
20177
20437
  const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
20178
20438
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
20179
20439
  const node = maybeNode.value;
@@ -20185,7 +20445,8 @@ var typeToEffectSchema = createRefactor({
20185
20445
  provideService(TypeCheckerApi, typeChecker),
20186
20446
  provideService(TypeScriptUtils, tsUtils),
20187
20447
  provideService(TypeScriptApi, ts),
20188
- provideService(TypeCheckerUtils, typeCheckerUtils)
20448
+ provideService(TypeCheckerUtils, typeCheckerUtils),
20449
+ provideService(TypeParser, typeParser)
20189
20450
  )
20190
20451
  };
20191
20452
  })
@@ -20200,6 +20461,7 @@ var typeToEffectSchemaClass = createRefactor({
20200
20461
  const tsUtils = yield* service(TypeScriptUtils);
20201
20462
  const typeChecker = yield* service(TypeCheckerApi);
20202
20463
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
20464
+ const typeParser = yield* service(TypeParser);
20203
20465
  const maybeNode = yield* findNodeToProcess2(sourceFile, textRange);
20204
20466
  if (isNone2(maybeNode)) return yield* fail3(new RefactorNotApplicableError());
20205
20467
  const node = maybeNode.value;
@@ -20211,7 +20473,8 @@ var typeToEffectSchemaClass = createRefactor({
20211
20473
  provideService(TypeCheckerApi, typeChecker),
20212
20474
  provideService(TypeScriptUtils, tsUtils),
20213
20475
  provideService(TypeScriptApi, ts),
20214
- provideService(TypeCheckerUtils, typeCheckerUtils)
20476
+ provideService(TypeCheckerUtils, typeCheckerUtils),
20477
+ provideService(TypeParser, typeParser)
20215
20478
  )
20216
20479
  };
20217
20480
  })