npm package: @schematizer/json-schema
Description: schema for listen or alter structures
Author: Raymundo
Latest version: 0.1.0

# json schema
This library allows make js schemas to read and overwrite data structures

## Usage
`JsonSchema` is the main class of this library, you can registriy listeners or alters with the following methods

- **listenValue**: Listen values by path
- **listenField**: Listen the field that constains the specified path
- **alterValue**: Alter the specified value
- **alterField**: Alter the specified field found in the path

now, you will call `triggerListeners` and `triggerAlterators` with the target value

```ts
const schema = new JsonSchema();

schema.triggerListeners({ foo: 1, bar: 1 });
const alteredValue = schema.triggerAlterators([1, 2, 3]);
```

## Examples
The following examples will use this structure
```ts
const myStructure = {
  a: 'alpaca',
  b: 'buffalo',
  c: 'camel',
  s: 'snake',
  object: {
    foo: 1,
    bar: 2,
  },
  array: [1, 2, 3],
  products: [
    { name: 'cup', price: 4 },
    { name: 'glass jar', price: 10 },
    { name: 'spoon', price: 1 },
  ],
};
```

*test: listen values*
```ts
const schema = new JsonSchema()
  .listenValue(['a'], ({ value }) => {
    expect(value).toBe('alpaca');
  })
  .listenValue(['object', 'foo'], ({ value }) => {
    expect(value).toBe(1);
  })
  .listenValue(['array'], ({ value }) => {
    expect([1, 2, 3]).toContain(value); // each array element
  })
  .listenValue(['products', 'name'], ({ value }) => {
    expect(['cup', 'glass jar', 'spoon']).toContain(value); // name of each array element
  });

schema.triggerListeners(myStructure);
```

*test: listen fields*
```ts
const schema = new JsonSchema()
  .listenField(['array'], ({ value }) => {
    expect(value).toEqual([1, 2, 3]); // array
  })
  .listenField(['products'], ({ value }) => {
    // array
    expect(value).toEqual([
      { name: 'cup', price: 4 },
      { name: 'glass jar', price: 10 },
      { name: 'spoon', price: 1 },
    ]);
  });

schema.triggerListeners(myStructure);
```

*test: alter fields*
```ts
const schema = new JsonSchema()
  .alterField(['array'], ({ value }) => {
    return value.filter((el: number) => el > 1);
  })
  .alterField(['products'], ({ value }) => {
    return (value as any[]).map(el => ({
      name: el.name,
      price: `$${el.price}.00`,
    }));
  });

expect(schema.triggerAlterators(myStructure)).toEqual({
  a: 'alpaca',
  b: 'buffalo',
  c: 'camel',
  s: 'snake',
  object: {
    foo: 1,
    bar: 2,
  },
  array: [2, 3],
  products: [
    { name: 'cup', price: '$4.00' },
    { name: 'glass jar', price: '$10.00' },
    { name: 'spoon', price: '$1.00' },
  ],
});
```

## Arguments
the handler of the `listenValue`, `listenField`, `alterValue`, `alterField` methods receive the followind structure

- **path**: `string[]` path of the selection
- **value**: `any` selection value
- **parent**: `any` parent of the selection
- **context**: `<Context>` second argument sended to `triggerListeners` or `triggerAlterators`

## Nested schemas
a `JsonSchema` can be appended into other with the method `append`

```ts
const movementSchema = new JsonSchema();
const summarySchema = new JsonSchema();

const rootSchema = new JsonSchema();
rootSchema.append(['movements'], movementSchema);
rootSchema.append(['summary'], summarySchema);
```