Dagger TypeScript SDK 中的 JSONValueContentsOpts:JSONValue.contents() 格式化选项深度解析

📅 发布时间:2026/9/18 19:25:56
Dagger TypeScript SDK 中的 JSONValueContentsOpts:JSONValue.contents() 格式化选项深度解析
Dagger TypeScript SDK 中的 JSONValueContentsOptsJSONValue.contents() 格式化选项深度解析【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger导读JSONValueContentsOpts是 Dagger TypeScript SDK 中用于调用JSONValue.contents()方法的选项类型别名它通过pretty与indent两个可选属性控制 JSON 值的输出格式。本文以该类型别名为主线结合 Dagger 仓库中 TypeScript SDK 的生成代码client.gen.ts与 Go 侧 GraphQL 引擎的实现jsonvalue.go完整讲解该类型的定义、两个参数的语义与默认值、底层执行链路以及实战用法帮助你精准控制 Dagger 流水线中 JSON 数据的序列化输出。一、类型别名全景JSONValueContentsOpts 的定义JSONValueContentsOpts在 Dagger TypeScript SDK 中是一个对象类型别名其权威定义位于 SDK 的自动生成 API 文件中sdk/typescript/src/api/client.gen.ts#L2226-L2236export type JSONValueContentsOpts { /** * Pretty-print */ pretty?: boolean /** * Optional line prefix */ indent?: string }对应的 API 参考文档位于 docs/versioned_docs/version-0.21/reference/typescript/api/client.gen/type-aliases/JSONValueContentsOpts.md与自动生成代码中的定义完全一致。该类型包含两个可选属性属性类型必填语义原文档描述实际作用pretty?boolean否Pretty-print是否对 JSON 进行美化换行缩进排版indent?string否Optional line prefix美化输出时每一行的缩进前缀行前缀需要注意该类型被描述为“行前缀”line prefix而非单纯的“缩进字符串” —— 因为底层实现中它会被直接作为json.MarshalIndent的第二个参数使用因此理论上可以是任意字符串前缀如--而不限于空白字符这正是“line prefix”这一措辞的来源。二、使用场景contents() 方法与 JSONValue 对象JSONValueContentsOpts只服务于一个方法JSONValue.contents()。在 Dagger 的 TypeScript SDK 中JSONValue是表示“任意 JSON 编码值”的核心对象类型其类声明位于 sdk/typescript/src/api/client.gen.ts#L11179-L11204而JSONValue的值本身在 SDK 中被建模为带标记的字符串类型/** * An arbitrary JSON-encoded value. */ export type JSON string { __JSON: never }即JSON是一个“结构类型 名义标记”的字符串运行时仍是普通字符串但在类型层面与普通string区分防止误用。contents()方法将JSONValue对象序列化为 JSON 字符串返回其实现位于 sdk/typescript/src/api/client.gen.ts#L11288-L11298/** * Return the value encoded as json * param opts.pretty Pretty-print * param opts.indent Optional line prefix */ contents async (opts?: JSONValueContentsOpts): PromiseJSON { if (this._contents) { return this._contents } const ctx this._ctx.select(contents, { ...opts }) const response: AwaitedJSON await ctx.execute() return response }从实现可以看出三点关键行为惰性缓存若客户端已持有_contents值则直接返回避免重复查询否则将opts展开后通过this._ctx.select(contents, { ...opts })构建 GraphQL 查询节点并执行。参数透传pretty与indent会作为 GraphQL 参数一并下发给 Dagger 引擎。返回值返回PromiseJSON即满足JSON标记类型的字符串。JSONValue对象本身可以通过多种途径获得例如顶层查询构造器json()见 client.gen.ts#L14294-L14296或者从容器环境变量、文件内容等场景间接取得。三、底层原理pretty 与 indent 在引擎端的真实语义仅仅知道两个参数名是不够的 —— 它们的具体行为由 Dagger Go 引擎中的 GraphQL schema 实现决定。定义位于 core/schema/jsonvalue.go#L24-L28schema 注册与 core/schema/jsonvalue.go#L65-L87具体实现dagql.Func(contents, s.contents).Doc(Return the value encoded as json).Args( dagql.Arg(pretty).Doc(Pretty-print), dagql.Arg(indent).Doc(Optional line prefix), ),func (s jsonvalueSchema) contents(ctx context.Context, obj *core.JSONValue, args struct { Pretty dagql.Optional[dagql.Boolean] default:false Indent dagql.Optional[dagql.String] default: }) (core.JSON, error) { if args.Pretty.Valid args.Pretty.Value.Bool() { var v any if err : json.Unmarshal(obj.Data, v); err ! nil { return nil, err } indent : if args.Indent.Valid { indent args.Indent.Value.String() } formatted, err : json.MarshalIndent(v, , indent) if err ! nil { return nil, err } return core.JSON(formatted), nil } return core.JSON(obj.Data), nil }由此可以确认引擎端的真实行为prettyfalse默认值直接返回原始 JSON 数据obj.Data不做任何格式化。此时indent参数被完全忽略。prettytrue先将内部 JSON 数据json.Unmarshal到any中再通过json.MarshalIndent(v, , indent)重新序列化生成带换行与缩进的美化输出。indent的默认值为两个空格default: 即便 TypeScript 侧不传indent只要prettytrue引擎也会以两个空格作为缩进。显式传入indent时会覆盖默认值并且它可以是非空白字符串作为行前缀直接插入每行开头。校验兜底若内部数据无法被json.Unmarshal解析contents会返回错误保证输出始终是合法 JSON。此外withContents()方法jsonvalue.go#L89-L98在写入时会先执行json.Unmarshal校验非法的 JSON 内容会在进入系统前被拒绝从而保证JSONValue内部数据始终可被格式化。四、实战用法从压缩输出到美化输出4.1 默认输出紧凑 JSON不传任何选项时contents()返回紧凑compact的 JSON 字符串适合日志单行输出、机器解析或减小体积import { connect } from dagger.io/dagger connect(async (client) { // 初始化一个 JSON 值 const jv client.json() // 写入内容并读取未格式化 const raw await jv .withContents({name:dagger,versions:{go:0.21}}) .contents() console.log(raw) // {name:dagger,versions:{go:0.21}} })4.2 美化输出pretty 默认缩进设置pretty: true引擎会自动以两个空格缩进并逐行展开const pretty await jv .withContents({name:dagger,versions:{go:0.21}}) .contents({ pretty: true }) console.log(pretty) // { // name: dagger, // versions: { // go: 0.21 // } // }4.3 自定义行前缀indent传入自定义indent可以控制每行的缩进或前缀风格。例如使用四个空格缩进或使用非空白前缀// 四空格缩进 const fourSpaces await jv .withContents({a:1}) .contents({ pretty: true, indent: }) // 自定义行前缀每行以 // 开头类似注释风格输出 const commented await jv .withContents({a:1}) .contents({ pretty: true, indent: // })注意indent只在pretty: true时生效仅传indent而pretty缺省为false时输出仍是紧凑 JSON不会产生任何缩进效果。4.4 组合使用把格式化后的 JSON 写入文件借助 Dagger 的Container.withNewFile可以轻松将格式化结果落盘供后续步骤消费import { connect } from dagger.io/dagger connect(async (client) { const src client.host().directory(.) const jv client.json().withContents({module:dagger,sdk:typescript}) const formatted await jv.contents({ pretty: true, indent: }) const ctr client .container() .from(alpine:latest) .withNewFile(/out/config.json, formatted) // 将产物导出到宿主目录 await ctr.file(/out/config.json).export(./config.json) })五、扩展阅读JSONValueContentsOpts 所属的 JSONValue API 生态JSONValueContentsOpts仅是JSONValue对象众多能力中的一环。从 client.gen.ts#L11179 起JSONValue类还提供以下成员可与contents()搭配形成完整的 JSON 读写链路方法作用引擎端 schemajsonvalue.goid()返回该 JSONValue 的唯一标识字段idasBoolean()/asInteger()/asString()将 JSON 解码为布尔 / 整数 / 字符串asBoolean/asInteger/asStringasArray()将 JSON 解码为数组返回JSONValue[]asArrayfield(path)/fields()按路径查找字段 / 列出对象字段field/fieldsnewBoolean()/newInteger()/newString()从基本类型构造 JSON 值newBoolean/newInteger/newStringwithContents(contents)从 JSON 字符串构造新值写入前校验withContentswithField(path, value)在指定路径设置字段并返回新值withFieldwith(fn)以当前值为参数执行回调链式便捷方法—这些方法在引擎端统一注册于 core/schema/jsonvalue.go#L24-L54并通过 dagql 框架对外暴露为 GraphQL 字段。TypeScript 侧对应的完整 API 参考可查看 docs/current_docs/reference/api/json-value.mdx该文档同样由 GraphQL schema 自动生成注明“Content comes from docs-graphql/schema.graphqls; edit the schema”。六、注意事项与限制类型别名不可实例化JSONValueContentsOpts是object类型的 type alias只能作为contents()的参数类型使用不需要也不能new它。indent不是严格的“缩进”校验引擎直接把它交给json.MarshalIndent因此非空白前缀也能生效但输出仍保持合法 JSON 结构。缓存语义contents()在客户端存在已解析值时直接返回缓存见 client.gen.ts#L11289-L11291同一JSONValue上调用withContents会构造新对象避免缓存污染。版本差异本文基于仓库当前 SDK 生成代码与 GraphQL schema对应 version-0.21 的 API 参考文档。SDK 的client.gen.ts为自动生成文件如需修改参数行为应在上游 GraphQL schemacore/schema/jsonvalue.go的 dagql 注册处进行而非直接编辑生成文件。总结JSONValueContentsOpts虽然只是一个仅有pretty与indent两个可选属性的类型别名但它串联起了 Dagger TypeScript SDK 与 Go 引擎两端的 JSON 格式化链路SDK 负责类型约束与 GraphQL 参数透传引擎负责json.MarshalIndent的实际美化与默认值兜底。理解这层关系后你便可以在 Dagger 流水线中自如地控制 JSON 输出的紧凑与美观、缩进风格乃至自定义行前缀让结构化数据的展示完全贴合你的使用场景。【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考