1.0.0 • Published 2 years ago

@honoluluhenk/typesafe-json-path v1.0.0

Weekly downloads
-
License
LGPL-2.1-or-later
Repository
github
Last release
2 years ago

typesafe-json-path

Typesafe navigation in JSON data structures for typescrpt.

Contributors Forks Stargazers Issues MIT License

CI NPM

About The Project

  • Ever had a JSON data structure that is implemented in more than one file? Translation-files anyone?
  • You wanted to access these values in a typesafe manner? I.e.: without resorting to string-keys?
  • You want refactoring support from your IDE when renaming properties?
  • You want compilation to fail if you mistyped a property name?

Read the examples in Usage to find out how!

Usage

Best shown by example:

Minimal example

import {TypesafeJsonPath} from '@honoluluhenk/typesafe-json-path';

const translationsRoot = {
  FOO: {
    BAR: {
      BAZ: 'Baz was here!',
      HELLO: 'Hello World',
    }
  }
};

const path = TypesafeJsonPath.init<typeof translationsRoot>();

// please note: this is not string but real property access!
const pathAsString = path.FOO.BAR.HELLO.$path.path;
// 'FOO.BAR.HELLO'
const value = path.FOO.BAR.HELLO.$path.get(translationsRoot);

console.log(value);
// 'Hello World'

Full example

The full power can be seen here: use a custom Resolver and go wild.

This example implements a translation service that is not access-by-string but fully typesafe!

import {type PathSegment, Resolver, TypesafeJsonPath} from '@honoluluhenk/typesafe-json-path';

const translationsRoot = {
  FOO: {
    BAR: {
      BAZ: 'Baz was here!',
      HELLO: 'Hello %s',
      RUCKSACK: 'Rucksack',
    },
  },
};
// some other translation
const translationsDE = {
  FOO: {
    BAR: {
      BAZ: 'Baz war hier!',
      HELLO: 'Hallo %s',
    },
  },
};

// your custom path resolver
class Translator<T extends object> extends Resolver<unknown, T> {
  constructor(
    path: ReadonlyArray<PathSegment>,
    private readonly myTranslateService: MyCustomTranslateService,
  ) {
    super(path);
  }

  translate(...args: unknown[]): string {
    // Delegate to some translation service.
    return this.myTranslateService.translate(this.path, args);
  }
}

// include all variants to have full refactoring support in your IDE
type TranslationType = typeof translationsRoot & typeof translationsDE;

// Now the real fun begins...
const translations = TypesafeJsonPath.init<TranslationType, Translator<any>>(
  path => new Translator(
    path,
    new MyCustomTranslateService(navigator.languages[0], {en: translationsRoot, de: translationsDE}),
  ),
);

// again: this is not string but real property access in a typesafe and refactoring-friendly way!
const text = translations.FOO.BAR.HELLO.$path.translate('Welt');
// internally, myTranslateService.translate() was called with the path-string 'FOO.BAR.HELLO'.
console.log(text);
// Assuming the user language was some german (de) locale:
// 'Hallo Welt'

Getting Started

Prerequisites

The implementation makes heavy use of the Proxy object.

As such, this lib can only be used if it is available.

Installation

This npm library is intended to be used in typescript projects where the

Just install the NPM package:

npm install @honoluluhenk/typesafe-json-path

Changelog

See releases

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Run tests/linting (npm run prepush)
  5. Push to the Branch (git push origin feature/AmazingFeature)
  6. Open a Pull Request

License

Distributed under the Lesser Gnu Public License 2.1 (LGPL-2.1) License. See LICENSE for more information.

Contact

Christoph Linder - post@christoph-linder.ch

Project Link: https://github.com/HonoluluHenk/typesafe-json-path