update to use == in JSON Path Queries
This commit is contained in:
@@ -149,7 +149,7 @@ export class UmbBlockGridEntriesElement extends UmbFormControlMixin(UmbLitElemen
|
||||
// Currently there is no server validation for areas. So we can leave out the data path for it for now. [NL]
|
||||
this.#controlValidator = new UmbFormControlValidator(this, this);
|
||||
|
||||
//new UmbBindServerValidationToFormControl(this, this, "$.values.[?(@.alias = 'my-input-alias')].value");
|
||||
//new UmbBindServerValidationToFormControl(this, this, "$.values.[?(@.alias == 'my-input-alias')].value");
|
||||
}
|
||||
}
|
||||
public get areaKey(): string | null | undefined {
|
||||
|
||||
@@ -2,14 +2,14 @@ import type { UmbBlockDataModel } from '../types.js';
|
||||
|
||||
/**
|
||||
* Validation Data Path Query generator for Block Element Data.
|
||||
* write a JSON-Path filter similar to `?(@.key = 'my-key://1234')`
|
||||
* write a JSON-Path filter similar to `?(@.key == 'my-key://1234')`
|
||||
* @param key {string} - The key of the block Element data.
|
||||
* @param data {{key: string}} - A data object with the key property.
|
||||
* @returns
|
||||
*/
|
||||
export function UmbDataPathBlockElementDataQuery(data: Pick<UmbBlockDataModel, 'key'>): string {
|
||||
// write a array of strings for each property, where alias must be present and culture and segment are optional
|
||||
//const filters: Array<string> = [`@.key = '${key}'`];
|
||||
//const filters: Array<string> = [`@.key == '${key}'`];
|
||||
//return `?(${filters.join(' && ')})`;
|
||||
return `?(@.key = '${data.key}')`;
|
||||
return `?(@.key == '${data.key}')`;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ export class UmbBlockElementManager<LayoutDataType extends UmbBlockLayoutBaseMod
|
||||
this.observe(this.contentTypeId, (id) => this.structure.loadType(id));
|
||||
this.observe(this.unique, (key) => {
|
||||
if (key) {
|
||||
this.validation.setDataPath('$.' + dataPathPropertyName + `[?(@.key = '${key}')]`);
|
||||
this.validation.setDataPath('$.' + dataPathPropertyName + `[?(@.key == '${key}')]`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ A Validation message consist of a type, path and body. This typically looks like
|
||||
```
|
||||
{
|
||||
type: "client",
|
||||
path: "$.values[?(@.alias = 'my-property-alias')].value",
|
||||
path: "$.values[?(@.alias == 'my-property-alias')].value",
|
||||
message: "Must contain at least 3 words"
|
||||
}
|
||||
```
|
||||
@@ -61,7 +61,7 @@ Data:
|
||||
|
||||
JsonPath:
|
||||
```
|
||||
"$.values.[?(@.alias = 'my-alias')].value"
|
||||
"$.values.[?(@.alias == 'my-alias')].value"
|
||||
```
|
||||
|
||||
Paths are based on JSONPath, using JSON Path Queries when looking up data of an Array. Using Queries enables Paths to not point to specific index, but what makes a entry unique.
|
||||
@@ -107,7 +107,7 @@ Such conversation could be from this path:
|
||||
|
||||
To this path:
|
||||
```
|
||||
"$.values.[?(@.alias = 'my-alias')].value"
|
||||
"$.values.[?(@.alias == 'my-alias')].value"
|
||||
```
|
||||
|
||||
Once this path is converted to use Json Path Queries, the Data can be changed. The concerned entry might get another index. Without that affecting the accuracy of the path.
|
||||
@@ -135,7 +135,7 @@ The Data Path is a JSON Path defining where the data of this input is located in
|
||||
this.#validationMessageBinder = new UmbBindServerValidationToFormControl(
|
||||
this,
|
||||
this.querySelector('#myInput"),
|
||||
"$.values.[?(@.alias = 'my-input-alias')].value",
|
||||
"$.values.[?(@.alias == 'my-input-alias')].value",
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
@@ -100,10 +100,10 @@ export class UmbValidationController extends UmbControllerBase implements UmbVal
|
||||
* @example
|
||||
* ```ts
|
||||
* const validationContext = new UmbValidationContext(this);
|
||||
* validationContext.setDataPath("$.values[?(@.alias='my-property')].value");
|
||||
* validationContext.setDataPath("$.values[?(@.alias == 'my-property')].value");
|
||||
* ```
|
||||
*
|
||||
* A message with the path: '$.values[?(@.alias='my-property')].value.innerProperty', will for above example become '$.innerProperty' for the local Validation Context.
|
||||
* A message with the path: '$.values[?(@.alias == 'my-property')].value.innerProperty', will for above example become '$.innerProperty' for the local Validation Context.
|
||||
*/
|
||||
setDataPath(dataPath: string): void {
|
||||
if (this.#baseDataPath) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { UmbVariantPropertyValueModel } from '@umbraco-cms/backoffice/varia
|
||||
|
||||
/**
|
||||
* Validation Data Path Query generator for Property Value.
|
||||
* write a JSON-Path filter similar to `?(@.alias = 'myAlias' && @.culture == 'en-us' && @.segment == 'mySegment')`
|
||||
* write a JSON-Path filter similar to `?(@.alias == 'myAlias' && @.culture == 'en-us' && @.segment == 'mySegment')`
|
||||
* where culture and segment are optional
|
||||
* @param {UmbVariantPropertyValueModel} value - the object holding value and alias.
|
||||
* @returns {string} - a JSON-path query
|
||||
@@ -12,12 +12,12 @@ export function UmbDataPathPropertyValueQuery(
|
||||
value: UmbPartialSome<Omit<UmbVariantPropertyValueModel, 'value'>, 'culture' | 'segment'>,
|
||||
): string {
|
||||
// write a array of strings for each property, where alias must be present and culture and segment are optional
|
||||
const filters: Array<string> = [`@.alias = '${value.alias}'`];
|
||||
const filters: Array<string> = [`@.alias == '${value.alias}'`];
|
||||
if (value.culture !== undefined) {
|
||||
filters.push(`@.culture = ${value.culture ? `'${value.culture}'` : 'null'}`);
|
||||
filters.push(`@.culture == ${value.culture ? `'${value.culture}'` : 'null'}`);
|
||||
}
|
||||
if (value.segment !== undefined) {
|
||||
filters.push(`@.segment = ${value.segment ? `'${value.segment}'` : 'null'}`);
|
||||
filters.push(`@.segment == ${value.segment ? `'${value.segment}'` : 'null'}`);
|
||||
}
|
||||
return `?(${filters.join(' && ')})`;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ export function UmbDataPathVariantQuery(
|
||||
value: UmbPartialSome<Pick<UmbVariantPropertyValueModel, 'culture' | 'segment'>, 'segment'>,
|
||||
): string {
|
||||
// write a array of strings for each property, where culture must be present and segment is optional
|
||||
const filters: Array<string> = [`@.culture = ${value.culture ? `'${value.culture}'` : 'null'}`];
|
||||
const filters: Array<string> = [`@.culture == ${value.culture ? `'${value.culture}'` : 'null'}`];
|
||||
if (value.segment !== undefined) {
|
||||
filters.push(`@.segment = ${value.segment ? `'${value.segment}'` : 'null'}`);
|
||||
filters.push(`@.segment == ${value.segment ? `'${value.segment}'` : 'null'}`);
|
||||
}
|
||||
return `?(${filters.join(' && ')})`;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @param path
|
||||
* @param {object} data - object to traverse for the value.
|
||||
* @param {string} path - the JSON path to the value that should be found
|
||||
* @returns {unknown} - the found value.
|
||||
*/
|
||||
export function GetValueByJsonPath(data: any, path: string): any {
|
||||
export function GetValueByJsonPath(data: unknown, path: string): unknown {
|
||||
// strip $ from the path:
|
||||
const strippedPath = path.startsWith('$.') ? path.slice(2) : path;
|
||||
// get value from the path:
|
||||
@@ -12,23 +13,9 @@ export function GetValueByJsonPath(data: any, path: string): any {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
export function GetPropertyNameFromPath(path: string): string {
|
||||
// find next '.' or '[' in the path, using regex:
|
||||
const match = path.match(/\.|\[/);
|
||||
// If no match is found, we assume its a single key so lets return the value of the key:
|
||||
if (match === null || match.index === undefined) return path;
|
||||
|
||||
// split the path at the first match:
|
||||
return path.slice(0, match.index);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @param path
|
||||
* @returns {any}
|
||||
* @param {object} data - object to traverse for the value.
|
||||
* @param {string} path - the JSON path to the value that should be found
|
||||
* @returns {unknown} - the found value.
|
||||
*/
|
||||
function GetNextPropertyValueFromPath(data: any, path: string): any {
|
||||
if (!data) return undefined;
|
||||
@@ -90,8 +77,8 @@ function GetNextPropertyValueFromPath(data: any, path: string): any {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filter
|
||||
* @returns {Array<(queryFilter: any) => boolean>} - array of methods that returns true if the given items property value matches the value of the query.
|
||||
* @param {string} filter - A JSON Query, limited to filtering features. Do not support other JSON PATH Query features.
|
||||
* @returns {Array<(queryFilter: any) => boolean>} - An array of methods that returns true if the given items property value matches the value of the query.
|
||||
*/
|
||||
function JsFilterFromJsonPathFilter(filter: string): Array<(item: any) => boolean> {
|
||||
// strip ?( and ) from the filter
|
||||
@@ -101,7 +88,7 @@ function JsFilterFromJsonPathFilter(filter: string): Array<(item: any) => boolea
|
||||
// map each part to a function that returns true if the part is true
|
||||
return parts.map((part) => {
|
||||
// split the part into key and value
|
||||
const [path, equal] = part.split(' = ');
|
||||
const [path, equal] = part.split(' == ');
|
||||
// remove @.
|
||||
const key = path.slice(2);
|
||||
// remove quotes:
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('UmbJsonPathFunctions', () => {
|
||||
});
|
||||
|
||||
it('query of first entry in an array', () => {
|
||||
const result = GetValueByJsonPath({ values: [{ id: '123', value: 'test' }] }, "$.values[?(@.id = '123')].value");
|
||||
const result = GetValueByJsonPath({ values: [{ id: '123', value: 'test' }] }, "$.values[?(@.id == '123')].value");
|
||||
|
||||
expect(result).to.eq('test');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user