Clients and tools for building on AWS.
@pureskillgg/awsjs is a shared Node.js library of thin, opinionated wrappers around the AWS SDK for JavaScript v3. It gives every PureSkill.gg Node service one uniform, camelCase interface for S3, DynamoDB, SQS, Lambda, EventBridge, and EventBridge Scheduler — with automatic request-id threading, gzip/JSON helpers, and structured Pino logging baked in.
The package exports six client classes (re-exported through index.js → lib/index.js → lib/clients/index.js). Each class wraps exactly one AWS SDK v3 client and is constructed with a resource binding (a bucket, a tableName/hashKey/rangeKey, a queueUrl, a functionName, an eventBusName, or a scheduler groupName) plus an optional reqId (defaults to a UUID v4), a Pino child logger, and any SDK params.
Every method follows the same shape:
- Build a child logger tagged with
client/class/method/reqIdand the resource binding. - Log
start. - PascalCase the request keys (
keysToPascalCase, via @pureskillgg/phi'srenameKeysWith+change-case) and inject the resource binding. - Send the AWS command.
- camelCase the response (
keysToCamelCase). - Log
end(orerror/failwith the error) and return the normalized data.
The result is a consistent camelCase API, automatic reqId propagation, and uniform structured logs across every AWS call in the platform.
Notable per-client behavior:
S3Client—putObjectJson/getObjectJsonserialize/deserialize JSON, setContentType: application/json, transparently gzip/gunzip whenContentEncodingisgzip(detected byisGzipped, which splits the header on,, trims the first token, and checks it equalsgzip), and stamp areq-idobject Metadata header.getObjectJsonreturns both the raw body buffer and the parsed data.DynamodbDocumentClient— wraps the DynamoDB Document client (get/put/update/delete/query/transactGet/transactWrite) with marshall options (remove undefined, convert class instances to map, no number wrapping). It validates at construction thathashKeyis a non-empty string and thatrangeKey, if present, is a non-empty string, and throwsDynamodbMissingKeyError(err_dynamodb_missing_key) when input is missing the configured keys.get/queryreturn[data, rest]tuples. It also exposes the rawthis.dbclient andthis.tableNameas public escape hatches.LambdaClient—invokeJsonBuffer-encodes a JSON payload (injectingreqId), checks the HTTPStatusCodeis 2xx (elseLambdaStatusCodeError,err_lambda_status_code) and that there is noFunctionError(elseLambdaFunctionError,err_lambda_function_error, carrying the decoded error payload), then decodes the JSON response payload.SqsClient—sendMessageJsonJSON-stringifies the body and attaches areqIdString message attribute (note: the attribute key is literallyreqId, distinct from S3'sreq-idmetadata key).EventbridgeClient—putEventsstampsEventBusNameon each entry, JSON-stringifiesdetail, normalizes thetimefield through @pureskillgg/tau (fromIsoUtc→toIso), drops nil fields, and throwsEventbridgeFailedEntriesError(err_eventbridge_failed_entries) ifFailedEntryCountis nonzero.SchedulerClient—getSchedule/createSchedule/updateSchedule/deleteScheduledo CRUD on EventBridge Scheduler schedules with deep PascalCase/camelCase conversion of the nestedTargetobject. The schedule-groupgroupNamedefaults todefault.
A small createCache helper (lib/cache.js) memoizes the underlying AWS SDK client instance per logical name so the raw client is reused across class instances within a process.
This is foundational infrastructure code, not a pipeline stage. It is published to npm as @pureskillgg/awsjs and imported by the platform's Node.js services (lambdas, handlers, web/API backends) wherever they need to talk to AWS — for example it is consumed by csgo-profile and other services.
It sits underneath the CS2 coaching pipeline: any Node service that reads/writes match, demo, replay/csds, or assessment data in S3/DynamoDB, sends SQS messages, invokes lambdas, emits EventBridge events, or manages EventBridge schedules does so through these clients. The library itself produces no domain data and owns no cloud resources; the consuming service supplies the concrete bucket / table / queue / function identity at construction time.
It consumes only the AWS SDK and sibling PSGG libraries: @pureskillgg/phi (FP / key-rename utilities), @pureskillgg/tau (ISO time), and @pureskillgg/mlabs-logger (logging).
This library ships no deployed AWS infrastructure — there is no serverless.yml, no Terraform, no CDK, and no SAM template. It never hardcodes a table, queue, bucket, or function name; the consuming service passes the resource binding into the constructor. The real exports are:
All client errors carry a stable code string for instanceof-free matching:
err_dynamodb_missing_key—DynamodbMissingKeyErrorerr_lambda_status_code—LambdaStatusCodeErrorerr_lambda_function_error—LambdaFunctionErrorerr_eventbridge_failed_entries—EventbridgeFailedEntriesError
This is a pure published npm library — it owns no CloudWatch log groups, DLQs, Step Functions, Sentry projects, or EventBridge buses. There is nothing in this repo to look up in CloudWatch.
- Where its logs actually appear: in the consuming service's logs. The library logs through @pureskillgg/mlabs-logger (Pino), created with
createLogger()and child-scoped with{ client, class, method, reqId, queueUrl/bucket/table, messageId }. So to find a given AWS call, look at the log group of whatever lambda/service imported the client (e.g.csgo-*-prod-*), filtered byreqId. - Normal logs:
startandendevents atinfo; payloads atdebug. - Error logs: each client method wraps the SDK call in
try/catch, logslog.error({ err }, 'fail'), and re-throws. The error then propagates to the caller, where the caller's own infrastructure (Lambda DLQ, Step Functions state, Sentry) is where it ultimately lands. - Verbosity: standard Pino
LOG_LEVEL/levelenv behavior applies in the consuming process. - CI logs for this repo: build/test output lives in this repo's GitHub Actions, not in AWS.
- Client caching, key-case, and error conventions — the shared-client memoization footgun in
createCache, the PascalCase-in / camelCase-out request lifecycle, and the per-client error-code contract.
Add this as a dependency to your project using npm with
$ npm install @pureskillgg/awsjs
$ git clone https://github.com/pureskillgg/awsjs.git
$ cd awsjs
$ nvm install
$ npm install
Run the command below in a separate terminal window:
$ npm run test:watch
Primary development tasks are defined under scripts in package.json
and available via npm run.
View them with
$ npm run
The source code is hosted on GitHub. Clone the project with
$ git clone git@github.com:pureskillgg/awsjs.git
You will need Node.js with npm and a Node.js debugging client.
Be sure that all commands run under the correct Node version, e.g., if using nvm, install the correct version with
$ nvm install
Set the active version for each shell session with
$ nvm use
Install the development dependencies with
$ npm install
Use the npm version command to release a new version.
This will push a new git tag which will trigger a GitHub action.
Publishing may be triggered using on the web using a workflow_dispatch on GitHub Actions.
GitHub Actions should already be configured: this section is for reference only.
The following repository secrets must be set on GitHub Actions:
NPM_TOKEN: npm token for publishing packages.
These must be set manually.
The docs, version, and format GitHub actions require a user with write access to the repository including access to read and write packages. Set these additional secrets to enable the action:
GH_USER: The GitHub user's username.GH_TOKEN: A personal access token for the user.GIT_USER_NAME: The GitHub user's real name.GIT_USER_EMAIL: The GitHub user's email.GPG_PRIVATE_KEY: The GitHub user's GPG private key.GPG_PASSPHRASE: The GitHub user's GPG passphrase.
Please submit and comment on bug reports and feature requests.
To submit a patch:
- Fork it (https://github.com/pureskillgg/awsjs/fork).
- Create your feature branch (
git checkout -b my-new-feature). - Make changes.
- Commit your changes (
git commit -am 'Add some feature'). - Push to the branch (
git push origin my-new-feature). - Create a new Pull Request.
This npm package is licensed under the MIT license.
This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright holder or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
