@apollo/federation-internals 2.13.2 → 2.14.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.
@@ -6,6 +6,7 @@ const graphql_1 = require("graphql");
6
6
  const coreSpec_1 = require("./specs/coreSpec");
7
7
  const utils_1 = require("./utils");
8
8
  const values_1 = require("./values");
9
+ const tagSpec_1 = require("./specs/tagSpec");
9
10
  const inaccessibleSpec_1 = require("./specs/inaccessibleSpec");
10
11
  const print_1 = require("./print");
11
12
  const types_1 = require("./types");
@@ -725,6 +726,8 @@ class CoreFeatures {
725
726
  this.coreItself = coreItself;
726
727
  this.byAlias = new Map();
727
728
  this.byIdentity = new Map();
729
+ this.byImportName = new Map();
730
+ this.conflictsByAlias = new utils_1.SetMultiMap();
728
731
  this.add(coreItself);
729
732
  const coreDef = (0, coreSpec_1.findCoreSpecVersion)(coreItself.url);
730
733
  if (!coreDef) {
@@ -733,16 +736,44 @@ class CoreFeatures {
733
736
  this.coreDefinition = coreDef;
734
737
  }
735
738
  getByIdentity(identity) {
736
- return this.byIdentity.get(identity);
739
+ var _a;
740
+ return (_a = this.byIdentity.get(identity)) === null || _a === void 0 ? void 0 : _a[0];
737
741
  }
738
742
  allFeatures() {
739
- return this.byIdentity.values();
743
+ return [...this.byIdentity.values()].map(([feature]) => feature);
740
744
  }
741
745
  removeFeature(featureIdentity) {
742
- const feature = this.byIdentity.get(featureIdentity);
743
- if (feature) {
746
+ const entry = this.byIdentity.get(featureIdentity);
747
+ if (entry) {
748
+ const [feature] = entry;
744
749
  this.byIdentity.delete(featureIdentity);
745
- this.byAlias.delete(feature.nameInSchema);
750
+ const alias = feature.nameInSchema;
751
+ this.byAlias.delete(alias);
752
+ for (const { name: importInSpec, as } of feature.imports) {
753
+ const importInSchema = as !== null && as !== void 0 ? as : importInSpec;
754
+ const isDirective = importInSpec.charAt(0) === "@";
755
+ const nameInSchema = isDirective
756
+ ? importInSchema.slice(1)
757
+ : importInSchema;
758
+ this.byImportName.delete(importInSchema);
759
+ const split = CoreFeatures.splitPrefixedName(nameInSchema);
760
+ if (!split) {
761
+ continue;
762
+ }
763
+ const [splitAlias] = split;
764
+ if (splitAlias === alias) {
765
+ continue;
766
+ }
767
+ let conflicts = this.conflictsByAlias.get(importInSchema);
768
+ if (!conflicts) {
769
+ continue;
770
+ }
771
+ conflicts.delete(importInSchema);
772
+ if (conflicts.size) {
773
+ continue;
774
+ }
775
+ this.conflictsByAlias.delete(importInSchema);
776
+ }
746
777
  }
747
778
  }
748
779
  maybeAddFeature(directive) {
@@ -753,10 +784,6 @@ class CoreFeatures {
753
784
  const typedDirective = directive;
754
785
  const args = typedDirective.arguments();
755
786
  const url = this.coreDefinition.extractFeatureUrl(args);
756
- const existing = this.byIdentity.get(url.identity);
757
- if (existing) {
758
- throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Duplicate inclusion of feature ${url.identity}`);
759
- }
760
787
  const imports = (0, coreSpec_1.extractCoreFeatureImports)(url, typedDirective);
761
788
  const feature = new CoreFeature(url, (_b = args.as) !== null && _b !== void 0 ? _b : url.name, directive, imports, args.for);
762
789
  this.add(feature);
@@ -764,44 +791,404 @@ class CoreFeatures {
764
791
  return feature;
765
792
  }
766
793
  add(feature) {
767
- this.byAlias.set(feature.nameInSchema, feature);
768
- this.byIdentity.set(feature.url.identity, feature);
794
+ var _a, _b;
795
+ const identity = feature.url.identity;
796
+ if (this.byIdentity.has(identity)) {
797
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot link feature "${identity}" since it has already been linked in the schema.`);
798
+ }
799
+ const alias = feature.nameInSchema;
800
+ if (!(identity === tagSpec_1.tagIdentity &&
801
+ alias === 'federation__tag' &&
802
+ feature.imports.length === 0) &&
803
+ !(identity === inaccessibleSpec_1.inaccessibleIdentity &&
804
+ alias === 'federation__inaccessible' &&
805
+ feature.imports.length === 0)) {
806
+ if (alias.indexOf('__') !== -1) {
807
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot link feature "${identity}" as "${alias}" since it contains "__". Please rename to a compliant name via "as".`);
808
+ }
809
+ }
810
+ if (alias.charAt(alias.length - 1) === '_') {
811
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot link feature "${identity}" as "${alias}" since it ends in "_". Please rename to a compliant name via "as".`);
812
+ }
813
+ if (!aliasRegexp.test(alias)) {
814
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot link feature "${identity}" as "${alias}" since it is not a valid GraphQL name. Please rename to a compliant name via "as".`);
815
+ }
816
+ const conflicts = this.conflictsByAlias.get(alias);
817
+ if (conflicts) {
818
+ const importInSchema = (_b = (_a = conflicts === null || conflicts === void 0 ? void 0 : conflicts.values()) === null || _a === void 0 ? void 0 : _a.next()) === null || _b === void 0 ? void 0 : _b.value;
819
+ (0, utils_1.assert)(importInSchema !== undefined, `Unexpectedly empty conflicts set`);
820
+ const entry = this.byImportName.get(importInSchema);
821
+ (0, utils_1.assert)(entry, `Unexpectedly cannot find feature for import`);
822
+ const [conflictFeature, importInSpec] = entry;
823
+ const conflictIdentity = conflictFeature.url.identity;
824
+ this.checkTagInaccessibleConflict(conflictIdentity, identity);
825
+ const importInErrorMessage = importInSchema !== importInSpec
826
+ ? `"${importInSpec}" as "${importInSchema}"`
827
+ : `"${importInSpec}"`;
828
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${conflictIdentity}" since it can be confused with a namespaced name from another linked feature "${identity}". Please rename the import or feature to avoid conflicts via "as".`);
829
+ }
830
+ const importInSchema = "@" + alias;
831
+ const entry = this.byImportName.get(importInSchema);
832
+ if (entry) {
833
+ const [conflictFeature, importInSpec] = entry;
834
+ const conflictIdentity = conflictFeature.url.identity;
835
+ this.checkTagInaccessibleConflict(conflictIdentity, identity);
836
+ const importInErrorMessage = importInSchema !== importInSpec
837
+ ? `"${importInSpec}" as "${importInSchema}"`
838
+ : `"${importInSpec}"`;
839
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${conflictIdentity}" since it can be confused with a namespaced name from another linked feature "${identity}". Please rename the import or feature to avoid conflicts via "as".`);
840
+ }
841
+ const existingFeature = this.byAlias.get(alias);
842
+ if (existingFeature !== undefined) {
843
+ const existingIdentity = existingFeature.url.identity;
844
+ this.checkTagInaccessibleConflict(existingIdentity, identity);
845
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot link feature ${identity} as "${alias}" since another feature "${existingIdentity}" already uses that alias. Please rename the feature to avoid conflicts via "as".`);
846
+ }
847
+ const importsMap = new Map();
848
+ for (const { name: importInSpec, as } of feature.imports) {
849
+ const importInSchema = as !== null && as !== void 0 ? as : importInSpec;
850
+ const importInErrorMessage = importInSchema !== importInSpec
851
+ ? `"${importInSpec}" as "${importInSchema}"`
852
+ : `"${importInSpec}"`;
853
+ const isDirective = importInSpec.charAt(0) === "@";
854
+ const nameInSpec = isDirective
855
+ ? importInSpec.slice(1)
856
+ : importInSpec;
857
+ const nameInSchema = isDirective
858
+ ? importInSchema.slice(1)
859
+ : importInSchema;
860
+ const split = CoreFeatures.splitPrefixedName(nameInSchema);
861
+ if (split) {
862
+ const [splitAlias, splitNameInSpec] = split;
863
+ if (splitAlias === alias) {
864
+ if (splitNameInSpec !== nameInSpec) {
865
+ const splitImportInSpec = isDirective
866
+ ? "@" + splitNameInSpec
867
+ : splitNameInSpec;
868
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it can be confused with the namespaced name for "${splitImportInSpec}". Please rename the import to avoid conflicts via "as".`);
869
+ }
870
+ }
871
+ else {
872
+ const conflictFeature = this.byAlias.get(splitAlias);
873
+ if (conflictFeature) {
874
+ const conflictIdentity = conflictFeature.url.identity;
875
+ this.checkTagInaccessibleConflict(conflictIdentity, identity);
876
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it can be confused with a namespaced name from another linked feature "${conflictIdentity}". Please rename the import or feature to avoid conflicts via "as".`);
877
+ }
878
+ else {
879
+ this.conflictsByAlias.add(splitAlias, importInSchema);
880
+ }
881
+ }
882
+ }
883
+ if (isDirective) {
884
+ if (nameInSchema === alias) {
885
+ if (nameInSpec !== feature.url.name) {
886
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it can be confused with the namespaced name for "@${feature.url.name}". Please rename the import to avoid conflicts via "as".`);
887
+ }
888
+ }
889
+ else {
890
+ const conflictFeature = this.byAlias.get(nameInSchema);
891
+ if (conflictFeature) {
892
+ const conflictIdentity = conflictFeature.url.identity;
893
+ this.checkTagInaccessibleConflict(conflictIdentity, identity);
894
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it can be confused with a namespaced name from another linked feature "${conflictIdentity}". Please rename the import or feature to avoid conflicts via "as".`);
895
+ }
896
+ }
897
+ }
898
+ const existingImportInSchema = importsMap.get(importInSpec);
899
+ if (existingImportInSchema === undefined) {
900
+ importsMap.set(importInSpec, importInSchema);
901
+ }
902
+ else {
903
+ if (existingImportInSchema !== importInSchema) {
904
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it was previously imported as "${existingImportInSchema}". Please remove one of these imports.`);
905
+ }
906
+ }
907
+ const entry = this.byImportName.get(importInSchema);
908
+ if (entry === undefined) {
909
+ this.byImportName.set(importInSchema, [feature, importInSpec]);
910
+ }
911
+ else {
912
+ const [existingFeature, existingImportInSpec] = entry;
913
+ const existingIdentity = existingFeature.url.identity;
914
+ if (existingIdentity !== identity) {
915
+ this.checkTagInaccessibleConflict(existingIdentity, identity);
916
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it was previously imported from feature "${existingIdentity}". Please rename the import to avoid conflicts via "as".`);
917
+ }
918
+ if (existingImportInSpec !== importInSpec) {
919
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${identity}" since it was previously imported for "${existingImportInSpec}". Please rename the import to avoid conflicts via "as".`);
920
+ }
921
+ }
922
+ }
923
+ this.byAlias.set(alias, feature);
924
+ this.byIdentity.set(identity, [feature, importsMap]);
925
+ }
926
+ isAliasValid(alias, identity, importConflictsByIdentity) {
927
+ if (alias.indexOf('__') !== -1) {
928
+ return false;
929
+ }
930
+ if (alias.charAt(alias.length - 1) === '_') {
931
+ return false;
932
+ }
933
+ if (!nameRegexp.test(alias)) {
934
+ return false;
935
+ }
936
+ for (const [otherIdentity, importConflicts] of importConflictsByIdentity.entries()) {
937
+ if (identity === otherIdentity) {
938
+ if (importConflicts.self.has(alias)) {
939
+ return false;
940
+ }
941
+ }
942
+ else {
943
+ if (importConflicts.other.has(alias)) {
944
+ return false;
945
+ }
946
+ }
947
+ }
948
+ if (this.byAlias.has(alias)) {
949
+ return false;
950
+ }
951
+ return true;
952
+ }
953
+ static computeAliasConflicts(specAliases, elementNames) {
954
+ const trieNames = elementNames;
955
+ const importConflictsByIdentity = new Map();
956
+ for (const { url, alias, imports } of specAliases) {
957
+ trieNames.add(alias);
958
+ const self = new Set();
959
+ const other = new Set();
960
+ for (const { name: importInSpec, as } of imports) {
961
+ const importInSchema = as !== null && as !== void 0 ? as : importInSpec;
962
+ const isDirective = importInSpec.charAt(0) === "@";
963
+ const nameInSpec = isDirective
964
+ ? importInSpec.slice(1)
965
+ : importInSpec;
966
+ const nameInSchema = isDirective
967
+ ? importInSchema.slice(1)
968
+ : importInSchema;
969
+ trieNames.add(nameInSchema);
970
+ const split = CoreFeatures.splitPrefixedName(nameInSchema);
971
+ if (split) {
972
+ const [splitAlias, splitNameInSpec] = split;
973
+ if (splitNameInSpec !== nameInSpec) {
974
+ self.add(splitAlias);
975
+ }
976
+ other.add(splitAlias);
977
+ }
978
+ if (isDirective) {
979
+ if (nameInSpec !== url.name) {
980
+ self.add(nameInSchema);
981
+ }
982
+ other.add(nameInSchema);
983
+ }
984
+ }
985
+ importConflictsByIdentity.set(url.identity, { self, other });
986
+ }
987
+ let prefix = null;
988
+ let index = 0;
989
+ let computeUniqueAlias = (specName) => {
990
+ if (prefix === null) {
991
+ const aliasStart = [
992
+ '_',
993
+ 'abcdefghijklmnopqrstuvwxyz',
994
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
995
+ ].join('');
996
+ const aliasContinue = [
997
+ 'abcdefghijklmnopqrstuvwxyz',
998
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
999
+ '0123456789',
1000
+ ].join('');
1001
+ const root = { children: new Map(), parent: null, char: '' };
1002
+ for (const name of trieNames) {
1003
+ let node = root;
1004
+ for (const char of name) {
1005
+ let child = node.children.get(char);
1006
+ if (!child) {
1007
+ child = { children: new Map(), parent: node, char };
1008
+ node.children.set(char, child);
1009
+ }
1010
+ node = child;
1011
+ }
1012
+ }
1013
+ const queue = [root];
1014
+ let head = 0;
1015
+ while (prefix === null) {
1016
+ const possibleChars = head === 0 ? aliasStart : aliasContinue;
1017
+ const node = queue[head++];
1018
+ for (const char of possibleChars) {
1019
+ const child = node.children.get(char);
1020
+ if (child) {
1021
+ queue.push(child);
1022
+ }
1023
+ else {
1024
+ const chars = [char];
1025
+ for (let cur = node; cur === null || cur === void 0 ? void 0 : cur.parent; cur = cur.parent) {
1026
+ chars.push(cur.char);
1027
+ }
1028
+ prefix = chars.reverse().join('');
1029
+ break;
1030
+ }
1031
+ }
1032
+ }
1033
+ }
1034
+ const suffix = specName.replace(/[^a-zA-Z]/g, '');
1035
+ return `${prefix}${index++}${suffix}`;
1036
+ };
1037
+ return {
1038
+ importConflictsByIdentity,
1039
+ computeUniqueAlias,
1040
+ };
1041
+ }
1042
+ checkTagInaccessibleConflict(identity1, identity2) {
1043
+ const federationIdentity = 'https://specs.apollo.dev/federation';
1044
+ const identities = new Set([identity1, identity2]);
1045
+ if (!identities.has(federationIdentity)) {
1046
+ return;
1047
+ }
1048
+ const [directive, identity] = identities.has(tagSpec_1.tagIdentity)
1049
+ ? ['tag', tagSpec_1.tagIdentity]
1050
+ : identities.has(inaccessibleSpec_1.inaccessibleIdentity)
1051
+ ? ['inaccessible', inaccessibleSpec_1.inaccessibleIdentity]
1052
+ : [undefined, undefined];
1053
+ if (directive && identity) {
1054
+ throw error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Please import "@${directive}" from the feature "${federationIdentity}" instead of using "${identity}" to avoid potential unexpected behavior in the future.`);
1055
+ }
769
1056
  }
770
1057
  sourceFeature(element) {
771
1058
  const isDirective = element instanceof DirectiveDefinition || element instanceof Directive;
772
- const splitted = element.name.split('__');
773
- if (splitted.length > 1) {
774
- const feature = this.byAlias.get(splitted[0]);
775
- return feature ? {
1059
+ const importName = isDirective ? '@' + element.name : element.name;
1060
+ const entry = this.byImportName.get(importName);
1061
+ if (entry) {
1062
+ const [feature, importInSpec] = entry;
1063
+ return {
776
1064
  feature,
777
- nameInFeature: splitted.slice(1).join('__'),
778
- isImported: false,
779
- } : undefined;
1065
+ nameInFeature: isDirective ? importInSpec.slice(1) : importInSpec,
1066
+ isImported: true,
1067
+ };
780
1068
  }
781
- else {
782
- const importName = isDirective ? '@' + element.name : element.name;
783
- const allFeatures = [this.coreItself, ...this.byIdentity.values()];
784
- for (const feature of allFeatures) {
785
- for (const { as, name } of feature.imports) {
786
- if ((as !== null && as !== void 0 ? as : name) === importName) {
787
- return {
788
- feature,
789
- nameInFeature: isDirective ? name.slice(1) : name,
790
- isImported: true,
791
- };
1069
+ const defaultEntry = this.sourceDefaultName(isDirective, element.name);
1070
+ if (!defaultEntry) {
1071
+ return undefined;
1072
+ }
1073
+ const [feature, nameInSpec] = defaultEntry;
1074
+ const importInSpec = isDirective ? '@' + nameInSpec : nameInSpec;
1075
+ return {
1076
+ feature,
1077
+ nameInFeature: this.getImportName(feature, importInSpec) === undefined
1078
+ ? nameInSpec
1079
+ : null,
1080
+ isImported: false,
1081
+ };
1082
+ }
1083
+ validateNoShadowingImports(schema) {
1084
+ const errors = [];
1085
+ for (const element of [...schema.allTypes(), ...schema.allDirectives()]) {
1086
+ const shadowingImport = this.getShadowingImport(element);
1087
+ if (!shadowingImport) {
1088
+ continue;
1089
+ }
1090
+ const isUsed = element instanceof DirectiveDefinition
1091
+ ? element.applications().size !== 0
1092
+ : this.getReferencingRootElements(element)
1093
+ .some((referencer) => {
1094
+ return referencer.kind === 'SchemaDefinition'
1095
+ ? true
1096
+ : !this.getShadowingImport(referencer);
1097
+ });
1098
+ if (!isUsed) {
1099
+ continue;
1100
+ }
1101
+ const { feature, importInSpec, importInSchema } = shadowingImport;
1102
+ const importInErrorMessage = importInSchema !== importInSpec
1103
+ ? `"${importInSpec}" as "${importInSchema}"`
1104
+ : `"${importInSpec}"`;
1105
+ errors.push(error_1.ERRORS.INVALID_LINK_DIRECTIVE_USAGE.err(`Cannot import ${importInErrorMessage} from feature "${feature.url.identity}" since there's a used definition for the namespaced name "${element.coordinate}". Please switch usages of the namespaced name to the import name and remove the definition.`));
1106
+ }
1107
+ return errors;
1108
+ }
1109
+ getShadowingImport(element) {
1110
+ const isDirective = element instanceof DirectiveDefinition || element instanceof Directive;
1111
+ const defaultEntry = this.sourceDefaultName(isDirective, element.name);
1112
+ if (!defaultEntry) {
1113
+ return undefined;
1114
+ }
1115
+ const importName = isDirective ? '@' + element.name : element.name;
1116
+ const [feature, nameInSpec] = defaultEntry;
1117
+ const importInSpec = isDirective ? '@' + nameInSpec : nameInSpec;
1118
+ const importInSchema = this.getImportName(feature, importInSpec);
1119
+ return importInSchema !== undefined && importInSchema !== importName
1120
+ ? {
1121
+ feature,
1122
+ importInSpec,
1123
+ importInSchema,
1124
+ }
1125
+ : undefined;
1126
+ }
1127
+ getReferencingRootElements(element) {
1128
+ const referencers = [];
1129
+ for (const referencer of element.referencers()) {
1130
+ switch (referencer.kind) {
1131
+ case 'ObjectType':
1132
+ referencers.push(referencer);
1133
+ break;
1134
+ case 'InterfaceType':
1135
+ referencers.push(referencer);
1136
+ break;
1137
+ case 'UnionType':
1138
+ referencers.push(referencer);
1139
+ break;
1140
+ case 'SchemaDefinition':
1141
+ referencers.push(referencer);
1142
+ break;
1143
+ case 'FieldDefinition':
1144
+ referencers.push(referencer.parent);
1145
+ break;
1146
+ case 'InputFieldDefinition':
1147
+ referencers.push(referencer.parent);
1148
+ break;
1149
+ case 'ArgumentDefinition':
1150
+ const parent = referencer.parent;
1151
+ switch (parent.kind) {
1152
+ case 'DirectiveDefinition':
1153
+ referencers.push(parent);
1154
+ break;
1155
+ case 'FieldDefinition':
1156
+ referencers.push(parent.parent);
1157
+ break;
1158
+ default:
1159
+ (0, utils_1.assertUnreachable)(parent);
792
1160
  }
793
- }
1161
+ break;
1162
+ default:
1163
+ (0, utils_1.assertUnreachable)(referencer);
794
1164
  }
795
- const directFeature = this.byAlias.get(element.name);
796
- if (directFeature && isDirective) {
797
- return {
798
- feature: directFeature,
799
- nameInFeature: element.name,
800
- isImported: false,
801
- };
1165
+ }
1166
+ return referencers;
1167
+ }
1168
+ getImportName(feature, importInSpec) {
1169
+ var _a, _b;
1170
+ return (_b = (_a = this.byIdentity.get(feature.url.identity)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.get(importInSpec);
1171
+ }
1172
+ sourceDefaultName(isDirective, name) {
1173
+ const split = CoreFeatures.splitPrefixedName(name);
1174
+ if (split) {
1175
+ const [alias, nameInSpec] = split;
1176
+ const feature = this.byAlias.get(alias);
1177
+ if (feature) {
1178
+ return [feature, nameInSpec];
802
1179
  }
1180
+ }
1181
+ if (!isDirective) {
803
1182
  return undefined;
804
1183
  }
1184
+ const feature = this.byAlias.get(name);
1185
+ return feature ? [feature, feature.url.name] : undefined;
1186
+ }
1187
+ static splitPrefixedName(name) {
1188
+ const splitIndex = name.indexOf('__');
1189
+ return splitIndex !== -1
1190
+ ? [name.slice(0, splitIndex), name.slice(splitIndex + 2)]
1191
+ : undefined;
805
1192
  }
806
1193
  }
807
1194
  exports.CoreFeatures = CoreFeatures;
@@ -846,6 +1233,8 @@ const graphQLBuiltInDirectivesSpecifications = [
846
1233
  ],
847
1234
  }),
848
1235
  ];
1236
+ const aliasRegexp = /^[_A-Za-z][_0-9A-Za-z.-]*$/;
1237
+ const nameRegexp = /^[_A-Za-z][_0-9A-Za-z]*$/;
849
1238
  const coordinateRegexp = /^@?[_A-Za-z][_0-9A-Za-z]*(\.[_A-Za-z][_0-9A-Za-z]*)?(\([_A-Za-z][_0-9A-Za-z]*:\))?$/;
850
1239
  class Schema {
851
1240
  constructor(blueprint = exports.defaultSchemaBlueprint, config = {}) {
@@ -1148,6 +1537,7 @@ class Schema {
1148
1537
  this.isValidated = true;
1149
1538
  }
1150
1539
  validate() {
1540
+ var _a, _b;
1151
1541
  if (this.isValidated) {
1152
1542
  return;
1153
1543
  }
@@ -1156,6 +1546,7 @@ class Schema {
1156
1546
  });
1157
1547
  let errors = (0, validate_1.validateSDL)(this.toAST(), undefined, this.blueprint.validationRules()).map((e) => this.blueprint.onGraphQLJSValidationError(this, e));
1158
1548
  errors = errors.concat((0, validate_2.validateSchema)(this));
1549
+ errors = errors.concat((_b = (_a = this.coreFeatures) === null || _a === void 0 ? void 0 : _a.validateNoShadowingImports(this)) !== null && _b !== void 0 ? _b : []);
1159
1550
  if (errors.length === 0) {
1160
1551
  this.runWithBuiltInModificationAllowed(() => {
1161
1552
  errors = this.blueprint.onValidation(this);