npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@worktif/purews

v0.4.0

Published

Target Pure AWS – TypeScript-based AWS infrastructure toolkit featuring DynamoDB integration, AppSync support, SES functionality, and GraphQL capabilities with comprehensive audit logging and AWS Signature V4 authentication.

Readme


Contents


Overview

@worktif/purews centralizes common AWS infrastructure code used by TypeScript Lambda services:

  • Configuration: EnvConfigPurews validates package-specific environment shape with Zod and extends EnvConfigDefault from @worktif/utils.
  • Bundle / DI: BundlePurews and bundlePurews expose the configured environment and default service accessors.
  • DynamoDB: DynamoDbService is an abstract base class for table-specific services with typed CRUD/query helpers.
  • S3: S3Service reads S3 object content as UTF-8 text.
  • SES: SesService sends emails and manages SES email verification checks.
  • Lambda: lambdaApi, lambdaSqs, composeLambdaLogger, injectApi, injectValidation, and zodValidationMiddleware standardize Lambda event parsing, logging, and validation.
  • Serialization: SerializerPurews composes serializers supplied by @worktif/utils.

This README tracks APIs present in the current src exports.


Installation

npm install @worktif/purews
yarn add @worktif/purews

Most consumers also need reflect-metadata imported once at application startup:

import 'reflect-metadata';

Runtime Requirements

  • Node.js: >=20.0.0
  • TypeScript: strict mode is supported; this package is built with TypeScript 5.8.x
  • AWS credentials: resolved from the runtime environment or the execution role used by the workload
  • Package manager for this repository: Yarn 1.22.22

Public API

The package root exports:

export * from './config';
export * from './services';
export * from './bundle';
export * from './utils';

Bundle and Config

  • BundlePurews
  • bundlePurews
  • PurewsContainer
  • PurewsDi
  • BundleAws
  • EnvConfigPurews
  • envConfigPurewsSchema
  • EnvConfigPurewsSchema

Services

  • DynamoDbService
  • DynamoEntity
  • AuditLogs
  • AwsSignatureV4HeaderOptions
  • S3Service
  • SesService
  • LambdaApi
  • InternalContext
  • InternalContextLogger
  • InternalContextLoggerService
  • LambdaEventApi
  • LambdaEventMethod
  • LambdaEventSqs
  • ResponseOptionalFields

Utilities

  • lambdaApi
  • lambdaSqs
  • composeLambdaLogger
  • injectApi
  • injectValidation
  • zodValidationMiddleware
  • SerializerPurews
  • ValidationService
  • LambdaContext

Usage

Read Validated Environment

import 'reflect-metadata';

import { bundlePurews } from '@worktif/purews';

const env = bundlePurews.env;

console.log(env.aws.credentials.region);

Send Email with SES

SesService is registered in the default bundle. SES_NOTIFICATION_EMAIL must be set before sending mail.

import 'reflect-metadata';

import { bundlePurews, SesService } from '@worktif/purews';

const ses = bundlePurews.aws.services.ses as SesService;

await ses.sendEmail(
  '<b>Hello from PureWS</b>',
  '[email protected]',
  'Message from @worktif/purews',
);

Create a Table-Specific DynamoDB Service

DynamoDbService is abstract. Extend it for each table and provide tableName.

import 'reflect-metadata';

import {
  bundlePurews,
  DynamoDbService,
  type DynamoEntity,
} from '@worktif/purews';

type User = {
  email: string;
  name: string;
};

class UserDynamoDbService extends DynamoDbService {
  tableName = 'users';
}

const users = new UserDynamoDbService(bundlePurews.env);

const created = await users.put<User>({
  email: '[email protected]',
  name: 'Ada',
});

const user = created?.id
  ? await users.get<DynamoEntity<User>>(created.id)
  : undefined;

console.log(user);

Read an S3 Object as Text

import 'reflect-metadata';

import { bundlePurews, S3Service } from '@worktif/purews';

const s3 = new S3Service(bundlePurews.env);

const content = await s3.getS3ObjectContent({
  Bucket: 'example-bucket',
  Key: 'path/to/file.txt',
});

console.log(content);

Wrap an API Gateway Lambda

lambdaApi parses JSON request bodies for POST requests, normalizes the HTTP method to lowercase, injects AWS Lambda Powertools logger context, and passes the optional internal logger context to the handler.

import 'reflect-metadata';

import { lambdaApi, type LambdaEventApi } from '@worktif/purews';

type CreateUserPayload = {
  email: string;
  name: string;
};

export const handler = lambdaApi<CreateUserPayload, 'post'>(
  async (
    event: LambdaEventApi<CreateUserPayload, 'post'>,
    _context,
    internal,
  ) => {
    internal?.log?.now(
      { body: event.body },
      { message: 'Create user request' },
    );

    return {
      statusCode: 201,
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ created: true }),
    };
  },
  {
    logger: {
      service: {
        entity: 'Users',
        name: 'CreateUser',
      },
    },
  },
);

Validate a Lambda Body with Zod Middleware

import 'reflect-metadata';

import { z } from 'zod';
import { lambdaApi, zodValidationMiddleware } from '@worktif/purews';

const CreateUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

type CreateUserPayload = z.infer<typeof CreateUserSchema>;

export const handler = lambdaApi<CreateUserPayload, 'post'>(
  async (event) => ({
    statusCode: 201,
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ email: event.body.email }),
  }),
).use(zodValidationMiddleware(CreateUserSchema));

Validate Before Calling a Decorated Handler

injectValidation returns a function that can normalize API Gateway or EventBridge payloads before the decorated method receives them.

import 'reflect-metadata';

import { z } from 'zod';
import { injectApi, injectValidation } from '@worktif/purews';

const BodySchema = z.object({
  email: z.string().email(),
});

class CreateUserController {
  @injectApi(injectValidation({ body: BodySchema }))
  async handle(event: { body: z.infer<typeof BodySchema> }) {
    return {
      statusCode: 200,
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ email: event.body.email }),
    };
  }
}

Environment Variables

The current package-specific configuration is scoped to SES notification email:

| Variable | Required | Used By | | --- | --- | --- | | SES_NOTIFICATION_EMAIL | No, but required by SesService.sendEmail | SES source, BCC, and reply-to address |

AWS credential values are read through the inherited default environment configuration:

| Variable | Fallback | Purpose | | --- | --- | --- | | AWS_REGION | us-east-1 | AWS client region | | AWS_ACCESS_KEY_ID | dump in support mode | Explicit AWS access key for non-role execution | | AWS_SECRET_ACCESS_KEY | dump in support mode | Explicit AWS secret key for non-role execution | | AWS_SESSION_TOKEN | dump in support mode | Optional AWS session token |

Prefer IAM roles for deployed Lambda workloads. Use explicit credentials only for local development or controlled automation.


Development

Install dependencies:

yarn install

Generate TypeDoc documentation:

yarn docs

Emit declaration files:

yarn types

Build the package:

yarn build

Publish through the configured package script:

yarn publish:npm

Current repository note: package.json does not define a real test runner; yarn test exits with Error: no test specified. Do not add passing-test badges until a test suite exists and is wired into the package scripts.


Release Process

This package is published to npm as @worktif/purews. Keep releases traceable:

  1. Implement the change and run the applicable local validation.
  2. Open a PR and wait for review approval.
  3. Merge the implementation PR into main.
  4. Pull the latest main.
  5. Create a release branch using a semantic-versioned name, for example releases/v0.3.2-next-release-description.
  6. Bump the version in package.json.
  7. Open and merge the release PR after required checks pass.
  8. Pull the latest main again.
  9. Confirm the package version.
  10. Publish with yarn publish:npm.

If npm rejects the publish because the version already exists, bump the version and repeat the release branch flow. If publishing fails for another reason, capture the command output, Node/npm/Yarn versions, and CI logs before escalating to the maintainer.


Security

  • Do not commit secrets.
  • Do not include secrets in examples, tests, fixtures, or generated documentation.
  • Prefer IAM roles over long-lived AWS credentials.
  • Keep SES source identities verified before sending production mail.
  • Report vulnerabilities privately to the maintainer contact below.

License

This package is distributed under the Elastic License 2.0.

  • See LICENSE for the full license text.
  • See NOTICE for the relicensing notice.
  • See THIRD_PARTY_LICENSES.txt if it is distributed with the package artifact.

Maintainers / Contact

  • Maintainer: Raman Marozau, [email protected]
  • Documentation and support: docs/ generated via TypeDoc

For security reports, please contact [email protected].