open-index/open-npm huggingface dataset:
npm package: @labdigital/apollo-gateway-directives
Description: This plugin allows you to handle GraphQL directives within Apollo Gateway.
Author: Lab Digital
Latest version: 0.2.0

# Apollo Gateway Directives Plugin

This plugin allows you to handle GraphQL directives within Apollo Gateway.

## Installation

```bash
pnpm add @labdigital/apollo-gateway-directives
```

## Usage

```ts
import { GatewayDirectivesPlugin } from '@labdigital/apollo-gateway-directives';
import type { BaseContext } from "@apollo/server";
import { buildSchema } from "graphql";

type ContextValue extends BaseContext {
  foobar: string;
}

const directivesPlugin = new GatewayDirectivesPlugin<ContextValue>({
  // Define the directive handlers here
  myDirective: async (
    args: Record<string, unknown>,
    context: ContextValue,
  ) => {
    // Do something with the directive
  }
});

const gateway = new ApolloGateway({
  // ...
});

gateway.onSchemaLoadOrUpdate((schema) => {
  // Parse the schema ourselves since `schema.apiSchema` has not all
  // directives available. See https://github.com/apollographql/federation/issues/2895
  const sdl = buildSchema(schema.coreSupergraphSdl);
  directivesPlugin.parseSchema(sdl);
});

const server = new ApolloServer({
  gateway,
  plugins: [
    directivesPlugin,
  ]
});

await server.start();
```
npm package: @labdigital/apollo-server-integration-fastify
Description: This is a plugin to integrate Apollo Server with Fastify. Code based on:  - https://github.com/apollo-server-integrations/apollo-server-integration-fastify  - https://github.com/apollo-server-integrations/apollo-server-integration-fastify/issues/296
Author: Lab Digital
Latest version: 0.1.1

# @labdigital/apollo-server-integration-fastify

This is a plugin to integrate Apollo Server with Fastify. Code based on:
 - https://github.com/apollo-server-integrations/apollo-server-integration-fastify
 - https://github.com/apollo-server-integrations/apollo-server-integration-fastify/issues/296
npm package: @labdigital/apollo-trusted-documents
Description: This plugin enables support for trusted documents (persisted queries) in Apollo Server, with built-in support for GraphQL Hive's App Deployments.
Author: Lab Digital
Latest version: 0.1.1

# Apollo Trusted Documents Plugin

This plugin enables support for trusted documents (persisted queries) in Apollo Server, with built-in support for GraphQL Hive's App Deployments.

## Installation

```bash
pnpm add @labdigital/apollo-trusted-documents
```

## Usage

### With GraphQL Hive

```ts
import { ApolloServer } from "@apollo/server";
import { TrustedDocumentsPlugin, HiveStore } from "@labdigital/apollo-trusted-documents";
import Keyv from "keyv";

// Create a cache for the documents (e.g., using Keyv)
const cache = new Keyv();

const trustedDocumentsPlugin = new TrustedDocumentsPlugin({
  store: new HiveStore({
    endpoint: "https://cdn.graphql-hive.com",
    accessToken: process.env.HIVE_CDN_ACCESS_TOKEN,
    cache,
  }),
  // Optional: strict mode (default: true)
  // When enabled, only trusted documents are allowed
  strict: true,
  // Optional: bypass header for development/testing
  bypassHeader: "x-bypass-trusted-operations",
  bypassSecret: process.env.BYPASS_SECRET,
});

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [trustedDocumentsPlugin],
});

await server.start();
```

### Custom Document Store

You can implement your own document store by implementing the `DocumentStore` interface:

```ts
import type { DocumentStore } from "@labdigital/apollo-trusted-documents";

class MyCustomStore implements DocumentStore {
  async get(documentId: string): Promise<string | undefined> {
    // Fetch the document from your custom store
    return myDatabase.getDocument(documentId);
  }
}

const trustedDocumentsPlugin = new TrustedDocumentsPlugin({
  store: new MyCustomStore(),
});
```

## Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `store` | `DocumentStore` | - | The document store to use for fetching trusted documents |
| `strict` | `boolean` | `true` | When enabled, only trusted documents are allowed |
| `bypassHeader` | `string` | `"x-bypass-trusted-operations"` | Header name to check for bypass secret |
| `bypassSecret` | `string` | - | Secret value to allow bypassing trusted documents check |
npm package: @labdigital/bluestonepim-sdk
Description: Bluestone PIM SDK
Author: Lab Digital
Latest version: 0.0.4

# BluestonePIM SDK

This SDK provides methods to interact with the BluestonePIM API. It includes methods to retrieve differences in products
and relations during synchronization operations.

## Installation

To install the SDK, use npm:

```sh
# Using npm
npm install @labdigital/bluestonepim-sdk

# Using yarn
yarn add @labdigital/bluestonepim-sdk

# Using pnpm
pnpm add @labdigital/bluestonepim-sdk
```

## Usage

```typescript
import { DifferencesApi, Configuration } from "@labdigital/bluestonepim-sdk";

const config = new Configuration({
  apiKey: "your-api-key-here",
  basePath: "https://api.test.bluestonepim.com/v1",
});

const differencesApi = new DifferencesApi(config);

const requestParameters = {
  id: "sync-id",
  diffType: "type",
  itemsOnPage: 10,
  pageNo: 1,
};

const productDifferences =
  await differencesApi.getProductDifferencesOnSyncDeletes(requestParameters);
console.log(productDifferences);
```

### Retrying requests

The Bluestone PIM API may return a 429 status code when the rate limit is exceeded. To handle this, you can use the
`retry` function from the `fetch-retry` package. This function will retry the request a number of times with a delay
between each attempt.

```sh
# Using npm
npm install fetch-retry isomorphic-fetch

# Using yarn
yarn add fetch-retry isomorphic-fetch

# Using pnpm
pnpm add fetch-retry isomorphic-fetch
```

```typescript
const config = new Configuration({
  fetchApi: retry(fetch, {
    retries: 5, //Retry 5 times
    retryDelay: 1000, //Retry after 1 second
    retryOn: (attempt: number, error, response: Response | null): boolean => {
      // Only retry when 429 is hit, otherwise we continue
      if (response != null && response.status === 429) {
        logger.debug({
          msg: "Retrying Bluestone PIM request",
          attempt: attempt,
          responseStatus: response.status,
        });
        return true;
      }
      return false;
    },
  }),
  // Your other configuration options
});
```

## Development

To regenerate the SDK, run the following command:

```sh
pnpm run sdk:generate
```

This will generate the SDK in the `src` directory.
npm package: @labdigital/commercetools-federated-schema
Description: ## Installation
Author: Lab Digital
Latest version: 0.0.3

# Commercetools Schema Federation

## Installation

`yarn add @labdigital/commercetools-federated-schema`

## Usage

```ts
import { createCommercetoolsSchema } from '@labdigital/commercetools-federated-schema';

let commercetoolsSchema: GraphQLSchema;

export const getCommercetoolsSchema = () => {
  if (!commercetoolsSchema) {
    commercetoolsSchema = createCommercetoolsSchema({
      endpoint: `${process.env.CT_API_URL}/${process.env.CT_PROJECT_KEY}/graphql`,
      transforms: transforms,
      typeDefs: [commercetoolsTypeDefs],
      resolvers: [commercetoolsResolvers],
    });
  }
  return commercetoolsSchema;
};
```
npm package: @labdigital/commercetools-mock
Description: [<img src="https://img.shields.io/npm/v/@labdigital/commercetools-mock">](https://www.npmjs.com/package/@labdigital/commercetools-mock) [![codecov](https://codecov.io/gh/labd/commercetools-node-mock/branch/main/graph/badge.svg?token=muKkNunJ95)](https://c
Author: Michael van Tellingen
Latest version: 2.66.0
npm package: @labdigital/commercetools-utilities
Description: ## CommercetoolsClient
Author: Lab Digital
Latest version: 0.8.3

# Lab Digital Commercetools Utilities

## CommercetoolsClient

This is a more straight-forward helper to create a commercetools client for
interacting with Commercetools.

```ts
const client = CommercetoolsClient({
  host: 'https://api.europe-west1.gcp.commercetools.com/',
  projectKey: 'my-project',
  auth: {
    host: 'https://auth.europe-west1.gcp.commercetools.com/',
    credentials: {
      clientId: 'my-client-id',
      clientSecret: 'my-client-secret',
    },
    scopes: ['view_orders:my-project', 'view_products:my-project'],
  },
});

const projectApi = await client.getProjectApi();
projectApi.products().get().execute()
```

When the options are not passed it will read it from the ENV vars:

- `CT_PROJECT_KEY`
- `CT_API_URL`
- `CT_AUTH_URL`
- `CT_CLIENT_ID`
- `CT_CLIENT_SECRET`
- `CT_SCOPES`

```ts
const client = CommercetoolsClient();
client.getProjectApi();
```

You can also pass a callable to `auth` which returns a token to be used.

```ts
const client = createClient({
  host: process.env.CT_API_URL,
  projectKey,
  auth: async () => {
    return 'mytoken';
  },
});

client.getProjectApi();
```

Note that the ApiRoot object is cached on the client instance for 900 seconds

### Pass custom middleware to the Commercetools client

```ts
const client = CommercetoolsClient({
  host: 'https://api.europe-west1.gcp.commercetools.com/',
  projectKey: 'my-project',
  auth: {
    host: 'https://auth.europe-west1.gcp.commercetools.com/',
    credentials: {
      clientId: 'my-client-id',
      clientSecret: 'my-client-secret',
    },
    scopes: ['view_orders:my-project', 'view_products:my-project'],
  },
  middlewares: [yourMiddleware]
});
```

See the [commercetools sdk docs](https://docs.commercetools.com/sdk/js-sdk-middleware#custom-middleware) for an example of custom middleware or check the tests in `client.test.ts`.
npm package: @labdigital/dataloader-cache-wrapper
Description: Wrapper around dataloader to cache the results of the loader
Author: Lab Digital
Latest version: 0.6.2

# node-dataloader-cache-wrapper


## Usage
```ts
import { DataLoaderCache } from "@labdigital/dataloader-cache-wrapper"

const loader = new DataLoaderCache<ProductReference, any>(ProductDataLoader, {
	cache: {
		storeFn: () => new Keyv(),
		ttl: 3600,
	},
	cacheKeyFn: (ref: ProdProductReferenceuctRef) => {
		const key = `${ref.store}-${ref.locale}-${ref.currency}`;
		return `some-data:${key}:id:${ref.slug}`
	},
	maxBatchSize: 50,
});

```

Or use the older API with the `dataloaderCache` function:

```ts
import { dataloaderCache } from "@labdigital/dataloader-cache-wrapper"

export const createProductBySlugLoader = () => {
  return new DataLoader<ProductReference, any>(ProductDataLoader, {
    maxBatchSize: 50,
  });
};

export const ProductDataLoader = async (keys: readonly any[]): Promise<(Product | null)[]> => {
  return dataloaderCache(_uncachedProductDataLoader, keys, {
    store: new Keyv(),
    ttl: 3600,

    cacheKeysFn: (ref: ProductReference) => {
      const key = `${ref.store}-${ref.locale}-${ref.currency}`;
      return [`some-data:${key}:id:${ref.slug}`];
    },
  })
}
```
npm package: @labdigital/enviconf
Description: A simple library to parse environment variables
Author: Lab Digital
Latest version: 1.0.0

# @labdigital/enviconf

A simple configuration library that loads configuration from environment
variables and provides a simple interface to access them.

Inspired by https://github.com/caarlos0/env


## Example

```ts

import { BaseConfig, EnviConfig, envfield } from "@labdigital/enviconf";

class SampleConfig extends BaseConfig {
	/** The port number to listen on */
	readonly HTTP_PORT: number = 4000

	config(): EnviConfig {
		return {
			HTTP_PORT: envfield.number({
				// optional, defaults to false. Sets empty value if no env variable is set
				optional: true,

				// optional, defaults to false. Unsets the env variable after reading
				unset: true,

				// optional, env variable to read the value from, defaults to the property name
				envName: "MY_HTTP_PORT",

				// optional, defaults to undefined. Allows setting a custom validator, should
				// throw an error if the value is invalid
				validator:  (value: number) => value > 0,
			}),
		}
	}
}
const config = SampleConfig.load()

config.HTTP_PORT === 4000
```
npm package: @labdigital/exporter-oltp-sqs
Description: An OpenTelemetry exporter for traces and metrics that pushes them to an SQS queue. This is useful when running in a serverless environment. The [exporter-oltp-sqs-consumer](https://github.com/labd/exporter-oltp-sqs-consumer) can be used to consume the tra
Author: Lab Digital B.V.
Latest version: 1.0.7

# OpenTelemetry SQS Exporter
An OpenTelemetry exporter for traces and metrics that pushes them to an SQS
queue. This is useful when running in a serverless environment. The
[exporter-oltp-sqs-consumer](https://github.com/labd/exporter-oltp-sqs-consumer)
can be used to consume the traces and metrics from the SQS queue and push them
to a collector.

## Usage
```sh
pnpm add @labdigital/exporter-oltp-sqs
```

Set the `OTEL_EXPORTER_OTLP_SQS_QUEUE_URL` env var to the SQS query to push the traces and metrics to.

```ts
import {
  OTLPMetricExporterSQS,
  OTLPTraceExporterSQS,
} from "@labdigital/exporter-oltp-sqs";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-node";
import type { NodeSDKConfiguration } from "@opentelemetry/sdk-node";
import { NodeSDK } from "@opentelemetry/sdk-node";

const traceExporter = new OTLPTraceExporterSQS();
const metricExporter = new OTLPMetricExporterSQS({
  // Optional if no env var is set
  sqsQueueURL: "https://sqs.eu-west-1.amazonaws.com/xxxx/honeycomb-refinery-exporter.fifo",
});

const config: Partial<NodeSDKConfiguration> = {
  traceExporter: traceExporter,
  metricReader: new PeriodicExportingMetricReader({
    exporter: metricExporter,
    exportIntervalMillis: 5000,
  }),
  spanProcessors: [new BatchSpanProcessor(traceExporter)],
};

const sdk = new NodeSDK(config);
sdk.start();
```
npm package: @labdigital/federated-token-apollo
Description: Federate JWT tokens between Apollo servers
Author: Lab Digital
Latest version: 2.2.1

# Federated Token - Apollo Plugin

[![npm](https://img.shields.io/npm/v/@labdigital/federated-token.svg)](https://www.npmjs.com/package/@labdigital/federated-token)

This package provides support for both Apollo Server (including Gateway). It
processes the token and forwards it to downstream services and also reads
new/updated tokens from downstream services.

It provides three Apollo specific classes:

- `GatewayAuthPlugin` - An Apollo plugin for the GraphQL gateway that verifies
  the signature of the token passed and decrypts the embedded JWE property. It
  stores the verified and decrypted token on the context as `federatedToken`.

- `FederatedGraphQLDataSource` - An Apollo GraphQL data source used in the
  GraphQL Gateway which passes the `federatedToken` from the context to the
  datasource (federated service) as `x-access-token` HTTP header.

- `FederatedAuthPlugin` - An Apollo plugin for federated services that reads
  the token passed in the `x-access-token` header and stores it on the context
  as `federatedToken`.

When a federated services creates a new token (when non exist) it can also
return a refresh token in the `x-refresh-token` header. The gateway will then
encrypt all refresh tokens and encrypt them before passing them to the client
as `x-refresh-token` header.
npm package: @labdigital/federated-token-envelop
Description: Federate JWT tokens between GraphQL servers
Author: Lab Digital
Latest version: 1.0.4

# Federated Token - Envelop Plugin

[![npm](https://img.shields.io/npm/v/@labdigital/federated-token.svg)](https://www.npmjs.com/package/@labdigital/federated-token)

This packages provides an Envelop plugin so that for example Yoga can be used as
a federated service. I

It provides three Apollo specific classes:

- `federatedAuthPlugin` - An Apollo plugin for federated services that reads
  the token passed in the `x-access-token` header and stores it on the context
  as `federatedToken`.

When a federated services creates a new token (when non exist) it can also
return a refresh token in the `x-refresh-token` header. The gateway will then
encrypt all refresh tokens and encrypt them before passing them to the client
as `x-refresh-token` header.
npm package: @labdigital/federated-token-react
Description: Federate JWT tokens for React clients
Author: Lab Digital
Latest version: 2.2.0

# Federated Token - React Provider

The package `@labdigital/federated-token-react` provides a React context provider
to manage the token state in a React application.

# Usage

Register the `AuthProvider` in your application. This will provide the token to
all components in the application.

```tsx
import {
	AuthProvider,
	AuthProviderProps,
} from "@labdigital/federated-token-react";

const authProviderProps: AuthProviderProps = {
	logoutMutation: JSON.stringify({
		query: "mutation { clearToken }",
	}),
	refreshTokenMutation: JSON.stringify({
		query: "mutation { refreshToken }",
	}),
	authEndpoint: `${clientApiHostname}/auth/graphql`,
};

return <AuthProvider options={authProviderProps}>{children}</AuthProvider>;
```

Use the token data

```tsx
import { useAuth } from '@labdigital/federated-token-react';

const { loading, isAuthenticated, values, refreshToken } = useAuth();

if (loading) {
	return <div>Loading...</div>;
}
return (
	<div>User is authenticated {isAuthenticated}</div>
	<div>Values: {values}</div>
)
```

## Manual Token Refresh with AbortSignal

You can manually refresh the token and optionally provide an AbortSignal for cancellation:

```tsx
import { useAuth } from '@labdigital/federated-token-react';

function MyComponent() {
	const { refreshToken } = useAuth();

	const handleRefresh = async () => {
		try {
			// Simple refresh (uses default 10s timeout)
			await refreshToken();
			console.log('Token refreshed successfully');
		} catch (error) {
			console.error('Token refresh failed:', error);
		}
	};

	const handleRefreshWithTimeout = async () => {
		try {
			// Use AbortSignal.timeout for clean timeout handling
			await refreshToken(AbortSignal.timeout(5000)); // 5 second timeout
			console.log('Token refreshed successfully');
		} catch (error) {
			if (error.name === 'AbortError') {
				console.error('Token refresh timed out');
			} else {
				console.error('Token refresh failed:', error);
			}
		}
	};

	const handleRefreshWithCancel = async () => {
		const controller = new AbortController();
		
		// Start the refresh
		const refreshPromise = refreshToken(controller.signal);
		
		// Cancel after 3 seconds if still pending
		setTimeout(() => {
			console.log('Cancelling refresh request...');
			controller.abort();
		}, 3000);

		try {
			await refreshPromise;
		} catch (error) {
			console.error('Refresh was cancelled or failed:', error);
		}
	};

	return (
		<div>
			<button onClick={handleRefresh}>Refresh Token</button>
			<button onClick={handleRefreshWithTimeout}>Refresh with 5s Timeout</button>
			<button onClick={handleRefreshWithCancel}>Refresh with Cancel</button>
		</div>
	);
}
```

## Configuration Options

The `AuthProvider` accepts the following options:

- `refreshTimeoutMs`: Default timeout in milliseconds for token refresh requests (default: 10000ms)
- `refreshHandler`: Custom function to handle token refresh with optional AbortSignal support
npm package: @labdigital/federated-token-yoga
Description: Federated token plugin for GraphQL Yoga
Author: Lab Digital
Latest version: 2.2.0

# Federated Token - Yoga Plugin

[![npm](https://img.shields.io/npm/v/@labdigital/federated-token.svg)](https://www.npmjs.com/package/@labdigital/federated-token)

This packages provides a GraphQL Yoga plugin so that for Yoga can be used as a
federated service.

## Usage

- `useFederatedToken()` - The plugin for federated services that reads
  the token passed in the `x-access-token` header and stores it on the context
  as `federatedToken`.

When a federated services creates a new token (when non exist) it can also
return a refresh token in the `x-refresh-token` header. The gateway will then
encrypt all refresh tokens and encrypt them before passing them to the client
as `x-refresh-token` header.