Skip to content

Update dependency @crossplane-org/function-sdk-typescript to ^0.7.0 - #22

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/crossplane-org-function-sdk-typescript-0.x
Open

Update dependency @crossplane-org/function-sdk-typescript to ^0.7.0#22
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/crossplane-org-function-sdk-typescript-0.x

Conversation

@renovate

@renovate renovate Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@crossplane-org/function-sdk-typescript ^0.5.0^0.7.0 age confidence

Release Notes

crossplane/function-sdk-typescript (@​crossplane-org/function-sdk-typescript)

v0.7.0

Compare Source

v0.7.0 - serve(), a one-call function entrypoint

A function should not have to assemble a gRPC server to run. This release adds
serve(), which turns a function's entrypoint into a single call, and
ComposeFunction, which lets composition logic be a plain function rather than a
class implementing an interface.

This is a minor release: it only adds API. Nothing was removed or changed, so
FunctionHandler implementations and hand-built servers keep working exactly as
they did in v0.6.0.

Installation

npm install @crossplane-org/function-sdk-typescript@0.7.0

What's Changed

serve() — the whole entrypoint

Previously every function shipped its own copy of the same main.ts: parse flags
(usually with commander, a dependency the SDK does not provide), build a pino
logger, construct a FunctionRunner, create a server, start it, and wire up
signal handlers. Roughly sixty lines, identical in every function, and a place for
functions to drift apart on flag names and shutdown behaviour.

That is now one call:

#!/usr/bin/env node

import { serve } from '@crossplane-org/function-sdk-typescript';
import { compose } from './function.js';

serve(compose);

serve() parses the standard flags, builds a logger from --debug, starts the
gRPC server, and shuts down cleanly on SIGINT and SIGTERM. It accepts either a
ComposeFunction or a FunctionHandler, so existing handlers can be passed
directly.

Every function served this way accepts the same flags, with --help:

Usage: main.js [flags]

A Crossplane composition function.

Flags:
      --address <value>               Address to listen for gRPC connections. Default 0.0.0.0:9443.
  -d, --debug                         Emit debug logs.
      --insecure                      Run without mTLS credentials.
      --tls-server-certs-dir <value>  Directory holding tls.key, tls.crt and ca.crt. Default /tls/server.
  -h, --help                          Show this help.

Flags come from node:util's parseArgs, so there is no new runtime dependency.
An unrecognised flag prints the message and a pointer to --help, then exits 2,
rather than surfacing as a stack trace through Node's internals.

serve() takes an options object for the cases the defaults do not cover — name
for the program name in --help, argv, logger, and serverOptions overrides
applied on top of the parsed flags. These mostly matter in tests.

ComposeFunction — composition logic as a plain function

A function can now be written as a function:

import { Resource, type ComposeFunction } from '@crossplane-org/function-sdk-typescript';

export const compose: ComposeFunction = (req, rsp, logger) => {
  rsp.desired.resources['config'] = Resource.fromJSON({
    resource: {
      apiVersion: 'v1',
      kind: 'ConfigMap',
      metadata: { name: 'my-config' },
      data: { key: 'value' },
    },
  });
  return rsp;
};

The response is handed in already initialised from the request, so there is no
call to to() to forget. Its type, ComposeResponse, is a RunFunctionResponse
whose desired is guaranteed present — rsp.desired.resources[name] needs no
non-null assertion, even though the protobuf schema marks desired optional.
Returning the response is required by the signature, so forgetting is a compile
error rather than an empty response at runtime.

FunctionHandler is unchanged and still the right choice when a function needs
the full interface. fromCompose() adapts a ComposeFunction to it.

One thing worth knowing: for every function after the first in a pipeline, the
request already carries desired state, and rsp.desired is then the same object
as req.desired, not a copy. This is inherited from to() and is usually
harmless — a function reads observed state and writes desired state — but do not
rely on req.desired still holding what the previous function left once you have
started writing.

New exports
  • serve(fn, opts?)
  • fromCompose(compose)
  • parseArgs(argv) — the standard flags, for functions that add flags of their own
  • helpText(name)
  • DEFAULT_ADDRESS, DEFAULT_TLS_SERVER_CERTS_DIR
  • Types: ComposeFunction, ComposeResponse, ServeOptions
Documentation

README.md and USAGE.md now lead with serve() and ComposeFunction. The
previous hand-rolled entrypoint — which used commander, never an SDK dependency
— has moved to a "Building the Server Yourself" section for functions that need
to own their process.

Breaking Changes

None.

Upgrading

npm install @crossplane-org/function-sdk-typescript@0.7.0 is enough; nothing
else has to change. To adopt serve(), replace the body of your main.ts with
serve(myHandler) — it accepts your existing FunctionHandler — and drop
commander from your dependencies if it was only there for flag parsing.

Full Changelog: crossplane/function-sdk-typescript@v0.6.0...v0.7.0

v0.6.0

Compare Source

v0.6.0 - Dependency Modernization and fromModel() Fix

A maintenance release. There are no new SDK features; this release picks up two dependency majors, fixes fromModel() so it works with generated model classes, and hardens protobuf decoding.

This is a minor rather than a patch release because kubernetes-models 4 → 5 moves @kubernetes-models/base from 5 to 6, which is visible to consumers.

Installation

npm install @crossplane-org/function-sdk-typescript@0.6.0

What's Changed

fromModel() accepts any model with a toJSON() method

fromModel() previously constrained its argument's toJSON() to return Record<string, unknown>:

// Before (v0.5.0)
export function fromModel<T extends Record<string, unknown>>(
  obj: { toJSON: () => T },
  connectionDetails?: ConnectionDetails,
  ready?: Ready
): Resource

@kubernetes-models/base declares toJSON(): unknown, so model classes generated from CRDs — including the crossplane-models package the Crossplane CLI generates for your project's schemas — did not satisfy that constraint and failed to type-check. The signature is now widened:

// After (v0.6.0)
export function fromModel(
  obj: { toJSON: () => unknown },
  connectionDetails?: ConnectionDetails,
  ready?: Ready
): Resource

Passing a generated model now works directly:

import { fromModel, setDesiredComposedResources } from '@crossplane-org/function-sdk-typescript';
import { ConfigMap } from 'kubernetes-models/v1/ConfigMap';

const cm = new ConfigMap({
  metadata: { name: 'app-config', namespace: 'default' },
  data: { region: 'us-west-2' },
});

setDesiredComposedResources(rsp, { config: fromModel(cm) });

See the Breaking Changes section below if you were passing an explicit type argument.

kubernetes-models 5 (@kubernetes-models/base 6)

The kubernetes-models dependency moves from ^4.5.1 to ^5.0.0, which brings @kubernetes-models/base from 5 to 6. This is the change that makes this release a minor rather than a patch.

It also aligns the SDK with what the Crossplane CLI's generated crossplane-models package pins, so projects using both end up with a single copy of @kubernetes-models/base rather than one hoisted and one nested.

If you pass typed models to fromModel(), bump your own kubernetes-models dependency to ^5.0.0.

Protobuf decoding hardening

The generated protobuf code was regenerated with ts-proto 2.12.1, which adds two robustness improvements to the decode path used for every RunFunctionRequest:

  • Recursion depth limit — nested message decoding now throws protobuf decode recursion limit exceeded beyond 100 levels, instead of exhausting the stack.
  • Prototype-pollution hardening — map entries are constructed with Object.defineProperty rather than direct property assignment.

These are upstream generator changes; no SDK API is affected.

ts-deepmerge 8

ts-deepmerge moves from ^7.0.3 to ^8.0.0. Its return types are tighter, which let three internal casts be removed. The merge semantics of update() are unchanged — arrays are still replaced by default, and { mergeArrays: true } still concatenates.

Build toolchain: TypeScript 7

The SDK now builds with TypeScript 7, the native compiler. This is build-time only and requires no change from consumers.

Because TypeScript 7 no longer exposes the JavaScript compiler API that typescript-eslint's type-aware rules depend on, the repository installs both compilers side by side: TypeScript 7 as @typescript/native (providing tsc), and TypeScript 6 aliased as typescript (providing tsc6). This arrangement is temporary and will be removed once typescript-eslint supports TypeScript 7.

Verified against the published package: @crossplane-org/function-sdk-typescript@0.6.0 type-checks and runs in a clean project on TypeScript 5.9.3 with skipLibCheck: false.

Other maintenance
  • ESLint 10 and @eslint/js 10, with rethrown errors now preserving the original via { cause }
  • flatted updated to address a vulnerability
  • GitHub Actions updated and pinned to digests

Requirements

  • Node.js 18+
  • TypeScript 5.9+ (unchanged)
  • kubernetes-models ^5.0.0, if you pass typed models to fromModel()
  • Compatible with Crossplane Function Runtime API v1
  • Requires Crossplane v2.2+ for capability advertisement, required resources, and required schemas

Breaking Changes

Two narrow ones. Most functions will need no changes at all.

1. fromModel() no longer takes a type parameter.

The generic was removed when the signature was widened. An explicit type argument is now an error:

// No longer compiles: "Expected 0 type arguments, but got 1"
fromModel<MyModelShape>(model);

// Use
fromModel(model);

Calls that relied on inference — which is nearly all of them — are unaffected.

2. kubernetes-models 4 → 5.

If your function passes typed models to fromModel(), update your dependency to ^5.0.0. Staying on 4.x leaves you with two copies of @kubernetes-models/base and can produce type mismatches at the fromModel() boundary.

Migration Guide

  1. Update the SDK:
    npm install @crossplane-org/function-sdk-typescript@^0.6.0
  2. If you use kubernetes-models, update it to ^5.0.0:
    npm install kubernetes-models@^5.0.0
  3. Remove any explicit type arguments from fromModel() calls.

No other changes are required. Your TypeScript version does not need to change.

Documentation

📖 README.md - Complete documentation
📖 USAGE.md - Usage guide

Full Changelog

Full Changelog: crossplane/function-sdk-typescript@v0.5.0...v0.6.0

Pull Requests
  • #​31: release: v0.6.0
  • #​30: update flatted to address vulnerability
  • #​29: build: run TypeScript 7 alongside TypeScript 6
  • #​28: chore(deps): update dependency @​eslint/js to v10
  • #​27: chore(deps): update all non-major dependencies
  • #​26: Accept models whose toJSON() returns unknown in fromModel
  • #​25: fix(deps): update dependency ts-deepmerge to v8
  • #​24: fix(deps): update dependency kubernetes-models to v5
  • #​23: chore(deps): update github actions (major)
  • #​20: chore(deps): update github actions
Commits
  • release: v0.6.0 (ce7c3a6)
  • update flatted to address vuln (9c3b9fe)
  • fix(lint): attach cause to rethrown errors (ad569e7)
  • chore(deps): update dependency @​eslint/js to v10 (8efb047)
  • build: run TypeScript 7 alongside TypeScript 6 (16836f3)
  • chore: regenerate protobuf and drop redundant merge casts (70d4145)
  • chore(deps): update all non-major dependencies (4ec2940)
  • Accept models whose toJSON() returns unknown in fromModel (dcdbfb4)
  • chore(deps): update github actions (29c1a6e)
  • fix(deps): update dependency ts-deepmerge to v8 (bf776fc)
  • fix(deps): update dependency kubernetes-models to v5 (0e5564b)
  • chore(deps): update github actions (f6bfb0d)

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/crossplane-org-function-sdk-typescript-0.x branch from 51954cb to 5494baf Compare August 29, 2026 08:28
@renovate renovate Bot changed the title Update dependency @crossplane-org/function-sdk-typescript to ^0.6.0 Update dependency @crossplane-org/function-sdk-typescript to ^0.7.0 Aug 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants