Skip to content

Commit

Permalink
add jq filter to ValueSchemaError
Browse files Browse the repository at this point in the history
  • Loading branch information
shimataro committed Jan 1, 2025
1 parent d249b92 commit 1f89a74
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 4 deletions.
38 changes: 36 additions & 2 deletions dist-deno/libs/ValueSchemaError.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Key, Values } from "./types.ts";
import { isNumber, Key, Values } from "./types.ts";
export const RULE = {
TYPE: "type",
UNDEFINED: "undefined",
Expand All @@ -21,6 +21,7 @@ export class ValueSchemaError extends Error {
/** the rule that input value didn't satisfy */
public readonly rule: RULE;
public readonly value: unknown;
public readonly filter: string;
public readonly keyStack: Key[];
/**
* throw an error
Expand All @@ -47,10 +48,43 @@ export class ValueSchemaError extends Error {
* @param keyStack path to key that caused error
*/
constructor(rule: RULE, value: unknown, keyStack: Key[]) {
super(`${rule}; ${value}; ${keyStack}`);
const filter = buildFilter(keyStack);
super(`rule=${rule}; value=${value}; filter=${filter}`);
this.name = "ValueSchemaError";
this.rule = rule;
this.value = value;
this.filter = filter;
this.keyStack = [...keyStack];
}
}
/**
* build ilter of `jq` command
* @param keyStack key stack; array of property(string) or index(number)
* @returns `jq` filter
* @see {@link https://jqlang.github.io/jq/manual/ jq manual}
* @example
* // returns '.foo[1]."bar baz"'
* const filter = buildJqFilter(["foo", 1, "bar baz"]);
*/
function buildFilter(keyStack: Key[]): string {
const REGEXP_ID = /^\w+$/;
let filter = "";
for (const key of keyStack) {
if (isNumber(key)) {
// index
filter += `[${key}]`;
continue;
}
if (REGEXP_ID.test(key)) {
// property that doesn't need to be quoted
filter += `.${key}`;
continue;
}
// other property; quote by JSON.stringify()
filter += `.${JSON.stringify(key)}`;
}
if (!filter.startsWith(".")) {
filter = `.${filter}`;
}
return filter;
}
45 changes: 43 additions & 2 deletions src/libs/ValueSchemaError.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Key, Values} from "./types";
import {isNumber, Key, Values} from "./types";

export const RULE =
{
Expand Down Expand Up @@ -28,6 +28,7 @@ export class ValueSchemaError extends Error
/** the rule that input value didn't satisfy */
public readonly rule: RULE;
public readonly value: unknown;
public readonly filter: string;
public readonly keyStack: Key[];

/**
Expand Down Expand Up @@ -60,11 +61,51 @@ export class ValueSchemaError extends Error
*/
constructor(rule: RULE, value: unknown, keyStack: Key[])
{
super(`${rule}; ${value}; ${keyStack}`);
const filter = buildFilter(keyStack);
super(`rule=${rule}; value=${value}; filter=${filter}`);

this.name = "ValueSchemaError";
this.rule = rule;
this.value = value;
this.filter = filter;
this.keyStack = [...keyStack];
}
}

/**
* build ilter of `jq` command
* @param keyStack key stack; array of property(string) or index(number)
* @returns `jq` filter
* @see {@link https://jqlang.github.io/jq/manual/ jq manual}
* @example
* // returns '.foo[1]."bar baz"'
* const filter = buildJqFilter(["foo", 1, "bar baz"]);
*/
function buildFilter(keyStack: Key[]): string
{
const REGEXP_ID = /^\w+$/;
let filter = "";
for(const key of keyStack)
{
if(isNumber(key))
{
// index
filter += `[${key}]`;
continue;
}
if(REGEXP_ID.test(key))
{
// property that doesn't need to be quoted
filter += `.${key}`;
continue;
}

// other property; quote by JSON.stringify()
filter += `.${JSON.stringify(key)}`;

Check warning on line 104 in src/libs/ValueSchemaError.ts

View check run for this annotation

Codecov / codecov/patch

src/libs/ValueSchemaError.ts#L104

Added line #L104 was not covered by tests
}
if(!filter.startsWith("."))
{
filter = `.${filter}`;
}
return filter;
}

0 comments on commit 1f89a74

Please sign in to comment.