open-index/open-npm huggingface dataset:
npm package: @mcansh/eslint-config
Description: my usual eslint config
Author: Logan McAnsh
Latest version: 5.0.0

# eslint-config-mcansh

## Installation

```bash
$ yarn add -D @mcansh/eslint-config
```

then install the peerDependencies

```bash
$ npx install-peerdeps @mcansh/eslint-config --dev
```

followed by adding it to your eslint config

for react (javascript)

```javascript
module.exports = {
  extends: ['@mcansh'],
};
```

for react (typescript)

```typescript
module.exports = {
  extends: ['@mcansh/eslint-config/typescript'],
};
```

for everything else

```javascript
module.exports = {
  extends: ['@mcansh/eslint-config/base'],
};
```
npm package: @mcansh/headers.getsetcookie
Description: To install dependencies:
Author: Logan McAnsh
Latest version: 0.1.0

# @mcansh/headers.getsetcookie

To install dependencies:

```bash
bun install
```

To run:

```bash
bun run index.ts
```

This project was created using `bun init` in bun v0.8.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
npm package: @mcansh/http-helmet
Description: easily add CSP and other security headers to your web application.
Author: Logan McAnsh
Latest version: 0.13.2

# HTTP Helmet

easily add CSP and other security headers to your web application.

## Install

```sh
# npm
npm i @mcansh/http-helmet
```

## Usage

basic example using [`@mjackson/node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server)

```js
import * as http from "node:http";
import { createRequestListener } from "@mjackson/node-fetch-server";
import { createNonce, createSecureHeaders } from "@mcansh/http-helmet";

let html = String.raw;

let handler = (request) => {
  let nonce = createNonce();
  let headers = createSecureHeaders({
    "Content-Security-Policy": {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", `'nonce-${nonce}'`],
    },
  });

  headers.append("content-type", "text/html");

  return new Response(
    html`
      <!doctype html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
          />
          <title>Hello World</title>
        </head>
        <body>
          <h1>Hello World</h1>

          <script nonce="${nonce}">
            console.log("nonce configured");
          </script>

          <script>
            alert("nonce not configured");
          </script>
        </body>
      </html>
    `,
    { headers },
  );
};

let server = http.createServer(createRequestListener(handler));

server.listen(3000);

console.log("✅ app ready: http://localhost:3000");
```
npm package: @mcansh/next-now-base-url
Description: get the base url for your now.sh deployment in next.js
Author: Logan McAnsh
Latest version: 1.2.0

# @mcansh/next-now-base-url

> get the base url for your now.sh deployment in next.js

```tsx
import { getBaseURL } from '@mcansh/next-now-base-url';
import fetch from 'isomorphic-unfetch';

const Index: NextPage = () => <h1>Hello</h1>;

Index.getInitialProps = async ({ req }) => {
  const base = getBaseURL(req);
  const data = await fetch(`${base}/api/something`);
  return { data };
};

export default Index;
```
npm package: @mcansh/next-nprogress
Description: Easily integrate NProgress inside your Next.js app using styled-components
Author: Logan McAnsh
Latest version: 1.1.2

# @mcansh/next-progress

Easily integrate [NProgress](https://github.com/rstacruz/nprogress) into your
[Next.js](https://github.com/zeit/next.js) app using styled-components

## A note about typescript types

In order to get typescript types be sure to install the types for `nprogress`.

```bash
$ yarn add -D @types/nprogress

or

$ npm install -D @types/nprogress
```

## Usage

```js
import * as React from 'react';
import App from 'next/app';
import { NProgress } from '@mcansh/next-nprogress';

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;
    return (
      <>
        <NProgress
          color="#FE7912"
          options={{ trickleSpeed: 50 }}
          spinner={false}
        />
        <Component {...pageProps} />
      </>
    );
  }
}
```
npm package: @mcansh/next-svgr
Description: easily use @svgr/webpack with next.js
Author: Logan McAnsh
Latest version: 1.3.0

# @mcansh/next-svgr

Use [@svgr/webpack](https://github.com/gregberge/svgr/tree/master/packages/webpack) with [Next.js](https://github.com/vercel/next.js)

## Installation

```
npm install @mcansh/next-svgr
```

or

```
yarn add @mcansh/next-svgr
```

## Usage

Create a `next.config.js` in your project

```js
// next.config.js
const withSVG = require("@mcansh/next-svgr")();
module.exports = withSVG();
```

Optionally you can provide [options](https://github.com/gregberge/svgr/tree/master/packages/webpack#passing-options):

```js
// next.config.js
const withSVG = require("@mcansh/next-svgr")({
  native: true,
  svgoConfig: {
    removeViewBox: true,
  },
});
module.exports = withSVG();
```

Optionally you can add your custom Next.js configuration as parameter

```js
// next.config.js
const withSVG = require("@mcansh/next-svgr")();
module.exports = withSVG({
  webpack(config, options) {
    return config;
  },
});
```

## TypeScript

TypeScript doesn't know how interpret imported svgs.
**you need to add reference to our types** (third line) into your `next-env.d.ts` file.

```diff
/// <reference types="next" />
/// <reference types="next/types/global" />

+ /// <reference types="@mcansh/next-svgr" />
```
npm package: @mcansh/oxford-comma
Description: Convert an array to an oxford comma string based on the Intl.ListFormat api
Author: Logan McAnsh
Latest version: 1.0.0

# oxford-comma [![Build Status](https://travis-ci.org/mcansh/oxford-comma.svg?branch=master)](https://travis-ci.org/mcansh/oxford-comma)

> Convert an array to an oxford comma string based on the Intl.ListFormat api


## Install

```
$ npm install @mcansh/oxford-comma
```


## Usage

```js
const oxfordComma = require('@mcansh/oxford-comma');

oxfordComma(['Motorcycle', 'Bus', 'Car']);
//=> 'Motorcycle, Bus, and Car
```

## Created by

- [Logan McAnsh](https://github.com/mcansh)

## License

MIT
npm package: @mcansh/pid-from-port-cli
Description: Get PID from a port
Author: Logan McAnsh
Latest version: 1.0.1

# pid-from-port-cli

> Get PID from a port

## Install

```bash
$ npm install -g @mcansh/pid-from-port-cli
```

```bash
pid-from-port -p 3000
# > 18369

pid-from-port -p 3000 -p 8080
# > port 3000 is pid 18369
# > port 8080 is pid 18846

pid-from-port -p 4000
# > Couldn't find a process with port 4000
```

## Related
[pid-from-port](https://github.com/kevva/pid-from-port) - API
npm package: @mcansh/prettier-config
Description: ## install ```bash yarn add -D @mcansh/eslint-config ```
Author: Logan McAnsh
Latest version: 1.0.1
Deprecated: prettier config is now available through the eslint config, 'eslint-config-mcansh/prettier.config'

# prettier-config-mcansh

## install
```bash
yarn add -D @mcansh/eslint-config
```

### add to `prettier.config.js`
```js
module.exports = {
  ...require('@mcansh/prettier-config'),
};
```
npm package: @mcansh/remark-definition-links
Description: This plugin is based on [remark-reference-links][reference-links] and [remark-defsplit][defsplit] in that it converts inline links to a definition list, but unlike remark-defsplit it puts them all at the bottom
Author: Logan McAnsh
Latest version: 2.4.1

# remark-definition-links

This plugin is based on [remark-reference-links][reference-links] and [remark-defsplit][defsplit] in that it converts inline links to a definition list, but unlike remark-defsplit it puts them all at the bottom

[reference-links]: https://github.com/remarkjs/remark-reference-links
[defsplit]: https://github.com/remarkjs/remark-defsplit
npm package: @mcansh/remix-fastify
Description: Fastify server request handler for Remix and React Router
Author: Logan McAnsh
Latest version: 4.1.2

# Remix Fastify

Use [Remix](https://remix.run) with [Fastify](http://fastify.io)

## Quick Start

These are the currently available templates that you can get jump started with:

- Using the Remix Vite plugin (recommended)

  ```sh
  npx create-remix@latest --template mcansh/remix-fastify/examples/vite
  ```

- The basic example using the old Remix compiler
  ```sh
  npx create-remix@latest --template mcansh/remix-fastify/examples/basic
  ```

Get started with an existing boilerplate that integrates React Router 7 & Fastify:

- https://github.com/simonsmith/react-router-fastify

## Add to existing remix vite app

### Install dependencies

```shell
pnpm add @mcansh/remix-fastify fastify source-map-support get-port chalk @fastify/{middie,static}
```

### Install dev dependencies

```shell
pnpm add -D @types/source-map-support tsx
```

in the root of your project create a server directory and add index.ts
`server/index.ts`

```ts
import chalk from "chalk";
import { remixFastify } from "@mcansh/remix-fastify";
import { fastify } from "fastify";
import sourceMapSupport from "source-map-support";
import getPort, { portNumbers } from "get-port";

sourceMapSupport.install();

let app = fastify();

await app.register(remixFastify);

let host = process.env.HOST || "127.0.0.1";
let desiredPort = Number(process.env.PORT) || 3000;
let portToUse = await getPort({
  port: portNumbers(desiredPort, desiredPort + 100),
});

let address = await app.listen({ port: portToUse, host });

if (portToUse !== desiredPort) {
  console.warn(
    chalk.yellow(
      `⚠️ Port ${desiredPort} is not available, using ${portToUse} instead.`,
    ),
  );
}

console.log(chalk.green(`✅ app ready: ${address}`));
```

Update the `package.json` dev, start and build commands

```json
"build": "remix vite:build && tsc --project ./tsconfig.server.json",
"dev": "cross-env NODE_ENV=development tsx --watch-path ./server/index.ts ./server/index.ts",
"start": "cross-env NODE_ENV=production node ./server/index.js",
```

Add the `tsconfig.server.json` file to the root of the project

```json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "./tsconfig.json",
  "include": ["./server/**/*.ts"],
  "exclude": ["node_modules"],
  "compilerOptions": {
    "noEmit": false,
    "outDir": "./server"
  }
}
```

run `pnpm dev` to test that the server starts
npm package: @mcansh/remix-secure-headers
Description: easily add CSP and other security headers to your web application.
Author: Logan McAnsh
Latest version: 0.8.2
Deprecated: this package has been renamed to `@mcansh/http-helmet`

# HTTP Helmet

easily add CSP and other security headers to your web application.

## Install

```sh
# npm
npm i @mcansh/http-helmet
```

## Usage

basic example using hono

```js
import crypto from "node:crypto";

import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { createSecureHeaders } from "@mcansh/http-helmet";

const app = new Hono();

let html = String.raw;

app.get("/", () => {
  let nonce = crypto.randomBytes(16).toString("base64");

  let headers = createSecureHeaders({
    "Content-Security-Policy": {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", `'nonce-${nonce}'`],
    },
  });

  headers.append("Content-Type", "text/html; charset=utf-8");

  return new Response(
    html`
      <!doctype html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
          />
          <title>Hello World</title>
        </head>
        <body>
          <h1>Hello World</h1>

          <script nonce="${nonce}">
            console.log("nonce configured");
          </script>

          <script>
            alert("nonce not configured");
          </script>
        </body>
      </html>
    `,
    { headers },
  );
});

serve(app, (info) => {
  console.log(`✅ app ready: http://${info.address}:${info.port}`);
});
```
npm package: @mcansh/remix-v1-routes
Description: Continue to use the old nested folders route convention from Remix v1 in your v2 app.
Author: Logan McAnsh
Latest version: 0.0.3

# remix-v1-routes

Continue to use the old nested folders route convention from Remix v1 in your v2 app.

## Usage

```js
const { defineConventionalRoutes } = require("@mcansh/remix-v1-routes");

/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
  appDirectory: "app",
  assetsBuildDirectory: "public/build",
  serverBuildPath: "build/index.js",
  publicPath: "/build/",
  future: {
    v2_routeConvention: true,
  },

  ignoredRouteFiles: ["**/*"],
  routes: (defineRoutes) => defineConventionalRoutes("app", defineRoutes),
};
```
npm package: @mcansh/remix-web-vitals
Description: Web Vitals for Remix
Author: Logan McAnsh
Latest version: 0.3.6

# Vercel Remix Web Vitals

Save Web Vitals to Vercel

## Installation

```sh
# npm
npm i @mcansh/remix-web-vitals

# pnpm
pnpm i @mcansh/remix-web-vitals

# yarn
yarn add @mcansh/remix-web-vitals

# bun
bun add @mcansh/remix-web-vitals
```

## Usage

```tsx
import { WebVitals } from "@mcansh/remix-web-vitals";

export async function loader() {
  return json({ analyticsId: process.env.VERCEL_WEB_ANALYTICS_ID });
}

export default function App() {
  let { analyticsId } = useLoaderData<typeof loader>();

  return (
    <html lang="en">
      <head>
        <meta charSet="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
        {analyticsId ? <WebVitals analyticsId={analyticsId} /> : null}
      </body>
    </html>
  );
}
```
npm package: @mcansh/url
Description: a template string function to create urls and only keeping search params with values - based on [this tweet](https://x.com/Steve8708/status/1792939860820644201)
Author: Logan McAnsh
Latest version: 0.3.0

# @mcansh/url

a template string function to create urls and only keeping search params with values - based on [this tweet](https://x.com/Steve8708/status/1792939860820644201)

```ts
let filter = undefined;
let user = null;
let q = "my search";
urlString`https://site.com/path?q=${q}&user=${user}&filter=${filter}`;
// => "https://site.com/path?q=my+search"
```

```ts
import { UrlBuilder } from "@mcansh/url";

new UrlBuilder()
  .domain("site.com")
  .path("/path")
  .param("q", "my search")
  .param<number>("userId", 5)
  .param<string>("filter", "category")
  .build();
// => "https://site.com/path?q=my+search&userId=5&filter=category"
```
npm package: @mcansh/vite-plugin-remix
Description: a Vite plugin for Remix v3 (modified from https://github.com/jacob-ebey/vite-plugin-remix/tree/a5f372a4d48f9545e94d60cc401b865031ceecd7z)
Author: Logan McAnsh
Latest version: 0.0.1

# vite-plugin-remix

heavily inspired from work done by [Jacob Ebey](https://github.com/jacob-ebey/vite-plugin-remix/tree/a5f372a4d48f9545e94d60cc401b865031ceecd7) that wasn't published

## Install

```shellscript
pnpm i -D @mcansh/vite-plugin-remix
```
npm package: @mcansh/vite-plugin-svg-sprite
Description: this vite plugin will transform any imported svg files and combine them into an svg sprite sheet
Author: Logan McAnsh
Latest version: 0.7.1

# @mcansh/vite-plugin-svg-sprite

this vite plugin will transform any imported svg files and combine them into an svg sprite sheet

## installation and set up

```sh
npm i -D @mcansh/vite-svg-sprite-plugin
```

this is an example using Remix, but this plugin works with any vite configuration

```ts
import { svgSprite } from "@mcansh/vite-plugin-svg-sprite";
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [remix(), tsconfigPaths(), svgSprite()],
});
```

you can configure the generated sprite file name as well as the generated symbol id pattern

```ts
import { DEFAULT_COPY_ATTRS, svgSprite } from "@mcansh/vite-plugin-svg-sprite";

svgSprite({
  spriteOutputName: "sprite.svg",
  symbolId: "icon-[name]-[hash]",
  svgstoreOptions: {
    copyAttrs: [
      ...DEFAULT_COPY_ATTRS,
      // any additional attributes you want to copy from the svg to the symbol
    ],
  },
});
```

## usage

```tsx
import spriteUrl from "virtual:@mcansh/vite-plugin-svg-sprite";
import linkIconHref from "@primer/octicons/build/svg/link-16.svg";
import type { LinksFunction } from "@remix-run/node";

export const links: LinksFunction = () => {
  return [
    { rel: "preload", as: "image", href: spriteUrl, type: "image/svg+xml" },
  ];
};

export default function Component() {
  return (
    <svg className="size-4" aria-hidden>
      <use href={linkIconHref} />
    </svg>
  );
}
```
npm package: @mcansh/vite-svg-sprite-plugin
Description: this vite plugin will transform any imported svg files and combine them into an svg sprite sheet
Author: Logan McAnsh
Latest version: 0.6.0

# @mcansh/vite-svg-sprite-plugin

this vite plugin will transform any imported svg files and combine them into an svg sprite sheet

## installation and set up

```sh
  npm i -D @mcansh/vite-svg-sprite-plugin
```

this is an example using Remix, but this plugin should work everywhere else as well

```ts
import { createSvgSpritePlugin } from "@mcansh/vite-svg-sprite-plugin";
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [remix(), tsconfigPaths(), createSvgSpritePlugin()],
});
```

you can configure the generated sprite file name as well as the generated symbol id pattern

```ts
import { createSvgSpritePlugin } from "@mcansh/vite-svg-sprite-plugin";

createSvgSpritePlugin({
  spriteOutputName: "sprite.svg",
  symbolId: "icon-[name]-[hash]",
});
```

## usage

```tsx
import spriteUrl from "virtual:@mcansh/vite-svg-sprite-plugin";
import linkIconHref from "@primer/octicons/build/svg/link-16.svg";
import type { LinksFunction } from "@remix-run/node";

export const links: LinksFunction = () => {
  return [
    { rel: "preload", as: "image", href: spriteUrl, type: "image/svg+xml" },
  ];
};

export default function Component() {
  return (
    <svg className="size-4" aria-hidden>
      <use href={linkIconHref} />
    </svg>
  );
}
```
npm package: @mcansh/vitest-response-matchers
Description: Response assertion matchers for vitest
Author: Logan McAnsh
Latest version: 0.1.0

# @mcansh/vitest-response-matchers

Response assertion matchers for vitest

## Installation

```shell
npm install @mcansh/vitest-response-matchers
```

```json
// tsconfig.json
{
  "compilerOptions": {
    "types": ["@mcansh/vitest-response-matchers/client"]
  }
}
```

```typescript
// vitest.setup.ts
import "@mcansh/vitest-response-matchers";
```

## Usage

### `toHaveStatus`

Check if the response has a specific status code.

```typescript
let response = new Response("Hello World!");

expect(response).toHaveStatus(200);
```

### `toHaveHeader`

Check if the response has a specific header.

```typescript
let response = new Response("Hello World!", {
  headers: {
    "x-custom-header": "value",
  },
});

expect(response).toHaveHeader("x-custom-header", "value");
```

### `toHaveCookies`

Check if the response has a specific cookie.

```typescript
let response = new Response("Hello World!", {
  headers: {
    "Set-Cookie": "name=value; Path=/",
  },
});

expect(response).toHaveCookies(["name=value; Path=/"]);
```

### `toHaveStatusText`

Check if the response has a specific status text.

```typescript
let response = new Response("Hello World!");

expect(response).toHaveStatusText("OK");
```

### `toHaveStrictStatusText`

Check if the response has a specific status text according to the HTTP specification. (uses node:http)

```typescript
let response = new Response("Hello World!", {
  status: 400,
  statusText: "nah",
});

expect(response).toHaveStrictStatusText("OK"); // fails
```

### `toMatchResponse`

Check if the response matches another response.

```typescript
let response = new Response("Hello World!");

expect(response).toMatchResponse(response);
expect(response).toMatchResponse({ status: 200, statusText: "OK" });
```

### `toHaveTextBody`

Check if the response has a specific text body.

```typescript
let response = new Response("Hello World!");

expect(response).toHaveTextBody("Hello World!");
```

### `toHaveJsonBody`

Check if the response has a specific JSON body.

```typescript
let response = new Response(JSON.stringify({ foo: "bar" }));

expect(response).toHaveJsonBody({ foo: "bar" });
```

### `toThrowResponse`

Check if a function throws a Response

```typescript
function throwResponse() {
  throw new Response("Hello World!");
}

expect(() => throwResponse()).toThrowResponse(new Response("Hello World!"));
```
npm package: @mcarbaugh/jinq
Description: A LINQ inspired package which extends and/or enhances native javascript data structures.
Author: Michael Carbaugh
Latest version: 3.0.0

# jinq

A LINQ inspired package which extends and/or enhances native javascript data structures.

## Example
```ts
import { List } from "@mcarbaugh/jinq";

const list = new List([
  { firstName: 'John', lastName: 'Smith', favoriteColor: 'blue', age: 20 },
  { firstName: 'Susy', lastName: 'Q', favoriteColor: 'green', age: 45 },
  { firstName: 'Jane', lastName: 'Doe', favoriteColor: 'blue', age: 33 },
]);

const averageAge = list.average(item => item.age);
const minAge = list.min(item => item.age);
const maxAge = list.max(item => item.age);
const count = list.count(item => item.age >= 33);

console.log(averageAge, minAge, maxAge, count); // prints 31 20 45 2
```

## Sorting

### Example (Array of Numbers)
```ts
import { List } from "@mcarbaugh/jinq";

const list = new List([10, 3, 6, 8]);

const ascending = list
  .orderBy(x => x)
  .toJSON();

const descending = list
  .orderByDescending(x => x)
  .toJSON();

console.log(ascending); // prints 3 6 8 10
console.log(descending); // prints 10 8 6 3
```

### Example (Array of Objects)
```ts
import { List } from "@mcarbaugh/jinq";

const list = new List([
  { firstName: 'John', lastName: 'Smith', favoriteColor: 'blue', age: 20 },
  { firstName: 'Susy', lastName: 'Q', favoriteColor: 'green', age: 45 },
  { firstName: 'Jane', lastName: 'Doe', favoriteColor: 'blue', age: 33 },
]);

const sorted = list
  .orderBy(item => item.favoriteColor) // applies a primary sort on favoriteColor
  .thenBy(item => item.lastName) // applies a secondary sort on lastName
  .toJSON();

console.log(sorted);
```

## Grouping
```ts
import { List } from "@mcarbaugh/jinq";

const list = new List([
  { firstName: 'John', lastName: 'Smith', favoriteColor: 'blue', age: 20 },
  { firstName: 'Susy', lastName: 'Q', favoriteColor: 'green', age: 45 },
  { firstName: 'Jane', lastName: 'Doe', favoriteColor: 'blue', age: 33 },
]);

const grouped = list
  .groupBy(item => item.favoriteColor)
  .toJSON();

console.log(grouped);
/**
 * {
 *    blue: [
 *      { firstName: 'John', lastName: 'Smith', favoriteColor: 'blue', age: 20 },
 *      { firstName: 'Jane', lastName: 'Doe', favoriteColor: 'blue', age: 33 },
 *    ],
 *    green: [
 *      { firstName: 'Susy', lastName: 'Q', favoriteColor: 'green', age: 45 },
 *    ]
 * }
 */
```
npm package: @mcard/jxa-global-type
Description: JXA typing for global
Author: azu
Latest version: 1.4.1

# @jxa/global-type

JXA typing for global.

This typing enable auto-complete in your editor.

![auto complete example](./docs/example.gif)

- [TypeScript Editor Support · Microsoft/TypeScript Wiki](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support)

## Install

Install with [npm](https://www.npmjs.com/):

    npm install @jxa/global-type

## Usage

Install and includes `@jxa/global-type` as typing.
Then, automatically inject `Application` to `global`

### via `import("@jxa/global-type")`

You can add JSX types to `global` by import `@jxa/global-type`:

```ts
import "@jxa/global-type";

// your JXA application
var userName = Application("System Events").currentUser().name();
```

### via tsconfig.json

- [ ] welcome PR

### Via reference comment

```ts
/// <reference path="./node_modules/@jxa/global-type/src/index.d.ts" />

// your JXA application
var userName = Application("System Events").currentUser().name();
```

## Changelog

See [Releases page](https://github.com/JXA-userland/JXA/releases).

## Running tests

    yarn test

## Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, [please create an issue](https://github.com/JXA-userland/JXA/issues).

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D

## Author

- [github/azu](https://github.com/azu)
- [twitter/azu_re](https://twitter.com/azu_re)

## License

MIT © azu
npm package: @mcard/jxa-repl
Description: REPL for JXA.
Author: azu
Latest version: 1.4.1

# @jxa/repl

REPL for JXA.

## Install

Install with [npm](https://www.npmjs.com/):

    npm install -g @jxa/repl

**Requirement:**

- Node.js 10+

## Usage

    $ npx @jxa/repl
    # or
    $ npm install -g @jxa/repl
    $ jxa-repl
    > Application("System Events").currentUser().name();

## Command

### `.clear`

Clear current buffer and history.
It will release defined variables.
 
## Changelog

See [Releases page](https://github.com/JXA-userland/JXA/releases).

## Reference

- [REPL | Node.js v10.5.0 Documentation](https://nodejs.org/api/repl.html)

## Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, [please create an issue](https://github.com/JXA-userland/JXA/issues).

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D

## Author

- [github/azu](https://github.com/azu)
- [twitter/azu_re](https://twitter.com/azu_re)

## License

MIT © azu
npm package: @mcard/jxa-run
Description: Run JXA code and get result.
Author: azu
Latest version: 1.4.1

# @jxa/run

Run JXA code and get result.

## Install

Install with [npm](https://www.npmjs.com/):

    npm install @jxa/run

Requirement:

- macOS 10.10 or later.

## Usage

### `export declare function run<R>(jxaCodeFunction: (...args: any[]) => void, ...args: any[]): Promise<R>`

Illustration of usage

```js
const resultPromise = run(JSXFn, argumentsOfJSXFn);
```

- `JSXFn`: This function is run as JXA.
    - :memo: This `JSXFn` is serialized(`toString`) and pass to JXA environment.
    - **Warning** The function cannot close over variables in a parent's scope.
    - You need to pass arguments as `argumentsOfJSXFn` explicitly 
- `argumentsOfJSXFn`: An arguments of `JSXFn`

**OK:**

```ts
// OK
(async () => {
    // `name` is "nodejs"
    const result = await run(name => {
        return "Hello there, " + name + "!"
    }, "nodejs");
    assert.strictEqual(result, "Hello there, nodejs!");
})();
```

**NG:**

```ts
// NG
(async () => {
    const name = "nodejs"
    const result = await run(name => {
        return "Hello there, " + name + "!"; // can not access to `name` from JXA enviroment
    });
    assert.strictEqual(result, "Hello there, nodejs!");
})();
```

## Example

```ts
(async () => {
    const result = await run(
        // run this function as JXA code
        () => {
            return Application("System Events")
                .currentUser()
                .name()
        }
    );
    assert.strictEqual(result, process.env.USER);
})();
```

## Changelog

See [Releases page](https://github.com/JXA-userland/JXA/releases).

## Running tests

    yarn test

## Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, [please create an issue](https://github.com/JXA-userland/JXA/issues).

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D

## Author

- [github/azu](https://github.com/azu)
- [twitter/azu_re](https://twitter.com/azu_re)


## Related

- [wtfaremyinitials/osa2: Interact with Apple's Open Scripting Architecture in node.js](https://github.com/wtfaremyinitials/osa2 "wtfaremyinitials/osa2: Interact with Apple's Open Scripting Architecture in node.js")
- [sindresorhus/run-jxa: Run JXA code and get the result](https://github.com/sindresorhus/run-jxa "sindresorhus/run-jxa: Run JXA code and get the result")

## License

MIT © azu
npm package: @mcard/jxa-sdef-to-dts
Description: Scripting definition files (sdefs) to TypeScript (d.ts)
Author: azu
Latest version: 1.4.0

# @jxa/sdef-to-dts

Convert Scripting definition files (`.sdefs`) to TypeScript(d.ts)

## Install

Install with [npm](https://www.npmjs.com/):

    npm install @jxa/sdef-to-dts

## Usage as library

Convert `./input/*.sdef` file and output it as `d.ts` to `./output` directory.

```ts
const fs = require("fs");
const path = require("path");
const { transform } = require("@jxa/sdef-to-dts");
const sdefDir = path.join(__dirname, "./input");
const outputDir = path.join(__dirname, "./output");
const promises = fs.readdirSync(sdefDir).map(async caseName => {
    const fileName = path.basename(caseName, ".sdef");
    const normalizedTestName = fileName.replace(/\s/g, "");
    const actualContent = fs.readFileSync(path.join(fixturesDir, caseName), "utf-8");
    console.log("transform " + normalizedTestName);
    const actual = await transform(normalizedTestName, actualContent);
    fs.writeFileSync(path.join(outputDir, normalizedTestName) + ".d.ts", actual, "utf-8");
});
Promise.all(promises).then(() => {
    console.log("All write");
});
```

## Usage as command

Convert application bundles (e.g. `/Applications/Safari.app`) and output as `d.ts`.

```
  Scripting definition files (sdefs) to TypeScript (d.ts)

  Usage
    $ npx @jxa/sdef-to-dts <input> --output <output>

    <input>       path to an Application.app to read

  Options
    --output, -o  path to an Application.d.ts or a directory to write to
    --version     show the version
    --help        show this help page

  Examples
    $ npx @jxa/sdef-to-dts /Applications/Safari.app --output ./safari.d.ts
```

## Running tests

    yarn test

## Changelog

See [Releases page](https://github.com/JXA-userland/JXA/releases).

## Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, [please create an issue](https://github.com/JXA-userland/JXA/issues).

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D

## Author

- [github/azu](https://github.com/azu)
- [twitter/azu_re](https://twitter.com/azu_re)

## License

MIT © azu
npm package: @mcard/jxa-types
Description: TypeScript definition for JXA core.
Author: azu
Latest version: 1.4.1

# @jxa/types

TypeScript definition for JXA core.

## Install

Install with [npm](https://www.npmjs.com/):

    npm install @jxa/types

## Usage

This library is just TypeScript definition files.
In other words, this library only used for importing.

If you want to modify `global`, see [@jxa/global-type](../global-type).

### Use with custom Application type

`Application` support [generics type](https://www.typescriptlang.org/docs/handbook/generics.html) that return `T & Application`

Example: `GoogleChrome` Application

```ts
import { Application } from "@jxa/types";
import { GoogleChrome } from "./fixtures/GoogleChrome";
// Pass Custom Application type as generics
const chrome = Application<GoogleChrome>("Google Chrome");
const frontWindow: GoogleChrome.Window = chrome.app.windows[0];
```

### Update Core d.ts

1. Update `tools/sdefs/*.sdefes`
2. Update d.ts with follows command:
    
    yarn run dts:update

## Running tests

    yarn test

## Changelog

See [Releases page](https://github.com/JXA-userland/JXA/releases).

## Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, [please create an issue](https://github.com/JXA-userland/JXA/issues).

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D

## Author

- [github/azu](https://github.com/azu)
- [twitter/azu_re](https://twitter.com/azu_re)

## License

MIT © azu
npm package: @mcarlssen/typeon-react
Description: A simple, easily customizable React typewriter-effect component with no dependencies
Author: Mike Thorn
Latest version: 1.0.3

# TypeOn React Component
A simple and customizable React component that creates a typewriter effect for text animation. Written in TypeScript with zero dependencies.

https://github.com/mcarlssen/react-typeon

## Features
- Lightweight and performant
- Zero dependencies
- Fully customizable

## Installation
```bash
npm install @mcarlssen/typeon-react
# or
yarn add @mcarlssen/typeon-react
```

## Usage
```tsx
import { TypeOn } from 'typeon-react';

function App() {
  return (
    <TypeOn
      phrases={['Hello World!', 'Welcome to my website', 'This is a typewriter effect']}
      baseSpeed={24}
      pauseDuration={3000}
      className="my-custom-class"
    />
  );
}
```

## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| phrases | string[] | required | Array of phrases to type |
| baseSpeed | number | 24 | Characters per second |
| pauseDuration | number | 3000 | Milliseconds to pause between phrases |
| className | string | 'title-keyword-text' | CSS class name for styling |

## Styling
The component renders a `span` element with your provided className, which contains the phrases being typed-on. The typing cursor is rendered as a `span` with the class `cursor`. The cursor character is an underscore `_` by default; you can change this by modifying the contents of the `cursor` span in `TypeOn.tsx`. You can style the typed phrase span and the cursor elements using CSS:

```css
.type-on-text {
  font-family: monospace;
}

.cursor {
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  from, to { opacity: 1; }
  50% { opacity: 0; }
}
```

## Examples

### Basic Usage
```tsx
<TypeOn phrases={['Simple', 'Easy', 'Fast']} />
```

### Custom Speed and Pause Duration
```tsx
<TypeOn 
  phrases={['Faster typing', 'Longer pauses']}
  baseSpeed={50}  // Faster typing
  pauseDuration={5000}  // Longer pauses
/>
```

### Custom Styling
```tsx
<TypeOn 
  phrases={['Custom styled text']}
  className="my-fancy-text"
/>
```

## Dependencies
This library has zero dependencies and only requires React as a peer dependency.

Note: The demo project in the repository includes additional dependencies, but these are only for demonstration purposes and are not required to use the library in your project.

## Contributing
Contributions are welcome! 

## License
MIT © Mike Thorn (@mcarlssen)
npm package: @mcartoixa/leaflet-binglayer
Description: Bing Maps Layer for Leaflet
Latest version: 1.0.0-11

# leaflet-binglayer
Yet another Leaflet plugin that handles Bing Maps layers.

[![Build status](https://travis-ci.org/mcartoixa/leaflet-binglayer.svg?branch=master)](https://travis-ci.org/mcartoixa/leaflet-binglayer)

This plugin is loosely based on [leaflet-bing-layer](https://github.com/digidem/leaflet-bing-layer/blob/gh-pages/leaflet-bing-layer.js) and
[leaflet-plugins](https://github.com/shramov/leaflet-plugins/blob/master/layer/tile/Bing.js). Check them out, you might find there is better
support there ;-)

The main difference here is that :
* this plugin has no dependency (outside of [leaflet](http://leafletjs.com/) v1+ of course).
* it caches Bing metadata in memory, which should result in fewer [Bing Maps transactions](https://msdn.microsoft.com/en-us/library/ff859477.aspx) when:
  * you need more than 1 map in the same page.
  * your maps are part of a Single Page Application.

## Usage

## Development
You can live test the plugin:
* create a `.env` file (cf. [dotenv](https://github.com/motdotla/dotenv)) at the root of your project that defines the `BING_KEY` variable with your Bing Maps key.
* run `npm run-script debug`.
* open your browser at http://localhost:8000.
npm package: @mcastiello/cancellable-promise
Description: As the name suggests, this promise can be cancelled while still running.
Author: Marco Castiello
Latest version: 0.0.3

# Cancellable Promise
As the name suggests, this promise can be cancelled while still running.

### Install
`yarn add @mcastiello/cancellable-promise`

`npm install @mcastiello/cancellable-promise`

### How to use

```ts
import { CancellablePromise } from "@mcastiello/cancellable-promise";

const promise = new CancellablePromise((resolve) => resolve("Hello World"));

promise.cancel();

console.log(await promise); // undefined
```

## Static methods
It also provides a few static methods to simplify the use of promises:

### `defer`
Make functions asynchronous by deferring them. Once the deferred function will be executed, it will return a cancellable promise that will be resolved with the value returned by the original function.
```ts
import { CancellablePromise } from "@mcastiello/cancellable-promise";

const callback = () => true;

// This will make the above callback asynchronous
const deferred = CancellablePromise.defer(callback);

// The function will return a function that, once executed, it will resolve the cancellable promise
const result = await deferred();
// As the returned value is a cancellable promise, the execution can be cancelled at any point
```

### `wait`
Wait for a fixed amount of time before resolving the promise.
```ts
import { CancellablePromise } from "@mcastiello/cancellable-promise";

const waiting = async () => {
  console.log("Hello World1");
  
  await CancellablePromise.wait(1000);
  
  console.log("One second is passed!");
}
```
npm package: @mcastiello/html-context
Description: An HTML WebComponent capable of propagating a context across the DOM tree.
Author: Marco Castiello
Latest version: 0.0.1

# HTML Context
An HTML WebComponent capable of propagating a context across the DOM tree.

### Install
`yarn add @mcastiello/html-context`

`npm install @mcastiello/html-context`

## Propagate context
The component is able to propagate a context across the DOM tree by passing it between children on the same branch.

It also allows you to pass a store element which, whenever the state is updated, it will trigger the render function
```ts
import { ActionDefinition, createStore, Reducer } from "@mcastiello/simple-store";
import { HTMLContextElement, WebComponentEvents } from "@mcastiello/html-context";

enum Action {
  Update,
}

type Definitions = {
  [Action.Update]: ActionDefinition<Action.Update, string>;
};

type State = {
  value?: string;
};

type Context = {
  emptyValue: string;
};

class ContextComponent extends HTMLContextElement<Context, State, Action> {
  constructor() {
    super();
    this.addEventListener(WebComponentEvents.Initialised, () => {
      this.innerHTML = "<span></span>";
    });
  }
  
  render() {
    const span = this.querySelector("span");
    if (span) {
      span.textContent = this.state?.value || this.context?.emptyValue || null;
    }
  }
}
customElements.define("ctx-component", ContextComponent);
```

Once you created your component, you can simply add it to the DOM and let the context element propagate the data.

```ts
import { createStore, Reducer } from "@mcastiello/simple-store";

document.body.innerHTML = `
  <html-context class="context">
    <div class="container">
      <ctx-component class="component"></ctx-component>
    </div>
  </html-context>
`;

const container = document.body.querySelector(".context") as HTMLContextElement<Context, State, Action>;

const reducer: Reducer<State, Definitions> = (state = {}, action) => {
  switch (action.type) {
    case Action.Update:
      return {...state, value: action.payload};
  }
};
const store = createStore(reducer);

container.context = {
  emptyString: "-",
};
container.store = store;

console.log(document.body.querySelector(".component span").textContent); // "-";

store.dispatch(Action.Update, "test");

console.log(document.body.querySelector(".component span").textContent); // "test";
```
npm package: @mcastiello/time-functions
Description: A collection of functions that can be used to simplify the asynchronous execution of your code.
Author: Marco Castiello
Latest version: 0.0.4

# Time Functions
A collection of functions that can be used to simplify the asynchronous execution of your code.

### Install
`yarn add @mcastiello/time-functions`

`npm install @mcastiello/time-functions`

## Functions

### `debounce`

Delay the execution of a function. If while waiting for the execution,
the function is called again, the previous call is cancelled and
delay is reset. The function will not be executed until the delay
is successfully completed without any rest.

```ts
import { debounce, sleep } from "@mcastiello/time-functions";

const myFunction = () => console.log("Hello World!");

const debounced = debounce(myFunction, 20);

debounced();
debounced();
debounced();

await sleep(50);
debounced();

// Hello World!
// Hello World!
```

### `throttle`

Run the function the first time is called, but hold successive
executions until the requested delay is reached.

```ts
import { throttle, sleep } from "@mcastiello/time-functions";

const myFunction = () => console.log("Hello World!");

const throttled = throttle(myFunction, 20);

throttled();
// Hello World!

throttled();
throttled();

await sleep(50);
throttled();
// Hello World!
```

### `sleep`

Put on hold an asynchronous execution for the requested delay.

```ts
import { sleep } from "@mcastiello/time-functions";

sleep(50).then(() => {
  console.log("Hello World!");
})
```

### `retry`

Keep retrying to execute the provided function until it returns
a valid value without throwing errors, or until the timeout is reached.

```ts
import { retry } from "@mcastiello/time-functions";
import { API_ENDPOINT } from "./constants";

const makeRequest = retry(async (url: string): Promise<{ valid: boolean }> => {
  const response = await fetch(url);
  return await response.json();
}, {
  delay: 250,
  timeout: 5000,
  validate: (result) => result.valid
});

try {
  console.log(await makeRequest(API_ENDPOINT));
} catch (error) {
  console.error(error);
}
```