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 functionsSlsLogger: Structured logging in SLS formatType(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¶
SLS logger (recommended)¶
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 logslogger.info(message, params?)- Info-level logslogger.warn(message, params?)- Warning logslogger.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"}
替代方案: 任何包含 log、info、warn 和 error 方法的对象(例如 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 上获取: