open-index/open-npm huggingface dataset:
npm package: @stefano_magrassi/ts-starter
Description: A simple Typescript starter - bare minimum
Author: StefanoMagrassi
Latest version: 1.0.1
Deprecated: Package no longer supported. Use at your own risk.

# ts-starter

A simple Typescript starter - bare minimum with a nice command:

```sh
# Install package
$ npm i -g @stefano_magrassi/ts-starter

# Run command
$ ts-starter ./path/to/directory
```

## Disclaimer

No tests, no production-ready, just fun fun fun! Use it at your risk
npm package: @stefanoa1/eslint-plugin-sab
Description: Common ESLint config for Personal projects
Author: Stefano Acosta
Latest version: 3.1.1

# Multi purpose ESLint plugin

[![npm](https://img.shields.io/npm/v/@stefanoa1/eslint-plugin-sab.svg)](https://www.npmjs.com/package/@stefanoa1/eslint-plugin-sab)
[![GitHub Actions](https://github.com/StefanoA1/eslint-plugin-sab/actions/workflows/main.yml/badge.svg)](https://github.com/StefanoA1/eslint-plugin-sab/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Personal ESLint rules and configs (testing config).

## Installation

```console
npm install --save-dev eslint @stefanoa1/eslint-plugin-sab
```

It supports node >= v20 (by default, this repo runs on v24).

## Usage

This package provides multiple configurations for different purposes, that you can apply together in your project as needed.
To use them, set each needed extension on the `extends` key of your `.eslintrc` file (if you only need ava, set ava only) and add `@stefanoa1/stefanoa1` to your list of plugins.

```json
{
  "extends": [
    "plugin:@stefanoa1/sab/core",
    "plugin:@stefanoa1/sab/ava",
    "plugin:@stefanoa1/sab/es20-xx",
    "plugin:@stefanoa1/sab/lodash-fp",
    "plugin:@stefanoa1/sab/prettier",
    "plugin:@stefanoa1/sab/react",
    "..."
  ],
  "plugins": [
    "@stefanoa1/sab"
  ]
}
```

To overwrite rules (check the rule sets on [the github repo](https://github.com/StefanoA1/eslint-plugin-sab/tree/main/src/rules)):
```json
{
  "rules": [
    "@stefanoa1/sab/no-overwriting-spread": "off",
    "n/no-missing-import": "off",
    "..."
  ]
}
```

Available rule sets are (code is minified on node_modules, checkout the repo or go
to the project Github page to check the rules):
- [ava](./src/config/ava.js): when using AVA
- [core](./src/config/core.js): Shared ESLint rules
- [es20-xx](./src/config/es20-xx.js): when using ES2015+ syntax
- [lodash-fp](./src/config/lodash-fp.js): when using Lodash's FP flavor
- [prettier](./src/config/prettier.js): Disables all stylistic rules but adds source code auto-formatting.
- [react](./src/config/react.js): when using React

## PR conventions

When creating a PR, use a title like:
```
 release: patch - fix bug #123
 release: minor - add new feature #456
 release: major - breaking changes #789.
```
The `release: ${VERSION}` part of the title is used by Github Actions to detect to which version to bump.
npm package: @stefanolazzaroni/eslint-config
Description: StefanoLazzaroni ESLint extensible configuration
Author: StefanoLazzaroni
Latest version: 0.0.2

# @stefanolazzaroni/eslint-config

Shared ESLint & Prettier extensible configuration

## Installation

```sh
npm install -D @stefanolazzaroni/eslint-config
```

**Note** `eslint`, `prettier`, `typescript` are a peer dependencies

## Prettier config

_prettier.config.js_

```js
module.exports = require('@stefanolazzaroni/eslint-config/prettierrc.json');
```

## ESLint config

### React

_create eslint.config.mjs_

```ts
import tsParser from '@typescript-eslint/parser';
import { defineConfig, globalIgnores } from 'eslint/config';
import react from '@stefanolazzaroni/eslint-config/react';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default defineConfig([
  globalIgnores(['dist/**', '/node_modules/**', 'eslint.config.mjs']),
  {
    extends: [react],
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        tsconfigRootDir: __dirname,
        projectService: true,
      },
    },
  },
]);
```

### Next

_create eslint.config.mjs_

```ts
import tsParser from '@typescript-eslint/parser';
import { defineConfig, globalIgnores } from 'eslint/config';
import next from '@stefanolazzaroni/eslint-config/next';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default defineConfig([
  globalIgnores(['dist/**', '/node_modules/**', 'eslint.config.mjs']),
  {
    extends: [next],
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        tsconfigRootDir: __dirname,
        projectService: true,
      },
    },
  },
]);
```

### Nest

_create eslint.config.mjs_

```ts
import tsParser from '@typescript-eslint/parser';
import { defineConfig, globalIgnores } from 'eslint/config';
import nest from '@stefanolazzaroni/eslint-config/nest';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default defineConfig([
  globalIgnores(['dist/**', '/node_modules/**', 'eslint.config.mjs']),
  {
    extends: [nest],
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        tsconfigRootDir: __dirname,
        projectService: true,
      },
    },
  },
]);
```
npm package: @stefanolazzaroni/tsconfig
Description: Shared TypeScript config
Author: StefanoLazzaroni
Latest version: 0.0.0-alpha.3

# @StefanoLazzaroni/tsconfig

Shared TypeScript config

## Installation

```sh
npm install -D @stefanolazzaroni/tsconfig
```

## tsconfig common

Add to your `tsconfig.json`:

```json
"extends": "@stefanolazzaroni/tsconfig/tsconfig.json"
```

## tsconfig React.js

Add to your `tsconfig.json`:

```json
"extends": "@stefanolazzaroni/tsconfig/tsconfig-react.json"
```

## tsconfig Next.js

Add to your `tsconfig.json`:

```json
"extends": "@stefanolazzaroni/tsconfig/tsconfig-next.json"
```

## tsconfig Nest.js

Add to your `tsconfig.json`:

```json
"extends": "@stefanolazzaroni/tsconfig/tsconfig-nest.json"
```
npm package: @stefanoruth/classnames
Description: A simple classnames javascript utility function for combining conditional classnames together.
Author: Stefano Ruth
Latest version: 1.1.1

# Classnames

A simple classnames javascript utility function for combining conditional classnames together.

![npm](https://img.shields.io/npm/v/@stefanoruth/classnames)
![npm](https://img.shields.io/npm/dt/@stefanoruth/classnames)
![Build & Tests](https://github.com/stefanoruth/classnames/workflows/Build%20&%20Tests/badge.svg)

## Installation

```sh
# npm
npm install @stefanoruth/classnames

# Yarn
yarn add @stefanoruth/classnames
```

## Example

```tsx
import React from 'react
import { css } from '@stefanoruth/classnames'

export const Card = props => {
    return <div className={css('bg-white w-full shadow rounded', props.spacing && 'px-4 py-6' props.className)}>{props.children}</div>
}
```
npm package: @stefanoruth/graphql-codegen-graphql-hooks
Description: ![npm](https://img.shields.io/npm/v/@stefanoruth/graphql-codegen-graphql-hooks)
Author: Stefano Ruth
Latest version: 1.4.1

# GraphQL Codegen - GraphQL Hooks

![npm](https://img.shields.io/npm/v/@stefanoruth/graphql-codegen-graphql-hooks)

-   [GraphQL Code Generator](https://www.graphql-code-generator.com/)
-   [GraphQL Hooks](https://github.com/nearform/graphql-hooks)

## Install

`yarn add @stefanoruth/graphql-codegen-graphql-hooks`

or

`npm install @stefanoruth/graphql-codegen-graphql-hooks`

## Quick Start

Add the plugin to youre codegen.yml config

```yml
schema: 'my-schema.graphql'
generates:
    output.ts:
        plugins:
            - 'typescript'
            - 'typescript-operations'
            - '@stefanoruth/graphql-codegen-graphql-hooks'
```
npm package: @stefanoruth/password-strength
Description: Easy to use password strength validator.
Latest version: 0.1.0
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# Password Strength

Easy to use password strength validator.

[![Build](https://github.com/stefanoruth/password-strength/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/stefanoruth/password-strength/actions/workflows/build.yml)

## Installation

```
yarn add @stefanoruth/password-strength
```

## Usage

```ts
import { passwordStrength } from '@stefanoruth/password-strength'

const validation = passwordStrength('input-password', {
    min: 8,
    max: 40,
    lowercase: true,
    uppercase: true,
    numbers: true,
    symbols: true,
})

if (validation.valid) {
    // Password meets all criteria.
} else {
    // Password failed to meet all criteria.
    // See validation.errors for missing criterias.
}
```
npm package: @stefanoruth/react-helpers
Description: A small set of components to help bulding simpler code.
Author: Stefano Ruth
Latest version: 1.0.27
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# React Helpers

A small set of components to help bulding simpler code.

![version](https://badgen.net/npm/v/@stefanoruth/react-helpers)
![license](https://badgen.net/npm/license/@stefanoruth/react-helpers)
![size](https://badgen.net/bundlephobia/minzip/@stefanoruth/react-helpers)

## Features

-   Scroll lock
-   Focus trap
-   Click away listener
-   Keyboard listiner
-   Simple Portals
-   ClassName builder
-   Config Builder
-   Interval Hook

## Installation

```shell
yarn add @stefanoruth/react-helpers
```

or

```shell
npm install @stefanoruth/react-helpers --save
```

## Basic usage

```js
import { Portal, useScrollLockEffect, useTabFocus, useOnClickAway, useOnEscKey } from '@stefanoruth/react-helpers'

export const Modal: React.FunctionComponent<{ onClose: () => void }> = props => {
    const modalRef = React.useRef < HTMLDivElement > null

    useScrollLockEffect()

    useTabFocus(modalRef)

    useOnClickAway(modalRef, () => {
        props.onClose()
    })

    useOnEscKey(() => {
        props.onClose()
    })

    return (
        <Portal>
            <div ref={modalRef}>
                <button onClick={props.onClose}>Close</button>
                {props.children}
            </div>
        </Portal>
    )
}
```

## Development

https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react

```
npm link example/node_modules/react

yarn dev
```

## License

[MIT](https://github.com/stefanoruth/react-helpers/blob/master/LICENSE)
npm package: @stefanoruth/react-portal-ssr
Description: Simple implementation of server side rendering of portals.
Author: Stefano Ruth
Latest version: 2.1.0

# React Portal SSR

Simple implementation of server side rendering of portals.

![version](https://badgen.net/npm/v/@stefanoruth/react-portal-ssr)
![license](https://badgen.net/npm/license/@stefanoruth/react-portal-ssr)
![size](https://badgen.net/bundlephobia/minzip/@stefanoruth/react-portal-ssr)

## Features

-   Server Side Rendered Portals
-   Simple API
-   Support Multiple Portals

## Installation

```shell
yarn add @stefanoruth/react-portal-ssr
```

or

```shell
npm install @stefanoruth/react-portal-ssr --save
```

## API

### `@stefanoruth/react-portal-ssr`

-   `Portal`
-   `prepareClientPortals`
-   `PortalContext`

### `@stefanoruth/react-portal-ssr/server`

-   `PortalServer(PortalContext)`
    -   `collectPortals`
    -   `appendPortals`

## License

[MIT](https://github.com/stefanoruth/react-portal-ssr/blob/master/LICENSE)
npm package: @stefanprobst/diacritics
Description: remove diacritics from strings
Author: Andrew Kelley
Latest version: 1.3.0-umlaut

# node-diacritics

Remove diacritics from strings.

Useful when implementing some kind of search or filter functionality.

## Installation

```sh
yarn add @stefanprobst/diacritics
```

## API

```js
var removeDiacritics = require("diacritics").remove;
console.log(removeDiacritics("Iлｔèｒｎåｔïｏｎɑｌíƶａｔï߀ԉ"));
// prints "Internationalizati0n"
```

## Umlaut handling

This fork treats `Ä`, `ä`, `Ö`, `ö`, `Ü`, `ü` as German umlaut characters, which are transformed to `Ae`, `ae`, `Oe`, `oe`, `Ue`, `ue`. This differs from upstream behavior!
The motivation for this change was to adjust how `netlifycms` creates slugs using this package.
npm package: @stefanprobst/eslint-config-next-component
Description: Shareable ESLint config for Next.js component packages. See the [ESLint docs](https://eslint.org/docs/user-guide/configuring) for installation instructions.
Author: Stefan Probst
Latest version: 1.0.10

# eslint-config-next-component

Shareable ESLint config for Next.js component packages. See the [ESLint docs](https://eslint.org/docs/user-guide/configuring) for installation instructions.
npm package: @stefanprobst/favicons
Description: ## How to use
Latest version: 2.4.0

# Generate favicons

## How to use

```sh
npx generate-favicons -i [FILE] -o [FOLDER] [...OPTIONS]
```

Options:

- `-i`, `--input`: path to input file
- `-o`, `--output`: path to output folder
- `-n`, `--name`: name for webmanifest (optional)
- `-s`, `--short`: short name for webmanifest (optional)
- `-c`, `--color`: theme color for webmanifest (optional)
- `-m`, `--maskable`: mark images as maskable (optional)
- `-u`, `--url`: set the start_url path (optional)
- `-h`, `--help`: show help message

If the `--color` option is not provided, the theme color will be set to the image's dominant color.

Example:

```sh
npx generate-favicons -i src/assets/images/logo.svg -o public
```

The following files are generated:

- `android-chrome-192x192.png` (192x192px)
- `android-chrome-512x512.png` (512x512px)
- `apple-touch-icon.png` (180x180px)
- `favicon-16x16.png` (16x16px)
- `favicon-32x32.png` (32x32px)
- `favicon.ico` (16x16px, 32x32px, 48x48px)

To use the generated favicons, copy them to your site's root folder, and add the following to the
`<head>` element:

```html
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
```

Note: `favicon.ico` and the android icons don't need to be referenced explicitly as long as they
live in the root folder (the browser will automatically find them there).

## How to use in Node.js

It is possible to use the generator programmatically from Node.js:

```js
const generate = require("@stefanprobst/favicons");

async function createFavicons() {
	const stats = await generate({
		inputFilePath,
		outputFolder,
		name,
		shortName,
		color,
		maskable,
		startUrl,
	});
	console.log(stats);
}
```
npm package: @stefanprobst/lib
Description: ## how to install
Latest version: 0.1.5

# javascript utility library

## how to install

```bash
npm i @stefanprobst/lib
```

## utilities

- `assert`
- `capitalize`
- `clamp`
- `create-headers`
- `create-pagination`
- `create-timer`
- `create-url`
- `create-url-search-params`
- `debounce`
- `group-by`
- `is-non-nullable`
- `is-nonempty-array`
- `is-nonempty-string`
- `is-url`
- `key-by`
- `log`
- `noop`
- `omit`
- `pick`
- `promise`
- `range`
- `request`
- `times`
- `unique`
- `wait`
npm package: @stefanprobst/markdown-loader
Description: Webpack loader for markdown.
Author: Stefan Probst
Latest version: 1.0.10

# markdown-loader

Webpack loader for markdown.

## How to use

Add the loader to the webpack configuration:

```js
// webpack.config.js
module.exports = {
  /* ... */
  module: {
    rules: [
      {
        test: /\.md$/
        use: [{
          loader: require.resolve('@stefanprobst/markdown-loader')
          options: {}
        }]
      }
    ]
  }
}
```

The loader makes the generated html available as the default export, and
frontmatter on the `data` named export.

```js
import html, { data } from '@/contents/faq.md'

// Example for rendering in React
export default function FaqPage() {
  return (
    <main>
      <h1>{data.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: html }}>
    </main>
  )
}
```

## Options

- `allowDangerousHtml`: allow inline html in markdown (default: `false`).
- `sanitize`: when allowing inline html, sanitize unsafe markup (default:
  `true`).
- `sanitationSchema`: whan allowing inline html, sanitize with
  [custom schema](https://github.com/syntax-tree/hast-util-sanitize/blob/main/types/index.d.ts#L9-L66)
  (default:
  [github schema](https://github.com/syntax-tree/hast-util-sanitize/blob/main/lib/github.json))
- `remarkPlugins`: a list of additional remark plugins (or [plugin,
  pluginOptions] tuple), e.g.
  `remarkPlugins: [require('remark-smartypants'), [require('remark-footnotes'), { inlineNotes: true }]]`
npm package: @stefanprobst/netlify-cms-oauth-client
Description: ## How to install
Latest version: 0.4.0

# `netlify-cms-oauth-client`

## How to install

```bash
npm i @stefanprobst/netlify-cms-oauth-client
```

## How to set up

```ts
import { createHandlers } from "@stefanprobst/netlify-cms-oauth-client";

const handlers = createHandlers();
```

Then, use `handlers.authorize` and `handlers.callback` as request handlers for the
`/api/oauth/authorize` and `/api/oauth/callback` API routes. How exactly to do this will depend on
the framework you are using.

## How to configure

The following example assumes a website deployed at `https://example.com`, with the API routes for
the OAuth flow at `/api/oauth/authorize` and `/api/oauth/callback`.

(i) Create a new OAuth app on [GitHub](https://github.com/settings/applications/new) to get a
"Client ID" and "Client secret". Set the "Authorization callback URL" to
`https://example.com/api/oauth/callback`.

(ii) Add configuration to NetlifyCMS, and set environment variables.

```yaml config.yaml
backend:
  name: github
  repo: owner/repo
  branch: main
  base_url: https://example.com
  auth_endpoint: /api/oauth/authorize
```

```text .env
OAUTH_PROVIDER=github
# GitHub OAuth app client id.
OAUTH_CLIENT_ID=
# GitHub OAuth app client secret.
OAUTH_CLIENT_SECRET=
# GitHub OAuth app callback URL.
OAUTH_REDIRECT_URL=https://example.com/api/oauth/callback
# Deployed website's base URL.
OAUTH_ALLOWED_ORIGIN=https://example.com
```

Note: you can add environment variables to your Vercel deployment via CLI:

```bash
vercel env add OAUTH_PROVIDER github
```
npm package: @stefanprobst/next-active-link
Description: Replacement for Next.js's `Link` to inform child components whether the current route matches the link's `href`. Children can access this info with the `useActiveLink` hook.
Author: Stefan Probst
Latest version: 1.0.1

# next-active-link

Replacement for Next.js's `Link` to inform child components whether the current
route matches the link's `href`. Children can access this info with the
`useActiveLink` hook.

By default, `ActiveLink` matches pathnames exactly, ignoring query params and
hash. However, a custom matcher function can be provided.

## `ActiveLink`

In addition to Next.js's `LinkProps`, `ActiveLink` accepts an optional matcher
function as the `isMatchingRoute` prop, which receives the `ActiveLink`'s `href`
and `as` props, as well as the `current` route as arguments.

Note that `ActiveLink` inherits
[Next.js's `Link` behavior of accepting either a string, or an URL object for `href` and `as` props](https://nextjs.org/docs/api-reference/next/link#with-url-object).

The following props are suitable for comparison:

| current route                                              | LinkProps (as UrlObject, not string) |
| ---------------------------------------------------------- | ------------------------------------ |
| `current.pathname`                                         | `href.pathname`                      |
| `new URL(current.asPath, 'https://example.org/').pathname` | `(as ?? href).pathname`              |
| `current.query`                                            | `href.query`                         |
| `new URL(current.asPath, 'https://example.org/').hash`     | `href.hash`                          |

Example:

```ts
import ActiveLink from '@stefanprobst/next-active-link'
import type { RouteMatcher } from '@stefanprobst/next-active-link'

/** dummy base url, since the URL constructor only handles absolute URLs */
const baseUrl = new URL('https://example.org/')

const isMatchingPathnameExactly: RouteMatcher = ({ current, as, href }) => {
  const to = as ?? href
  const link = typeof to === 'string' ? new URL(to, baseUrl) : to
  const route = new URL(current.asPath, baseUrl)
  return route.pathname === link.pathname
}

return (
  <ActiveLink href="/" isMatchingRoute={isMatchingPathnameExactly} passHref>
    <ActiveAnchor>Click me</ActiveAnchor>
  </ActiveLink>
)
```

## `useActiveLink`

Must be nested inside an `ActiveLink`.

```ts
const isActive = useActiveLink()
```

## Example

```ts
import { forwardRef } from 'react'
import type { ComponentPropsWithoutRef, Ref } from 'react'
import ActiveLink, { useActiveLink } from '@stefanprobst/next-active-link'

const ActiveAnchor = forwardRef(function ActiveAnchor(
  props: ComponentPropsWithoutRef<'a'>,
  ref: Ref<HTMLAnchorElement>,
) {
  const isActive = useActiveLink()
  return <a aria-current={isActive ? 'page' : undefined} ref={ref} {...props} />
})

function Page() {
  return (
    <ActiveLink href="/docs/[slug]" as="/docs/intro" passHref>
      <ActiveAnchor>Click me</ActiveAnchor>
    </ActiveLink>
  )
}
```
npm package: @stefanprobst/next-app-layout
Description: A tiny component to add persistent layouts to a Next.js app.
Author: Stefan Probst
Latest version: 1.0.1

# next-app-layout

A tiny component to add persistent layouts to a Next.js app.

## How to use

Page components can add a static `Layout` property on the default export which
will be used by `next-app-layout` as persistent layout.

### Layout component in pages/\_app.tsx

To render the layout, place thw following in `pages/_app.tsx`:

```ts
import Layout from '@stefanprobst/next-app-layout'
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <Layout>
      <Component {...pageProps}>
    </Layout>
  )
}
```

The `Layout` component accepts a `default` prop, which will be rendered if no
`Component.Layout` prop is found.

```ts
import Layout from '@stefanprobst/next-app-layout'
import type { AppProps } from 'next/app'
import PageLayout from 'layouts/PageLayout'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <Layout default={PageLayout}>
      <Component {...pageProps}>
    </Layout>
  )
}
```

All additional props passed to `Layout` will be passed on to the layout
component.

### Defining a page layout

In a page component, add the following:

```ts
import CustomLayout from 'layouts/CustomLayout'

export default function AboutPage() {
  return <h1>About</h1>
}

AboutPage.Layout = CustomLayout
```

To explicitly render _no_ persistent layout component (i.e. also bybassing any
default layout defined with `<Layout default={DefaultLayout}>`), set the Layout
to `React.Fragment`:

```ts
AboutPage.Layout = React.Fragment
```

### A note on react refresh

Hot reloading with react refresh will work, as long as the layout component is
imported from another file. Defining the layout component in the same file as
the page component will not work with react refresh, as it does not register
changes on static function properties.
npm package: @stefanprobst/next-feed
Description: This package only exists for easier CommonJS interop. It simply bundles [`xast-util-feed`](https://github.com/syntax-tree/xast-util-feed).
Latest version: 1.0.0

# Generate RSS feed

This package only exists for easier CommonJS interop. It simply bundles [`xast-util-feed`](https://github.com/syntax-tree/xast-util-feed).
npm package: @stefanprobst/next-image
Description: Adds a Webpack loader for importing `.jpg` and `.png` images to the Next.js config.
Author: Stefan Probst
Latest version: 1.0.1

# next-image

Adds a Webpack loader for importing `.jpg` and `.png` images to the Next.js
config.

## How to use

First, add the loader to the Next.js configuration in `next.config.js`:

```js
const withImages = require('@stefanprobst/next-image')()

const nextConfig = {
  /** ... */
}

module.exports = withImages(nextConfig)
```

In your components, images can then be imported:

```tsx
import Logo from '@/assets/icons/logo.png'

export default function Page() {
  return (
    <h1>
      <img src={Logo} alt="Logo" /> How cool!
    </h1>
  )
}
```

## Options

This package uses [`url-loader`](https://github.com/webpack-contrib/url-loader),
which can be configured with the
[`limit` option](https://github.com/webpack-contrib/url-loader#limit).

```js
const createImagePlugin = require('@stefanprobst/next-image')

const withImages = createImagePlugin({
  limit: 8192,
})

const nextConfig = {
  /** ... */
}

module.exports = withImages(nextConfig)
```

## Typescript

To make typescript understand `.jpg` and `.png` imports, add the following to
`next-env.d.ts`:

```ts
/// <reference types="@stefanprobst/next-image" />
```

## SVG images

For importing `.svg` images, use
[`@stefanprobst/next-svg`](https://github.com/stefanprobst/next-svg)
npm package: @stefanprobst/next-image-loader
Description: This is the webpack image loader extracted from Next.js, so it can be used in Storybook. Also exposes a helper function to generate `width`, `height` and `blurDataURL`, which can be used e.g. in a `remark`/`rehype` plugin to generate static images from im
Latest version: 1.0.4

# next-image-loader

This is the webpack image loader extracted from Next.js, so it can be used in Storybook. Also
exposes a helper function to generate `width`, `height` and `blurDataURL`, which can be used e.g. in
a `remark`/`rehype` plugin to generate static images from image file paths in frontmatter metadata.
npm package: @stefanprobst/next-markdown
Description: Adds a Webpack loader for importing `.md` files as HTML to the Next.js config.
Author: Stefan Probst
Latest version: 1.0.10

# next-markdown

Adds a Webpack loader for importing `.md` files as HTML to the Next.js config.

## How to use

First, add the loader to the Next.js configuration in `next.config.js`:

```js
const withMarkdown = require('@stefanprobst/next-markdown')(/* options */)

const nextConfig = {
  /** ... */
}

module.exports = withMarkdown(nextConfig)
```

Markdown files can then be imported as HTML. Frontmatter data is accessible on
the named `data` export:

```tsx
import html, { data } from '@/content/faq.md'

export default function Page() {
  return (
    <main>
      <h1>{data.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: html }}>
    </main>
  )
}
```

## Options

See [`markdown-loader`](https://github.com/stefanprobst/markdown-loader) for
options to enable parsing inline HTML.

## Typescript

To make typescript understand `.md` imports, add the following to
`next-env.d.ts`:

```ts
/// <reference types="@stefanprobst/next-markdown" />
```
npm package: @stefanprobst/next-sitemap
Description: Create a basic sitemap for a Next.js project.
Author: Stefan Probst
Latest version: 1.0.6

# next-sitemap

Create a basic sitemap for a Next.js project.

## How to use

This package will read the `build-manifest.json` and `prerender-manifest.json`
files generated by Next.js's build process, and generate a `sitemap.xml` in the
`public` folder.

To run the sitemap generation automatically after build, place a `postbuild`
script in `package.json`:

```json
  "scripts": {
    "build": "next build",
    "postbuild": "create-sitemap"
  }
```

### CLI

Running the sitemap generator via CLI requires passing the site's base url
either via `baseUrl` argument, or via `BASE_URL` environment variable:

```bash
create-sitemap --baseUrl https://example.com
```

or

```bash
BASE_URL=https://example.com create-sitemap
```

#### CLI Options

- `--baseUrl`, `-b`: the site's fully qualified base url
- `--exclude`, `-e`: json array of routes to exclude, e.g.
  `--exclude '["success.md"]'`
- `--format`, `-f`: format the sitemap xml with `prettier`
- `--gzip`, `-z`: compress the sitemap with `gzip`
- `--robots`, `-r`: path to robots.txt, or `true` to use default template

### Node

```js
import generate from '@stefanprobst/next-sitemap'

await generate({ baseUrl: 'https://example.com' })
```

#### Options

```ts
type Options = {
  baseUrl: string
  filter: (route: string) => boolean
  shouldFormat?: boolean
  shouldGzip?: boolean
  robots?: boolean | string
}
```

## Current limitations

- setting a custom `distDir` in `next.config.js` is not supported. the default
  `.next` is assumed.
- [sitemap indexes](https://www.sitemaps.org/protocol.html#index) are not
  supported.
- only one sitemap (i.e. max 50.000 routes) is supported.
- [`<priority>`, `<lastmod>`, `<changefreq>`](https://www.sitemaps.org/protocol.html#xmlTagDefinitions)
  are not supported.
- adding
  [locale alternates](https://en.wikipedia.org/wiki/Hreflang#XML_Sitemaps) is
  not supported. place `<link rel="alternate">` elements in the `<head>`
  instead.
npm package: @stefanprobst/next-svg
Description: Next.js plugin to optimize svg images with [SVGO v2](https://github.com/svg/svgo). Output can be used with `next/image` by default, or as a React component when imported with a resource query.
Latest version: 4.2.1

# next-svg

Next.js plugin to optimize svg images with [SVGO v2](https://github.com/svg/svgo). Output can be
used with `next/image` by default, or as a React component when imported with a resource query.

The current version generates a thin wrapping component around a svg
[`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use) element.

## How to install

```bash
yarn add @stefanprobst/next-svg`
```

## How to use

Add the plugin to the Next.js configuration:

```js
// next.config.mjs
import createSvgPlugin from '@stefanprobst/next-svg'

/** @type {import('next').NextConfig} */
const nextConfig = {}

const withSvg = createSvgPlugin({
  // id: '__root__',
  // svgoPlugins: [],
})

export default withSvg(nextConfig)
```

There are three options for importing an svg image:

### Use with `next/image`

By default, the svg image will be imported for use with `next/image`. This is also the default
`next` behavior.

```js
import Image from 'next/image'
import RocketAsset from '../public/rocket.svg'

export default function HomePage() {
  return (
    <main>
      <Image src={RocketAsset} alt="Cartoon rocket" />
    </main>
  )
}
```

### Use as a React component with inlined svg

When used with a `?inline` resource query, the import returns a React component which inlines the
svg as jsx. This is similar to what `svgr` does.

```js
import RocketComponent from '../public/rocket.svg?inline'

export default function HomePage() {
  return (
    <main>
      <RocketComponent aria-label="Cartoon rocket" />
    </main>
  )
}
```

Alternatively, the `?inline-icon` resource query will add a default width and height of `1em`.

### Use as a React component with `<use>`

When used with a `?symbol` resource query, the import returns a React component which references the
svg image via `<use>`.

```js
import RocketComponent from '../public/rocket.svg?symbol'

export default function HomePage() {
  return (
    <main>
      <RocketComponent aria-label="Cartoon rocket" />
    </main>
  )
}
```

Alternatively, the `?symbol-icon` resource query will add a default width and height of `1em`.

### Plugin options

- `id`: Added to the image's root `svg` element, so it can be refereced via `<use href="#id">`.
  (Optional)
- `svgoPlugins`: Add [svgo plugins](https://github.com/svg/svgo#built-in-plugins). By default, the
  base svgo preset with `removeViewBox` disabled, and `removeDimensions`, `convertStyleToAttrs` and
  `prefixIds` enabled is added. (Optional)

### Types

When using typescript, add the following to `app.d.ts` (or any other `.d.ts` file referenced in
`tsconfig.json#include`):

```ts
/// <reference types="@stefanprobst/next-svg/types" />
```
npm package: @stefanprobst/notifications
Description: ## How to use
Latest version: 0.0.2

# `notifications`

## How to use

```tsx
import '@stefanprobst/notifications/notifications.css'
import '@stefanprobst/notifications/notification-message.css'

import {
  Announcer,
  createNotificationsStore,
  createNotify,
  NotificationMessage,
  Notifications,
  NotificationsProvider,
} from '@stefanprobst/notifications'

export const store = createNotificationsStore()

export const notify = createNotify(store)

export function NotificationsContainer() {
  return (
    <NotificationsProvider store={store}>
      {(notifications, store) => (
        <>
          <Notifications notifications={notifications} store={store}>
            {(notification) => <NotificationMessage notification={notification} store={store} />}
          </Notifications>
          <Announcer notifications={notifications} store={store}>
            {(notification) => <NotificationMessage notification={notification} store={store} />}
          </Announcer>
        </>
      )}
    </NotificationsProvider>
  )
}
```
npm package: @stefanprobst/openapi-client
Description: this is a minimal typed request utility to interact with openapi-specified backends.
Latest version: 0.0.3

# openapi-client

this is a minimal typed request utility to interact with openapi-specified backends.

it uses
[openapi-typescript](https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-typescript)
for generating types, and is mostly copied from
[openapi-fetch](https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-fetch).

## how to install

```bash
npm install @stefanprobst/openapi-client
```

## how to use

first, generate types from an openapi document:

```bash
npx openapi-typescript https://my-backend.org/openapi.json -o ./types/api.ts
```

second, instantiate a typed api client:

```ts
import { createClient } from "@stefanprobst/openapi-client";

import type { paths } from "./types/api";

const client = createClient<paths>({ baseUrl: "http://localhost:3000" });
```
npm package: @stefanprobst/prettier-config
Description: Shareable prettier config. See the [prettier docs](https://prettier.io/docs/en/configuration.html#sharing-configurations) for installation instructions.
Latest version: 4.1.0

# prettier-config

Shareable prettier config. See the
[prettier docs](https://prettier.io/docs/en/configuration.html#sharing-configurations) for
installation instructions.
npm package: @stefanprobst/rehype-extract-toc
Description: This is a [`rehype`](https://github.com/rehypejs/rehype) plugin which attaches a document's table of contents to the VFile.
Author: Stefan Probst
Latest version: 3.0.0

# rehype-extract-toc

This is a [`rehype`](https://github.com/rehypejs/rehype) plugin which attaches a document's table of
contents to the VFile.

## How to install

```sh
pnpm add @stefanprobst/rehype-extract-toc
```

## How to use

```js
import { rehype } from "rehype";
import withSlugs from "rehype-slug";
import withToc from "@stefanprobst/rehype-extract-toc";

const processor = rehype().use(withSlugs).use(withToc);

const file = processor.processSync(doc);

console.dir(file.data.toc, { depth: null });
```

The table of contents will be attached to the resulting VFile's `data.toc` property. It has the
following shape:

```ts
interface TocEntry {
	value: string;
	depth: number;
	id?: string;
	children?: Array<TocEntry>;
}

type Toc = Array<TocEntry>;
```

Note that this plugin does _not_ generate any ids, you will probably want to combine it with
`rehype-slug`.

How you render the table of contents is up to you.

## How to use with MDX

When transforming MDX documents, you can expose the table of contents as a named export, which
defaults to `tableOfContents`.

```js
import { compile } from "@mdx-js/mdx";
import withSlugs from "rehype-slug";
import withToc from "@stefanprobst/rehype-extract-toc";
import withTocExport from "@stefanprobst/rehype-extract-toc/mdx";

async function run() {
	const file = await compile(doc, {
		rehypePlugins: [
			withSlugs,
			withToc,
			withTocExport,
			/** Optionally, provide a custom name for the export. */
			// [withTocExport, { name: 'toc' }],
		],
	});

	console.log(String(file));
}

run();
```

If you are using TypeScript, you can add typings with:

```js
/** mdx.d.ts (should be referenced in `tsconfig.json#include`) */
declare module '*.mdx' {
  import type { MDXProps } from 'mdx/types'
  import type { Toc } from '@stefanprobst/rehype-extract-toc'

  export const tableOfContents: Toc
  export default function MDXContent(props: MDXProps): JSX.Element
}
```
npm package: @stefanprobst/remark-excerpt
Description: [`remark`](https://remark.js.org/) transformer plugin to extract an excerpt.
Latest version: 2.0.2

# remark-excerpt

[`remark`](https://remark.js.org/) transformer plugin to extract an excerpt.

## How to install

```bash
yarn add @stefanprobst/remark-excerpt
```

## How to use

The plugin creates an excerpt, which includes content until a top-level
`<!-- excerpt -->` comment. If no excerpt comment is found content will be
truncated at `maxLength`.

Examples:

```js
import { remark } from 'remark'
import excerpt from '@stefanprobst/remark-excerpt'

const contentWithComment = `
This is some text.

<!-- excerpt -->

This is some more text.
`

const contentWithoutComment = `
This is some text. This is some more text.
`

const processor = remark().use(excerpt, { maxLength: 25 })

console.log(processor.processSync(contentWithComment))
// This is some text.
console.log(processor.processSync(contentWithoutComment))
// This is some text. This...
```

## Options

- `maxLength`: truncate text at this length if no `<!-- excerpt -->` comment is
  found. defaults to 140 characters.
- `ellipsis`: if text is truncated, add this ellipsis. defaults to "...".
- `preferWordBoundaries`: truncate at word boundary. defaults to `false`.

## Usage in a processor pipeline

It is possible to use the plugin in "bridge mode" in a `unified` processor
pipeline without truncating the original tree:

```js
import { remark } from 'remark'
import excerpt from '@stefanprobst/remark-excerpt'
import bridge from '@stefanprobst/unified-util-bridge'

const content = `
This is some text. This is some more text.
`

const excerptProcessor = remark().use(excerpt, { maxLength: 25 })
const processor = remark().use(bridge, 'excerpt', excerptProcessor)

const { data, contents } = processor.processSync(content)

console.log(contents)
// This is some text. This is some more text.
console.log(data.excerpt)
// This is some text. This...
```
npm package: @stefanprobst/remark-extract-toc
Description: This is a [`remark`](https://github.com/remarkjs/remark) plugin which attaches a document's table of contents to the VFile.
Author: Stefan Probst
Latest version: 2.2.0

# remark-extract-toc

This is a [`remark`](https://github.com/remarkjs/remark) plugin which attaches a
document's table of contents to the VFile.

## How to install

```sh
yarn add @stefanprobst/remark-extract-toc
```

## How to use

```js
import { remark } from 'remark'
import withSlugs from 'remark-slug'
import withToc from '@stefanprobst/remark-extract-toc'

const processor = remark().use(withSlugs).use(withToc)

const { data, contents } = processor.processSync(doc)

console.dir(data.toc, { depth: null })
```

The table of contents will be attached to the resulting VFile's `data.toc`
property. It has the following shape:

```ts
interface TocEntry {
  value: string
  depth: number
  id?: string
  children?: Array<TocEntry>
}

type Toc = Array<TocEntry>
```

Note that this plugin does _not_ generate any ids, you will probably want to
combine it with `remark-slug`.

How you render the table of contents is up to you.

## How to use with MDX

When transforming MDX documents, you can expose the table of contents as a named
export, which defaults to `tableOfContents`.

```js
import { compile } from '@mdx-js/mdx'
import withSlugs from 'remark-slug'
import withToc from '@stefanprobst/remark-extract-toc'
import withTocExport from '@stefanprobst/remark-extract-toc/mdx'

async function run() {
  const file = await compile(doc, {
    remarkPlugins: [
      withSlugs,
      withToc,
      withTocExport,
      /** Optionally, provide a custom name for the export. */
      // [withTocExport, { name: 'toc' }],
    ],
  })

  console.log(String(file))
}

run()
```

If you are using TypeScript, you can add typings with:

```js
/** mdx.d.ts (should be referenced in `tsconfig.json#include`) */
declare module '*.mdx' {
  import type { MDXProps } from 'mdx/types'
  import type { Toc } from '@stefanprobst/remark-extract-toc'

  export const tableOfContents: Toc
  export default function MDXContent(props: MDXProps): JSX.Element
}
```
npm package: @stefanprobst/remark-extract-yaml-frontmatter
Description: [remark](https://github.com/remarkjs/remark) transformer plugin to parse `yaml` nodes and expose parsed data on `vfile.data.frontmatter`. Works on `yaml` nodes created by [`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter).
Author: Stefan Probst
Latest version: 3.0.0

# remark-extract-yaml-frontmatter

[remark](https://github.com/remarkjs/remark) transformer plugin to parse `yaml` nodes and expose
parsed data on `vfile.data.frontmatter`. Works on `yaml` nodes created by
[`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter).

## How to install

```bash
yarn add remark-frontmatter @stefanprobst/remark-extract-yaml-frontmatter
```

## How to use

```js
import { remark } from 'remark'
import withFrontmatter from 'remark-frontmatter'
import withParsedFrontmatter from '@stefanprobst/remark-extract-yaml-frontmatter'

const md = `---
title: Test
---

Text
`

const file = remark().use(withFrontmatter).use(withParsedFrontmatter).processSync(md)

const frontmatter = file.data.frontmatter

console.log(frontmatter)
// { title: 'Test' }
```

### Options

It is possible to optionally transform the parsed frontmatter by providing a `transform` option:

```js
const options = {
  transform(frontmatter) {
    return {
      ...frontmatter,
      authors: frontmatter.authors.map(getFullAuthorDetails),
    }
  },
}
const file = remark().use(withFrontmatter).use(withParsedFrontmatter, options).processSync(md)
```

## When not to use

If you just want to extract frontmatter (without a full unified processor pipeline), you can use
[`vfile-matter`](https://github.com/vfile/vfile-matter).

## How to use with MDX

When transforming MDX documents, you can expose the frontmatter as a named export, which defaults to
`metadata`.

```js
import { compile } from '@mdx-js/mdx'
import withFrontmatter from 'remark-frontmatter'
import withParsedFrontmatter from '@stefanprobst/remark-extract-yaml-frontmatter'
import withParsedFrontmatterExport from '@stefanprobst/remark-extract-yaml-frontmatter/mdx'

async function run() {
  const file = await compile(doc, {
    remarkPlugins: [
      withFrontmatter,
      withParsedFrontmatter,
      withParsedFrontmatterExport,
      /** Optionally, provide a custom name for the export. */
      // [withParsedFrontmatterExport, { name: 'frontmatter' }],
    ],
  })

  console.log(String(file))
}

run()
```

If you are using TypeScript, you can add typings with:

```js
/** mdx.d.ts (should be referenced in `tsconfig.json#include`) */
declare module '*.mdx' {
  import type { MDXProps } from 'mdx/types'

  export const metadata: Record<string, unknown>
  export default function MDXContent(props: MDXProps): JSX.Element
}
```
npm package: @stefanprobst/remark-graphviz
Description: This is a [`remark`](https://github.com/remarkjs/remark) plugin to generate svg images from graphviz (dot) code blocks.
Latest version: 2.0.1

# `remark-graphviz`

This is a [`remark`](https://github.com/remarkjs/remark) plugin to generate svg
images from graphviz (dot) code blocks.

## How to install

```bash
yarn add @stefanprobst/remark-graphviz
```

## How to use

Add the plugin to a [`unified`](https://github.com/unifiedjs/unified) pipeline
which transforms markdown to
[`hast`](https://github.com/syntax-tree/hast#list-of-utilities) with
[`remark-rehype`](https://github.com/remarkjs/remark-rehype). Note that the
plugin runs async, so `processor.runSync()` and `processor.processSync()` will
not work.

````js
import { unified } from 'unified'
import fromMarkdown from 'remark-parse'
import withGraphviz from '@stefanprobst/remark-graphviz'
import toHast from 'remark-rehype'
import toHtml from 'rehype-stringify'

const processor = unified()
  .use(fromMarkdown)
  .use(withGraphviz)
  .use(toHast)
  .use(toHtml)

const md = `
Some text before.

\```dot
digraph {
  a -> b
}
\```

Some text after.
`

processor.process(md).then((file) => {
  console.log(String(file))
})
````

### Options

By default, the svg image is wrapped in a HTML `figure` element:

```html
<figure>
  <!-- svg generated by graphviz -->
  <svg></svg>
</figure>
```

#### `outputFolder` and `publicFolder`

When the `outputFolder` and `publicFolder` options are provided, the svg image
is written to file, and an `<img>` element is created:

```js
const processor = unified()
  .use(fromMarkdown)
  .use(withGraphviz, {
    outputFolder: './public/assets',
    publicFolder: '/assets',
  })
  .use(toHast)
  .use(toHtml)
```

This will write the image to `./public/assets/contenthash.svg` and generate
`<img src="/assets/contenthash.svg" alt="" />`.

Note that relative paths in `outputFolder` are treated as relative to
`process.cwd()`.

#### `optimize`

When setting `optimize: true`, the generated svg string will be optimized with
[`svgo`](https://github.com/svg/svgo).

## How to use in the browser

The only option available is
[`wasmFolder`](https://github.com/hpcc-systems/hpcc-js-wasm#wasmFolder) to point
to a location of the required `graphviz.wasm`. It defaults to
`https://unpkg.com/@hpcc-js/wasm/dist`.

## TODO

- Allow providing `figcaption` / `alt` text via `node.meta`.
npm package: @stefanprobst/remark-lint-no-auto-links
Description: Remark plugin to lint markdown for autolinks. Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) characters, e.g. `<https://example.com>`. Autolinks are invalid in mdx v2.
Latest version: 2.0.1

# remark-lint-no-auto-links

Remark plugin to lint markdown for autolinks. Autolinks are URLs enclosed in `<`
(less than) and `>` (greater than) characters, e.g. `<https://example.com>`.
Autolinks are invalid in mdx v2.
npm package: @stefanprobst/remark-preset
Description: This is a remark lint preset, which is compatible with `prettier`. Both linting (`remark test.md`) and rewriting (`remark test.md -o`) should work.
Latest version: 2.0.1

# Remark lint preset

This is a remark lint preset, which is compatible with `prettier`. Both linting
(`remark test.md`) and rewriting (`remark test.md -o`) should work.

- extends `preset-markdown-style-guide` and `preset-recommended`
- checks local links
- checks empty links
- enforces ## as first heading level

## Example

```json
// package.json
{
  "scripts": {
    "format": "prettier . --check --ignore-path .gitignore",
    "format:fix": "yarn format --write",
    "lint:md": "remark . --ignore-path .gitignore",
    "lint:md:fix": "yarn lint:md --output"
  },
  "lint-staged": {
    "*.md": ["prettier --write", "remark --output --frail"],
    "*.json": "prettier --write"
  },
  "prettier": "@stefanprobst/prettier-config",
  "remarkConfig": {
    "plugins": [
      "remark-frontmatter",
      "remark-gfm",
      "remark-footnotes",
      "@stefanprobst/remark-preset",
      "remark-lint-no-dead-urls"
    ]
  },
  "simple-git-hooks": {
    "pre-commit": "yarn lint-staged"
  }
}
```
npm package: @stefanprobst/remark-resource-links
Description: This is a plugin for `remark-stringify` version <= 8.0, which enforces that links are never serialized as autolinks (`<https://example.com>`), which are not compatible with mdx. Newer versions of `remark-stringify` have a built-in `resourceLink` option fo
Latest version: 1.0.2

This is a plugin for `remark-stringify` version <= 8.0, which enforces that
links are never serialized as autolinks (`<https://example.com>`), which are not
compatible with mdx. Newer versions of `remark-stringify` have a built-in
`resourceLink` option for this.