@wundergraph/composition 0.58.3 → 0.59.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/dist/errors/errors.d.ts +18 -11
- package/dist/errors/errors.js +64 -29
- package/dist/errors/errors.js.map +1 -1
- package/dist/federation/types/results.d.ts +6 -0
- package/dist/federation/types/results.js +3 -0
- package/dist/federation/types/results.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/composition-version.js +1 -1
- package/dist/v1/federation/federation-factory.d.ts +9 -4
- package/dist/v1/federation/federation-factory.js +160 -45
- package/dist/v1/federation/federation-factory.js.map +1 -1
- package/dist/v1/federation/types/params.d.ts +15 -1
- package/dist/v1/normalization/normalization-factory.js +94 -11
- package/dist/v1/normalization/normalization-factory.js.map +1 -1
- package/package.json +2 -2
|
@@ -1801,6 +1801,12 @@ class NormalizationFactory {
|
|
|
1801
1801
|
sizedFields: [],
|
|
1802
1802
|
requireOneSlicingArgument: true, // per IBM cost spec
|
|
1803
1803
|
};
|
|
1804
|
+
/**
|
|
1805
|
+
* For each accepted slicing argument, capture the full resolved chain:
|
|
1806
|
+
* (argument + each intermediate input field + leaf).
|
|
1807
|
+
* Later we check the assumedSize against the default value of every element of the chain.
|
|
1808
|
+
*/
|
|
1809
|
+
const slicingArgChainByPath = new Map();
|
|
1804
1810
|
for (const argumentNode of args) {
|
|
1805
1811
|
const argumentName = argumentNode.name.value;
|
|
1806
1812
|
// type validation handled upstream
|
|
@@ -1830,18 +1836,61 @@ class NormalizationFactory {
|
|
|
1830
1836
|
if (valueNode.kind !== graphql_1.Kind.STRING) {
|
|
1831
1837
|
continue;
|
|
1832
1838
|
}
|
|
1833
|
-
|
|
1834
|
-
const
|
|
1839
|
+
// slicingArgPath could be just an argument "inputA" or a dot-path "inputA.page.first".
|
|
1840
|
+
const slicingArgPath = valueNode.value;
|
|
1841
|
+
const segments = slicingArgPath.split(string_constants_1.LITERAL_PERIOD);
|
|
1842
|
+
// Reject empty segments (e.g. "", "a.", ".b", "a..b").
|
|
1843
|
+
if (segments.length === 0 || segments.some((s) => s.length === 0)) {
|
|
1844
|
+
errorMessages.push((0, errors_1.listSizeSlicingArgumentMalformedPathErrorMessage)(directiveCoords, slicingArgPath));
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1847
|
+
// First segment should be valid argument name:
|
|
1848
|
+
const firstSegment = segments[0];
|
|
1849
|
+
const argData = data.argumentDataByName.get(firstSegment);
|
|
1835
1850
|
if (!argData) {
|
|
1836
|
-
errorMessages.push((0, errors_1.listSizeInvalidSlicingArgumentErrorMessage)(directiveCoords,
|
|
1851
|
+
errorMessages.push((0, errors_1.listSizeInvalidSlicingArgumentErrorMessage)(directiveCoords, slicingArgPath));
|
|
1852
|
+
continue;
|
|
1853
|
+
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Walk the rest of the path in the slicingArgument.
|
|
1856
|
+
* `current` tracks the input value reached so far:
|
|
1857
|
+
* the argument itself for a flat path, or the nested input field for each step of a
|
|
1858
|
+
* dot-path. After the loop it is the leaf, which must be Int/Int!.
|
|
1859
|
+
*/
|
|
1860
|
+
let current = argData;
|
|
1861
|
+
const chain = [argData];
|
|
1862
|
+
let isPathInvalid = false;
|
|
1863
|
+
for (let i = 1; i < segments.length; i++) {
|
|
1864
|
+
// Non-leaf step: `current` must unwrap to an Input Object. Lists are rejected here.
|
|
1865
|
+
const unwrapped = current.type.kind === graphql_1.Kind.NON_NULL_TYPE ? current.type.type : current.type;
|
|
1866
|
+
const parentTypeData = this.parentDefinitionDataByTypeName.get(current.namedTypeName);
|
|
1867
|
+
if (unwrapped.kind === graphql_1.Kind.LIST_TYPE ||
|
|
1868
|
+
!parentTypeData ||
|
|
1869
|
+
parentTypeData.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION) {
|
|
1870
|
+
errorMessages.push((0, errors_1.listSizeSlicingArgumentSegmentNotInputObjectErrorMessage)(directiveCoords, slicingArgPath, current.name, (0, merge_1.printTypeNode)(current.type)));
|
|
1871
|
+
isPathInvalid = true;
|
|
1872
|
+
break;
|
|
1873
|
+
}
|
|
1874
|
+
const inputValue = parentTypeData.inputValueDataByName.get(segments[i]);
|
|
1875
|
+
if (!inputValue) {
|
|
1876
|
+
errorMessages.push((0, errors_1.listSizeSlicingArgumentSegmentNotFoundErrorMessage)(directiveCoords, slicingArgPath, segments[i], current.namedTypeName));
|
|
1877
|
+
isPathInvalid = true;
|
|
1878
|
+
break;
|
|
1879
|
+
}
|
|
1880
|
+
current = inputValue;
|
|
1881
|
+
chain.push(inputValue);
|
|
1882
|
+
}
|
|
1883
|
+
if (isPathInvalid) {
|
|
1837
1884
|
continue;
|
|
1838
1885
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1886
|
+
// Leaf check: the final value must be Int or Int!
|
|
1887
|
+
const unwrappedType = current.type.kind === graphql_1.Kind.NON_NULL_TYPE ? current.type.type : current.type;
|
|
1888
|
+
if (unwrappedType.kind === graphql_1.Kind.LIST_TYPE || current.namedTypeName !== string_constants_1.INT_SCALAR) {
|
|
1889
|
+
errorMessages.push((0, errors_1.listSizeSlicingArgumentNotIntErrorMessage)(directiveCoords, slicingArgPath, (0, merge_1.printTypeNode)(current.type)));
|
|
1842
1890
|
continue;
|
|
1843
1891
|
}
|
|
1844
|
-
listSizeConfig.slicingArguments.push(
|
|
1892
|
+
listSizeConfig.slicingArguments.push(slicingArgPath);
|
|
1893
|
+
slicingArgChainByPath.set(slicingArgPath, chain);
|
|
1845
1894
|
}
|
|
1846
1895
|
break;
|
|
1847
1896
|
}
|
|
@@ -1897,10 +1946,44 @@ class NormalizationFactory {
|
|
|
1897
1946
|
errorMessages.push((0, errors_1.listSizeAssumedSizeWithRequiredSlicingArgumentErrorMessage)(directiveCoords));
|
|
1898
1947
|
}
|
|
1899
1948
|
else {
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1949
|
+
/**
|
|
1950
|
+
* When assumedSize is set together with slicingArguments, the slicing argument must not have
|
|
1951
|
+
* a default leaf value in any element of the slicingArgument's chain.
|
|
1952
|
+
* That will be checked for all slicing Arguments.
|
|
1953
|
+
* For example, if the query is defined like this:
|
|
1954
|
+
* search(a: SearchInput): [Book]
|
|
1955
|
+
* @listSize(assumedSize: 50, slicingArguments: ["a.b.c"], requireOneSlicingArgument: false)
|
|
1956
|
+
* any of those defaults are forbidden:
|
|
1957
|
+
* input SearchInput { b: PaginationInput = { c: 10 } }
|
|
1958
|
+
* input PaginationInput { c: Int = 10 }
|
|
1959
|
+
* Notably, this query definition is also forbidden with the @listSize above:
|
|
1960
|
+
* search(a: SearchInput = { b: { c: 10 } }): [Book]
|
|
1961
|
+
* A default along the chain only matters if it actually supplies a value for the leaf:
|
|
1962
|
+
* walk the remaining tail through the default's AST and reject only when the walk resolves.
|
|
1963
|
+
* E.g. `a: SearchInput = { b: {} }` is allowed, and the leaf stays undefined.
|
|
1964
|
+
*/
|
|
1965
|
+
for (const slicingArgPath of listSizeConfig.slicingArguments) {
|
|
1966
|
+
const chain = slicingArgChainByPath.get(slicingArgPath);
|
|
1967
|
+
if (!chain) {
|
|
1968
|
+
continue;
|
|
1969
|
+
}
|
|
1970
|
+
const segments = slicingArgPath.split(string_constants_1.LITERAL_PERIOD);
|
|
1971
|
+
// Outer loop: which default are we starting from?
|
|
1972
|
+
for (let i = 0; i < chain.length; i++) {
|
|
1973
|
+
let value = chain[i].defaultValue;
|
|
1974
|
+
// Inner loop: try to find a defined leaf in the chain:
|
|
1975
|
+
for (let j = i + 1; j < segments.length; j++) {
|
|
1976
|
+
if (!value || value.kind !== graphql_1.Kind.OBJECT) {
|
|
1977
|
+
value = undefined;
|
|
1978
|
+
break;
|
|
1979
|
+
}
|
|
1980
|
+
const field = value.fields.find((f) => f.name.value === segments[j]);
|
|
1981
|
+
value = field?.value;
|
|
1982
|
+
}
|
|
1983
|
+
if (value !== undefined) {
|
|
1984
|
+
errorMessages.push((0, errors_1.listSizeAssumedSizeSlicingArgDefaultErrorMessage)(directiveCoords, slicingArgPath));
|
|
1985
|
+
break;
|
|
1986
|
+
}
|
|
1904
1987
|
}
|
|
1905
1988
|
}
|
|
1906
1989
|
}
|