Skip to content

Releases: aligent/microservice-development-utilities

release/nx-cdk/0.9.0

05 Jun 05:56

Choose a tag to compare

0.9.0 (2026-06-05)

πŸš€ Features

  • appbuilder-util-lib (1ac5c69)

    • Update tsconfig extends to use local tsconfig.json and remove composite option in appbuilder-util-lib.

    nx-cdk

    • Migrate nx-cdk generators from rolldown to vite bundling, add unified vite.config.base.mjs template,
    • Update eslint configs, package dependencies, and service templates.

❀️ Thank You

  • Kai Nguyen

release/appbuilder-util-lib/0.2.1

05 Jun 05:56

Choose a tag to compare

0.2.1 (2026-06-05)

🩹 Fixes

  • appbuilder-util-lib (1ac5c69)

    • Update tsconfig extends to use local tsconfig.json and remove composite option in appbuilder-util-lib.

    nx-cdk

    • Migrate nx-cdk generators from rolldown to vite bundling, add unified vite.config.base.mjs template,
    • Update eslint configs, package dependencies, and service templates.

❀️ Thank You

  • Kai Nguyen

release/nx-openapi/2.1.2

04 Jun 06:36

Choose a tag to compare

2.1.2 (2026-06-04)

🩹 Fixes

  • Add logMiddleware to generated clients and make authMethod required (6bc89c0)

    • Include logMiddleware in the generated client template for request/response logging
    • Make authMethod a required parameter with an interactive prompt instead of defaulting to api-key
    • Update README to document logMiddleware and retryMiddleware in generated clients

❀️ Thank You

  • Kai Nguyen

release/nx-appbuilder/0.4.0

04 Jun 07:16

Choose a tag to compare

0.4.0 (2026-06-04)

πŸš€ Features

  • App generator: swap babel-loader for esbuild-loader (6750346)

    The scaffolded src/actions/webpack-config.cjs now uses esbuild-loader
    (with loader: 'ts' and target: 'node<major>', picked up from the
    workspace's .nvmrc) instead of babel-loader + @babel/preset-env +
    @babel/preset-typescript. The babel.actions.config.js file is no longer
    emitted, and the associated @babel/* / babel-loader dev-dependency pins
    have been removed from the generated app's package.json.

    Existing apps that want to adopt the same setup can:

    1. Replace the babel-loader rule in src/actions/webpack-config.cjs with
      the esbuild-loader block (see the generator template for the canonical
      shape).
    2. Delete babel.actions.config.js.
    3. Drop @babel/preset-env, @babel/preset-typescript and babel-loader
      from their package.json, and add esbuild-loader.

    App generator: backend-UI tsconfig now sets module: Preserve + moduleResolution: Bundler

    When hasAdminUI=true, the generated
    src/commerce-backend-ui-1/web-src/tsconfig.json now includes:

    "module": "Preserve",
    "moduleResolution": "Bundler"

    This lets TypeScript see ESM-style imports the way the webpack/esbuild
    pipeline does, matching what aio's web build expects.

❀️ Thank You

  • Lachlan Turner

release/microservice-util-lib/1.5.0

01 Jun 01:18

Choose a tag to compare

1.5.0 (2026-06-01)

πŸš€ Features

  • Retry middleware: onRetry hook now supports request transformation (6a4de66)

    The onRetry callback can now optionally return a Request to replace the current request before retrying. If it returns void, the original request is used as-is. This merges the observation and transformation concerns into a single hook.

    // Logging only (returns void)
    onRetry: (context) => {
        console.log(`Retrying (attempt ${context.attempt})`);
    },
    
    // Re-sign OAuth 1.0a + logging (returns Request)
    onRetry: async (context) => {
        console.log(`Retrying (attempt ${context.attempt})`);
        return resignOauth10aRequest(context.request, oauthConfig);
    },

    New: resignOauth10aRequest standalone function

    Re-signs a Request with fresh OAuth 1.0a credentials (nonce, timestamp, signature) without requiring openapi-fetch middleware context. Designed for use with the onRetry hook to regenerate signatures on retried requests.

    Internal: extracted signOauth10a core

    The shared OAuth 1.0a signing logic is now in a single signOauth10a helper, used by both generateOauthParams (middleware path) and resignOauth10aRequest (standalone path).

    Tests

    Added test coverage for onRetry request transformation, resignOauth10aRequest, HttpResponseError, and body parser utilities.

❀️ Thank You

  • Kai Nguyen

release/aws-wrappers/0.1.1

29 May 01:32

Choose a tag to compare

0.1.1 (2026-05-29)

🩹 Fixes

  • Fix: dual-publish @aligent/aws-wrappers as CJS + ESM (0d337a7)

    The 0.1.0 release widened the logger option to LoggerInterface to dodge the Powertools dual-package hazard, but that wasn't enough. LoggerInterface.createChild transitively references LogFormatter (a class with #private fields), so ESM consumers still saw TS2322 when passing a Logger instance into a CJS-built wrapper.

    The package is now dual-published. dist/cjs/ and dist/esm/ are emitted from separate tsconfigs and routed via the exports map in package.json, so each consumer resolves a single coherent build of every #private-bearing dependency type.

    Consumer impact:

    • ESM consumers (type: module) now resolve to dist/esm/ via the import condition and can pass a Logger from any Powertools build without TS errors.
    • CJS consumers (type: commonjs) continue to resolve via the require condition, unchanged at runtime.
    • Public API surface is identical β€” same exported class names, same constructor signatures, same method shapes.
    • Consumers who were deep-importing from @aligent/aws-wrappers/src/... (always discouraged) will need to switch to the top-level entry point.

    Internal: relative imports now carry explicit .js extensions (required for ESM under Node16), and aws-xray-sdk-core is imported as a default rather than a named import (the package is CJS-only with no exports map, so named ESM imports fail at runtime via cjs-module-lexer).

❀️ Thank You

  • Todd Hainsworth

release/nx-appbuilder/0.3.0

27 May 00:41

Choose a tag to compare

0.3.0 (2026-05-27)

πŸš€ Features

  • Fix lint hang in generated apps: add prettier and eslint as direct devDependencies at both workspace and app levels (eslint-plugin-prettier requires prettier as a peer dependency). (7e01a6b)
    Switch the generated app's eslint config to use the base preset by default and only opt into the React preset when hasAdminUI is set.
    Move the preset generator's workspace devDependency versions into a Dependabot-tracked template-package/package.json mirroring the existing app pattern, and factor the loadTemplatePackage + pickVersions helpers into a shared module.

❀️ Thank You

  • Lachlan Turner

release/nx-appbuilder/0.2.1

25 May 04:33

Choose a tag to compare

0.2.1 (2026-05-25)

🩹 Fixes

  • Add missing webpack-config.cjs to generated appbuilder apps (c4f6d2e)

❀️ Thank You

  • Lachlan Turner

release/aws-wrappers/0.1.0

25 May 06:13

Choose a tag to compare

0.1.0 (2026-05-25)

πŸš€ Features

  • New: @aligent/aws-wrappers package (c509819)

    Opinionated AWS SDK wrappers that bundle Powertools Logger and X-Ray tracing by default. Seven service classes: S3Service, DynamoDBService, SecretsManagerService, StepFunctionsService, SSMService, SQSService, SNSService.

    Constructor convention

    Every wrapper takes the same options bag: new XService({ logger?, client? }). The default logger is new Logger() so POWERTOOLS_SERVICE_NAME flows through from the environment (the Powertools idiom). The default client wraps the SDK constructor in captureAWSv3Client for X-Ray tracing; supplying a client opts out of that.

    The logger option is typed as LoggerInterface (from @aws-lambda-powertools/logger/types), not the concrete Logger class. Powertools ships dual ESM/CJS builds and TypeScript treats the two Logger classes as nominally distinct (each carries its own #private field), which would otherwise produce TS2322 when ESM consumers passed a Logger instance into a CJS-built wrapper. LoggerInterface is a structural type alias with no private brand, so a Logger from either build satisfies the wrapper's parameter type β€” and any structurally-compatible logger is accepted, giving consumers more flexibility.

    SNSService and SQSService additionally accept truncate?: boolean (see "Opt-in payload truncation" below).

    Logging convention

    Every public method emits exactly one logger.info('<verb> <noun>', { input }) line at the start of the call. The shape of input is level-driven:

    • At DEBUG (e.g. POWERTOOLS_LOG_LEVEL=DEBUG), the full SDK input is logged. Operators have explicitly opted into seeing payloads, secret material, and PII.
    • At any other level, only a per-method allowlist is logged.

    Implemented via the filterFieldsForLogLevel(logger, input, safeFields) helper. Per-method allowlists are defined as module-level <METHOD>_SAFE_FIELDS constants typed as ReadonlyArray<keyof CommandInput>.

    Redactions applied at INFO level:

    • S3 β€” putObject / putJsonObject omit Body. Batch methods (deleteObjects, emptyBucket) log { bucket, keyCount } only.
    • SNS β€” publish omits Message, Subject, MessageAttributes, PhoneNumber. publishBatch logs { TopicArn, entryCount }.
    • SQS β€” sendMessage omits MessageBody, MessageAttributes. Batch methods log { QueueUrl, entryCount }.
    • DynamoDB β€” getItem / deleteItem omit Key. putItem omits Item. updateItem omits Key and ExpressionAttributeValues. query / scan / paginateItems / paginateScan omit ExpressionAttributeValues. batchGet / batchWrite log { tables: Object.keys(RequestItems) }.
    • SecretsManager β€” write methods omit SecretString / SecretBinary.
    • SSM β€” putParameter omits Value.
    • SFN β€” startExecution omits the execution input (often carries PII).

    Batch methods and DynamoDB batchGet / batchWrite keep a bespoke inline DEBUG conditional rather than using the helper, because their safe shape includes a computed field (entryCount, keyCount, tables) that isn't a key on the SDK input.

    Pagination and chunking

    • Auto-pagination (flat array): S3.listObjects / getAllObjects / emptyBucket, SSM.getParametersByPath, SFN.listExecutions.
    • Generator pagination (yields items): DynamoDB.paginateItems / paginateScan β€” bounded memory for potentially unbounded result sets.
    • Auto-chunking: S3.deleteObjects / emptyBucket (1000-key cap), SQS.sendMessageBatch / deleteMessageBatch (10-entry cap), SNS.publishBatch (10-entry cap).
    • DynamoDB.batchWrite retries UnprocessedItems with jittered exponential backoff (5 attempts, 200ms base), throwing if items remain after the final attempt.

    Opt-in payload truncation

    SNS.publish and SQS.sendMessage expose a truncate knob at both the constructor and per-call layer for callers who prefer data loss over SDK-level failure on oversize (e.g. notification flows where dropped detail beats a thrown error). Default is off β€” fail-fast at the SDK is the right behaviour for most code paths.

    When enabled, truncateUtf8 byte-bounds Message / MessageBody to 256 KB and truncateCodepoints char-bounds SNS Subject to 100. Both helpers respect codepoint boundaries (no half-emoji, no malformed UTF-8). Each truncating call emits a single logger.warn listing the modified fields.

    DynamoDB specifics

    • Backed by DynamoDBDocumentClient. The base DynamoDBClient is wrapped with captureAWSv3Client before being passed to DynamoDBDocumentClient.from(...) so X-Ray captures every command.
    • marshallOptions: { removeUndefinedValues: true }.
    • Key-bearing methods (getItem, updateItem, deleteItem) take two generics β€” K extends Record<string, unknown> for the partition/sort key shape, R extends Record<string, unknown> for the return type. Input is threaded through WithTypedKey<TInput, K> so the SDK input is preserved with the typed Key substituted.
    • Methods that return command output (query, scan) preserve the full output and type only the data-bearing field (Items?: T[]).
    • paginateItems / paginateScan yield items typed as T.
    • batchGet is intentionally non-generic β€” multi-table Responses cannot be soundly described by a single T.
    • All generics default to Record<string, unknown> so callers can omit them.

    S3 specifics

    • Input shapes are intentionally tight (Bucket / Key / Body only) via Required<Pick<...>> projections. Callers needing SDK-level options (server-side encryption, tagging, version IDs) drop down to S3Client directly.
    • getPresignedUrl({ Bucket, Key, action, expiresIn? }) signs GET / PUT URLs via @aws-sdk/s3-request-presigner. GET URLs include ResponseContentDisposition: 'attachment'; expiresIn defaults to 3600 seconds.

    SSM specifics

    • getParameters takes an alias-to-path record so callers destructure with the names they want locally:
      const { username, password } = await ssm.getParameters({
          username: '/myapp/db/username',
          password: '/myapp/db/password',
      });
    • WithDecryption: true is baked into all read operations.
    • putParameter / deleteParameter exposed for runtime writes. Class-level TSDoc steers callers to IaC (CDK / Terraform) for parameter lifecycle; runtime writes are reserved for values that genuinely mutate within the application.

    SecretsManager specifics

    • getSecret / getJsonSecret throw on missing SecretString (e.g. binary-only secrets) and on invalid JSON respectively.
    • Write methods (createSecret, updateSecret, putSecretValue, deleteSecret) exposed for rotation flows and dynamically-issued credentials. Class-level TSDoc steers callers to IaC for the common-case secret lifecycle.

    Documentation

    Package-level CLAUDE.md captures the locked-in conventions, design rationale, the question checklists for adding a new service or modifying an existing one, the per-method redaction policy, the truncation pattern, and the aws-sdk-client-mock paginator-with-real-client test pattern.

    Infra

    • Adds nx-appbuilder to the package list in repo root README.md and the package table in repo root CLAUDE.md (pre-existing gap surfaced during the docs sweep).

❀️ Thank You

  • Todd Hainsworth

release/nx-cdk/0.8.1

18 May 00:46

Choose a tag to compare

0.8.1 (2026-05-18)

🩹 Fixes

    • Add stack-name to deployment workflow templates (d20b8cf)
    • Set default CDK environment (account/region) in ApplicationStage

❀️ Thank You

  • Kai Nguyen