跳转至

TypeScript SDK

The TypeScript SDK (@palantir/compute-module) for compute modules enables you to build deployed functions using TypeScript or JavaScript. The SDK provides type-safe function registration with schema validation, structured logging, and utilities for working with Foundry resources.

The TypeScript SDK provides:

  • ComputeModule: Main class for creating and registering functions
  • SlsLogger: Structured logging in SLS format
  • Type (from @sinclair/typebox): Runtime type validation and schema generation
  • Pipeline mode support with resource alias management
  • Source credential retrieval
  • Foundry service API access

Installation

Install the SDK using npm or yarn:

npm install @palantir/compute-module
yarn add @palantir/compute-module

Defining functions

Basic usage

Register functions using vanilla JavaScript:

import { ComputeModule } from "@palantir/compute-module";

new ComputeModule()
  .register("addOne", async ({ value }) => ({ value: value + 1 }))
  .register("stringify", async ({ n }) => "" + n)
  .default(() => ({ error: "Unsupported query name" }));

Schema registration

Use TypeBox ↗ for type-safe function registration with automatic schema inference:

import { ComputeModule, SlsLogger } from "@palantir/compute-module";
import { Type } from "@sinclair/typebox";

const myModule = new ComputeModule({
  logger: new SlsLogger(),
  definitions: {
    addOne: {
      input: Type.Object({
        value: Type.Number(),
      }),
      output: Type.Object({ value: Type.Number() }),
    },
  },
});

myModule.register("addOne", async ({ value }) => ({ value: value + 1 }));

Benefits of schema registration:

  • Automatic type inference for function parameters
  • Compile-time type safety
  • Runtime schema validation
  • Automatic function registration in Foundry

Streaming output

For large result sets, use streaming to send data progressively:

import { ComputeModule } from "@palantir/compute-module";
import { Type } from "@sinclair/typebox";

const computeModule = new ComputeModule({
  definitions: {
    greet: {
      input: Type.Object({ name: Type.String() }),
      output: Type.Array(Type.String()),
    },
  },
});

// Each write must produce valid JSON
computeModule.registerStreaming("greet", async ({ name }, writeable) => {
  writeable.write(JSON.stringify("Hello, "));
  writeable.write(JSON.stringify(name));
  writeable.end();
});

Streaming with complex types:

const User = Type.Object({
  name: Type.String(),
  role: Type.String(),
  active: Type.Boolean(),
});

const computeModule = new ComputeModule({
  definitions: {
    activeUsers: {
      input: Type.Object({ users: Type.Array(User) }),
      output: Type.Array(User),
    },
  },
});

computeModule.registerStreaming("activeUsers", async ({ users }, writeable) => {
  for (const user of users) {
    if (user.active) {
      writeable.write(JSON.stringify(user));
    }
  }
  writeable.end();
});

:::callout{theme="warning"} Important: The output type must be declared as Type.Array(...) for streaming. Each write() call must produce valid JSON. :::

Logging

Use SlsLogger for structured logging in Standard Logging Specification (SLS) format:

import { ComputeModule, SlsLogger } from "@palantir/compute-module";
import { Type } from "@sinclair/typebox";

const logger = new SlsLogger();

const myModule = new ComputeModule({
  logger,
  definitions: {
    addOne: {
      input: Type.Object({ value: Type.Number() }),
      output: Type.Object({ value: Type.Number() }),
    },
  },
});

myModule.register("addOne", async ({ value }) => {
  logger.info("Processing addOne", { input_value: String(value) });
  return { value: value + 1 };
});

Log methods:

  • logger.debug(message, params?) - Debug-level logs
  • logger.info(message, params?) - Info-level logs
  • logger.warn(message, params?) - Warning logs
  • logger.error(message, params?) - Error logs

Custom key-value pairs can be passed as the second argument and will be added to the log entry's parameters.

:::callout{theme="neutral"} Alternative: Any object with log, info, warn, and error methods (for example, console) can be used as a logger. :::

Learn more about debugging and viewing logs.

Pipeline mode

Retrieving resource aliases

In Pipeline mode, access configured inputs and outputs using resource aliases:

import { ComputeModule } from "@palantir/compute-module";

const resourceId = ComputeModule.getResource("myResourceAlias");
const result = await someDataFetcherForId(resourceId);

Environment detection

Retrieve execution environment details:

import { ComputeModule } from "@palantir/compute-module";

const environment = ComputeModule.getEnvironment();

// Pipeline mode
const buildToken = environment.type === "pipelines"
  ? environment.buildToken
  : undefined;

// Functions mode
const thirdPartyAppCredentials = environment.type === "functions"
  ? environment.thirdPartyApplication
  : undefined;

Learn more about execution modes.

Using sources

Retrieving source credentials

Access source credentials for external system authentication:

const myCredential = myModule.getCredential("MySourceApiName", "MyCredential");

Validating sources at startup

Declare and validate sources in the module configuration:

const myModule = new ComputeModule({
  sources: {
    MyApi: {
      credentials: ["MyCredential"]
    },
    AnotherApi: {} // Validates source exists, but not specific credentials
  }
});

// ✅ Passes type checking
myModule.getCredential("MyApi", "MyCredential");

// ❌ Will throw a type error
myModule.getCredential("YourApi", "YourCredential");

// ✅ Any credential name works for sources without declared credentials
myModule.getCredential("AnotherApi", "AnyString");

:::callout{theme="neutral"} Validation: If sources are declared, the module validates them at startup and provides compile-time type safety. Without declaration, no validation occurs. :::

Learn more about configuring sources.

Retrieving Foundry services

Access Foundry service API endpoints:

import { FoundryService } from "@palantir/compute-module";

const streamProxyApi = myModule.getServiceApi(FoundryService.STREAM_PROXY);

This allows calling Foundry endpoints without configuring a source for platform ingress.

Docker configuration

Dockerfile example

FROM node:18-alpine

WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production
COPY src .

# USER is required to be non-root and numeric
USER 5000
CMD ["node", "index.js"]

Learn more about container configuration.

GitHub repository

The TypeScript SDK is open source and available on GitHub:


中文翻译


TypeScript SDK

TypeScript SDK(@palantir/compute-module)为计算模块(compute modules)提供了使用 TypeScript 或 JavaScript 构建部署函数的能力。该 SDK 支持类型安全的函数注册、模式验证、结构化日志记录,以及用于操作 Foundry 资源的实用工具。

TypeScript SDK 提供以下功能:

  • ComputeModule:用于创建和注册函数的主类
  • SlsLogger:以 SLS 格式进行结构化日志记录
  • Type(来自 @sinclair/typebox):运行时类型验证和模式生成
  • 支持管道模式(Pipeline mode)及资源别名管理
  • 源凭据(source credential)检索
  • Foundry 服务 API 访问

安装

使用 npm 或 yarn 安装 SDK:

npm install @palantir/compute-module
yarn add @palantir/compute-module

定义函数

基本用法

使用原生 JavaScript 注册函数:

import { ComputeModule } from "@palantir/compute-module";

new ComputeModule()
  .register("addOne", async ({ value }) => ({ value: value + 1 }))
  .register("stringify", async ({ n }) => "" + n)
  .default(() => ({ error: "Unsupported query name" }));

模式注册

使用 TypeBox ↗ 实现类型安全的函数注册,并自动推断模式:

import { ComputeModule, SlsLogger } from "@palantir/compute-module";
import { Type } from "@sinclair/typebox";

const myModule = new ComputeModule({
  logger: new SlsLogger(),
  definitions: {
    addOne: {
      input: Type.Object({
        value: Type.Number(),
      }),
      output: Type.Object({ value: Type.Number() }),
    },
  },
});

myModule.register("addOne", async ({ value }) => ({ value: value + 1 }));

模式注册的优势:

  • 函数参数自动类型推断
  • 编译时类型安全
  • 运行时模式验证
  • 自动在 Foundry 中注册函数

流式输出

对于大型结果集,可使用流式输出逐步发送数据:

import { ComputeModule } from "@palantir/compute-module";
import { Type } from "@sinclair/typebox";

const computeModule = new ComputeModule({
  definitions: {
    greet: {
      input: Type.Object({ name: Type.String() }),
      output: Type.Array(Type.String()),
    },
  },
});

// 每次 write 必须生成有效的 JSON
computeModule.registerStreaming("greet", async ({ name }, writeable) => {
  writeable.write(JSON.stringify("Hello, "));
  writeable.write(JSON.stringify(name));
  writeable.end();
});

复杂类型的流式输出:

const User = Type.Object({
  name: Type.String(),
  role: Type.String(),
  active: Type.Boolean(),
});

const computeModule = new ComputeModule({
  definitions: {
    activeUsers: {
      input: Type.Object({ users: Type.Array(User) }),
      output: Type.Array(User),
    },
  },
});

computeModule.registerStreaming("activeUsers", async ({ users }, writeable) => {
  for (const user of users) {
    if (user.active) {
      writeable.write(JSON.stringify(user));
    }
  }
  writeable.end();
});

:::callout{theme="warning"} 重要提示: 流式输出时,输出类型必须声明为 Type.Array(...)。每次 write() 调用必须生成有效的 JSON。 :::

日志记录

SLS 日志记录器(推荐)

使用 SlsLogger 以标准日志规范(SLS)格式进行结构化日志记录:

import { ComputeModule, SlsLogger } from "@palantir/compute-module";
import { Type } from "@sinclair/typebox";

const logger = new SlsLogger();

const myModule = new ComputeModule({
  logger,
  definitions: {
    addOne: {
      input: Type.Object({ value: Type.Number() }),
      output: Type.Object({ value: Type.Number() }),
    },
  },
});

myModule.register("addOne", async ({ value }) => {
  logger.info("Processing addOne", { input_value: String(value) });
  return { value: value + 1 };
});

日志方法:

  • logger.debug(message, params?) - 调试级别日志
  • logger.info(message, params?) - 信息级别日志
  • logger.warn(message, params?) - 警告级别日志
  • logger.error(message, params?) - 错误级别日志

自定义键值对可作为第二个参数传递,并会添加到日志条目的参数中。

:::callout{theme="neutral"} 替代方案: 任何包含 loginfowarnerror 方法的对象(例如 console)均可作为日志记录器使用。 :::

了解更多关于调试和查看日志的信息。

管道模式

检索资源别名

在管道模式(Pipeline mode)下,使用资源别名访问配置的输入和输出:

import { ComputeModule } from "@palantir/compute-module";

const resourceId = ComputeModule.getResource("myResourceAlias");
const result = await someDataFetcherForId(resourceId);

环境检测

检索执行环境详情:

import { ComputeModule } from "@palantir/compute-module";

const environment = ComputeModule.getEnvironment();

// 管道模式
const buildToken = environment.type === "pipelines"
  ? environment.buildToken
  : undefined;

// 函数模式
const thirdPartyAppCredentials = environment.type === "functions"
  ? environment.thirdPartyApplication
  : undefined;

了解更多关于执行模式的信息。

使用源

检索源凭据

访问外部系统认证的源凭据:

const myCredential = myModule.getCredential("MySourceApiName", "MyCredential");

启动时验证源

在模块配置中声明并验证源:

const myModule = new ComputeModule({
  sources: {
    MyApi: {
      credentials: ["MyCredential"]
    },
    AnotherApi: {} // 验证源存在,但不验证特定凭据
  }
});

// ✅ 通过类型检查
myModule.getCredential("MyApi", "MyCredential");

// ❌ 将抛出类型错误
myModule.getCredential("YourApi", "YourCredential");

// ✅ 对于未声明凭据的源,任何凭据名称均可使用
myModule.getCredential("AnotherApi", "AnyString");

:::callout{theme="neutral"} 验证: 如果声明了源,模块将在启动时进行验证,并提供编译时类型安全。未声明则不进行验证。 :::

了解更多关于配置源的信息。

检索 Foundry 服务

访问 Foundry 服务 API 端点:

import { FoundryService } from "@palantir/compute-module";

const streamProxyApi = myModule.getServiceApi(FoundryService.STREAM_PROXY);

这允许在不配置平台入口源的情况下调用 Foundry 端点。

Docker 配置

Dockerfile 示例

FROM node:18-alpine

WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production
COPY src .

# USER 必须为非 root 用户且为数字
USER 5000
CMD ["node", "index.js"]

了解更多关于容器配置的信息。

GitHub 仓库

TypeScript SDK 是开源的,可在 GitHub 上获取: