open-index/open-npm huggingface dataset:
npm package: @shware/analytics
Description: layout.tsx
Latest version: 3.4.1

# Shware Analytics SDK

## Config

layout.tsx

```tsx
import { setupAnalytics } from '@shware/analytics';
import { getTags, getDeviceId, storage } from '@shware/analytics/web';
import { v4 as uuidv4 } from 'uuid';

setupAnalytics({
  storage,
  getTags,
  getDeviceId,
  endpoint: 'https://api.example.com/v1/analytics',
});

function App() {
  return <div>My React App</div>;
}
```

## Usage

```tsx
import { track } from '@shware/analytics';

function Button() {
  const onClick = async () => {
    await api.login();
    track('login', { method: 'google' });
  };
  return <button onClick={onClick}>Login with Google</button>;
}
```

## Backend API

- /analytics/tracks: track events
- /analytics/visitor: app visitors

## UTM params

- utm_source

## GAD params

[About gad\_\* URL parameters](https://support.google.com/google-ads/answer/16193746)

- gad_source
- gad_campaignid
- gclid

## Third Parties Advices

### Reddit

We strongly recommend using the Reddit Pixel and Conversions API (CAPI) together.

- rdt_cid: from url params
- \_rdt_uuid: from first-party cookie

### LinkedIn

If we receive an Insight Tag event and a Conversions API event from the same account with the same eventId, we discard the Conversions API event and count only the Insight Tag event in campaign reporting.

- [Click IDs](https://learn.microsoft.com/en-us/linkedin/marketing/conversions/enabling-first-party-cookies?view=li-lms-2025-10&source=recommendations): get li_fat_id from url params and cookie
npm package: @shware/error
Description: # Server Side Error Handling
Latest version: 0.2.0

# Client Side Error Handling

# Server Side Error Handling

## hono example

### With Adapter

```typescript
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { Status } from '@repo/error';

Status.adapter = (status, response) => {
  const headers = { 'Content-Type': 'application/json' };
  const res = new Response(JSON.stringify(response), { status, headers });
  return new HTTPException(status, { res });
};

const app = new Hono();

app.get('/', () => {
  throw Status.invalidArgument('Hello World!').error();
});

serve({ fetch: app.fetch, port: 3000 });
```

### With Global Error Handler

```typescript
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { Status, StatusError } from '@repo/error';

const app = new Hono();

app.onError((error, c) => {
  if (error instanceof StatusError) {
    return c.json(error.response, error.status);
  }
  return c.json({ error: 'Internal Server Error' }, 500);
});

app.get('/', () => {
  throw Status.invalidArgument('Hello World!').error();
});

serve({ fetch: app.fetch, port: 3000 });
```

## nestjs example
npm package: @shware/http
Description: ```typescript import { Hono } from 'hono'; import { HTTPException } from 'hono/http-exception'; import { Status } from '@repo/error';
Latest version: 2.10.2

# Error Handling

## hono example

### With Adapter

```typescript
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { Status } from '@repo/error';

Status.adapter = (status, response) => {
  const headers = { 'Content-Type': 'application/json' };
  const res = new Response(JSON.stringify(response), { status, headers });
  return new HTTPException(status, { res });
};

const app = new Hono();

app.get('/', () => {
  throw Status.invalidArgument('Hello World!').error();
});

serve({ fetch: app.fetch, port: 3000 });
```

### With Global Error Handler

```typescript
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { Status, StatusError } from '@repo/error';

const app = new Hono();

app.onError((error, c) => {
  if (error instanceof StatusError) {
    return c.json(error.response, error.status);
  }
  return c.json({ error: 'Internal Server Error' }, 500);
});

app.get('/', () => {
  throw Status.invalidArgument('Hello World!').error();
});

serve({ fetch: app.fetch, port: 3000 });
```

## Custom ErrorReason

By default, `ErrorInfo.reason` accepts any `string`. You can use TypeScript [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) to constrain it to a set of known keys:

```typescript
// e.g. shware-http.d.ts
import '@shware/http'; // Required: makes this file a module so that `declare module` augments rather than replaces

declare module '@shware/http' {
  interface ErrorReason {
    ACCOUNT_BLOCKED: string;
    ACCOUNT_LOCKED: string;
    SUBSCRIPTION_EXPIRED: string;
  }
}
```

Once declared, `Details.errorInfo({ reason })` will only accept the keys you defined, with full autocomplete support:

```typescript
import { Details } from '@shware/http';

// OK
Details.new().errorInfo({ reason: 'ACCOUNT_BLOCKED' });

// Type error: Type '"INVALID"' is not assignable to type 'keyof ErrorReason'
Details.new().errorInfo({ reason: 'INVALID' });
```

## nestjs example
npm package: @shware/security
Description: ```ts import { Hono } from 'hono'; import { Auth, RedisIndexedSessionRepository } from '@shware/security'; import { apple, github } from '@shware/security/oauth2/provider'; import { env, type Env } from '../env'; import { redis } from '../db'; import { on
Latest version: 2.3.1

# Auth lib

## Hono example

```ts
import { Hono } from 'hono';
import { Auth, RedisIndexedSessionRepository } from '@shware/security';
import { apple, github } from '@shware/security/oauth2/provider';
import { env, type Env } from '../env';
import { redis } from '../db';
import { onAuthorized } from '../services/auth';

// ------------------------------------------------- ⬇️ ioredis ⬇️ namespace
const repository = new RedisIndexedSessionRepository(redis, 'mywebsite:session');
repository.setDefaultMaxInactiveInterval(30 * 24 * 60 * 60);

const auth = new Auth({
  timing: true,
  repository,
  oauth2: {
    client: {
      baseUri: 'https://api.mywebsite.com', // backend
      errorUri: 'https://mywebsite.com', // frontend with query: error=string&error_description=string
      successUri: 'https://mywebsite.com',
      provider: { apple, github },
      registration: async () => ({
        appleApp: {
          provider: 'apple',
          clientId: env.OAUTH2_APPLE_APP_CLIENT_ID,
          clientSecret: env.OAUTH2_APPLE_APP_CLIENT_SECRET,
        },
        appleWeb: {
          provider: 'apple',
          clientId: env.OAUTH2_APPLE_WEB_CLIENT_ID,
          clientSecret: env.OAUTH2_APPLE_WEB_CLIENT_SECRET,
        },
        github: {
          provider: 'github',
          clientId: env.OAUTH2_GITHUB_CLIENT_ID,
          clientSecret: env.OAUTH2_GITHUB_CLIENT_SECRET,
        },
      }),
    },
  },
});

const app = new Hono<Env>();

app.get('/auth', (c) => c.json({ test: 'test' }));
app.get(auth.PATH_LOGGED, (c) => auth.logged(c.req.raw));
app.post(auth.PATH_LOGOUT, (c) => auth.logout(c.req.raw));

app.get(auth.PATH_OAUTH2_STATE, (c) => auth.oauth2State(c.req.raw));
app.get(auth.PATH_OAUTH2_AUTHORIZATION, (c) => auth.oauth2Authorization(c.req.raw));
app.get(auth.PATH_LOGIN_OAUTH2_CODE, (c) => auth.loginOAuth2Code(c.req.raw, onAuthorized));
app.post(auth.PATH_LOGIN_OAUTH2_CODE, (c) => auth.loginOAuth2Code(c.req.raw, onAuthorized));
app.post(auth.PATH_LOGIN_OAUTH2_NATIVE, (c) => auth.loginOAuth2Native(c.req.raw, onAuthorized));

export default app;
```