Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@apollo/federation-internals

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@apollo/federation-internals - npm Package Compare versions

Comparing version 2.1.2-alpha.1 to 2.1.2-alpha.2

1

dist/error.d.ts

@@ -57,3 +57,2 @@ import { ASTNode, GraphQLError, GraphQLErrorOptions, GraphQLFormattedError } from "graphql";

PROVIDES_FIELDS_HAS_ARGS: ErrorCodeDefinition;
REQUIRES_FIELDS_HAS_ARGS: ErrorCodeDefinition;
PROVIDES_MISSING_EXTERNAL: ErrorCodeDefinition;

@@ -60,0 +59,0 @@ REQUIRES_MISSING_EXTERNAL: ErrorCodeDefinition;

3

dist/error.js

@@ -129,3 +129,2 @@ "use strict";

const PROVIDES_FIELDS_HAS_ARGS = FIELDS_HAS_ARGS.createCode('provides');
const REQUIRES_FIELDS_HAS_ARGS = FIELDS_HAS_ARGS.createCode('requires');
const DIRECTIVE_FIELDS_MISSING_EXTERNAL = makeFederationDirectiveErrorCodeCategory('FIELDS_MISSING_EXTERNAL', (directive) => `The \`fields\` argument of a \`@${directive}\` directive includes a field that is not marked as \`@external\`.`, { addedIn: FED1_CODE });

@@ -220,3 +219,2 @@ const PROVIDES_MISSING_EXTERNAL = DIRECTIVE_FIELDS_MISSING_EXTERNAL.createCode('provides');

PROVIDES_FIELDS_HAS_ARGS,
REQUIRES_FIELDS_HAS_ARGS,
PROVIDES_MISSING_EXTERNAL,

@@ -306,3 +304,4 @@ REQUIRES_MISSING_EXTERNAL,

['NON_REPEATABLE_DIRECTIVE_ARGUMENTS_MISMATCH', 'Since federation 2.1.0, the case this error used to cover is now a warning (with code `INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS`) instead of an error'],
['REQUIRES_FIELDS_HAS_ARGS', 'Since federation 2.1.1, using fields with arguments in a @requires is fully supported'],
];
//# sourceMappingURL=error.js.map

@@ -1,2 +0,2 @@

import { CompositeType, CoreFeature, Directive, DirectiveDefinition, FieldDefinition, InputFieldDefinition, InterfaceType, NamedType, ObjectType, ScalarType, Schema, SchemaBlueprint, SchemaConfig, UnionType } from "./definitions";
import { CompositeType, CoreFeature, Directive, DirectiveDefinition, FieldDefinition, InputFieldDefinition, InterfaceType, NamedType, ObjectType, ScalarType, Schema, SchemaBlueprint, SchemaConfig, SchemaElement, UnionType } from "./definitions";
import { SDLValidationRule } from "graphql/validation/ValidationContext";

@@ -91,5 +91,5 @@ import { ASTNode, DocumentNode, GraphQLError } from "graphql";

export declare function newEmptyFederation2Schema(config?: SchemaConfig): Schema;
export declare function parseFieldSetArgument({ parentType, directive, fieldAccessor, validate, }: {
export declare function parseFieldSetArgument({ parentType, directive, fieldAccessor, validate, decorateValidationErrors, }: {
parentType: CompositeType;
directive: Directive<NamedType | FieldDefinition<CompositeType>, {
directive: Directive<SchemaElement<any, any>, {
fields: any;

@@ -99,2 +99,3 @@ }>;

validate?: boolean;
decorateValidationErrors?: boolean;
}): SelectionSet;

@@ -101,0 +102,0 @@ export declare function collectTargetFields({ parentType, directive, includeInterfaceFieldsImplementations, validate, }: {

@@ -34,3 +34,3 @@ "use strict";

const FEDERATION_VALIDATION_RULES = specifiedRules_1.specifiedSDLRules.filter(rule => !FEDERATION_OMITTED_VALIDATION_RULES.includes(rule)).concat(FEDERATION_SPECIFIC_VALIDATION_RULES);
function validateFieldSetSelections(directiveName, selectionSet, hasExternalInParents, federationMetadata, onError, allowOnNonExternalLeafFields) {
function validateFieldSetSelections({ directiveName, selectionSet, hasExternalInParents, metadata, onError, allowOnNonExternalLeafFields, allowFieldsWithArguments, }) {
for (const selection of selectionSet.selections()) {

@@ -43,4 +43,4 @@ const appliedDirectives = selection.element().appliedDirectives;

const field = selection.element().definition;
const isExternal = federationMetadata.isFieldExternal(field);
if (field.hasArguments()) {
const isExternal = metadata.isFieldExternal(field);
if (!allowFieldsWithArguments && field.hasArguments()) {
onError(error_1.ERROR_CATEGORIES.FIELDS_HAS_ARGS.get(directiveName).err(`field ${field.coordinate} cannot be included because it has arguments (fields with argument are not allowed in @${directiveName})`, { nodes: field.sourceAST }));

@@ -51,3 +51,3 @@ }

const errorCode = error_1.ERROR_CATEGORIES.DIRECTIVE_FIELDS_MISSING_EXTERNAL.get(directiveName);
if (federationMetadata.isFieldFakeExternal(field)) {
if (metadata.isFieldFakeExternal(field)) {
onError(errorCode.err(`field "${field.coordinate}" should not be part of a @${directiveName} since it is already "effectively" provided by this subgraph `

@@ -66,3 +66,3 @@ + `(while it is marked @${federationSpec_1.externalDirectiveSpec.name}, it is a @${federationSpec_1.keyDirectiveSpec.name} field of an extension type, which are not internally considered external for historical/backward compatibility reasons)`, { nodes: field.sourceAST }));

const fieldInImplem = implem.field(field.name);
if (fieldInImplem && federationMetadata.isFieldExternal(fieldInImplem)) {
if (fieldInImplem && metadata.isFieldExternal(fieldInImplem)) {
newHasExternalInParents = true;

@@ -73,11 +73,27 @@ break;

}
validateFieldSetSelections(directiveName, selection.selectionSet, newHasExternalInParents, federationMetadata, onError, allowOnNonExternalLeafFields);
validateFieldSetSelections({
directiveName,
selectionSet: selection.selectionSet,
hasExternalInParents: newHasExternalInParents,
metadata,
onError,
allowOnNonExternalLeafFields,
allowFieldsWithArguments,
});
}
}
else {
validateFieldSetSelections(directiveName, selection.selectionSet, hasExternalInParents, federationMetadata, onError, allowOnNonExternalLeafFields);
validateFieldSetSelections({
directiveName,
selectionSet: selection.selectionSet,
hasExternalInParents,
metadata,
onError,
allowOnNonExternalLeafFields,
allowFieldsWithArguments,
});
}
}
}
function validateFieldSet(type, directive, federationMetadata, errorCollector, allowOnNonExternalLeafFields, onFields) {
function validateFieldSet({ type, directive, metadata, errorCollector, allowOnNonExternalLeafFields, allowFieldsWithArguments, onFields, }) {
try {

@@ -94,3 +110,11 @@ const fieldAccessor = onFields

const selectionSet = parseFieldSetArgument({ parentType: type, directive, fieldAccessor });
validateFieldSetSelections(directive.name, selectionSet, false, federationMetadata, (error) => errorCollector.push(handleFieldSetValidationError(directive, error)), allowOnNonExternalLeafFields);
validateFieldSetSelections({
directiveName: directive.name,
selectionSet,
hasExternalInParents: false,
metadata,
onError: (error) => errorCollector.push(handleFieldSetValidationError(directive, error)),
allowOnNonExternalLeafFields,
allowFieldsWithArguments,
});
}

@@ -135,3 +159,3 @@ catch (e) {

}
function validateAllFieldSet(definition, targetTypeExtractor, errorCollector, federationMetadata, isOnParentType, allowOnNonExternalLeafFields, onFields) {
function validateAllFieldSet({ definition, targetTypeExtractor, errorCollector, metadata, isOnParentType = false, allowOnNonExternalLeafFields = false, allowFieldsWithArguments = false, onFields, }) {
for (const application of definition.applications()) {

@@ -147,3 +171,11 @@ const elt = application.parent;

}
validateFieldSet(type, application, federationMetadata, errorCollector, allowOnNonExternalLeafFields, onFields);
validateFieldSet({
type,
directive: application,
metadata,
errorCollector,
allowOnNonExternalLeafFields,
allowFieldsWithArguments,
onFields,
});
}

@@ -453,3 +485,3 @@ }

var _a;
const errors = super.onValidation(schema);
const errorCollector = super.onValidation(schema);
if (this.withRootTypeRenaming) {

@@ -462,3 +494,3 @@ for (const k of definitions_1.allSchemaRootKinds) {

if (existing) {
errors.push(error_1.ERROR_CATEGORIES.ROOT_TYPE_USED.get(k).err(`The schema has a type named "${defaultName}" but it is not set as the ${k} root type ("${type.name}" is instead): `
errorCollector.push(error_1.ERROR_CATEGORIES.ROOT_TYPE_USED.get(k).err(`The schema has a type named "${defaultName}" but it is not set as the ${k} root type ("${type.name}" is instead): `
+ 'this is not supported by federation. '

@@ -474,26 +506,45 @@ + 'If a root type does not use its default name, there should be no other type with that default name.', { nodes: (0, definitions_1.sourceASTs)(type, existing) }));

if (!metadata.isFed2Schema()) {
return errors;
return errorCollector;
}
const keyDirective = metadata.keyDirective();
validateAllFieldSet(keyDirective, type => type, errors, metadata, true, true, field => {
const type = (0, definitions_1.baseType)(field.type);
if ((0, definitions_1.isUnionType)(type) || (0, definitions_1.isInterfaceType)(type)) {
let kind = type.kind;
kind = kind.slice(0, kind.length - 'Type'.length);
throw error_1.ERRORS.KEY_FIELDS_SELECT_INVALID_TYPE.err(`field "${field.coordinate}" is a ${kind} type which is not allowed in @key`);
validateAllFieldSet({
definition: keyDirective,
targetTypeExtractor: type => type,
errorCollector,
metadata,
isOnParentType: true,
allowOnNonExternalLeafFields: true,
onFields: field => {
const type = (0, definitions_1.baseType)(field.type);
if ((0, definitions_1.isUnionType)(type) || (0, definitions_1.isInterfaceType)(type)) {
let kind = type.kind;
kind = kind.slice(0, kind.length - 'Type'.length);
throw error_1.ERRORS.KEY_FIELDS_SELECT_INVALID_TYPE.err(`field "${field.coordinate}" is a ${kind} type which is not allowed in @key`);
}
}
});
validateAllFieldSet(metadata.requiresDirective(), field => field.parent, errors, metadata, false, false);
validateAllFieldSet(metadata.providesDirective(), field => {
if (metadata.isFieldExternal(field)) {
throw error_1.ERRORS.EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE.err(`Cannot have both @provides and @external on field "${field.coordinate}"`, { nodes: field.sourceAST });
}
const type = (0, definitions_1.baseType)(field.type);
if (!(0, definitions_1.isCompositeType)(type)) {
throw error_1.ERRORS.PROVIDES_ON_NON_OBJECT_FIELD.err(`Invalid @provides directive on field "${field.coordinate}": field has type "${field.type}" which is not a Composite Type`, { nodes: field.sourceAST });
}
return type;
}, errors, metadata, false, false);
validateNoExternalOnInterfaceFields(metadata, errors);
validateAllExternalFieldsUsed(metadata, errors);
validateAllFieldSet({
definition: metadata.requiresDirective(),
targetTypeExtractor: field => field.parent,
errorCollector,
metadata,
allowFieldsWithArguments: true,
});
validateAllFieldSet({
definition: metadata.providesDirective(),
targetTypeExtractor: field => {
if (metadata.isFieldExternal(field)) {
throw error_1.ERRORS.EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE.err(`Cannot have both @provides and @external on field "${field.coordinate}"`, { nodes: field.sourceAST });
}
const type = (0, definitions_1.baseType)(field.type);
if (!(0, definitions_1.isCompositeType)(type)) {
throw error_1.ERRORS.PROVIDES_ON_NON_OBJECT_FIELD.err(`Invalid @provides directive on field "${field.coordinate}": field has type "${field.type}" which is not a Composite Type`, { nodes: field.sourceAST });
}
return type;
},
errorCollector,
metadata,
});
validateNoExternalOnInterfaceFields(metadata, errorCollector);
validateAllExternalFieldsUsed(metadata, errorCollector);
const tagDirective = metadata.tagDirective();

@@ -503,9 +554,9 @@ if (tagDirective) {

if (error) {
errors.push(error);
errorCollector.push(error);
}
}
for (const itf of schema.interfaceTypes()) {
validateInterfaceRuntimeImplementationFieldsTypes(itf, metadata, errors);
validateInterfaceRuntimeImplementationFieldsTypes(itf, metadata, errorCollector);
}
return errors;
return errorCollector;
}

@@ -740,5 +791,5 @@ validationRules() {

}
function parseFieldSetArgument({ parentType, directive, fieldAccessor, validate, }) {
function parseFieldSetArgument({ parentType, directive, fieldAccessor, validate, decorateValidationErrors = true, }) {
try {
return (0, operations_1.parseSelectionSet)({
const selectionSet = (0, operations_1.parseSelectionSet)({
parentType,

@@ -749,5 +800,13 @@ source: validateFieldSetValue(directive),

});
if (validate !== null && validate !== void 0 ? validate : true) {
selectionSet.forEachElement((elt) => {
if (elt.kind === 'Field' && elt.alias) {
throw new graphql_1.GraphQLError(`Cannot use alias "${elt.alias}" in "${elt}": aliases are not currently supported in @${directive.name}`);
}
});
}
return selectionSet;
}
catch (e) {
if (!(e instanceof graphql_1.GraphQLError)) {
if (!(e instanceof graphql_1.GraphQLError) || !decorateValidationErrors) {
throw e;

@@ -1014,2 +1073,5 @@ }

function addSubgraphToASTNode(node, subgraph) {
if ('subgraph' in node) {
return node;
}
return {

@@ -1016,0 +1078,0 @@ ...node,

@@ -167,2 +167,3 @@ import { DocumentNode, FieldNode, FragmentDefinitionNode, SelectionNode, SelectionSetNode } from "graphql";

private toOperationPathsInternal;
forEachElement(callback: (elt: OperationElement) => void): void;
clone(): SelectionSet;

@@ -169,0 +170,0 @@ toOperationString(rootKind: SchemaRootKind, variableDefinitions: VariableDefinitions, operationName?: string, expandFragments?: boolean, prettyPrint?: boolean): string;

@@ -545,3 +545,3 @@ "use strict";

if (!expectedType) {
throw error_1.ERRORS.INVALID_GRAPHQL.err(`Unknown argument "${name}" found in value: ${context} has no argument named "${name}"`);
throw error_1.ERRORS.INVALID_GRAPHQL.err(`Unknown argument "${name}" found in value: "${context}" has no argument named "${name}"`);
}

@@ -553,3 +553,3 @@ try {

if (e instanceof graphql_1.GraphQLError) {
throw error_1.ERRORS.INVALID_GRAPHQL.err(`Invalid value for argument ${name}: ${e.message}`);
throw error_1.ERRORS.INVALID_GRAPHQL.err(`Invalid value for argument "${name}": ${e.message}`);
}

@@ -556,0 +556,0 @@ throw e;

{
"name": "@apollo/federation-internals",
"version": "2.1.2-alpha.1",
"version": "2.1.2-alpha.2",
"description": "Apollo Federation internal utilities",

@@ -35,3 +35,3 @@ "main": "dist/index.js",

},
"gitHead": "d4da310a8aa3ef93350a3de0c5a32692bb2d8e0b"
"gitHead": "c7bb87702c5913f5a0ecc5c2a28d2f7228e2988c"
}

@@ -63,18 +63,2 @@ import { DocumentNode } from 'graphql';

it('rejects field defined with arguments in @requires', () => {
const subgraph = gql`
type Query {
t: T
}
type T {
f(x: Int): Int @external
g: Int @requires(fields: "f")
}
`
expect(buildForErrors(subgraph)).toStrictEqual([
['REQUIRES_FIELDS_HAS_ARGS', '[S] On field "T.g", for @requires(fields: "f"): field T.f cannot be included because it has arguments (fields with argument are not allowed in @requires)']
]);
});
it('rejects @provides on non-external fields', () => {

@@ -463,2 +447,57 @@ const subgraph = gql`

});
it('rejects aliases in @key', () => {
const subgraph = gql`
type Query {
t: T
}
type T @key(fields: "foo: id") {
id: ID!
}
`
expect(buildForErrors(subgraph)).toStrictEqual([
[ 'KEY_INVALID_FIELDS', '[S] On type "T", for @key(fields: "foo: id"): Cannot use alias "foo" in "foo: id": aliases are not currently supported in @key' ],
]);
});
it('rejects aliases in @provides', () => {
const subgraph = gql`
type Query {
t: T @provides(fields: "bar: x")
}
type T @key(fields: "id") {
id: ID!
x: Int @external
}
`
expect(buildForErrors(subgraph)).toStrictEqual([
[ 'PROVIDES_INVALID_FIELDS', '[S] On field "Query.t", for @provides(fields: "bar: x"): Cannot use alias "bar" in "bar: x": aliases are not currently supported in @provides' ],
]);
});
it('rejects aliases in @requires', () => {
const subgraph = gql`
type Query {
t: T
}
type T {
x: X @external
y: Int @external
g: Int @requires(fields: "foo: y")
h: Int @requires(fields: "x { m: a n: b }")
}
type X {
a: Int
b: Int
}
`
expect(buildForErrors(subgraph)).toStrictEqual([
[ 'REQUIRES_INVALID_FIELDS', '[S] On field "T.g", for @requires(fields: "foo: y"): Cannot use alias "foo" in "foo: y": aliases are not currently supported in @requires' ],
[ 'REQUIRES_INVALID_FIELDS', '[S] On field "T.h", for @requires(fields: "x { m: a n: b }"): Cannot use alias "m" in "m: a": aliases are not currently supported in @requires' ],
]);
});
});

@@ -465,0 +504,0 @@

@@ -226,3 +226,2 @@ import { ASTNode, GraphQLError, GraphQLErrorOptions, GraphQLFormattedError } from "graphql";

const PROVIDES_FIELDS_HAS_ARGS = FIELDS_HAS_ARGS.createCode('provides');
const REQUIRES_FIELDS_HAS_ARGS = FIELDS_HAS_ARGS.createCode('requires');

@@ -549,3 +548,2 @@ const DIRECTIVE_FIELDS_MISSING_EXTERNAL = makeFederationDirectiveErrorCodeCategory(

PROVIDES_FIELDS_HAS_ARGS,
REQUIRES_FIELDS_HAS_ARGS,
PROVIDES_MISSING_EXTERNAL,

@@ -649,2 +647,3 @@ REQUIRES_MISSING_EXTERNAL,

['NON_REPEATABLE_DIRECTIVE_ARGUMENTS_MISMATCH', 'Since federation 2.1.0, the case this error used to cover is now a warning (with code `INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS`) instead of an error'],
['REQUIRES_FIELDS_HAS_ARGS', 'Since federation 2.1.1, using fields with arguments in a @requires is fully supported'],
];

@@ -704,3 +704,3 @@ import {

throw ERRORS.INVALID_GRAPHQL.err(
`Unknown argument "${name}" found in value: ${context} has no argument named "${name}"`
`Unknown argument "${name}" found in value: "${context}" has no argument named "${name}"`
);

@@ -712,3 +712,3 @@ }

if (e instanceof GraphQLError) {
throw ERRORS.INVALID_GRAPHQL.err(`Invalid value for argument ${name}: ${e.message}`);
throw ERRORS.INVALID_GRAPHQL.err(`Invalid value for argument "${name}": ${e.message}`);
}

@@ -715,0 +715,0 @@ throw e;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc