Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/zoobzio/nuxt-cereal

🥣 Cereal-ize JSON data into literally-typed constants, enums, & options in Nuxt.
https://github.com/zoobzio/nuxt-cereal

nuxt nuxt-cereal nuxt-module nuxt3 nuxt3-module nuxt3-typescript zoobz-io

Last synced: 2 days ago
JSON representation

🥣 Cereal-ize JSON data into literally-typed constants, enums, & options in Nuxt.

Awesome Lists containing this project

README

        

# nuxt-cereal

🥣 Cereal-ize JSON data into literally-typed constants, enums, & options in Nuxt.

[✨  Release Notes](/CHANGELOG.md)

## Configuration

1. Install the module

```bash
pnpm add nuxt-cereal
```

2. Create a config

```ts
// ~/cereal.config.ts
import { defineCerealConfig } from "nuxt-cereal/config";

export default defineCerealConfig({
constants: {
foo: "an example string",
},
enums: {
bar: ["primary", "secondary", "tertiary"],
},
options: {
baz: [
{ key: 1, label: "One" },
{ key: 2, label: "Two" },
],
},
});
```

3. Activate the module

```ts
// ~/nuxt.config.ts
import cereal from "./cereal.config";

export default defineNuxtConfig({
modules: ["nuxt-cereal"],
cereal,
});
```

4. Eat some cereal, you are done!

## Features

Define a JSON config object for:

- `constants` A key/value collection of static strings & numbers
- `enums` A key/value collection of static string arrays & number arrays
- `options` A key/value collection of static option arrays w/ `key` & `label` properties

The config object is "cereal-ized" into read-only literals & implemented in Nuxt using a set of utility types/composables.

### Types

Type templates are created using the JSON definitions & are automatically available in composables/components:

| Type | Description |
| ----------------------------------- | ---------------------------------------------------- |
| `Constant` | String-literal keys of the `constants` cereal config |
| `ConstantValue` | Literal value of the provided `constants` config key |
| `Enum` | String-literal keys of the `enums` cereal config |
| `EnumValue` | Literal values of the provided `enums` config key |
| `EnumValueItem` | Template values of the provided `enums` config key |
| `Option` | String-literal keys of the `options` cereal config |
| `OptionValue` | Literal values of the provided `options` config key |
| `OptionValueItem` | Template values of the provided `options` config key |

#### Example

These utility types can be useful when creating components. Let's say we have a button component that has a `variant` property that can be set to either `filled`, `outlined`, or `plain`. We can configure that option as an `enum` and use the helper types to define our component properties:

```ts
// ~/cereal.config.ts
export default defineCerealConfig({
enums: {
buttonVariant: ["filled", "outlined", "plain"],
},
});
```

```vue

// ~/components/Button.vue
defineProps<{
variant: EnumValue<"buttonVariant">; // a string-literal type of the options in our config
}>();



```

### Functions

Type-safe utility functions that enable access to the configuration literal values are automatically imported in any component/composable:

| Function | Description |
| ---------------------- | ----------------------------------------------------------------------------- |
| `isConstant(key)` | Check if a provided string is a `constants` key & cast to `Constant` if valid |
| `useConstant(key)` | Grab the literal value represented by the provided `constants` key |
| `useConstantsConfig()` | Grab the entire `constants` configuration as an object literal |
| `useConstantsKeys()` | Grab an array ofavailable `constants` configuration keys |
| `isEnum(key)` | Check if a provided string is a `enums` key & cast to `Enum` if valid |
| `useEnum(key)` | Grab the literal value represented by the provided `enums` key |
| `useEnumsConfig()` | Grab the entire `enums` configuration as an object literal |
| `useEnumsKeys()` | Grab an array ofavailable `enums` configuration keys |
| `isOption(key)` | Check if a provided string is a `options` key & cast to `Option` if valid |
| `useOption(key)` | Grab the literal value represented by the provided `options` key |
| `useOptionsConfig()` | Grab the entire `options` configuration as an object literal |
| `useOptionsKeys()` | Grab an array ofavailable `options` configuration keys |

#### Example

These functions can be leveraged w/ generics to extend the power of our components even further. Imagine we have a pre-defined set of dropdowns needed for a form. We can quickly build a component that uses our cereal-ized data to provide a type-safe selector that only needs a `key` to get started:

```ts
// ~/cereal.config.ts
export default defineCerealConfig({
options: {
breakfast: [
{ key: "cereal", label: "Cereal" },
{ key: "pancakes", label: "Pancakes" },
{ key: "eggs", label: "Eggs" },
],
lunch: [
{ key: "sandwhich", label: "Sandwhich" },
{ key: "soup", label: "Soup" },
{ key: "salad", label: "Salad" },
],
dinner: [
{ key: "steak", label: "Steak" },
{ key: "lobster", label: "Lobster" },
{ key: "risotto", label: "Risotto" },
],
},
});
```

```vue

// ~/components/Select.vue
const props = defineProps<{
option: O; // "breakfast" | "lunch" | "dinner"
modelValue?: OptionValueItem<O>["key"]; // if "breakfast" is the option, allowed values are "cereal" | "pancakes" | "eggs"
}>();

const emits = defineEmits<{
"update:modelValue": [OptionValueItem<O>];
}>();

const options = useOption(props.option);
const modelValue = useVModel(props, "modelValue", emits, { passive: true }); // https://vueuse.org/core/useVModel/#usevmodel



{{ o.label }}

```

## License

MIT License © 2024-PRESENT [Alexander Thorwaldson](https://github.com/zoobzio)