@hestia-earth/data-validation 0.41.14 → 0.41.16

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.
@@ -57,7 +57,7 @@ declare const urlConfig: (baseUrl?: string) => IUrlConfig;
57
57
  * primary entry point). They are kept structurally compatible on purpose.
58
58
  */
59
59
  type validationErrorLevel = 'error' | 'warning';
60
- type validationErrorParam = 'missingProperty' | 'type' | 'term' | 'termType' | 'termIds' | 'model' | 'product' | 'range' | 'node' | 'allowedValues' | 'allowedValue' | 'additionalProperty' | 'expected' | 'default' | 'current' | 'percentage' | 'keys' | 'threshold' | 'outliers' | 'country' | 'min' | 'max' | 'mu' | 'sd' | 'defaultSource' | 'source' | 'group' | 'message' | 'distance' | 'siteType' | 'products' | 'units' | 'duplicatedIndexes' | 'invalidCoordinates' | 'ids' | 'limit' | 'delta' | 'newlyCovered' | 'recommended' | 'missing';
60
+ type validationErrorParam = 'missingProperty' | 'type' | 'term' | 'termType' | 'termIds' | 'model' | 'product' | 'range' | 'node' | 'allowedValues' | 'allowedValue' | 'additionalProperty' | 'expected' | 'default' | 'current' | 'percentage' | 'keys' | 'threshold' | 'outliers' | 'country' | 'min' | 'max' | 'mu' | 'sd' | 'defaultSource' | 'source' | 'group' | 'message' | 'distance' | 'siteType' | 'products' | 'units' | 'duplicatedIndexes' | 'invalidCoordinates' | 'ids' | 'limit' | 'delta' | 'newlyCovered' | 'recommended' | 'missing' | 'cause' | 'compound';
61
61
  type validationErrorKeyword = 'required' | 'type' | 'if' | 'then' | 'not';
62
62
  interface ICustomValidationRules {
63
63
  const?: any;
@@ -57,7 +57,7 @@ declare const urlConfig: (baseUrl?: string) => IUrlConfig;
57
57
  * primary entry point). They are kept structurally compatible on purpose.
58
58
  */
59
59
  type validationErrorLevel = 'error' | 'warning';
60
- type validationErrorParam = 'missingProperty' | 'type' | 'term' | 'termType' | 'termIds' | 'model' | 'product' | 'range' | 'node' | 'allowedValues' | 'allowedValue' | 'additionalProperty' | 'expected' | 'default' | 'current' | 'percentage' | 'keys' | 'threshold' | 'outliers' | 'country' | 'min' | 'max' | 'mu' | 'sd' | 'defaultSource' | 'source' | 'group' | 'message' | 'distance' | 'siteType' | 'products' | 'units' | 'duplicatedIndexes' | 'invalidCoordinates' | 'ids' | 'limit' | 'delta' | 'newlyCovered' | 'recommended' | 'missing';
60
+ type validationErrorParam = 'missingProperty' | 'type' | 'term' | 'termType' | 'termIds' | 'model' | 'product' | 'range' | 'node' | 'allowedValues' | 'allowedValue' | 'additionalProperty' | 'expected' | 'default' | 'current' | 'percentage' | 'keys' | 'threshold' | 'outliers' | 'country' | 'min' | 'max' | 'mu' | 'sd' | 'defaultSource' | 'source' | 'group' | 'message' | 'distance' | 'siteType' | 'products' | 'units' | 'duplicatedIndexes' | 'invalidCoordinates' | 'ids' | 'limit' | 'delta' | 'newlyCovered' | 'recommended' | 'missing' | 'cause' | 'compound';
61
61
  type validationErrorKeyword = 'required' | 'type' | 'if' | 'then' | 'not';
62
62
  interface ICustomValidationRules {
63
63
  const?: any;
@@ -297,6 +297,11 @@ var validations = [
297
297
  level: "error",
298
298
  message: "at least one landCover practice must match an equivalent product"
299
299
  },
300
+ {
301
+ function: "validate_coverCrop_landCover_primary_product",
302
+ level: "error",
303
+ message: "a cover crop can not be the land cover of the primary product"
304
+ },
300
305
  {
301
306
  function: "validate_practices_management",
302
307
  level: "error",
@@ -327,6 +332,11 @@ var validations = [
327
332
  level: "error",
328
333
  message: "is outside the allowed range"
329
334
  },
335
+ {
336
+ function: "validate_soilTexture_depths",
337
+ level: "warning",
338
+ message: "should be given at the same depths as the soil content"
339
+ },
330
340
  {
331
341
  function: "validate_depths",
332
342
  level: "error",
@@ -622,6 +632,11 @@ var validations = [
622
632
  level: "warning",
623
633
  message: "should add missing inputs"
624
634
  },
635
+ {
636
+ function: "validate_compound_fertiliser_composition",
637
+ level: "warning",
638
+ message: "should match the nutrient ratio of the compound fertiliser"
639
+ },
625
640
  {
626
641
  function: "validate_related_impacts",
627
642
  level: "error",
@@ -1433,6 +1448,25 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
1433
1448
  At least one measurement of sand, silt, or clay content does not match the possible range for the specified soil texture.`}
1434
1449
  ${errorCount === 1 ? "Please check the measurement, its depth intervals, and the dates of the measurement or update the soil texture if needed." : "Please check your measurements, their depth intervals, and the dates of the measurements or update the soil textures if needed."}`;
1435
1450
  },
1451
+ "should be given at the same depths as the soil content": ({ params }) => {
1452
+ var _a, _b, _c;
1453
+ const formatDepths = (depths) => {
1454
+ var _a2, _b2;
1455
+ return `${(_a2 = depths == null ? void 0 : depths.depthUpper) != null ? _a2 : "-"}-${(_b2 = depths == null ? void 0 : depths.depthLower) != null ? _b2 : "-"} cm`;
1456
+ };
1457
+ return `The soil texture ${termLink({
1458
+ id: (_a = params == null ? void 0 : params.term) == null ? void 0 : _a["@id"],
1459
+ name: (_b = params == null ? void 0 : params.term) == null ? void 0 : _b.name
1460
+ })} is given at ${code(
1461
+ formatDepths(params == null ? void 0 : params.current)
1462
+ )}, but the sand, silt and clay content are only given at ${joinValues(
1463
+ ((_c = params == null ? void 0 : params.expected) != null ? _c : []).map(formatDepths)
1464
+ )}.
1465
+ The soil texture is only checked against the sand, silt and clay content measured at the same ${code(
1466
+ "depthUpper"
1467
+ )} and ${code("depthLower")}, so at this depth the two are never compared.
1468
+ Please add the sand, silt and clay content at the same depths as the soil texture.`;
1469
+ },
1436
1470
  "should be equal to one of the allowed values": ({ params, dataPath, schemaPath }, count, errors) => {
1437
1471
  var _a, _b;
1438
1472
  const paths = parseDataPath(dataPath);
@@ -1940,26 +1974,29 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
1940
1974
  schema.TermTermType.liveAnimal
1941
1975
  )} to the ${schemaLink("Cycle#animals", "Animal")} blank nodes.
1942
1976
  The allowed product ids are: ${listAsCode(params == null ? void 0 : params.expected)}`,
1943
- "duration must be in specified interval": ({ params: { term } = {} }) => ["shortFallow", "shortBareFallow"].includes(term["@id"]) ? `${code("Short fallow")} is defined as land left fallow for less than 365 days.
1944
- Please check the ${schemaLink("Management#startDate", "startDate")} and ${schemaLink(
1945
- "Management#endDate",
1946
- "endDate"
1947
- )} on this term and ensure the difference between the two dates is less than 365 days.
1977
+ "duration must be in specified interval": ({ dataPath, params: { term } = {} }) => {
1978
+ const node = /\.practices\[\d+\]$/.test(dataPath != null ? dataPath : "") ? "Practice" : "Management";
1979
+ return ["shortFallow", "shortBareFallow"].includes(term["@id"]) ? `${code("Short fallow")} is defined as land left fallow for less than 365 days.
1980
+ Please check the ${schemaLink(`${node}#startDate`, "startDate")} and ${schemaLink(
1981
+ `${node}#endDate`,
1982
+ "endDate"
1983
+ )} on this term and ensure the difference between the two dates is less than 365 days.
1948
1984
  If it is more than 365 days, consider using the terms ${code("Long fallow")} or ${code("Set aside")} instead.` : ["longFallow", "longBareFallow"].includes(term["@id"]) ? `${code("Long fallow")} is defined as land left fallow for more than a year but less than five years.
1949
- Please check the ${schemaLink("Management#startDate", "startDate")} and ${schemaLink(
1950
- "Management#endDate",
1951
- "endDate"
1952
- )} on this term and ensure the difference between the two dates falls between 365 and 1826 days.
1985
+ Please check the ${schemaLink(`${node}#startDate`, "startDate")} and ${schemaLink(
1986
+ `${node}#endDate`,
1987
+ "endDate"
1988
+ )} on this term and ensure the difference between the two dates falls between 365 and 1826 days.
1953
1989
  If it is less than 365 days, consider using the term ${code("Short fallow")} instead.
1954
1990
  If it is more than 1826 days, consider using the term ${code("Set aside")} instead.` : `${code(
1955
- "Set aside"
1956
- )} is defined as the temporary set aside of land for more than five years but less than twenty years.
1957
- Please check the ${schemaLink("Management#startDate", "startDate")} and ${schemaLink(
1958
- "Management#endDate",
1959
- "endDate"
1960
- )} on this term and ensure the difference between the two dates falls between 1826 and 7305 days.
1991
+ "Set aside"
1992
+ )} is defined as the temporary set aside of land for more than five years but less than twenty years.
1993
+ Please check the ${schemaLink(`${node}#startDate`, "startDate")} and ${schemaLink(
1994
+ `${node}#endDate`,
1995
+ "endDate"
1996
+ )} on this term and ensure the difference between the two dates falls between 1826 and 7305 days.
1961
1997
  If it is less than 1826 days, consider using the terms ${code("Short fallow")}or ${code("Long fallow")} instead.
1962
- If it is more than 7305 days, consider using the term ${code("Other natural vegetation")} instead.`,
1998
+ If it is more than 7305 days, consider using the term ${code("Other natural vegetation")} instead.`;
1999
+ },
1963
2000
  "must not add the feed input to the Cycle as well": ({ params: { term } = {} }) => `You have added the animal feed Input ${code(term["@id"])} to the Cycle inputs as well, which might lead to double counting.
1964
2001
  If you do not know the amount of ${code(term["@id"])} given to each Animal, please add the Input to the Cycle only.`,
1965
2002
  "must provide value or min and max": ({ params }) => {
@@ -2160,6 +2197,11 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
2160
2197
  `If specifying fallow periods, you must also include the Product's equivalent Practice with a ${code("startDate")} and ${code("endDate")}.`,
2161
2198
  `Alternatively, do not set these ${code(schema.TermTermType.landCover)} practices, and they will be gap filled automatically from products.`
2162
2199
  ])}`,
2200
+ "a cover crop can not be the land cover of the primary product": ({ params }) => {
2201
+ var _a, _b, _c, _d;
2202
+ return `The ${termLink({ id: (_a = params == null ? void 0 : params.term) == null ? void 0 : _a["@id"], name: (_b = params == null ? void 0 : params.term) == null ? void 0 : _b.name })} Practice is set as a cover crop, but it is the land cover of ${termLink({ id: (_c = params == null ? void 0 : params.product) == null ? void 0 : _c["@id"], name: (_d = params == null ? void 0 : params.product) == null ? void 0 : _d.name })}, the primary Product of this Cycle. HESTIA counts the land cover of a cover crop separately from the main crop, so this land cover would be counted twice.
2203
+ Remove the cover crop property from this Practice, and add the cover crop as its own ${code(schema.TermTermType.landCover)} Practice if it is known.`;
2204
+ },
2163
2205
  "should match the site management node value": ({ params }) => `The data you have uploaded in the Management node are not consistent with the data provided in the Cycles.
2164
2206
  ${typeof (params == null ? void 0 : params.current) === "boolean" ? `A ${code("Management")} node must have the same ${code("value")} as every Practice using the same ${code("term")} between the same ${code("startDate")} and ${code("endDate")} \u2014 your Cycles say ${code(params == null ? void 0 : params.current)}, but the ${code("Management")} node has ${code(params == null ? void 0 : params.expected)}.` : `The ${code("value")} of a ${code("Management")} node must be the total of every Practice using the same ${code("term")} between the same ${code("startDate")} and ${code("endDate")} \u2014 your Cycles add up to ${code(params == null ? void 0 : params.current)}, but the ${code("Management")} node has ${code(params == null ? void 0 : params.expected)}.`}
2165
2207
  Please check your upload and ensure that the data is consistent throughout.`,
@@ -2257,6 +2299,23 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
2257
2299
  "must equal to endDate - startDate in decimal years": ({ params: { expected } }) => `Must be equal to ${code("endDate")} - ${code("startDate")} in years (~${expected})`,
2258
2300
  "must be more than or equal to other crop residues": ({ params: { expected } }) => `Must be more than or equal to sum(${expected.join(" + ")})`,
2259
2301
  "should add missing inputs": ({ params: { expected } }) => `Should add missing inputs: ${listAsCode(expected)}`,
2302
+ "should match the nutrient ratio of the compound fertiliser": ({ params }) => {
2303
+ var _a, _b;
2304
+ const [denominator, numerator] = ((_a = params == null ? void 0 : params.termIds) != null ? _a : []).map((id) => termLink({ id }));
2305
+ const expected = (params == null ? void 0 : params.min) === (params == null ? void 0 : params.max) ? code(params == null ? void 0 : params.min) : `${code(params == null ? void 0 : params.min)} to ${code(params == null ? void 0 : params.max)}`;
2306
+ const causes = {
2307
+ swapped: "This is close to the inverse of the expected ratio: the values of the two Inputs may have been swapped.",
2308
+ elemental: `This is close to the expected ratio converted to elements: the value may have been given as kg of elemental P or K rather than kg of ${code(
2309
+ "P2O5"
2310
+ )} or ${code("K2O")}.`,
2311
+ otherCompound: `This is close to the ratio of ${termLink({
2312
+ id: params == null ? void 0 : params.compound
2313
+ })}: the values may have been calculated from the composition of another fertiliser.`
2314
+ };
2315
+ return `The value of ${numerator} divided by the value of ${denominator} is ${code(params == null ? void 0 : params.current)}, but the composition of this fertiliser gives a ratio of ${expected}.
2316
+ ${(_b = causes[params == null ? void 0 : params.cause]) != null ? _b : ""}
2317
+ Please check that both Inputs are the amounts of each nutrient applied with this fertiliser.`;
2318
+ },
2260
2319
  "the property value type is incorrect": ({ params: { expected } }) => `The value must be a ${expected}.`,
2261
2320
  "the node value type is incorrect": ({ params: { expected } }) => `The value must be a ${expected}.`,
2262
2321
  "can not be linked to the same type": ({ params: { current } }) => `Cannot be linked to the same ${current}.`,
@@ -295,6 +295,11 @@ var validations = [
295
295
  level: "error",
296
296
  message: "at least one landCover practice must match an equivalent product"
297
297
  },
298
+ {
299
+ function: "validate_coverCrop_landCover_primary_product",
300
+ level: "error",
301
+ message: "a cover crop can not be the land cover of the primary product"
302
+ },
298
303
  {
299
304
  function: "validate_practices_management",
300
305
  level: "error",
@@ -325,6 +330,11 @@ var validations = [
325
330
  level: "error",
326
331
  message: "is outside the allowed range"
327
332
  },
333
+ {
334
+ function: "validate_soilTexture_depths",
335
+ level: "warning",
336
+ message: "should be given at the same depths as the soil content"
337
+ },
328
338
  {
329
339
  function: "validate_depths",
330
340
  level: "error",
@@ -620,6 +630,11 @@ var validations = [
620
630
  level: "warning",
621
631
  message: "should add missing inputs"
622
632
  },
633
+ {
634
+ function: "validate_compound_fertiliser_composition",
635
+ level: "warning",
636
+ message: "should match the nutrient ratio of the compound fertiliser"
637
+ },
623
638
  {
624
639
  function: "validate_related_impacts",
625
640
  level: "error",
@@ -1431,6 +1446,25 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
1431
1446
  At least one measurement of sand, silt, or clay content does not match the possible range for the specified soil texture.`}
1432
1447
  ${errorCount === 1 ? "Please check the measurement, its depth intervals, and the dates of the measurement or update the soil texture if needed." : "Please check your measurements, their depth intervals, and the dates of the measurements or update the soil textures if needed."}`;
1433
1448
  },
1449
+ "should be given at the same depths as the soil content": ({ params }) => {
1450
+ var _a, _b, _c;
1451
+ const formatDepths = (depths) => {
1452
+ var _a2, _b2;
1453
+ return `${(_a2 = depths == null ? void 0 : depths.depthUpper) != null ? _a2 : "-"}-${(_b2 = depths == null ? void 0 : depths.depthLower) != null ? _b2 : "-"} cm`;
1454
+ };
1455
+ return `The soil texture ${termLink({
1456
+ id: (_a = params == null ? void 0 : params.term) == null ? void 0 : _a["@id"],
1457
+ name: (_b = params == null ? void 0 : params.term) == null ? void 0 : _b.name
1458
+ })} is given at ${code(
1459
+ formatDepths(params == null ? void 0 : params.current)
1460
+ )}, but the sand, silt and clay content are only given at ${joinValues(
1461
+ ((_c = params == null ? void 0 : params.expected) != null ? _c : []).map(formatDepths)
1462
+ )}.
1463
+ The soil texture is only checked against the sand, silt and clay content measured at the same ${code(
1464
+ "depthUpper"
1465
+ )} and ${code("depthLower")}, so at this depth the two are never compared.
1466
+ Please add the sand, silt and clay content at the same depths as the soil texture.`;
1467
+ },
1434
1468
  "should be equal to one of the allowed values": ({ params, dataPath, schemaPath }, count, errors) => {
1435
1469
  var _a, _b;
1436
1470
  const paths = parseDataPath(dataPath);
@@ -1938,26 +1972,29 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
1938
1972
  TermTermType.liveAnimal
1939
1973
  )} to the ${schemaLink("Cycle#animals", "Animal")} blank nodes.
1940
1974
  The allowed product ids are: ${listAsCode(params == null ? void 0 : params.expected)}`,
1941
- "duration must be in specified interval": ({ params: { term } = {} }) => ["shortFallow", "shortBareFallow"].includes(term["@id"]) ? `${code("Short fallow")} is defined as land left fallow for less than 365 days.
1942
- Please check the ${schemaLink("Management#startDate", "startDate")} and ${schemaLink(
1943
- "Management#endDate",
1944
- "endDate"
1945
- )} on this term and ensure the difference between the two dates is less than 365 days.
1975
+ "duration must be in specified interval": ({ dataPath, params: { term } = {} }) => {
1976
+ const node = /\.practices\[\d+\]$/.test(dataPath != null ? dataPath : "") ? "Practice" : "Management";
1977
+ return ["shortFallow", "shortBareFallow"].includes(term["@id"]) ? `${code("Short fallow")} is defined as land left fallow for less than 365 days.
1978
+ Please check the ${schemaLink(`${node}#startDate`, "startDate")} and ${schemaLink(
1979
+ `${node}#endDate`,
1980
+ "endDate"
1981
+ )} on this term and ensure the difference between the two dates is less than 365 days.
1946
1982
  If it is more than 365 days, consider using the terms ${code("Long fallow")} or ${code("Set aside")} instead.` : ["longFallow", "longBareFallow"].includes(term["@id"]) ? `${code("Long fallow")} is defined as land left fallow for more than a year but less than five years.
1947
- Please check the ${schemaLink("Management#startDate", "startDate")} and ${schemaLink(
1948
- "Management#endDate",
1949
- "endDate"
1950
- )} on this term and ensure the difference between the two dates falls between 365 and 1826 days.
1983
+ Please check the ${schemaLink(`${node}#startDate`, "startDate")} and ${schemaLink(
1984
+ `${node}#endDate`,
1985
+ "endDate"
1986
+ )} on this term and ensure the difference between the two dates falls between 365 and 1826 days.
1951
1987
  If it is less than 365 days, consider using the term ${code("Short fallow")} instead.
1952
1988
  If it is more than 1826 days, consider using the term ${code("Set aside")} instead.` : `${code(
1953
- "Set aside"
1954
- )} is defined as the temporary set aside of land for more than five years but less than twenty years.
1955
- Please check the ${schemaLink("Management#startDate", "startDate")} and ${schemaLink(
1956
- "Management#endDate",
1957
- "endDate"
1958
- )} on this term and ensure the difference between the two dates falls between 1826 and 7305 days.
1989
+ "Set aside"
1990
+ )} is defined as the temporary set aside of land for more than five years but less than twenty years.
1991
+ Please check the ${schemaLink(`${node}#startDate`, "startDate")} and ${schemaLink(
1992
+ `${node}#endDate`,
1993
+ "endDate"
1994
+ )} on this term and ensure the difference between the two dates falls between 1826 and 7305 days.
1959
1995
  If it is less than 1826 days, consider using the terms ${code("Short fallow")}or ${code("Long fallow")} instead.
1960
- If it is more than 7305 days, consider using the term ${code("Other natural vegetation")} instead.`,
1996
+ If it is more than 7305 days, consider using the term ${code("Other natural vegetation")} instead.`;
1997
+ },
1961
1998
  "must not add the feed input to the Cycle as well": ({ params: { term } = {} }) => `You have added the animal feed Input ${code(term["@id"])} to the Cycle inputs as well, which might lead to double counting.
1962
1999
  If you do not know the amount of ${code(term["@id"])} given to each Animal, please add the Input to the Cycle only.`,
1963
2000
  "must provide value or min and max": ({ params }) => {
@@ -2158,6 +2195,11 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
2158
2195
  `If specifying fallow periods, you must also include the Product's equivalent Practice with a ${code("startDate")} and ${code("endDate")}.`,
2159
2196
  `Alternatively, do not set these ${code(TermTermType.landCover)} practices, and they will be gap filled automatically from products.`
2160
2197
  ])}`,
2198
+ "a cover crop can not be the land cover of the primary product": ({ params }) => {
2199
+ var _a, _b, _c, _d;
2200
+ return `The ${termLink({ id: (_a = params == null ? void 0 : params.term) == null ? void 0 : _a["@id"], name: (_b = params == null ? void 0 : params.term) == null ? void 0 : _b.name })} Practice is set as a cover crop, but it is the land cover of ${termLink({ id: (_c = params == null ? void 0 : params.product) == null ? void 0 : _c["@id"], name: (_d = params == null ? void 0 : params.product) == null ? void 0 : _d.name })}, the primary Product of this Cycle. HESTIA counts the land cover of a cover crop separately from the main crop, so this land cover would be counted twice.
2201
+ Remove the cover crop property from this Practice, and add the cover crop as its own ${code(TermTermType.landCover)} Practice if it is known.`;
2202
+ },
2161
2203
  "should match the site management node value": ({ params }) => `The data you have uploaded in the Management node are not consistent with the data provided in the Cycles.
2162
2204
  ${typeof (params == null ? void 0 : params.current) === "boolean" ? `A ${code("Management")} node must have the same ${code("value")} as every Practice using the same ${code("term")} between the same ${code("startDate")} and ${code("endDate")} \u2014 your Cycles say ${code(params == null ? void 0 : params.current)}, but the ${code("Management")} node has ${code(params == null ? void 0 : params.expected)}.` : `The ${code("value")} of a ${code("Management")} node must be the total of every Practice using the same ${code("term")} between the same ${code("startDate")} and ${code("endDate")} \u2014 your Cycles add up to ${code(params == null ? void 0 : params.current)}, but the ${code("Management")} node has ${code(params == null ? void 0 : params.expected)}.`}
2163
2205
  Please check your upload and ensure that the data is consistent throughout.`,
@@ -2255,6 +2297,23 @@ var createErrorFormatter = ({ renderer: r, urls }) => {
2255
2297
  "must equal to endDate - startDate in decimal years": ({ params: { expected } }) => `Must be equal to ${code("endDate")} - ${code("startDate")} in years (~${expected})`,
2256
2298
  "must be more than or equal to other crop residues": ({ params: { expected } }) => `Must be more than or equal to sum(${expected.join(" + ")})`,
2257
2299
  "should add missing inputs": ({ params: { expected } }) => `Should add missing inputs: ${listAsCode(expected)}`,
2300
+ "should match the nutrient ratio of the compound fertiliser": ({ params }) => {
2301
+ var _a, _b;
2302
+ const [denominator, numerator] = ((_a = params == null ? void 0 : params.termIds) != null ? _a : []).map((id) => termLink({ id }));
2303
+ const expected = (params == null ? void 0 : params.min) === (params == null ? void 0 : params.max) ? code(params == null ? void 0 : params.min) : `${code(params == null ? void 0 : params.min)} to ${code(params == null ? void 0 : params.max)}`;
2304
+ const causes = {
2305
+ swapped: "This is close to the inverse of the expected ratio: the values of the two Inputs may have been swapped.",
2306
+ elemental: `This is close to the expected ratio converted to elements: the value may have been given as kg of elemental P or K rather than kg of ${code(
2307
+ "P2O5"
2308
+ )} or ${code("K2O")}.`,
2309
+ otherCompound: `This is close to the ratio of ${termLink({
2310
+ id: params == null ? void 0 : params.compound
2311
+ })}: the values may have been calculated from the composition of another fertiliser.`
2312
+ };
2313
+ return `The value of ${numerator} divided by the value of ${denominator} is ${code(params == null ? void 0 : params.current)}, but the composition of this fertiliser gives a ratio of ${expected}.
2314
+ ${(_b = causes[params == null ? void 0 : params.cause]) != null ? _b : ""}
2315
+ Please check that both Inputs are the amounts of each nutrient applied with this fertiliser.`;
2316
+ },
2258
2317
  "the property value type is incorrect": ({ params: { expected } }) => `The value must be a ${expected}.`,
2259
2318
  "the node value type is incorrect": ({ params: { expected } }) => `The value must be a ${expected}.`,
2260
2319
  "can not be linked to the same type": ({ params: { current } }) => `Cannot be linked to the same ${current}.`,
package/index.js CHANGED
@@ -303,6 +303,11 @@ var validations = [
303
303
  level: "error",
304
304
  message: "at least one landCover practice must match an equivalent product"
305
305
  },
306
+ {
307
+ function: "validate_coverCrop_landCover_primary_product",
308
+ level: "error",
309
+ message: "a cover crop can not be the land cover of the primary product"
310
+ },
306
311
  {
307
312
  function: "validate_practices_management",
308
313
  level: "error",
@@ -333,6 +338,11 @@ var validations = [
333
338
  level: "error",
334
339
  message: "is outside the allowed range"
335
340
  },
341
+ {
342
+ function: "validate_soilTexture_depths",
343
+ level: "warning",
344
+ message: "should be given at the same depths as the soil content"
345
+ },
336
346
  {
337
347
  function: "validate_depths",
338
348
  level: "error",
@@ -628,6 +638,11 @@ var validations = [
628
638
  level: "warning",
629
639
  message: "should add missing inputs"
630
640
  },
641
+ {
642
+ function: "validate_compound_fertiliser_composition",
643
+ level: "warning",
644
+ message: "should match the nutrient ratio of the compound fertiliser"
645
+ },
631
646
  {
632
647
  function: "validate_related_impacts",
633
648
  level: "error",
package/index.mjs CHANGED
@@ -301,6 +301,11 @@ var validations = [
301
301
  level: "error",
302
302
  message: "at least one landCover practice must match an equivalent product"
303
303
  },
304
+ {
305
+ function: "validate_coverCrop_landCover_primary_product",
306
+ level: "error",
307
+ message: "a cover crop can not be the land cover of the primary product"
308
+ },
304
309
  {
305
310
  function: "validate_practices_management",
306
311
  level: "error",
@@ -331,6 +336,11 @@ var validations = [
331
336
  level: "error",
332
337
  message: "is outside the allowed range"
333
338
  },
339
+ {
340
+ function: "validate_soilTexture_depths",
341
+ level: "warning",
342
+ message: "should be given at the same depths as the soil content"
343
+ },
334
344
  {
335
345
  function: "validate_depths",
336
346
  level: "error",
@@ -626,6 +636,11 @@ var validations = [
626
636
  level: "warning",
627
637
  message: "should add missing inputs"
628
638
  },
639
+ {
640
+ function: "validate_compound_fertiliser_composition",
641
+ level: "warning",
642
+ message: "should match the nutrient ratio of the compound fertiliser"
643
+ },
629
644
  {
630
645
  function: "validate_related_impacts",
631
646
  level: "error",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hestia-earth/data-validation",
3
- "version": "0.41.14",
3
+ "version": "0.41.16",
4
4
  "description": "HESTIA Data Validation library",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
package/validation.json CHANGED
@@ -290,6 +290,11 @@
290
290
  "level": "error",
291
291
  "message": "at least one landCover practice must match an equivalent product"
292
292
  },
293
+ {
294
+ "function": "validate_coverCrop_landCover_primary_product",
295
+ "level": "error",
296
+ "message": "a cover crop can not be the land cover of the primary product"
297
+ },
293
298
  {
294
299
  "function": "validate_practices_management",
295
300
  "level": "error",
@@ -320,6 +325,11 @@
320
325
  "level": "error",
321
326
  "message": "is outside the allowed range"
322
327
  },
328
+ {
329
+ "function": "validate_soilTexture_depths",
330
+ "level": "warning",
331
+ "message": "should be given at the same depths as the soil content"
332
+ },
323
333
  {
324
334
  "function": "validate_depths",
325
335
  "level": "error",
@@ -615,6 +625,11 @@
615
625
  "level": "warning",
616
626
  "message": "should add missing inputs"
617
627
  },
628
+ {
629
+ "function": "validate_compound_fertiliser_composition",
630
+ "level": "warning",
631
+ "message": "should match the nutrient ratio of the compound fertiliser"
632
+ },
618
633
  {
619
634
  "function": "validate_related_impacts",
620
635
  "level": "error",