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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@zenginehq/handler-cli

v1.1.2

Published

A CLI used to generate and manage individual handlers within a NextZen handler workspace.

Downloads

750

Readme

@zenginehq-handler-cli

A CLI used to generate and manage individual handlers within a NextZen handler workspace.

The CLI provides TypeScript based development tools for building and managing custom handler function code.

These tools allow for multiple handlers to be authored in one central workspace repository. They allow for code formatting, linting, testing, and building.

Builds are bundled into a single ESM module file and zipped for uploading and publishing. The uploaded module zip file is scanned for viruses before being allowed to be invoked.

First Install @zenginehq/handler-workspace-cli and create the handler workspace. Then install the handler-workspace CLI via npm:

npm install -g @zenginehq/handler-workspace-cli@latest

You can check the version installed with:

handler --version

You can display it's usage with:

handler --help

which would yield:

handler <command>

Commands:
  handler generate <handler>  Generate a new handler           [aliases: g, gen]
  handler list [handler]      List handlers                     [aliases: l, ls]
  handler format <handler>    Format handler                        [aliases: f]
  handler lint <handler>      Lint handler
  handler test <handler>      Test handler
  handler build <handler>     Build handler                         [aliases: b]
  handler upload <handler>    Upload handler                    [aliases: u, up]
  handler publish <handler>   Publish handler                  [aliases: p, pub]
  handler verify <handler>    Verify handler
  handler logs <handler>      Logs for handler

Options:
  --help     Show help                                                 [boolean]
  --version  Show version                                              [boolean]

So to initialize a new handler within the workspace, use:

cd ~/parent_folder/handlers
handler generate example1

which would fetch an access token, validate the organization, check that handler doesn't already exist:

➜ fetch token
✔ fetched token
➜ query organization
✔ queried organization
➜ query handler
✔ queried handler
✔ Handler name example1

and then prompt for handler type:

? Enter handler type …
❯ http
  event
  decision
  score

then handler description:

? Enter handler description › Your Handler

then handler runtime:

? Enter handler runtime …
❯ nodejs20.x
  nodejs18.x

then handler entry name:

? Enter handler entry name › handler.handler

which would generate the following:

~/parent_folder/handlers/http/example1

README.md
eslint.config.mjs
handler.json
jest.config.js
rollup.config.ts
src/
tsconfig.json

and:

~/parent_folder/handlers/http/example1/src

env.ts
index.test.ts
index.ts

and:

~/parent_folder/handlers/http/example1/src/index.ts

//@ts-expect-error: will be generated by rollup virtual plugin
import env from './env.ts'

export const handler = async (event) => {
	const { method, url, headers, body } = event

	const { SLUG, PORTAL_URL, CLIENT_ID, CLIENT_SECRET } = env
	const mask = (s: string, mask = '*') => s.replace(/./g, mask)

	console.log(
		`handler: http: ${JSON.stringify(
			{ SLUG, PORTAL_URL, CLIENT_ID: mask(CLIENT_ID), CLIENT_SECRET: mask(CLIENT_SECRET) },
			null,
			2
		)}`
	)

	console.log(`handler: http: ${JSON.stringify({ method, url, headers, body }, null, 2)}`)

	return {
		statusCode: 200,
		headers: {
			'Content-Type': 'application/json'
		},
		body: {
			statusCode: 200,
			message: 'Ok...'
		}
	}
}

You can edit your handlers main index file using your choice of editor or IDE. It is recommended that you add additional typescript files in your handlers src folder as the complexity of your handlers code increases. Simply import those files into you handlers main index file and the build tools will bundle them into the final ESM module file.

Formatting

You can run Prettier formatting on your handler's source files with:

handler format example1

Which does:

➜ format http/example1
prettier --config .prettierrc.json --ignore-path .prettierignore http/example1 --write
http/example1/handler.json 17ms
http/example1/jest.config.js 4ms (unchanged)
http/example1/rollup.config.ts 28ms (unchanged)
http/example1/src/env.ts 1ms (unchanged)
http/example1/src/index.test.ts 2ms (unchanged)
http/example1/src/index.ts 4ms (unchanged)
http/example1/tsconfig.json 1ms (unchanged)
✔ formated http/example1

You can change the formating rules for your workspace by editing ~/parent_folder/handlers/.prettierrc.json

Linting

You can run ESLint linting on your handler's source files with:

handler lint example1

Which does:

➜ lint http/example1
eslint --config http/example1/eslint.config.mjs http/example1
✔ linted http/example1

You can change the linting rules for your workspace by editing ~/parent_folder/handlers/eslint.config.mjs

Testing

You can run Jest testing of your handler with:

handler test example1

Which does:

➜ test http/example1
jest --config http/example1/jest.config.js --color
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
Test Suites: 1 skipped, 0 of 1 total
Tests:       1 skipped, 1 total
Snapshots:   0 total
Time:        0.639 s
Ran all test suites.
✔ tested http/example1

You can add and extend Jest tests to increase coverage of your handlers functionally.

Building

You can build and bundle your handlers with:

handler build example1

Which does:

➜ format http/example1
prettier --config .prettierrc.json --ignore-path .prettierignore http/example1 --write
http/example1/handler.json 17ms (unchanged)
http/example1/jest.config.js 4ms (unchanged)
http/example1/rollup.config.ts 28ms (unchanged)
http/example1/src/env.ts 1ms (unchanged)
http/example1/src/index.test.ts 1ms (unchanged)
http/example1/src/index.ts 5ms (unchanged)
http/example1/tsconfig.json 1ms (unchanged)
✔ formated http/example1
➜ lint http/example1
eslint --config http/example1/eslint.config.mjs http/example1
✔ linted http/example1
➜ test http/example1
jest --config http/example1/jest.config.js --color
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
Test Suites: 1 skipped, 0 of 1 total
Tests:       1 skipped, 1 total
Snapshots:   0 total
Time:        0.624 s
Ran all test suites.
✔ tested http/example1
➜ build http/example1
rimraf dist/http/example1
rollup --config http/example1/rollup.config.ts --configPlugin typescript={tsconfig:'http/example1/tsconfig.json'}

http/example1/src/index.ts → dist/http/example1/handler.mjs...
created dist/http/example1/handler.mjs in 575ms
zip -mq handler.zip handler.mjs
✔ built http/example1
build: output: 'dist/http/example1/handler.zip'

The build output would reside in: ~/parent_folder/handlers/http/example1/handler.zip

Note that execution rules will ensure chaining of dependent execution steps. This means executing a build will first format, then lint, then test, and finally build your handler. If any dependent step fails, the execution terminates. This helps improve your handlers module integrity.

Uploading

You can upload your handlers built module zip file with:

handler upload example1

Which does:

➜ format http/example1
prettier --config .prettierrc.json --ignore-path .prettierignore http/example1 --write
http/example1/handler.json 17ms (unchanged)
http/example1/jest.config.js 4ms (unchanged)
http/example1/rollup.config.ts 27ms (unchanged)
http/example1/src/env.ts 1ms (unchanged)
http/example1/src/index.test.ts 2ms (unchanged)
http/example1/src/index.ts 4ms (unchanged)
http/example1/tsconfig.json 1ms (unchanged)
✔ formated http/example1
➜ lint http/example1
eslint --config http/example1/eslint.config.mjs http/example1
✔ linted http/example1
➜ test http/example1
jest --config http/example1/jest.config.js --color
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
Test Suites: 1 skipped, 0 of 1 total
Tests:       1 skipped, 1 total
Snapshots:   0 total
Time:        0.578 s
Ran all test suites.
✔ tested http/example1
➜ build http/example1
rimraf dist/http/example1
rollup --config http/example1/rollup.config.ts --configPlugin typescript={tsconfig:'http/example1/tsconfig.json'}

http/example1/src/index.ts → dist/http/example1/handler.mjs...
created dist/http/example1/handler.mjs in 548ms
zip -mq handler.zip handler.mjs
✔ built http/example1
➜ fetch token
✔ fetched token
➜ query handler
✔ queried handler
➜ upload handler file
✔ uploaded handler file
upload: organizationId:
upload: handlerId:
upload: fileId: '1CGhApVaNfZJPsNq9ozojY'

Publishing

You can publish your handlers built module zip file with:

handler publish example1

Which does:

➜ format http/example1
prettier --config .prettierrc.json --ignore-path .prettierignore http/example1 --write
http/example1/handler.json 16ms
http/example1/jest.config.js 3ms (unchanged)
http/example1/rollup.config.ts 27ms (unchanged)
http/example1/src/env.ts 0ms (unchanged)
http/example1/src/index.test.ts 1ms (unchanged)
http/example1/src/index.ts 5ms (unchanged)
http/example1/tsconfig.json 1ms (unchanged)
✔ formated http/example1
➜ lint http/example1
eslint --config http/example1/eslint.config.mjs http/example1
✔ linted http/example1
➜ test http/example1
jest --config http/example1/jest.config.js --color
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
Test Suites: 1 skipped, 0 of 1 total
Tests:       1 skipped, 1 total
Snapshots:   0 total
Time:        0.552 s
Ran all test suites.
✔ tested http/example1
➜ build http/example1
rimraf dist/http/example1
rollup --config http/example1/rollup.config.ts --configPlugin typescript={tsconfig:'http/example1/tsconfig.json'}

http/example1/src/index.ts → dist/http/example1/handler.mjs...
created dist/http/example1/handler.mjs in 554ms
zip -mq handler.zip handler.mjs
✔ built http/example1
➜ fetch token
✔ fetched token
➜ query handler
✔ queried handler
➜ upload handler file
✔ uploaded handler file
➜ query handler file
✔ queried handler file
➜ publish handler
✔ published handler
publish: enabled: true
publish: status: 'published'

Verifying

You can verify your published handler handler function with:

handler verify example1

Which does:

➜ fetch token
✔ fetched token
➜ query handler
✔ queried handler
➜ verify handler
✔ verified handler
verify: request: {
  method: 'POST',
  url: 'https://helping-hands.portals.zenginehq.dev:4201/handler/example1',
  headers: { 'user-agent': 'agent', 'content-type': 'application/json' },
  body: { foo: 1, bar: 2 }
}
verify: response: {
  statusCode: 200,
  headers: { 'Content-Type': 'application/json' },
  body: { statusCode: 200, message: 'Ok...' }
}

Your published handler will be invoked with a sample request. Your handlers response will then be validated for type compliance. You may wish to include console.log() statements within your handlers code to help in debugging. These can be removed or commented out later.

Viewing Logs

You can view recent logs from invocation of your handler function with:

handler logs example1

This will display up to 10 log entries from within the last sixty seconds:

➜ fetch token
✔ fetched token
➜ query handler
✔ queried handler
➜ query handler logs
✔ queried handler logs
logs: [
  'INIT_START Runtime Version: nodejs:20.v42\tRuntime Version ARN: arn:aws:lambda:us-east-1::runtime:af2737389420ddcdbcdc4db3585842c334ad2482127c15295905f54a62feefc6\n',
  'START RequestId: 16f1ca8a-4ea5-4f10-83ae-19aa5bbe7487 Version: $LATEST\n',
  '2024-10-29T23:20:16.126Z\t16f1ca8a-4ea5-4f10-83ae-19aa5bbe7487\tINFO\thandler: http: {\n' +
    '  "PORTAL_URL": "https://helping-hands.portals.zenginehq.dev:4201",\n' +
    '  "CLIENT_ID": "****************************************************************",\n' +
    '  "CLIENT_SECRET": "****************************************************************"\n' +
    '}\n',
  '2024-10-29T23:20:16.148Z\t16f1ca8a-4ea5-4f10-83ae-19aa5bbe7487\tINFO\thandler: http: {\n' +
    '  "method": "POST",\n' +
    '  "url": "https://helping-hands.portals.zenginehq.dev:4201/handler/example1",\n' +
    '  "headers": {\n' +
    '    "user-agent": "agent",\n' +
    '    "content-type": "application/json"\n' +
    '  },\n' +
    '  "body": {\n' +
    '    "foo": 1,\n' +
    '    "bar": 2\n' +
    '  }\n' +
    '}\n',
  'END RequestId: 16f1ca8a-4ea5-4f10-83ae-19aa5bbe7487\n',
  'REPORT RequestId: 16f1ca8a-4ea5-4f10-83ae-19aa5bbe7487\tDuration: 40.86 ms\tBilled Duration: 41 ms\tMemory Size: 128 MB\tMax Memory Used: 64 MB\tInit Duration: 133.32 ms\t\n'
]

Log entries will automatically expire after a short duration.